wmcalc: Add version 0.4 to repository.
[dockapps.git] / wmcalc / wmcalc.c
blob19990a6e1ebdefa6f76116f8ccadb22da9d2a6e6
1 /****************************************************************
2 * File: wmcalc.c
3 * Version: 0.3
4 * Date: January 17, 2001
5 * Author: Edward H. Flora <ehflora@access1.net>
7 * This file is a part of the wmcalc application. As such, this
8 * file is licensed under the GNU General Public License, version 2.
9 * A copy of this license may be found in the file COPYING that should
10 * have been distributed with this file. If not, please refer to
11 * http://www.gnu.org/copyleft/gpl.html for details.
13 ****************************************************************
14 Description:
15 This file contains the main program code for the wmcalc
16 application. Wmcalc is a dockapp designed for the WindowMaker or
17 Afterstep window managers (although it should run well in most
18 others.) wmcalc is a four-function (and more) calculator that
19 has a small enough footprint that you may leave it open on your
20 desktop at all times, for convenient use.
23 Change History:
24 Date Modification
25 01/17/01 Updated to use XLookupString
26 12/10/00 Revised includes, extracting X libs to wmcalc_x.h
27 11/09/00 Added "locked" memory capabilities
28 11/08/00 Added Code to Support Keyboard / focus
29 10/29/00 Implemented memory use, configuration files, and a
30 quickstart button for a larger calculator. Also
31 abstracted some of the macros, global vars, function
32 prototypes, etc out to independent header files, to
33 eliminate some dependency issues between source files.
34 02/10/00 Added keyboard event code, without success
35 12/21/99 Original product release, version 0.1
36 11/26/99 Original file creation
38 ****************************************************************/
40 #include "wmcalc_x.h"
41 #include <XKBlib.h>
42 #include <stdio.h>
43 #include <math.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <ctype.h>
47 #include "wmcalc_c.h"
48 #include "wmcalc_err.h"
49 #include "wmcalc_t.h"
50 #include "wmcalc_g.h"
51 #include "wmcalc_f.h"
53 #include "backdrop.xpm" // background graphic
54 #include "calcbuttons.xpm" // graphic of buttons
55 #include "charmap.xpm" // pixmap of characters
56 #include "mask.xbm"
58 /* Global Variables */
59 /* Ok, so I didn't get them all extracted. Should look into this
60 further */
61 int N = 1; /* Button number pressed to goto app # */
62 int border = 0;
63 int Verbose = 0; /* Debug flag */
64 int mmouse = 1; /* flag to enable middle mouse (hold
65 over from wmbutton */
66 int button_pressed = -1; /* button to be drawn pressed */
67 char PlusMinusFlag = '+'; /* flag for sign of number in display */
68 char OpFlag = ' '; /* Operation requested */
69 int ExpFlag = 0; /* Flag if in scientific notation */
70 int DecFlag = 0; /* Flag if a decimal is in display */
71 int ImgFlag = 0; /* Flag if a number is imaginary */
72 int StrCnt = 0;
73 double RegisterA = 0.0; /* Main working register, displayed */
74 double RegisterB = 0.0; /* Second register to add to, etc */
75 char DispString[DISPSIZE+1]; /* Pointer to string of display */
76 ButtonArea button_region[NUM_BUTTONS]; /* Array of buttons */
78 char *app_name = "wmcalc"; /* Name of app, for window management */
80 /****************************************************************
81 * Function: main
82 ****************************************************************
83 Description:
84 This is the main Program control function for wmcalc. It
85 contains all the X11 windows function calls, as well as other
86 general operations.
88 Change History:
89 Date Modification
90 01/17/01 Updated to use XLookupString to get KeySym
91 11/09/00 Added Events for focus and keyboard work.
92 11/01/00 File Header Added
93 21/09/01 Added global configfile by Gordon Fraser
94 ****************************************************************/
95 int main( int argc, char **argv ) {
96 XEvent report;
97 XGCValues xgcValues;
98 XTextProperty app_name_atom;
99 int err_code = OKAY;
100 int dummy = 0;
101 int i;
102 char Geometry_str[64] = "64x64+0+0";
103 char Display_str[64] = "";
104 int KeywithMask = NO_BUTTON;
105 KeySym ksym;
106 XComposeStatus compose;
107 char buffer[20];
108 int bufsize = 20;
109 int chcnt = 0;
112 strcpy(configfile, getenv("HOME")); // Added to wmbutton by Casey Harkin, 3/6/99
113 strcat(configfile, CONFFILENAME); // Fixed Bug - didn't look in home directory
114 // but startup directory
115 strcat(tempfile, CONFTEMPFILE); // Setup name for temp file
117 /* Clear the Calculator Display */
118 for(i=0; i<11; i++) DispString[i] = ' ';
119 DispString[11] = '\0';
121 /* Parse Command Line Arguments */
122 for ( i=1; i < argc; i++ ) {
123 if ( *argv[i] == '-' ) {
124 switch ( *(argv[i]+1) ) {
125 case 'v': // Turn on Verbose (debugging) Mode
126 Verbose = 1;
127 break;
128 case 'g': // Set Geometry Options
129 if ( ++i >= argc ) show_usage();
130 sscanf(argv[i], "%s", Geometry_str);
131 if ( Verbose ) printf("Geometry is: %s\n", Geometry_str);
132 break;
133 case 'd': // Set display
134 if ( ++i >= argc ) show_usage();
135 sscanf(argv[i], "%s", Display_str);
136 if ( Verbose ) printf("Display is: %s\n", Display_str);
137 break;
138 case 'h': // Show Help Message
139 show_usage();
140 break;
141 case 'f': // use config file <filename>
142 if ( ++i >= argc ) show_usage();
143 sscanf(argv[i], "%s", configfile);
144 if ( Verbose ) printf("Using Config File: %s\n", configfile);
145 break;
146 default: // other, unknown, parameters
147 show_usage();
148 break;
151 } /* End of loop to process command line options */
153 /* Open display on requested X server */
154 if ( (display = XOpenDisplay(Display_str)) == NULL ) {
155 error_handler(ERR_X_DISPLAY, Display_str);
158 screen = DefaultScreen(display);
159 rootwin = RootWindow(display,screen);
160 depth = DefaultDepth(display, screen);
162 bg_pixel = WhitePixel(display, screen );
163 fg_pixel = BlackPixel(display, screen );
165 xsizehints.flags = USSize | USPosition;
166 xsizehints.width = APP_WIDTH;
167 xsizehints.height = APP_HEIGHT;
169 /* Parse Geometry string and fill in sizehints fields */
170 XWMGeometry(display, screen,
171 Geometry_str,
172 NULL,
173 border,
174 &xsizehints,
175 &xsizehints.x,
176 &xsizehints.y,
177 &xsizehints.width,
178 &xsizehints.height,
179 &dummy);
181 if ( (win = XCreateSimpleWindow(display,
182 rootwin,
183 xsizehints.x,
184 xsizehints.y,
185 xsizehints.width,
186 xsizehints.height,
187 border,
188 fg_pixel, bg_pixel) ) == 0 ) {
189 error_handler(ERR_X_CREATE_WINDOW, NULL);
192 if ( (iconwin = XCreateSimpleWindow(display,
193 win,
194 xsizehints.x,
195 xsizehints.y,
196 xsizehints.width,
197 xsizehints.height,
198 border,
199 fg_pixel, bg_pixel) ) == 0 ) {
200 error_handler(ERR_X_CREATE_WINDOW, NULL);
203 /* Set up shaped windows */
204 /*Gives the appicon a border so you can grab and move it. */
206 if ( ( pixmask = XCreateBitmapFromData(display,
207 win,
208 mask_bits,
209 mask_width,
210 mask_height) ) == 0 ) {
211 error_handler(ERR_X_CREATE_BITMAP, NULL);
214 XShapeCombineMask(display, win, ShapeBounding, 0, 0, pixmask, ShapeSet );
215 XShapeCombineMask(display, iconwin, ShapeBounding, 0, 0, pixmask, ShapeSet);
217 /* Convert in pixmaps from .xpm includes. */
218 getPixmaps();
220 /* Interclient Communication stuff */
221 /* Appicons don't work with out this stuff */
222 xwmhints = XAllocWMHints();
223 xwmhints->flags = WindowGroupHint | IconWindowHint | StateHint;
224 xwmhints->icon_window = iconwin;
225 xwmhints->window_group = win;
226 xwmhints->initial_state = WithdrawnState;
227 XSetWMHints( display, win, xwmhints );
229 xclasshint.res_name = app_name;
230 xclasshint.res_class = app_name;
231 XSetClassHint( display, win, &xclasshint );
233 XSetWMNormalHints( display, win, &xsizehints );
235 /* Tell window manager what the title bar name is. We never see */
236 /* this anyways in the WithdrawnState */
237 if ( XStringListToTextProperty(&app_name, 1, &app_name_atom) == 0 ) {
238 error_handler(ERR_SETUP_WINDOW_NAME, app_name);
240 XSetWMName( display, win, &app_name_atom );
242 /* Create Graphic Context */
243 if (( gc = XCreateGC(display, win,(GCForeground | GCBackground), &xgcValues))
244 == NULL ) {
245 error_handler(ERR_CREATE_GC, NULL);
248 /* XEvent Masks. We want both windows to process X events */
249 XSelectInput(display, win,
250 ExposureMask |
251 ButtonPressMask |
252 ButtonReleaseMask | /* added ButtonReleaseMask *charkins*/
253 PointerMotionMask |
254 FocusChangeMask |
255 LeaveWindowMask |
256 KeyPressMask | /* Try this to get keyboard working */
257 StructureNotifyMask |
258 EnterWindowMask );
259 XSelectInput(display, iconwin,
260 ExposureMask |
261 ButtonPressMask |
262 ButtonReleaseMask | /* added ButtonReleaseMask *charkins*/
263 PointerMotionMask |
264 FocusChangeMask |
265 LeaveWindowMask |
266 KeyPressMask | /* Try this to get keyboard working */
267 StructureNotifyMask |
268 EnterWindowMask );
270 /* Store the 'state' of the application for restarting */
271 XSetCommand( display, win, argv, argc );
273 /* Window won't ever show up until it is mapped.. then drawn after a */
274 /* ConfigureNotify */
275 XMapWindow( display, win );
277 /* Read Configuration File */
278 err_code = read_config();
279 if (err_code) {
280 error_handler(err_code, configfile);
283 /* X Event Loop */
284 while (1) {
285 XNextEvent(display, &report );
286 switch (report.type) {
287 case Expose:
288 if (report.xexpose.count != 0) {
289 break;
291 if ( Verbose ) printf("Event: Expose\n");
292 redraw();
293 break;
294 case ConfigureNotify:
295 if ( Verbose ) printf("Event: ConfigureNotify\n");
296 // redraw();
297 break;
299 case KeyPress:
300 if (Verbose) printf("Event: Key state: 0x%x Key: 0x%x\n",
301 report.xkey.state, report.xkey.keycode);
303 // ksym = XLookupKeysym(&(report.xkey), report.xkey.state);
304 /* KeywithMask - this allows Left, middle, and right button functions
305 to be implemented via keyboard */
306 chcnt = XLookupString(&(report.xkey), buffer, bufsize, &ksym, &compose);
307 if (Verbose) printf("Keysym is: 0x%x\n", (int) ksym);
308 KeywithMask = whichKey(ksym);
309 ExecFunc( KeywithMask );
310 redraw();
311 break;
313 case ButtonPress: /* draw button pressed, don't launch *charkins*/
314 switch (report.xbutton.button) {
315 case Button1:
316 N = whichButton(report.xbutton.x, report.xbutton.y );
317 if ( (N >= 0) && (N <= NUM_BUTTONS) ) {
318 button_pressed = N + LMASK;
319 // redraw();
321 if ( Verbose )
322 printf("Button 1:x=%d y=%d N=%d\n",
323 report.xbutton.x, report.xbutton.y, N+LMASK);
324 break;
325 case Button2:
326 if (mmouse) {
327 N = whichButton(report.xbutton.x, report.xbutton.y );
328 if ( (N >= 0) && (N <= NUM_BUTTONS) ) {
329 button_pressed = N + MMASK;
330 // redraw();
332 if ( Verbose )
333 printf("Button 2:x=%d y=%d N=%d\n",
334 report.xbutton.x, report.xbutton.y, N+MMASK);
336 break;
337 case Button3:
338 N = whichButton(report.xbutton.x, report.xbutton.y );
339 if ( (N >= 0) && (N <= NUM_BUTTONS) ) {
340 button_pressed = N + RMASK;
341 // redraw();
343 if ( Verbose )
344 printf("Button 3:x=%d y=%d N=%d\n",
345 report.xbutton.x, report.xbutton.y, N+RMASK);
346 break;
348 break;
349 case ButtonRelease: /* If still over button, it was a real button press */
350 switch (report.xbutton.button) {
351 case Button1:
352 N = whichButton(report.xbutton.x, report.xbutton.y );
353 if ( (N >= 0) && (N <= NUM_BUTTONS) && (N == button_pressed - LMASK))
354 ExecFunc(N + LMASK);
355 button_pressed=-1;
356 redraw();
357 if ( Verbose )
358 printf("Button 1:x=%d y=%d N=%d\n",
359 report.xbutton.x, report.xbutton.y, N+LMASK);
360 break;
361 case Button2:
362 if (mmouse) {
363 N = whichButton(report.xbutton.x, report.xbutton.y );
364 if ( (N >= 0) && (N <= NUM_BUTTONS) && (N == button_pressed - MMASK))
365 ExecFunc( N + MMASK);
366 button_pressed=-1;
367 redraw();
368 if ( Verbose )
369 printf("Button 2:x=%d y=%d N=%d\n",
370 report.xbutton.x, report.xbutton.y, N+MMASK);
372 break;
373 case Button3:
374 N = whichButton(report.xbutton.x, report.xbutton.y );
375 if ( (N >= 0) && (N <= NUM_BUTTONS) && (N == button_pressed - RMASK))
376 ExecFunc( N + RMASK);
377 button_pressed=-1;
378 redraw();
379 if ( Verbose )
380 printf("Button 3:x=%d y=%d N=%d\n",
381 report.xbutton.x, report.xbutton.y, N+RMASK);
382 break;
384 break;
385 case DestroyNotify:
386 if ( Verbose ) printf("Requested Program Quit.\n");
387 XFreeGC(display, gc);
388 XDestroyWindow(display,win);
389 XDestroyWindow(display,iconwin);
390 XCloseDisplay(display);
391 exit(OKAY);
392 break;
393 case EnterNotify:
394 case LeaveNotify:
395 XSetInputFocus(display, PointerRoot, RevertToParent, CurrentTime);
396 if (Verbose) printf("Focus Change\n");
397 break;
400 return (OKAY);
401 } /***** End of main program ***********************************/
403 /****************************************************************
404 * Function: redraw
405 ****************************************************************
406 Description:
407 This function maintains the appearance of the application
408 by copying the "visible" pixmap to the two windows (the withdrawn
409 main window, and the icon window which is the main windows's icon
410 image).
412 Change History:
413 Date Modification
414 11/1/00 Function Header updated
415 ****************************************************************/
416 void redraw() {
418 XCopyArea(display, template.pixmap, visible.pixmap, gc, 0, 0,
419 template.attributes.width, template.attributes.height, 0, 0 );
421 defineButtonRegions();
423 /* Copy button to icon */
424 XCopyArea(display, buttons.pixmap, visible.pixmap, gc,
425 1, 1, 53, 40, 6, 20);
427 flush_expose( win );
428 XCopyArea(display, visible.pixmap, win, gc, 0, 0,
429 visible.attributes.width, visible.attributes.height, 0, 0 );
430 flush_expose( iconwin );
431 XCopyArea(display, visible.pixmap, iconwin, gc, 0, 0,
432 visible.attributes.width, visible.attributes.height, 0, 0 );
433 // if ( Verbose ) printf("In Redraw()\n");
434 displaystr();
435 } /***** End of function redraw() ********************************/
437 /****************************************************************
438 * Function: whichButton
439 ****************************************************************
440 Description:
441 Return the button at the x,y coordinates. The button need not
442 be visible ( drawn ). Return -1 if no button match.
444 Change History:
445 Date Modification
446 11/1/00 Function Header Updated
447 ****************************************************************/
448 int whichButton( int x, int y ) {
449 int index;
451 for ( index=0; index < NUM_BUTTONS; index++ ) {
452 if ( (x >= button_region[index].x) && (x <= button_region[index].i) &&
453 (y >= button_region[index].y) && (y <= button_region[index].j) ) {
454 return(index);
457 return(NO_BUTTON);
458 } /***** End of function whichButton() **************************/
460 /****************************************************************
461 * Function: whichKey
462 ****************************************************************
463 Description:
464 This function decodes the keycode passed in and converts this to
465 a function number to execute. This is not simply the Button number,
466 but also contains the LMASK, MMASK, or RMASK to pass into ExecFunc to
467 handle expanded functions.
469 Change History:
470 Date Modification
471 01/17/01 Updated to take a KeySym, rather than a KeyCode
472 11/09/00 Original Function creation
473 ****************************************************************/
474 int whichKey (KeySym keysym) {
475 extern int Verbose;
476 int func = NO_BUTTON;
478 if (Verbose) printf("KeySym 0x%x received, decoding...\n", (int) keysym);
480 switch(keysym) {
481 case XK_Escape:
482 case XK_space:
483 case XK_KP_Space:
484 func = LMASK + 0;
485 break;
486 case XK_Delete:
487 func = MMASK + 0;
488 break;
489 case XK_BackSpace:
490 func = RMASK + 0;
491 break;
492 case XK_Return:
493 case XK_KP_Equal:
494 case XK_KP_Enter:
495 case XK_equal:
496 func = LMASK + 19;
497 break;
498 case XK_KP_0:
499 case XK_0:
500 func = LMASK + 17;
501 break;
502 case XK_KP_1:
503 case XK_1:
504 func = LMASK + 12;
505 break;
506 case XK_KP_2:
507 case XK_2:
508 func = LMASK + 13;
509 break;
510 case XK_KP_3:
511 case XK_3:
512 func = LMASK + 14;
513 break;
514 case XK_KP_4:
515 case XK_4:
516 func = LMASK + 7;
517 break;
518 case XK_KP_5:
519 case XK_5:
520 func = LMASK + 8;
521 break;
522 case XK_KP_6:
523 case XK_6:
524 func = LMASK + 9;
525 break;
526 case XK_KP_7:
527 case XK_7:
528 func = LMASK + 2;
529 break;
530 case XK_KP_8:
531 case XK_8:
532 func = LMASK + 3;
533 break;
534 case XK_KP_9:
535 case XK_9:
536 func = LMASK + 4;
537 break;
538 case XK_KP_Decimal:
539 case XK_period:
540 func = LMASK + 18;
541 break;
542 case XK_KP_Divide:
543 case XK_slash:
544 func = LMASK + 5;
545 break;
546 case XK_KP_Subtract:
547 case XK_minus:
548 func = LMASK + 15;
549 break;
550 case XK_KP_Multiply:
551 case XK_asterisk:
552 func = LMASK + 10;
553 break;
554 case XK_KP_Add:
555 case XK_plus:
556 func = LMASK + 20;
557 break;
558 case XK_R:
559 case XK_r:
560 func = LMASK + 1;
561 break;
562 case XK_asciicircum:
563 func = LMASK + 6;
564 break;
565 case XK_C:
566 case XK_c:
567 func = LMASK + 11;
568 break;
569 case XK_N:
570 case XK_n:
571 func = LMASK + 16;
572 break;
573 case XK_F1:
574 func = MMASK + 12;
575 break;
576 case XK_F2:
577 func = MMASK + 13;
578 break;
579 case XK_F3:
580 func = MMASK + 14;
581 break;
582 case XK_F4:
583 func = MMASK + 7;
584 break;
585 case XK_F5:
586 func = MMASK + 8;
587 break;
588 case XK_F6:
589 func = MMASK + 9;
590 break;
591 case XK_F7:
592 func = MMASK + 2;
593 break;
594 case XK_F8:
595 func = MMASK + 3;
596 break;
597 case XK_F9:
598 func = MMASK + 4;
599 break;
600 case XK_F10:
601 func = MMASK + 17;
602 break;
603 default:
604 if (Verbose) printf("Unknown Keysym, ignoring.\n");
605 func = NO_BUTTON;
606 break;
608 return(func);
609 } /***** End of function whichKey() ****************************/
611 /****************************************************************
612 * Function: getPixmaps
613 ****************************************************************
614 Description:
615 Load XPM data into X Pixmaps.
617 * Pixmap 'template' contains the untouched window backdrop image.
618 * Pixmap 'visible' is the template pixmap with buttons drawn on it.
619 -- what is seen by the user.
620 * Pixmap 'buttons' holds the images for individual buttons that are
621 later copied onto Pixmap visible.
622 * Pixmap 'charmap' holds the character map for the characters in
623 the display.
625 Change History:
626 Date Modification
627 11/1/00 Function Header Updated
628 ****************************************************************/
629 void getPixmaps() {
630 template.attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
631 visible.attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
632 buttons.attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
633 charmap.attributes.valuemask |= (XpmReturnPixels | XpmReturnExtensions);
635 /* Template Pixmap. Never Drawn To. */
636 if ( XpmCreatePixmapFromData( display, rootwin, backdrop_xpm,
637 &template.pixmap, &template.mask,
638 &template.attributes) != XpmSuccess ) {
639 error_handler(ERR_CREATE_PIXMAP, "template");
642 /* Visible Pixmap. Copied from template Pixmap and then drawn to. */
643 if ( XpmCreatePixmapFromData( display, rootwin, backdrop_xpm,
644 &visible.pixmap, &visible.mask,
645 &visible.attributes) != XpmSuccess ) {
646 error_handler(ERR_CREATE_PIXMAP, "visible");
649 /* Button Pixmap. */
650 if ( XpmCreatePixmapFromData( display, rootwin, calcbuttons_xpm,
651 &buttons.pixmap, &buttons.mask,
652 &buttons.attributes) != XpmSuccess ) {
653 error_handler(ERR_CREATE_PIXMAP, "buttons");
656 /* Character Map Pixmap. */
657 if ( XpmCreatePixmapFromData( display, rootwin, charmap_xpm,
658 &charmap.pixmap, &charmap.mask,
659 &charmap.attributes) != XpmSuccess ) {
660 error_handler(ERR_CREATE_PIXMAP, "charmap");
662 } /***** End of function getPixmaps() *****************************/
664 /****************************************************************
665 * Function: flush_expose
666 ****************************************************************
667 Description:
668 This function is a hold-over from previous programs (wmcp).
669 The use of this function is not well understood.
671 Change History:
672 Date Modification
673 11/1/00 Function header updated.
674 ****************************************************************/
675 int flush_expose(Window w) {
676 XEvent dummy;
677 int i=0;
679 while (XCheckTypedWindowEvent(display, w, Expose, &dummy)) i++;
680 return(i);
681 } /***** End of function flush_expose() *************************/
683 /****************************************************************
684 * Function: defineButtonRegion
685 ****************************************************************
686 Description:
687 This function defines the start and end x and y coordinates for
688 the various buttons used in wmcalc.
690 There should be a better way to do this, as right now, changing
691 the pixmap calcbuttons.xpm may require the modification of these
692 magic numbers.
694 Change History:
695 Date Modification
696 11/1/00 Function header updated
697 ****************************************************************/
698 void defineButtonRegions(void) {
699 int ndx = 0; /* button index */
701 button_region[0].x = 1; // Define display region button
702 button_region[0].i = 62;
703 button_region[0].y = 6;
704 button_region[0].j = 17;
706 for (ndx = 1; ndx <= 5; ndx++) { // Define y coord's for top row
707 button_region[ndx].y = 20;
708 button_region[ndx].j = 29;
710 for (ndx = 6; ndx <= 10; ndx++) { // Define y coord's for 2nd row
711 button_region[ndx].y = 30;
712 button_region[ndx].j = 39;
714 for (ndx = 11; ndx <= 15; ndx++) { // Define y coord's for 3rd row
715 button_region[ndx].y = 40;
716 button_region[ndx].j = 49;
718 for (ndx = 16; ndx <= 20; ndx++) { // Define y coord's for bottom row
719 button_region[ndx].y = 50;
720 button_region[ndx].j = 59;
722 for (ndx = 1; ndx <= 16; ndx+=5) { // Define x coord's for Left column
723 button_region[ndx].x = 5;
724 button_region[ndx].i = 16;
726 for (ndx = 2; ndx <= 17; ndx+=5) { // Define x coord's for 2nd Left column
727 button_region[ndx].x = 17;
728 button_region[ndx].i = 26;
730 for (ndx = 3; ndx <= 18; ndx+=5) { // Define x coord's for middle column
731 button_region[ndx].x = 27;
732 button_region[ndx].i = 36;
734 for (ndx = 4; ndx <= 19; ndx+=5) { // Define x coord's for 2nd right column
735 button_region[ndx].x = 37;
736 button_region[ndx].i = 46;
738 for (ndx = 5; ndx <= 20; ndx+=5) { // Define x coord's for 2nd right column
739 button_region[ndx].x = 47;
740 button_region[ndx].i = 57;
742 } /***** End of function defineButtonRgions() *************************/
744 /****************************************************************
745 * Function: displaychar
746 ****************************************************************
747 Description:
748 This function displays individual characters to the "display".
749 This function should only be called from displaystr().
751 Change History:
752 Date Modification
753 11/09/00 Added "Locked" character and capabilities
754 11/01/00 Function header updated
755 10/30/00 Updated to include the memory indicators as well.
756 ****************************************************************/
757 void displaychar(char ch, int location) {
758 ButtonArea dispchar;
759 int locatx, locaty;
761 dispchar = getboundaries(ch); /* Get the region of the charmap
762 containing the character to
763 display */
765 locaty = 6;
766 locatx = 2 + location * 6;
768 /* If the character is a memory display character, use the memory
769 location display region. Valid Characters are:
770 '_' - No data in Memory Location
771 '=' - Value in Memory Location, Not Locked
772 '#' - Constant in Memory Location, Locked
774 if ((ch == '=') || (ch == '_') || ch == '#') {
775 locaty = 15;
778 XCopyArea(display, charmap.pixmap, win, gc,
779 dispchar.x, dispchar.y,
780 dispchar.i-dispchar.x, dispchar.j-dispchar.y,
781 locatx, locaty);
782 XCopyArea(display, charmap.pixmap, iconwin, gc,
783 dispchar.x, dispchar.y,
784 dispchar.i-dispchar.x, dispchar.j-dispchar.y,
785 locatx, locaty);
787 } /***** End of Function displaychar() **************************/
789 /****************************************************************
790 * Function: displaystr
791 ****************************************************************
792 Description:
794 Change History:
795 Date Modification
796 11/09/00 Added Capabilities for "Locked" memories
797 11/01/00 Function header updated
798 10/30/00 Added memory location indicators
799 ****************************************************************/
800 void displaystr(void) {
801 extern char DispString[];
802 extern int MemLock[];
803 extern double MemArray[];
804 extern int Verbose;
805 int i;
807 if (Verbose) printf("Displaystr %s\n", DispString);
809 /* Update the alphanumeric display */
810 for (i = 0; i < DISPSIZE; i++)
811 displaychar(DispString[i], i);
813 /* Update the memory location indicators */
814 for (i = 0; i < NUM_MEM_CELLS; i++) {
815 if (MemArray[i] == 0.0)
816 displaychar('_', i); /* Value NOT stored here */
817 else if (MemLock[i] == 0)
818 displaychar('=', i); /* Value IS stored here */
819 else
820 displaychar('#', i); /* Constant IS stored here */
824 } /***** End of function displaystr() ***************************/
826 /****************************************************************
827 * Function: show_usage
828 ****************************************************************
829 Description:
830 This function prints a brief usage message to stdout,
831 and exits.
833 Change History:
834 Date Modification
835 11/01/00 Function header updated
836 ****************************************************************/
837 void show_usage(void) {
839 printf("\n");
840 printf(" %s: Ver %d Rel %d\n",app_name, VER, REL);
841 printf("\n");
842 printf("usage: %s [-g geometry] [-d display] [-f <filename>] [-v] [-h] \n",
843 app_name);
844 printf("\n");
845 printf("-g <geometry> Window Geometry - ie: 64x64+10+10\n");
846 printf("-d <display> Display - ie: 127.0.0.1:0.0\n");
847 printf("-f <filename> Name of Config file - ie: /home/user/.wmcalc\n");
848 printf("-v Verbose Mode. \n");
849 printf("-h Help. This message.\n");
850 printf("\n");
851 exit(OKAY);
852 } /***** End of function show_usage() ***************************/
854 /****************************************************************
855 * Function: error_handler
856 ****************************************************************
857 Description:
858 This function will handle all fatal error conditions that exist.
859 Error condition codes are kept in wmcalc_err.h
861 Change History:
862 Date Modification
863 11/1/00 Function created
864 ****************************************************************/
865 void error_handler (int err_code, char *err_string) {
866 extern char tempfile[];
868 if (err_code == OKAY) {
869 /* This case should never happen.
870 If it does, somebody screwed up (probably me),
871 but don't kill the program!! */
872 return;
874 else {
875 fprintf(stderr, "Error Code %d: ", err_code);
876 switch (err_code) {
877 case ERR_FILE_NOT_FOUND:
878 fprintf(stderr, "Could not open file %s\n",configfile);
879 break;
880 case ERR_TMP_FILE_FAILED:
881 fprintf(stderr, "Could not open temporary file %s\n", tempfile);
882 break;
883 case ERR_X_CREATE_WINDOW:
884 fprintf(stderr, "Could not create simple window\n");
885 break;
886 case ERR_X_CREATE_BITMAP:
887 fprintf(stderr, "Could not create bitmap from data\n");
888 break;
889 case ERR_SETUP_WINDOW_NAME:
890 fprintf(stderr, "Could not setup window name %s\n", err_string);
891 break;
892 case ERR_CREATE_GC:
893 fprintf(stderr, "XCreateGC\n");
894 break;
895 case ERR_X_DISPLAY:
896 fprintf(stderr, "Could not open display on %s\n", err_string);
897 break;
898 case ERR_CREATE_PIXMAP:
899 fprintf(stderr, "Can't Create %s Pixmap\n", err_string);
900 break;
901 /* case : */
902 /* break; */
903 default:
904 fprintf(stderr, "Unknown Error\n");
905 break;
908 exit(err_code);
909 } /***** End of Function error_handler **************************/