1 /****************************************************************************
2 **
3 *W xcmds.c XGAP Source Frank Celler
4 **
5 **
6 *Y Copyright 1995-1997, Lehrstuhl D fuer Mathematik, RWTH Aachen, Germany
7 *Y Copyright 1997, Frank Celler, Huerth, Germany
8 */
9 #include "utils.h" /* utility functions */
10
11 #include "popdial.h" /* popup dialogs */
12 #include "gapgraph.h" /* gap graphic sheet */
13 #include "gaptext.h" /* gap text sheet */
14 #include "xgap.h"
15 #include "pty.h"
16 #include "selfile.h"
17
18 #include "xcmds.h"
19
20 /****************************************************************************
21 **
22
23 *F * * * * * * * * * * * * * local variables * * * * * * * * * * * * * * *
24 */
25
26
27 /****************************************************************************
28 **
29
30 *V DialogOkCancel . . . . . . . . . . . . . . . . . Cancel/OK popup dialog
31 */
32 static TypePopupDialog DialogOkCancel;
33
34
35 /****************************************************************************
36 **
37 *V GapWindows . . . . . . . . . . . . . . . . . . . list of all gap windows
38 */
39 static TypeList GapWindows;
40
41
42 /****************************************************************************
43 **
44 *V HugeFont . . . . . . . . . . . . . . . . . . . huge font for text output
45 */
46 static XFontStruct * HugeFont;
47
48
49 /****************************************************************************
50 **
51 *V LargeFont . . . . . . . . . . . . . . . . . . large font for text output
52 */
53 static XFontStruct * LargeFont;
54
55
56 /****************************************************************************
57 **
58 *V NormalFont . . . . . . . . . . . . . . . . . normal font for text output
59 */
60 XFontStruct * NormalFont;
61
62
63 /****************************************************************************
64 **
65 *V PopupMenus . . . . . . . . . . . . . . . . . . . list of all popup menus
66 */
67 static TypeList PopupMenus;
68
69
70 /****************************************************************************
71 **
72 *V RunCursor . . . . . . . . . . . . cursor used when GAP is accepting input
73 */
74 static Cursor RunCursor;
75
76
77 /****************************************************************************
78 **
79 *V SleepCursor . . . . . . . . . cursor used when GAP isn't accepting input
80 */
81 static Cursor SleepCursor;
82
83
84 /****************************************************************************
85 **
86 *V SmallFont . . . . . . . . . . . . . . . . . . small font for text output
87 */
88 static XFontStruct * SmallFont;
89
90
91 /****************************************************************************
92 **
93 *V TextSelectors . . . . . . . . . . . . . . . . list of all text selectors
94 */
95 static TypeList TextSelectors;
96
97
98 /****************************************************************************
99 **
100 *V TinyFont . . . . . . . . . . . . . . . . . . . tiny font for text output
101 */
102 static XFontStruct * TinyFont;
103
104
105 /****************************************************************************
106 **
107
108 *F * * * * * * * * * * * * communication with GAP * * * * * * * * * * * * *
109 */
110
111
112 /****************************************************************************
113 **
114
115 *F AnswerGap( <format>, <arg1>, <arg2>, <arg3>, <arg4> ) . . . return answer
116 */
117 #define ANSWER_GAP(a,b,c,d,e) \
118 AnswerGap( a, (Long)(b), (Long)(c), (Long)(d), (Long)(e) )
119
AnswerGap(String format,Long a1,Long a2,Long a3,Long a4)120 static Boolean AnswerGap (
121 String format,
122 Long a1,
123 Long a2,
124 Long a3,
125 Long a4 )
126 {
127 Int arg;
128 Int len;
129 Int m;
130 Int n;
131 Long args[4];
132 String ptr;
133 String qtr;
134 String str;
135 String wtr;
136 Char hdr[14];
137
138 /* give debug information */
139 DEBUG( D_COMM, ( "AnswerGap( \"%s\", ... )\n", format ) );
140
141 /* compute length of return string */
142 args[0] = a1; args[1] = a2; args[2] = a3; args[3] = a4;
143 len = 12;
144 arg = 0;
145 for ( ptr = format; *ptr; ptr++ )
146 {
147 if ( arg == 4 )
148 return False;
149 switch ( *ptr )
150 {
151 case 'O':
152 case 'o': len += 9; break;
153 case 'E':
154 case 'e': len += 9; break;
155 case 'D':
156 case 'd': len += 9; arg++; break;
157 case 'S':
158 case 's': len += 9 + strlen((String)args[arg++]); break;
159 default : return False;
160 }
161 }
162
163 /* allocate a string of length <len> */
164 str = XtMalloc(len);
165
166 /* parse arguments again */
167 arg = 0;
168 qtr = str;
169 for ( ptr = format; *ptr; ptr++ )
170 {
171 switch ( *ptr )
172 {
173 case 'O':
174 case 'o':
175 strcpy( qtr, "I0+" );
176 qtr += 3;
177 break;
178 case 'E':
179 case 'e':
180 strcpy( qtr, "I1+" );
181 qtr += 3;
182 break;
183 case 'D':
184 case 'd':
185 *qtr++ = 'I';
186 n = (Int)args[arg++];
187 for ( m = ( 0 < n ) ? n : -n; 0 < m; m /= 10 )
188 *qtr++ = '0' + (m%10);
189 if ( n < 0 )
190 *qtr++ = '-';
191 else
192 *qtr++ = '+';
193 break;
194 case 'S':
195 case 's':
196 *qtr++ = 'S';
197 wtr = (String)(args[arg++]);
198 for ( m = strlen(wtr); 0 < m; m /= 10 )
199 *qtr++ = '0' + (m%10);
200 *qtr++ = '+';
201 while ( *wtr )
202 *qtr++ = *wtr++;
203 break;
204 }
205 }
206 *qtr = '\0';
207
208 /* write header */
209 hdr[0] = '@';
210 hdr[1] = 'a';
211 qtr = hdr+2;
212 for ( m = strlen(str); 0 < m; m/= 10 ) {
213 *qtr++ = '0' + (m%10);
214 }
215 *qtr++ = '+';
216 *qtr = '\0';
217 WriteGap( hdr, strlen(hdr) );
218
219 /* write result back to gap process */
220 WriteGap( str, strlen(str) );
221 XtFree(str);
222 return True;
223 }
224
225
226 /****************************************************************************
227 **
228 *F ParseInt( <buf>, <val> ) . . . . . . . . . . . . . . . get a int value
229 */
ParseInt(String * buf,Int * val)230 static Boolean ParseInt (
231 String * buf,
232 Int * val )
233 {
234 Int mult;
235
236 if ( *(*buf)++ != 'I' )
237 return False;
238 *val = 0;
239 mult = 1;
240 do
241 {
242 if ( **buf == '+' )
243 {
244 (*buf)++;
245 return True;
246 }
247 else if ( **buf == '-' )
248 {
249 (*buf)++;
250 *val = -*val;
251 return True;
252 }
253 else if ( '0' <= **buf && **buf <= '9' )
254 *val += mult * (*((*buf)++)-'0');
255 else
256 return False;
257 mult = mult * 10;
258 } while (1);
259 }
260
261
262 /****************************************************************************
263 **
264 *F ParseString( <buf>, <str>, <len> ) . . . . . . . get a string from <ptr>
265 */
ParseString(String * buf,String * str,Int * len)266 static Boolean ParseString (
267 String * buf,
268 String * str,
269 Int * len )
270 {
271 Int i;
272 Int m;
273 String ptr;
274
275 if ( (*buf)[0] != 'S' )
276 return False;
277 ptr = (*buf)+1;
278 for ( m=1,*len=0; '0' <= *ptr && *ptr <= '9'; ptr++,m *= 10 )
279 *len += ( *ptr - '0' ) * m;
280 *buf = ptr+1;
281 *str = XtMalloc( (*len)+1 );
282 for ( ptr = *str, i = *len; 0 < i; i--, ptr++, (*buf)++ )
283 if ( **buf == '@' )
284 {
285 (*buf)++;
286 if ( **buf == '@' )
287 *ptr = **buf;
288 else
289 *ptr = (**buf) - 'A';
290 }
291 else
292 *ptr = **buf;
293 *ptr = 0;
294 return True;
295 }
296
297
298 /****************************************************************************
299 **
300 *F GapWindowCmd( <cstr>, <len> ) . . . . . . . execute window command <cstr>
301 */
302 extern TypeWindowCommand WindowCommands[];
303
GapWindowCmd(String cstr,Int len)304 Boolean GapWindowCmd (
305 String cstr,
306 Int len )
307 {
308 Boolean ret;
309 Int ca;
310 Int ci;
311 Int cs;
312 Int i;
313 String pa;
314 String str = cstr+3;
315 TypeArg arg;
316 TypeWindowCommand * cmd;
317 char name[4];
318
319 /* give debug information */
320 name[0] = cstr[0]; name[1] = cstr[1]; name[2] = cstr[2]; name[3] = 0;
321 DEBUG( D_XCMD, ( "GapWindowCmd( \"%s\" )\n", name ) );
322
323 /* try to find the command in <WindowCommands> */
324 cmd = WindowCommands;
325 while ( cmd->name )
326 if ( !strncmp( cmd->name, name, 3 ) )
327 break;
328 else
329 cmd++;
330 if ( !cmd->name )
331 return ANSWER_GAP( "esss", "unknown command '", name, "'", 0 );
332
333 /* parse arguments */
334 arg.opts = 0;
335 ci = cs = 0;
336 ca = 1;
337 pa = cmd->args;
338 while ( *pa )
339 {
340 if ( *pa == '*' )
341 {
342 arg.opts = str;
343 break;
344 }
345 else if ( *pa == 'S' || *pa == 's' )
346 {
347 if ( !ParseString( &str, &(arg.sargs[cs]), &len ) )
348 {
349 ret = ANSWER_GAP("eds",ca,".th arg must be a string",0,0);
350 goto free_strings;
351 }
352 else
353 cs++;
354 }
355 else if ( *pa == '#' )
356 {
357 if ( !ParseInt( &str, &i ) )
358 {
359 ret = ANSWER_GAP("eds",ca,".th arg must be a window nr",0,0);
360 goto free_strings;
361 }
362 arg.iargs[ci++] = i;
363 if ( LEN(GapWindows) <= arg.iargs[0] || arg.iargs[0] < 0 )
364 {
365 ret = ANSWER_GAP( "es", "illegal window number", 0, 0, 0 );
366 goto free_strings;
367 }
368 arg.win = (TypeGapWindow*)(ELM(GapWindows,arg.iargs[0]));
369 if ( ! arg.win->used )
370 {
371 ret = ANSWER_GAP( "es", "window not used", 0, 0, 0 );
372 goto free_strings;
373 }
374 }
375 else if ( *pa == 'T' )
376 {
377 if ( !ParseInt( &str, &i ) )
378 {
379 ret = ANSWER_GAP("eds",ca,".th arg must be a selector",0,0);
380 goto free_strings;
381 }
382 arg.iargs[ci++] = i;
383 if ( LEN(TextSelectors) <= arg.iargs[0] || arg.iargs[0] < 0 )
384 {
385 ret = ANSWER_GAP( "es", "illegal selector number", 0, 0, 0 );
386 goto free_strings;
387 }
388 arg.sel = (TypeTextSelector*)(ELM(TextSelectors,arg.iargs[0]));
389 if ( arg.sel == 0)
390 {
391 ret = ANSWER_GAP( "es", "selector not used", 0, 0, 0 );
392 goto free_strings;
393 }
394 }
395 else if ( *pa == 'F' )
396 {
397 if ( !ParseInt( &str, &i ) )
398 {
399 ret = ANSWER_GAP("eds",ca,".th arg must be an integer",0,0);
400 goto free_strings;
401 }
402 arg.iargs[ci++] = i;
403 switch ( (int)arg.iargs[ci-1] )
404 {
405 case 1: arg.font = TinyFont; break;
406 case 2: arg.font = SmallFont; break;
407 case 3: arg.font = NormalFont; break;
408 case 4: arg.font = LargeFont; break;
409 case 5: arg.font = HugeFont; break;
410 default:
411 ret = ANSWER_GAP( "eds", ca,
412 ".th arg must be a font number", 0, 0 );
413 goto free_strings;
414 break;
415 }
416 }
417 else
418 {
419 if ( !ParseInt( &str, &i ) )
420 {
421 ret = ANSWER_GAP("eds",ca,".th arg must be an integer",0,0);
422 goto free_strings;
423 }
424 arg.iargs[ci++] = i;
425 }
426 ca++;
427 pa++;
428 }
429 if ( *pa != '*' && *str )
430 {
431 ret = ANSWER_GAP( "es", "too many arguments", 0, 0, 0 );
432 goto free_strings;
433 }
434
435
436 /* call command */
437 ret = cmd->func( &arg );
438
439 /* free argument strings */
440 free_strings:
441 for ( i = 0; i < cs; i++ )
442 XtFree( arg.sargs[i] );
443 return ret;
444 }
445
446
447 /****************************************************************************
448 **
449
450 *F * * * * * * * * * * * functions for TextSelectors * * * * * * * * * * * *
451 */
452
453
454 /****************************************************************************
455 **
456
457 *F FunOpenSelector( <name>, <list>, <buttons> ) . open a new text selector
458 */
ButtonSelected(Widget w,XtPointer cl,XtPointer ca)459 static void ButtonSelected (
460 Widget w,
461 XtPointer cl,
462 XtPointer ca )
463 {
464 Int i = ((Int) ((Long)cl&0xffff)) % 256;
465 Int n = ((Int) ((Long)cl&0xffff)) / 256;
466 char buf[128];
467
468 DEBUG( D_XCMD, ("ButtonSelected( #%ld, #%ld )\n", (long)n, (long)i) );
469 sprintf( buf, "ButtonSelected(%ld,%ld);\n", (long)n, (long)i );
470 SimulateInput(buf);
471 }
472
TextSelected(Widget w,XtPointer cl,XtPointer ca)473 static void TextSelected (
474 Widget w,
475 XtPointer cl,
476 XtPointer ca )
477 {
478 XawListReturnStruct * ret = (XawListReturnStruct*) ca;
479 Int n = (Int) ((Long)cl&0xffff);
480 Int m = (Int) ret->list_index;
481 char buf[128];
482
483 DEBUG( D_XCMD, ("TextSelected( #%ld, $%ld )\n", (long)n, (long)m+1 ) );
484 sprintf( buf, "TextSelected(%ld,%ld);\n", (long)n, (long)m+1 );
485 SimulateInput(buf);
486 }
487
NotifyClick(Widget w,XEvent * evt,String * str,Cardinal * n)488 static void NotifyClick (
489 Widget w,
490 XEvent * evt,
491 String * str,
492 Cardinal * n )
493 {
494 XawListReturnStruct * ret;
495 Int i;
496 char buf[128];
497
498 /* get currently selected */
499 ret = XawListShowCurrent(w);
500
501 /* if something is set, return */
502 if ( ret->list_index != XAW_LIST_NONE )
503 return;
504
505 /* find widget */
506 for ( i = 0; i < LEN(TextSelectors); i++ )
507 if ( ((TypeTextSelector*)ELM(TextSelectors,i))->list == w )
508 {
509 sprintf( buf, "TextSelected(%ld,0);\n", (long)i );
510 SimulateInput(buf);
511 return;
512 }
513
514 }
515
516 static char ButtonPressTrans[] =
517 "<Btn1Down>,<Btn1Up>: Notify() NotifyClick()";
518
FunOpenSelector(TypeArg * arg)519 static Boolean FunOpenSelector (
520 TypeArg * arg )
521 {
522 Int i;
523 Int n;
524 String name = arg->sargs[0];
525 String ptr;
526 String qtr;
527 TypeTextSelector * selector;
528 Widget box;
529 Widget button;
530 Widget paned;
531 Widget viewport;
532 char buf[512];
533
534 /* give debug info */
535 DEBUG( D_XCMD, ( "OpenSelector( \"%s\", \"%s\", \"%s\" )\n",
536 arg->sargs[0], arg->sargs[1], arg->sargs[2] ) );
537
538 /* create a new selector entry */
539 selector = (TypeTextSelector*) XtMalloc( sizeof(TypeTextSelector) );
540
541 /* create a new top level shell */
542 selector->top = XtAppCreateShell(
543 "TextSelector", "XGap", topLevelShellWidgetClass,
544 GapDisplay, 0, 0 );
545
546 /* create a "paned" for the menu and text window */
547 paned = XtVaCreateManagedWidget(
548 "textSelector", panedWidgetClass, selector->top, (String)NULL );
549
550 /* create a headline */
551 XtVaCreateManagedWidget(
552 "textSelectorTitle", labelWidgetClass, paned,
553 XtNlabel, (XtArgVal)name, (String)NULL );
554
555
556 /* create a viewport for the text selectors */
557 viewport = XtVaCreateManagedWidget(
558 "textSelectorViewport", viewportWidgetClass, paned,
559 XtNallowHoriz, (XtArgVal)False,
560 XtNallowVert, (XtArgVal)True,
561 XtNuseBottom, (XtArgVal)True,
562 XtNshowGrip, (XtArgVal)False,
563 (String)NULL );
564
565 /* compute number of entries */
566 for ( i = 2, qtr = arg->sargs[1]; *qtr; qtr++ )
567 if ( *qtr == '|' )
568 i++;
569 selector->text = (String*) XtMalloc(i*sizeof(String));
570
571 /* parse text */
572 for ( ptr = arg->sargs[1], i = 0; *ptr; i++ )
573 {
574 qtr = buf;
575 while ( *ptr && *ptr != '|' )
576 *qtr++ = *ptr++;
577 *qtr = 0;
578 if ( *ptr ) ptr++;
579 DEBUG( D_XCMD, ( " entry = \"%s\"\n", buf ) );
580 selector->text[i] = (String) XtMalloc(strlen(buf)+1);
581 strcpy( selector->text[i], buf );
582 }
583 selector->text[i] = 0;
584
585 /* find free entry in <TextSelectors> */
586 for ( n = 0; n < LEN(TextSelectors); n++ )
587 if ( ELM(TextSelectors,n) == 0 )
588 break;
589 if ( n == LEN(TextSelectors) )
590 AddList( TextSelectors, selector );
591 else
592 ELM(TextSelectors,n) = selector;
593
594 /* create a list widget containing the text */
595 selector->list = XtVaCreateManagedWidget(
596 "textSelectorList", listWidgetClass, viewport,
597 XtNlist, (XtArgVal)selector->text,
598 XtNdefaultColumns, (XtArgVal)1,
599 XtNforceColumns, (XtArgVal)True,
600 (String)NULL );
601 XtOverrideTranslations( selector->list,
602 XtParseTranslationTable(ButtonPressTrans) );
603 XtAddCallback( selector->list, XtNcallback, TextSelected,
604 (XtPointer)(n&0xffffL) );
605
606 /* create a box containing the buttons */
607 box = XtVaCreateManagedWidget(
608 "textSelectorBox", boxWidgetClass, paned,
609 XtNorientation, (XtArgVal)XtorientHorizontal,
610 XtNshowGrip, (XtArgVal)False,
611 XtNskipAdjust, (XtArgVal)True,
612 XtNresizeToPreferred, (XtArgVal)True,
613 (String)NULL );
614
615 /* parse buttons */
616 selector->buttons = List(0);
617 for ( ptr = arg->sargs[2], i = 1; *ptr; i++ )
618 {
619 qtr = buf;
620 while ( *ptr && *ptr != '|' )
621 *qtr++ = *ptr++;
622 *qtr = 0;
623 if ( *ptr ) ptr++;
624 DEBUG( D_XCMD, ( " button = \"%s\"\n", buf ) );
625 button = XtVaCreateManagedWidget(
626 "textSelectorButton", commandWidgetClass, box,
627 XtNlabel, (XtArgVal)buf,
628 XtNshapeStyle, (XtArgVal)XmuShapeOval,
629 (String)NULL );
630 XtAddCallback(button,XtNcallback,ButtonSelected,
631 (XtPointer)((i+n*256)&0xffffL));
632 AddList( selector->buttons, button );
633 }
634
635
636 /* realize the window and return the number */
637 XtRealizeWidget(selector->top);
638
639 /* add window to list and return window number */
640 return ANSWER_GAP( "od", n, 0, 0, 0 );
641 }
642
643
644 /****************************************************************************
645 **
646 *F FunCloseSelector( <sel> ) . . . . . . . . . destroy an open text selector
647 */
FunCloseSelector(TypeArg * arg)648 static Boolean FunCloseSelector (
649 TypeArg * arg )
650 {
651 Int i;
652
653 /* give debug info */
654 DEBUG( D_XCMD, ( "CloseSelector( #%ld )\n", (long)arg->iargs[0] ) );
655
656 /* destroy top level shell (this will destroy all children) */
657 XtDestroyWidget(arg->sel->top);
658
659 /* clear text */
660 for ( i = 0; arg->sel->text[i]; i++ )
661 XtFree( arg->sel->text[i] );
662 XtFree( (char*) arg->sel->text );
663
664 /* clear button list */
665 XtFree( (char*) arg->sel->buttons->ptr );
666 XtFree( (char*) arg->sel->buttons );
667
668 /* clear entry in <TextSelectors> */
669 ELM(TextSelectors,arg->iargs[0]) = 0;
670 XtFree((char*)arg->sel);
671
672 /* return OK */
673 return AnswerGap( "o", 0, 0, 0, 0 );
674 }
675
676
677 /****************************************************************************
678 **
679 *F FunChangeList( <sel>, <buttons> ) . . . . change list in text selector
680 */
FunChangeList(TypeArg * arg)681 static Boolean FunChangeList (
682 TypeArg * arg )
683 {
684 Int i;
685 String ptr;
686 String qtr;
687 String * text;
688 char buf[512];
689
690 /* give debug info */
691 DEBUG( D_XCMD, ( "ChangeList( #%ld, \"%s\" )\n", (long)arg->iargs[0],
692 arg->sargs[0] ) );
693
694 /* compute number of entries */
695 for ( i = 2, qtr = arg->sargs[0]; *qtr; qtr++ )
696 if ( *qtr == '|' )
697 i++;
698 text = (String*) XtMalloc(i*sizeof(String));
699
700 /* parse text */
701 for ( ptr = arg->sargs[0], i = 0; *ptr; i++ )
702 {
703 qtr = buf;
704 while ( *ptr && *ptr != '|' )
705 *qtr++ = *ptr++;
706 *qtr = 0;
707 if ( *ptr ) ptr++;
708 DEBUG( D_XCMD, ( " entry = \"%s\"\n", buf ) );
709 text[i] = (String) XtMalloc(strlen(buf)+1);
710 strcpy( text[i], buf );
711 }
712 text[i] = 0;
713
714 /* change list */
715 XawListChange( arg->sel->list, text, 0, 0, True );
716
717 /* clear old text */
718 for ( i = 0; arg->sel->text[i]; i++ )
719 XtFree( arg->sel->text[i] );
720 XtFree( (char*) arg->sel->text );
721 arg->sel->text = text;
722
723 /* return OK */
724 return AnswerGap( "o", 0, 0, 0, 0 );
725 }
726
727
728 /****************************************************************************
729 **
730 *F FunEnableButton( <sel>, <but>, <enable> ) . . . . enable/disable a button
731 */
FunEnableButton(TypeArg * arg)732 static Boolean FunEnableButton (
733 TypeArg * arg )
734 {
735 Int i;
736 Widget entry;
737
738 /* give debug info */
739 DEBUG( D_XCMD, ( "EnableButton( #%ld, #%ld, #%ld )\n",
740 (long)arg->iargs[0], (long)arg->iargs[1], (long)arg->iargs[2] ) );
741
742 /* check button number */
743 i = arg->iargs[1]-1;
744 if ( LEN(arg->sel->buttons) <= i || i < 0 )
745 return ANSWER_GAP( "es", "illegal button number", 0, 0, 0 );
746 entry = ELM(arg->sel->buttons,i);
747
748 /* enable/disable */
749 if ( arg->iargs[2] )
750 XtVaSetValues( entry, XtNsensitive, (XtArgVal)True, (String)NULL );
751 else
752 XtVaSetValues( entry, XtNsensitive, (XtArgVal)False, (String)NULL );
753
754 /* return OK */
755 return AnswerGap( "o", 0, 0, 0, 0 );
756 }
757
758
759 /****************************************************************************
760 **
761 *F FunUnhighlihtSelector( <sel> ) . . . . . . . . . . .. unhighlight entry
762 */
FunUnhighlihtSelector(TypeArg * arg)763 static Boolean FunUnhighlihtSelector (
764 TypeArg * arg )
765 {
766 /* give debug info */
767 DEBUG( D_XCMD, ( "Unhighlight( #%ld )\n", (long)arg->iargs[0] ) );
768
769 /* unhighlight entry */
770 XawListUnhighlight(arg->sel->list);
771
772 /* return OK */
773 return AnswerGap( "o", 0, 0, 0, 0 );
774 }
775
776
777 /****************************************************************************
778 **
779
780 *F * * * * * * * * * * * functions for PopupMenus * * * * * * * * * * * * *
781 */
782
783
784 /****************************************************************************
785 **
786
787 *F FunPopupShell( <name>, <str> ) . . . . . . . . . . create a popup shell
788 */
789 static Int ChosenPane = 0;
790
PaneChosen(Widget w,XtPointer cl,XtPointer ca)791 static void PaneChosen (
792 Widget w,
793 XtPointer cl,
794 XtPointer ca )
795 {
796 TypePaneData * pd = (TypePaneData*) cl;
797
798 DEBUG( D_XCMD, ( "PaneChosen( #%ld, #%ld )\n", (long)pd->popup,
799 (long)pd->pane ) );
800 ChosenPane = pd->pane;
801 }
802
PopingDown(Widget w,XtPointer cl,XtPointer ca)803 static void PopingDown (
804 Widget w,
805 XtPointer cl,
806 XtPointer ca )
807 {
808 DEBUG( D_XCMD, ( "PopingDown\n" ) );
809 ANSWER_GAP( "od", ChosenPane, 0, 0, 0 );
810 }
811
812 static char PopingDownTrans[] =
813 "<BtnUp>: notify() MenuPopdown() unhighlight()";
814
FunPopupShell(TypeArg * arg)815 static Boolean FunPopupShell (
816 TypeArg * arg )
817 {
818 Int i;
819 String ptr;
820 String qtr;
821 TypeMenu * menu;
822 TypePaneData * pd;
823 Widget pane;
824 Widget pshell;
825 char buf[128];
826
827 /* search for an identical popup shell */
828 for ( i = 0; i < LEN(PopupMenus); i++ )
829 {
830 menu = ELM(PopupMenus,i);
831 if ( ! strcmp( menu->name, arg->sargs[0] )
832 && ! strcmp( menu->string, arg->sargs[1]) )
833 break;
834 }
835 if ( i < LEN(PopupMenus) )
836 return ANSWER_GAP( "od", i, 0, 0, 0 );
837
838 /* create a shell */
839 pshell = XtVaCreatePopupShell( "pshell", simpleMenuWidgetClass,
840 XGap, XtNcursor, (XtArgVal)CursorTL,
841 (String)NULL );
842 XtOverrideTranslations( pshell,
843 XtParseTranslationTable(PopingDownTrans) );
844
845 /* create headline */
846 DEBUG( D_XCMD, ( "PopupShell( \"%s\", ... )\n", arg->sargs[0] ) );
847 XtVaCreateManagedWidget( "menulabel", smeBSBObjectClass, pshell,
848 XtNsensitive, (XtArgVal)False,
849 XtNlabel, (XtArgVal)(arg->sargs[0]),
850 (String)NULL );
851 XtVaCreateManagedWidget( "line", smeLineObjectClass, pshell, (String)NULL );
852
853 /* add popdown callback */
854 XtAddCallback( pshell, XtNpopdownCallback, PopingDown, 0 );
855
856 /* create menu entries */
857 menu = (TypeMenu*) XtMalloc( sizeof(TypeMenu) );
858 menu->shell = pshell;
859 menu->entries = List(0);
860 menu->name = XtMalloc(strlen(arg->sargs[0])+1);
861 menu->string = XtMalloc(strlen(arg->sargs[1])+1);
862 strcpy( menu->name, arg->sargs[0] );
863 strcpy( menu->string, arg->sargs[1] );
864 for ( ptr = arg->sargs[1], i = 1; *ptr; i++ )
865 {
866 qtr = buf;
867 while ( *ptr && *ptr != '|' )
868 *qtr++ = *ptr++;
869 *qtr = 0;
870 if ( *ptr ) ptr++;
871 DEBUG( D_XCMD, ( " entry = \"%s\"\n", buf ) );
872 pane = XtVaCreateManagedWidget( "menupane", smeBSBObjectClass,
873 pshell, XtNlabel, (XtArgVal)buf,
874 (String)NULL );
875 pd = (TypePaneData*) XtMalloc( sizeof(TypePaneData) );
876 pd->pane = i;
877 pd->popup = LEN(PopupMenus);
878 pd->shell = pshell;
879 XtAddCallback( pane, XtNcallback, PaneChosen, pd );
880 AddList( menu->entries, (void*) pd );
881 }
882
883 /* add shell to popup shell list */
884 AddList( PopupMenus, (void*) menu );
885 return ANSWER_GAP( "od", LEN(PopupMenus)-1, 0, 0, 0 );
886 }
887
888
889 /****************************************************************************
890 **
891 *F FunShowPopup( <nr> ) . . . . . . . . . . . . . . . . popup a popup shell
892 */
FunShowPopup(TypeArg * arg)893 static Boolean FunShowPopup (
894 TypeArg * arg )
895 {
896 Dimension w1, h1, bw;
897 Int x, y, x2, y2;
898 Position tmp;
899 UInt bt;
900 Widget popup;
901 Window child;
902 Window root;
903
904 /* check popup number */
905 if ( LEN(PopupMenus) <= arg->iargs[0] || arg->iargs[0] < 0 )
906 return ANSWER_GAP("esd","illegal popup menu ",arg->iargs[0],0,0);
907 popup = ((TypeMenu*)ELM(PopupMenus,arg->iargs[0]))->shell;
908
909 /* get size of popup dialog */
910 XtVaGetValues( popup,
911 XtNwidth, (XtArgVal)&w1,
912 XtNheight, (XtArgVal)&h1,
913 XtNborderWidth, (XtArgVal)&bw,
914 (String)NULL );
915
916 /* compute screen position */
917 XQueryPointer( GapDisplay, MyRootWindow,
918 &root, &child, &x, &y, &x2, &y2, &bt );
919 tmp = DisplayWidth( GapDisplay, GapScreen );
920 if ( x+w1 > tmp )
921 x = tmp-w1;
922 tmp = DisplayHeight( GapDisplay, GapScreen );
923 if ( y+h1 > tmp )
924 y = tmp-h1;
925
926 /* popup the popup shell */
927 XtVaSetValues( popup, XtNx, (XtArgVal)(x-10), XtNy, (XtArgVal)(y-10),
928 (String)NULL );
929 XawSimpleMenuClearActiveEntry( popup );
930 XtPopupSpringLoaded( popup );
931 XtGrabPointer( popup, True, ButtonPressMask|ButtonReleaseMask,
932 GrabModeAsync, GrabModeAsync, None, None, CurrentTime );
933
934 /* reset 'ChosenPane' */
935 ChosenPane = 0;
936
937 /* gap will be answered by 'PopingDown' */
938 return True;
939 }
940
941
942 /****************************************************************************
943 **
944
945 *F * * * * * * * * * * * * functions for Dialogs * * * * * * * * * * * * * *
946 */
947
948
949 /****************************************************************************
950 **
951
952 *F FunShowDialog( <nr>, <msg>, <def> ) . . . . . . . . . . show popup dialog
953 */
FunShowDialog(TypeArg * arg)954 static Boolean FunShowDialog (
955 TypeArg * arg )
956 {
957 Int first;
958 Int res;
959 String str;
960 #ifndef NO_FILE_SELECTOR
961 static String tmp = 0;
962 #endif
963
964 /* OK/Cancel dialog */
965 if ( arg->iargs[0] == 1 )
966 {
967 first = 4;
968 res = PopupDialog( DialogOkCancel, arg->sargs[0],
969 arg->sargs[1], &str );
970 }
971
972 /* filename dialog */
973 else if ( arg->iargs[0] == 2 )
974 {
975 # ifdef NO_FILE_SELECTOR
976 first = 4;
977 res = PopupDialog( DialogOkCancel, arg->sargs[0],
978 arg->sargs[1], &str );
979 # else
980
981 /* free memory from the previous run */
982 if ( tmp ) {
983 XtFree(tmp);
984 tmp = NULL;
985 }
986
987 /* call the file selector */
988 if ( *(arg->sargs[1]) )
989 res = XsraSelFile(XGap,arg->sargs[0],arg->sargs[1],0,&str);
990 else
991 res = XsraSelFile(XGap,arg->sargs[0],0,0,&str);
992
993 /* ok is first button */
994 first = 1;
995 if ( res != first )
996 str = "";
997 else
998 tmp = str;
999
1000 # endif
1001 }
1002
1003 /* unkown dialog */
1004 else
1005 return ANSWER_GAP("esd","illegal popup dialog ",arg->iargs[0],0,0);
1006
1007 /* return the result */
1008 return ANSWER_GAP( "ods", (res==first)?0:1, str, 0, 0 );
1009 }
1010
1011
1012 /****************************************************************************
1013 **
1014
1015 *F * * * * * * * * * * * * functions for Windows * * * * * * * * * * * * * *
1016 */
1017
1018
1019 /****************************************************************************
1020 **
1021
1022 *F CloseWindow( <win> ) . . . . . . . . . . . . . . . close an open window
1023 */
CloseWindow(TypeGapWindow * win)1024 static void CloseWindow (
1025 TypeGapWindow * win )
1026 {
1027 Int i;
1028 Int j;
1029 TypeMenu * menu;
1030
1031 /* set <used> to false */
1032 win->used = False;
1033
1034 /* free all menus */
1035 for ( i = 0; i < LEN(win->menus); i++ )
1036 if ( (menu=ELM(win->menus,i)) != 0 )
1037 {
1038 for ( j = 0; j < LEN(menu->entries); j++ )
1039 XtFree((char*)ELM(menu->entries,j));
1040 XtFree((char*)menu->entries->ptr);
1041 XtFree((char*)menu->entries);
1042 XtFree((char*)menu);
1043 }
1044 XtFree((char*)win->menus->ptr);
1045 XtFree((char*)win->menus);
1046
1047 /* destroy top level shell (this will destroy all children) */
1048 XtDestroyWidget(win->top);
1049 }
1050
1051
1052 /****************************************************************************
1053 **
1054 *F MouseClickWindow( <talk>, <cd>, <evt>, <ctd> ) . . handle a mouse click
1055 */
MouseClickWindow(Widget talk,XtPointer cd,XEvent * evt,Boolean * ctd)1056 static void MouseClickWindow (
1057 Widget talk,
1058 XtPointer cd,
1059 XEvent * evt,
1060 Boolean * ctd )
1061 {
1062 Int bn;
1063 TypeGapWindow * gap = ELM(GapWindows,(Int)((Long)cd&0xffff));
1064 char buf[100];
1065
1066 /* we only have a two button mouse */
1067 if ( evt->xbutton.button == Button1 )
1068 bn = 1;
1069 else if ( evt->xbutton.button == Button3 )
1070 bn = 2;
1071 else
1072 return;
1073
1074 /* check boundaries */
1075 if ( gap->width <= evt->xbutton.x || gap->height <= evt->xbutton.y )
1076 return;
1077
1078 /* give debug information */
1079 DEBUG( D_XCMD, ( "MouseClickWindow( %ld, %ld, %ld, %ld )\n", (long)cd,
1080 (long)(evt->xbutton.x), (long)(evt->xbutton.y), (long)bn ) );
1081
1082 /* construct gap command */
1083 sprintf( buf, "PointerButtonDown(%ld,%ld,%ld,%ld);\n", (long)cd,
1084 (long)evt->xbutton.x, (long)evt->xbutton.y, (long)bn );
1085 SimulateInput(buf);
1086 }
1087
1088
1089 /****************************************************************************
1090 **
1091 *F WmDeleteWindow( <w>, <event>, <pars>, <n> ) . . . . . . wm delete request
1092 */
1093 static char * WmDeleteWindowTranslation =
1094 "<Message>WM_PROTOCOLS: WmDeleteWindow()\n";
1095
WmDeleteWindow(Widget w,XEvent * event,String * pars,Cardinal * n)1096 static void WmDeleteWindow (
1097 Widget w,
1098 XEvent * event,
1099 String * pars,
1100 Cardinal * n )
1101 {
1102 TypeGapWindow * win;
1103 Int i;
1104
1105 if ( event->type == ClientMessage
1106 && event->xclient.data.l[0] != WmDeleteWindowAtom )
1107 return;
1108 for ( i = 0; i < LEN(GapWindows); i++ )
1109 {
1110 win = (TypeGapWindow*)ELM(GapWindows,i);
1111 if ( win->used && win->top == w )
1112 break;
1113 }
1114 if ( i < LEN(GapWindows) )
1115 CloseWindow(win);
1116 }
1117
1118
1119 /****************************************************************************
1120 **
1121 *F FunOpenWindow( <name>, <width>, <height> ) . open a new window, external
1122 */
CreateTitleWindow(Widget paned)1123 static Widget CreateTitleWindow (
1124 Widget paned )
1125 {
1126 return XtVaCreateManagedWidget(
1127 "xgapWindowText",
1128 labelWidgetClass, paned,
1129 XtNlabel, (XtArgVal)"GAP window",
1130 XtNskipAdjust, (XtArgVal)True,
1131 XtNshowGrip, (XtArgVal)False,
1132 (String)NULL );
1133 }
1134
1135
FunOpenWindow(TypeArg * arg)1136 static Boolean FunOpenWindow (
1137 TypeArg * arg )
1138 {
1139 Int h = arg->iargs[1];
1140 Int w = arg->iargs[0];
1141 Short h1;
1142 Short w1;
1143 String name = arg->sargs[0];
1144 String title;
1145 TypeGapWindow * window;
1146 Widget button;
1147 Widget paned;
1148
1149 /* check arguments */
1150 if ( arg->iargs[0] < 1 || arg->iargs[1] < 1 )
1151 return ANSWER_GAP( "esdsd", "illegal window dimensions ",
1152 arg->iargs[0], "x", arg->iargs[1] );
1153 /* give debug info */
1154 DEBUG( D_XCMD, ( "OpenWindow( \"%s\", %ld, %ld )\n", arg->sargs[0],
1155 (long)arg->iargs[0], (long)arg->iargs[1] ) );
1156
1157 /* setup a new window structure, this structure will live forever */
1158 window = (TypeGapWindow*) XtMalloc( sizeof(TypeGapWindow) );
1159 window->line_width = 0;
1160 window->color = C_BLACK;
1161 window->menus = List(0);
1162 window->used = True;
1163 window->text = 0;
1164
1165 /* find title position */
1166 XtVaGetValues( GapTalk, XtNtitlePosition, (XtArgVal)&title, (String)NULL );
1167
1168 /* create a new top level shell */
1169 window->top = XtVaAppCreateShell(
1170 "XGap", "GraphicSheet",
1171 topLevelShellWidgetClass, GapDisplay,
1172 (String)NULL );
1173
1174 /* create a "paned" for the menu and text window */
1175 paned = XtVaCreateManagedWidget(
1176 "xgapWindow", panedWidgetClass, window->top, (String)NULL );
1177
1178 /* add TOP tile */
1179 if ( *title == 'T' || *title == 't' )
1180 window->text = CreateTitleWindow(paned);
1181
1182 /* create a menu box for the menu buttons */
1183 window->box = XtVaCreateManagedWidget(
1184 "xgapWindowMenu", boxWidgetClass, paned,
1185 XtNskipAdjust, (XtArgVal)True,
1186 XtNresizeToPreferred, (XtArgVal)True,
1187 XtNshowGrip, (XtArgVal)False,
1188 (String)NULL );
1189
1190 /* create a dummy menu button */
1191 button = XtVaCreateManagedWidget( "dummy", commandWidgetClass,
1192 window->box, XtNx, (XtArgVal)0,
1193 (String)NULL );
1194
1195 /* add MIDDLE tile */
1196 if ( *title == 'M' || *title == 'm' )
1197 window->text = CreateTitleWindow(paned);
1198
1199 /* create a viewport for the window */
1200 window->viewport = XtVaCreateManagedWidget(
1201 "xgapWindowViewport",
1202 viewportWidgetClass, paned,
1203 XtNallowHoriz, (XtArgVal)True,
1204 XtNallowVert, (XtArgVal)True,
1205 XtNuseBottom, (XtArgVal)True,
1206 XtNshowGrip, (XtArgVal)False,
1207 XtNresizable, (XtArgVal)True,
1208 (String)NULL );
1209
1210 /* create a drawable */
1211 window->draw = XtVaCreateManagedWidget(
1212 "xgapWindowDrawable",
1213 gapGraphicWidgetClass, window->viewport,
1214 XtNwidth, (XtArgVal)w,
1215 XtNheight, (XtArgVal)h,
1216 (String)NULL );
1217 window->width = w;
1218 window->height = h;
1219
1220 /* fix dimensions of viewport */
1221 XtVaGetValues( window->viewport, XtNwidth, (XtArgVal)&w1,
1222 XtNheight, (XtArgVal)&h1,
1223 (String)NULL );
1224 w1 = ( w1 < w ) ? w1 : w;
1225 h1 = ( h1 < h ) ? h1 : h;
1226 XtVaSetValues( window->viewport, XtNwidth, (XtArgVal)w1,
1227 XtNheight, (XtArgVal)h1, (String)NULL );
1228
1229 /* add BOTTOM tile */
1230 if ( window->text == 0 )
1231 window->text = CreateTitleWindow(paned);
1232
1233 /* realize the window and return the number */
1234 XtRealizeWidget(window->top);
1235
1236 /* add event handler for mouse clicks */
1237 XtAddEventHandler( window->draw, ButtonPressMask,
1238 False, MouseClickWindow,
1239 (XtPointer)(LEN(GapWindows)&0xffffL) );
1240
1241 /* set handler for WM_DELETE_WINDOW */
1242 XSetWMProtocols(GapDisplay,XtWindow(window->top),&WmDeleteWindowAtom,1);
1243 XtOverrideTranslations(
1244 window->top,
1245 XtParseTranslationTable(WmDeleteWindowTranslation) );
1246
1247 /* remove dummy button and dummy text */
1248 XtDestroyWidget(button);
1249 XtVaSetValues( window->text, XtNlabel, (XtArgVal)name, (String)NULL );
1250
1251 /* define cursor */
1252 XDefineCursor( GapDisplay, XtWindow(window->top), SleepCursor );
1253
1254 /* add window to list and return window number */
1255 AddList( GapWindows, (void*) window );
1256 return ANSWER_GAP( "od", LEN(GapWindows)-1, 0, 0, 0 );
1257 }
1258
1259
1260 /****************************************************************************
1261 **
1262 *F FunCloseWindow( <win> ) . . . . . . . . . close an open window, external
1263 */
FunCloseWindow(TypeArg * arg)1264 static Boolean FunCloseWindow (
1265 TypeArg * arg )
1266 {
1267 /* give debug info */
1268 DEBUG( D_XCMD, ( "CloseWindow( #%ld )\n", (long)arg->iargs[0] ) );
1269
1270 /* close window */
1271 CloseWindow(arg->win);
1272
1273 /* return OK */
1274 return AnswerGap( "o", 0, 0, 0, 0 );
1275 }
1276
1277 /****************************************************************************
1278 **
1279 *F FunAddTitle( <win>, <str> ) . . . . . . . . . . . . . . add a (sub) title
1280 */
FunAddTitle(TypeArg * arg)1281 static Boolean FunAddTitle (
1282 TypeArg * arg )
1283 {
1284 XtVaSetValues( arg->win->text, XtNlabel, (XtArgVal)(arg->sargs[0]),
1285 (String)NULL );
1286 return ANSWER_GAP( "o", 0, 0, 0, 0 );
1287 }
1288
1289
1290 /****************************************************************************
1291 **
1292 *F FunColorModel() . . . . . . . color model used for gap graphics, external
1293 */
FunColorModel(TypeArg * arg)1294 static Boolean FunColorModel (
1295 TypeArg * arg )
1296 {
1297 return ANSWER_GAP( "od", GCColorModel(GapDisplay), 0, 0, 0 );
1298 }
1299
1300
1301 /****************************************************************************
1302 **
1303 *F FunFastUpdate( <win>, <flag> ) . . . . . . . . . en-/disable fast update
1304 */
FunFastUpdate(TypeArg * arg)1305 static Boolean FunFastUpdate (
1306 TypeArg * arg )
1307 {
1308 Boolean flag;
1309
1310 flag = ( arg->iargs[1] == 0 ) ? False : True;
1311 if ( arg->win->fast_update != flag )
1312 {
1313 arg->win->fast_update = flag;
1314 GGFastUpdate( arg->win->draw, flag );
1315 }
1316 return ANSWER_GAP( "o", 0, 0, 0, 0 );
1317 }
1318
1319
1320
1321 /****************************************************************************
1322 **
1323 *F FunFontInfo( <win>, <fid> ) . . . . . . . . . . information about fonts
1324 */
FunFontInfo(TypeArg * arg)1325 static Boolean FunFontInfo (
1326 TypeArg * arg )
1327 {
1328 XFontStruct * font = arg->font;
1329
1330 return ANSWER_GAP( "oddd", font->ascent, font->descent,
1331 font->max_bounds.width, 0 );
1332 }
1333
1334
1335 /****************************************************************************
1336 **
1337 *F FunQueryPointer( <win> ) . . . . . . . . . . . . . . . . . query pointer
1338 */
FunQueryPointer(TypeArg * arg)1339 static Boolean FunQueryPointer (
1340 TypeArg * arg )
1341 {
1342 Int x, y, x2, y2;
1343 UInt bt;
1344 UInt md;
1345 UInt pt;
1346 Window child;
1347 Window root;
1348
1349 /* query pointer */
1350 XQueryPointer( XtDisplay(arg->win->draw), XtWindow(arg->win->draw),
1351 &root, &child, &x, &y, &x2, &y2, &pt );
1352
1353 /* and make a sanity check */
1354 if ( arg->win->width < x2 || x2 < 0 )
1355 x2 = -1;
1356 if ( arg->win->height < y2 || y2 < 0 )
1357 y2 = -1;
1358
1359 /* check mouse buttons */
1360 bt = 0;
1361 if ( pt & Button1Mask )
1362 bt |= 1;
1363 if ( pt & Button3Mask )
1364 bt |= 2;
1365
1366 /* check modifier keys */
1367 md = 0;
1368 if ( pt & ShiftMask )
1369 md |= 1;
1370 if ( pt & ControlMask )
1371 md |= 2;
1372 if ( pt & Mod1Mask )
1373 md |= 4;
1374
1375 /* gap will be answered by 'PopingDown' */
1376 return ANSWER_GAP( "odddd", x2, y2, bt, md );
1377 }
1378
1379
1380 /****************************************************************************
1381 **
1382 *F FunResize( <win>, <width>, <height> ) . . . . . . . . . . . resize window
1383 */
FunResize(TypeArg * arg)1384 static Boolean FunResize (
1385 TypeArg * arg )
1386 {
1387 ViewportWidget viewport = (ViewportWidget)arg->win->viewport;
1388 Widget dummy;
1389
1390 /* check arguments */
1391 if ( arg->iargs[1] < 1 || arg->iargs[2] < 1 )
1392 return ANSWER_GAP( "esdsd", "illegal window dimensions ",
1393 arg->iargs[1], "x", arg->iargs[2] );
1394
1395 /* resize window */
1396 arg->win->width = arg->iargs[1];
1397 arg->win->height = arg->iargs[2];
1398 GGResize( arg->win->draw, arg->iargs[1], arg->iargs[2] );
1399
1400 /* try to update scrollbars */
1401 XtUnmanageChild(arg->win->draw);
1402 dummy = XtVaCreateManagedWidget(
1403 "xgapWindowDrawable",
1404 gapGraphicWidgetClass, (Widget)viewport,
1405 XtNwidth, (XtArgVal)(arg->win->width),
1406 XtNheight, (XtArgVal)(arg->win->height),
1407 (String)NULL );
1408 XtUnmanageChild(dummy);
1409 XtManageChild(arg->win->draw);
1410 XtDestroyWidget(dummy);
1411
1412 /* and return */
1413 return ANSWER_GAP( "o", 0, 0, 0, 0 );
1414 }
1415
1416
1417 /****************************************************************************
1418 **
1419
1420 *F * * * * * * * * * * * * * functions for Menus * * * * * * * * * * * * * *
1421 */
1422
1423
1424 /****************************************************************************
1425 **
1426
1427 *F FunMenu( <win>, <name>, <str> ) . . . . . . . . . . . create a menu entry
1428 */
MenuClick(Widget w,XtPointer cl,XtPointer ca)1429 static void MenuClick (
1430 Widget w,
1431 XtPointer cl,
1432 XtPointer ca )
1433 {
1434 TypeMenuData * pd = (TypeMenuData*) cl;
1435 char buf[128];
1436
1437 DEBUG( D_XCMD, ("MenuSelected( #%ld, #%ld, #%ld )\n", (long)pd->window,
1438 (long)pd->popup, (long)pd->pane) );
1439 sprintf( buf, "MenuSelected( %ld, %ld, %ld );\n", (long)pd->window,
1440 (long)pd->popup, (long)pd->pane );
1441 SimulateInput(buf);
1442 }
1443
FunMenu(TypeArg * arg)1444 static Boolean FunMenu (
1445 TypeArg * arg )
1446 {
1447 Int i;
1448 String ptr;
1449 String qtr;
1450 TypeMenu * menu;
1451 TypeMenuData * pd;
1452 Widget button;
1453 Widget pane;
1454 Widget pshell;
1455 char buf[128];
1456
1457 /* create a menu button */
1458 DEBUG( D_XCMD, ( "Menu( \"%s\", ... )\n", arg->sargs[0] ) );
1459 button = XtVaCreateManagedWidget( "menuButton", menuButtonWidgetClass,
1460 arg->win->box,
1461 XtNlabel, (XtArgVal)(arg->sargs[0]),
1462 XtNshapeStyle, (XtArgVal)XmuShapeOval,
1463 XtNleftBitmap, (XtArgVal)MenuSymbol,
1464 (String)NULL );
1465
1466 /* create a shell */
1467 pshell = XtVaCreatePopupShell( "menu", simpleMenuWidgetClass,
1468 button, XtNcursor, (XtArgVal)CursorTL,
1469 (String)NULL );
1470
1471 /* create menu entries */
1472 menu = (TypeMenu*) XtMalloc( sizeof(TypeMenu) );
1473 menu->button = button;
1474 menu->shell = pshell;
1475 menu->entries = List(0);
1476 for ( ptr = arg->sargs[1], i = 1; *ptr; )
1477 {
1478 qtr = buf;
1479 while ( *ptr && *ptr != '|' )
1480 *qtr++ = *ptr++;
1481 *qtr = 0;
1482 if ( *ptr ) ptr++;
1483 DEBUG( D_XCMD, ( " entry = \"%s\"\n", buf ) );
1484 if ( *buf == '-' )
1485 XtVaCreateManagedWidget( "line", smeLineObjectClass, pshell,
1486 (String)NULL );
1487 else
1488 {
1489 pane = XtVaCreateManagedWidget( buf, smeBSBObjectClass,
1490 pshell,
1491 XtNlabel, (XtArgVal)buf,
1492 XtNrightMargin, (XtArgVal)14,
1493 XtNrightBitmap,
1494 (XtArgVal)EmptyMarkSymbol,
1495 (String)NULL );
1496 pd = (TypeMenuData*) XtMalloc( sizeof(TypeMenuData) );
1497 pd->window = arg->iargs[0];
1498 pd->pane = i;
1499 pd->popup = LEN(arg->win->menus);
1500 pd->shell = pane;
1501 XtAddCallback( pane, XtNcallback, MenuClick, pd );
1502 i++;
1503 AddList( menu->entries, (void*) pd );
1504 }
1505 }
1506
1507 /* add shell to popup shell list */
1508 AddList( arg->win->menus, (void*) menu );
1509 return ANSWER_GAP( "od", LEN(arg->win->menus)-1, 0, 0, 0 );
1510 }
1511
1512
1513 /****************************************************************************
1514 **
1515 *F FunDeleteMenu( <win>, <menu> ) . . . . . . . . . . . . . . delete a menu
1516 */
FunDeleteMenu(TypeArg * arg)1517 static Boolean FunDeleteMenu (
1518 TypeArg * arg )
1519 {
1520 TypeMenu * menu;
1521 Int j;
1522
1523 /* check menu number */
1524 DEBUG( D_XCMD, ( "CheckMenuEntry( #%ld, #%ld, #%ld, %ld )\n",
1525 (long)arg->iargs[0], (long)arg->iargs[1], (long)arg->iargs[2],
1526 (long)arg->iargs[3] ) );
1527 if ( LEN(arg->win->menus) <= arg->iargs[1] || arg->iargs[1] < 0 )
1528 return ANSWER_GAP("esd","illegal menu number ",arg->iargs[1],0,0);
1529 menu = (TypeMenu*)ELM(arg->win->menus,arg->iargs[1]);
1530 if ( menu == 0 )
1531 return ANSWER_GAP( "esds", "menu ", arg->iargs[1],
1532 " is no longer used", 0 );
1533
1534 /* delete this entry */
1535 ELM( arg->win->menus, arg->iargs[1] ) = 0;
1536 for ( j = 0; j < LEN(menu->entries); j++ )
1537 XtFree((char*)ELM(menu->entries,j));
1538 XtFree((char*)menu->entries->ptr);
1539 XtFree((char*)menu->entries);
1540 XtDestroyWidget(menu->button);
1541 XtFree((char*)menu);
1542 return ANSWER_GAP( "o", 0, 0, 0, 0 );
1543 }
1544
1545
1546 /****************************************************************************
1547 **
1548 *F FunCheckMenuEntry( <win>, <menu>, <entry>, <check> ) . . add check mark
1549 */
FunCheckMenuEntry(TypeArg * arg)1550 static Boolean FunCheckMenuEntry (
1551 TypeArg * arg )
1552 {
1553 TypeMenu * menu;
1554 Widget entry;
1555
1556 /* check menu number */
1557 DEBUG( D_XCMD, ( "CheckMenuEntry( #%ld, #%ld, #%ld, %ld )\n",
1558 (long)arg->iargs[0], (long)arg->iargs[1], (long)arg->iargs[2],
1559 (long)arg->iargs[3] ) );
1560 if ( LEN(arg->win->menus) <= arg->iargs[1] || arg->iargs[1] < 0 )
1561 return ANSWER_GAP("esd","illegal menu number ",arg->iargs[1],0,0);
1562 menu = (TypeMenu*)ELM(arg->win->menus,arg->iargs[1]);
1563 if ( menu == 0 )
1564 return ANSWER_GAP( "esds", "menu ", arg->iargs[1],
1565 " is no longer used", 0 );
1566
1567 /* check menu entry number */
1568 if ( LEN(menu->entries) < arg->iargs[2] || arg->iargs[2] <= 0 )
1569 return ANSWER_GAP("esd","illegal menu entry ",arg->iargs[2],0,0);
1570 entry = ((TypeMenuData*)ELM(menu->entries,arg->iargs[2]-1))->shell;
1571
1572 /* set or clear check mark */
1573 if ( arg->iargs[3] )
1574 XtVaSetValues( entry, XtNrightBitmap, (XtArgVal)CheckMarkSymbol,
1575 (String)NULL );
1576 else
1577 XtVaSetValues( entry, XtNrightBitmap, (XtArgVal)EmptyMarkSymbol,
1578 (String)NULL );
1579 return ANSWER_GAP( "o", 0, 0, 0, 0 );
1580 }
1581
1582
1583 /****************************************************************************
1584 **
1585 *F FunEnableMenuEntry( <win>, <menu>, <entry>, <check> ) . . enable/disable
1586 */
FunEnableMenuEntry(TypeArg * arg)1587 static Boolean FunEnableMenuEntry (
1588 TypeArg * arg )
1589 {
1590 TypeMenu * menu;
1591 Widget entry;
1592
1593 /* check menu number */
1594 DEBUG( D_XCMD, ( "EnableMenuEntry( #%ld, #%ld, #%ld, %ld )\n",
1595 (long)arg->iargs[0], (long)arg->iargs[1], (long)arg->iargs[2],
1596 (long)arg->iargs[3] ) );
1597 if ( LEN(arg->win->menus) <= arg->iargs[1] || arg->iargs[1] < 0 )
1598 return ANSWER_GAP("esd","illegal menu number ",arg->iargs[1],0,0);
1599 menu = (TypeMenu*)ELM(arg->win->menus,arg->iargs[1]);
1600 if ( menu == 0 )
1601 return ANSWER_GAP( "esds", "menu ", arg->iargs[1],
1602 " is no longer used", 0 );
1603
1604 /* check menu entry number */
1605 if ( LEN(menu->entries) < arg->iargs[2] || arg->iargs[2] <= 0 )
1606 return ANSWER_GAP("esd","illegal menu entry ",arg->iargs[2],0,0);
1607 entry = ((TypeMenuData*)ELM(menu->entries,arg->iargs[2]-1))->shell;
1608
1609 /* set or clear check mark */
1610 if ( arg->iargs[3] )
1611 XtVaSetValues( entry, XtNsensitive, (XtArgVal)True, (String)NULL );
1612 else
1613 XtVaSetValues( entry, XtNsensitive, (XtArgVal)False, (String)NULL );
1614 return ANSWER_GAP( "o", 0, 0, 0, 0 );
1615 }
1616
1617
1618 /****************************************************************************
1619 **
1620
1621 *F * * * * * * * * * * * functions for GraphicObjects * * * * * * * * * * *
1622 */
1623
1624
1625 /****************************************************************************
1626 **
1627
1628 *D CHECK_BBOX( <obj> ) . . . . . . . . . . check dimensions of bounding box
1629 */
1630 #define CHECK_BBOX(obj) obj->x = ( obj->x < 0 ) ? 0 : obj-> x; \
1631 obj->y = ( obj->y < 0 ) ? 0 : obj-> y
1632
1633
1634 /****************************************************************************
1635 **
1636 *F FunClearAll( <win> ) . . . . . . . . . . . . . . . . . clear all objects
1637 */
FunClearAll(TypeArg * arg)1638 static Boolean FunClearAll (
1639 TypeArg * arg )
1640 {
1641 GGFreeAllObjects( arg->win->draw );
1642 return ANSWER_GAP( "o", 0, 0, 0, 0 );
1643 }
1644
1645
1646 /****************************************************************************
1647 **
1648 *F FunRemoveObjects( <win>, <obj>, ... ) . . . . . remove a window object
1649 */
FunRemoveObjects(TypeArg * arg)1650 static Boolean FunRemoveObjects (
1651 TypeArg * arg )
1652 {
1653 String str;
1654 Int n;
1655
1656 /* return if no optional args are given */
1657 if ( (str=arg->opts) == 0 )
1658 return ANSWER_GAP( "es", "no objects given", 0, 0, 0 );
1659
1660 /* give debug info */
1661 DEBUG( D_XCMD, ("RemoveObject( #%ld, %s )\n",(long)arg->iargs[0],str) );
1662
1663 /* remove objects */
1664 if ( !arg->win->fast_update )
1665 GGStartRemove(arg->win->draw);
1666 while ( *str )
1667 {
1668 if ( !ParseInt( &str, &n ) )
1669 {
1670 if ( !arg->win->fast_update )
1671 GGStopRemove(arg->win->draw);
1672 return ANSWER_GAP( "es", "illegal argument", 0, 0, 0 );
1673 }
1674 if ( GGRemoveObject( arg->win->draw, n ) )
1675 {
1676 if ( !arg->win->fast_update )
1677 GGStopRemove(arg->win->draw);
1678 return ANSWER_GAP("esds","illegal object number: '",n,"'",0);
1679 }
1680 }
1681 if ( !arg->win->fast_update )
1682 GGStopRemove(arg->win->draw);
1683 return ANSWER_GAP( "o", 0, 0, 0, 0 );
1684 }
1685
1686
1687 /****************************************************************************
1688 **
1689 *F FunSetLineWidth( <win>, <wdt> ) . . . . . set line width for next objects
1690 */
FunSetLineWidth(TypeArg * arg)1691 static Boolean FunSetLineWidth (
1692 TypeArg * arg )
1693 {
1694 arg->win->line_width = ( arg->iargs[1] <= 1 ) ? 0 : arg->iargs[1];
1695 return ANSWER_GAP( "o", 0, 0, 0, 0 );
1696 }
1697
1698
1699 /****************************************************************************
1700 **
1701 *F FunSetColor( <win>, <col> ) . . . . . . . . . set color for next objects
1702 */
FunSetColor(TypeArg * arg)1703 static Boolean FunSetColor (
1704 TypeArg * arg )
1705 {
1706 if ( arg->iargs[1] < 0 )
1707 arg->win->color = C_BLACK;
1708 else if ( C_LAST < arg->iargs[1] )
1709 arg->win->color = C_BLACK;
1710 else
1711 arg->win->color = arg->iargs[1];
1712 return ANSWER_GAP( "o", 0, 0, 0, 0 );
1713 }
1714
1715
1716 /****************************************************************************
1717 **
1718 *F FunDrawBox( <win>, <x1>, <y1>, <x2>, <y2> ) . . . draw a filled rectangle
1719 */
FunDrawBox(TypeArg * arg)1720 static Boolean FunDrawBox (
1721 TypeArg * arg )
1722 {
1723 TypeGapGraphicObject * obj;
1724 Int n;
1725
1726 /* create a line object */
1727 obj = (TypeGapGraphicObject*) XtMalloc( sizeof(TypeGapGraphicObject) );
1728
1729 /* convert <x> and <y> coordinates to X windows style */
1730 obj->type = T_BOX;
1731 obj->color = arg->win->color;
1732 obj->desc.rect.x1 = MIN( arg->iargs[1], arg->iargs[3] );
1733 obj->desc.rect.y1 = MIN( arg->iargs[2], arg->iargs[4] );
1734 obj->desc.rect.x2 = MAX( arg->iargs[1], arg->iargs[3] );
1735 obj->desc.rect.y2 = MAX( arg->iargs[2], arg->iargs[4] );
1736 obj->x = MIN( obj->desc.rect.x1, obj->desc.rect.x2 )-1;
1737 obj->y = MIN( obj->desc.rect.y1, obj->desc.rect.y2 )-1;
1738 obj->w = MAX( obj->desc.rect.x1, obj->desc.rect.x2 )+1;
1739 obj->h = MAX( obj->desc.rect.y1, obj->desc.rect.y2 )+1;
1740 CHECK_BBOX(obj);
1741 DEBUG( D_XCMD, ( "DrawBox( #%ld, %ld, %ld, %ld )\n",
1742 (long)arg->iargs[0], (long)arg->iargs[1],
1743 (long)arg->iargs[2], (long)arg->iargs[3] ) );
1744
1745 /* use 'GGAddObject' to draw the object */
1746 n = GGAddObject( arg->win->draw, obj );
1747 return ANSWER_GAP( "od", n, 0, 0, 0 );
1748 }
1749
1750
1751 /****************************************************************************
1752 **
1753 *F FunDrawCircle( <win>, <x>, <y>, <r> ) . . . . . . . . . . . draw a circle
1754 */
FunDrawCircle(TypeArg * arg)1755 static Boolean FunDrawCircle (
1756 TypeArg * arg )
1757 {
1758 TypeGapGraphicObject * obj;
1759 Int n;
1760 Int w;
1761
1762 /* create a circle object */
1763 obj = (TypeGapGraphicObject*) XtMalloc( sizeof(TypeGapGraphicObject) );
1764
1765 /* convert <x> and <y> coordinates to X windows style */
1766 obj->type = T_CIRCLE;
1767 obj->color = arg->win->color;
1768 obj->desc.circle.r = 2 * arg->iargs[3];
1769 obj->desc.circle.x = arg->iargs[1] - arg->iargs[3];
1770 obj->desc.circle.y = arg->iargs[2] - arg->iargs[3];
1771 w = obj->desc.circle.w = arg->win->line_width;
1772 obj->x = obj->desc.circle.x - w - 1;
1773 obj->y = obj->desc.circle.y - w - 1;
1774 obj->w = obj->desc.circle.r+1 + 2*w + 2;
1775 obj->h = obj->desc.circle.r+1 + 2*w + 2;
1776 CHECK_BBOX(obj);
1777 DEBUG( D_XCMD, ( "DrawCircle( #%ld, %ld, %ld, %ld )\n",
1778 (long)arg->iargs[0], (long)arg->iargs[1],
1779 (long)arg->iargs[2], (long)arg->iargs[3] ) );
1780
1781 /* use 'GGAddObject' to draw the object */
1782 n = GGAddObject( arg->win->draw, obj );
1783 return ANSWER_GAP( "od", n, 0, 0, 0 );
1784 }
1785
1786
1787 /****************************************************************************
1788 **
1789 *F FunDrawDisc( <win>, <x>, <y>, <r> ) . . . . . . . . . . draw a solid disc
1790 */
FunDrawDisc(TypeArg * arg)1791 static Boolean FunDrawDisc (
1792 TypeArg * arg )
1793 {
1794 TypeGapGraphicObject * obj;
1795 Int n;
1796
1797 /* create a disc object */
1798 obj = (TypeGapGraphicObject*) XtMalloc( sizeof(TypeGapGraphicObject) );
1799
1800 /* convert <x> and <y> coordinates to X windows style */
1801 obj->type = T_DISC;
1802 obj->color = arg->win->color;
1803 obj->desc.disc.r = 2 * arg->iargs[3];
1804 obj->desc.disc.x = arg->iargs[1] - arg->iargs[3];
1805 obj->desc.disc.y = arg->iargs[2] - arg->iargs[3];
1806 obj->x = obj->desc.disc.x;
1807 obj->y = obj->desc.disc.y;
1808 obj->w = obj->desc.disc.r+1;
1809 obj->h = obj->desc.disc.r+1;
1810 CHECK_BBOX(obj);
1811 DEBUG( D_XCMD, ( "DrawCircle( #%ld, %ld, %ld, %ld )\n",
1812 (long)arg->iargs[0], (long)arg->iargs[1],
1813 (long)arg->iargs[2], (long)arg->iargs[3] ) );
1814
1815 /* use 'GGAddObject' to draw the object */
1816 n = GGAddObject( arg->win->draw, obj );
1817 return ANSWER_GAP( "od", n, 0, 0, 0 );
1818 }
1819
1820
1821 /****************************************************************************
1822 **
1823 *F FunDrawLine( <win>, <x1>, <y1>, <x2>, <y2> ) . . . . . . . . draw a line
1824 */
FunDrawLine(TypeArg * arg)1825 static Boolean FunDrawLine (
1826 TypeArg * arg )
1827 {
1828 TypeGapGraphicObject * obj;
1829 Int n;
1830 Int w;
1831
1832 /* create a line object */
1833 obj = (TypeGapGraphicObject*) XtMalloc( sizeof(TypeGapGraphicObject) );
1834 obj->type = T_LINE;
1835 obj->color = arg->win->color;
1836 obj->desc.line.x1 = arg->iargs[1];
1837 obj->desc.line.y1 = arg->iargs[2];
1838 obj->desc.line.x2 = arg->iargs[3];
1839 obj->desc.line.y2 = arg->iargs[4];
1840 w = obj->desc.line.w = arg->win->line_width;
1841 obj->x = MIN( obj->desc.line.x1, obj->desc.line.x2 ) - w;
1842 obj->y = MIN( obj->desc.line.y1, obj->desc.line.y2 ) - w;
1843 obj->w = MAX( obj->desc.line.x1, obj->desc.line.x2 ) - obj->x + 1 + 2*w;
1844 obj->h = MAX( obj->desc.line.y1, obj->desc.line.y2 ) - obj->y + 1 + 2*w;
1845 CHECK_BBOX(obj);
1846 DEBUG( D_XCMD, ( "DrawLine( #%ld, %ld, %ld, %ld, %ld )\n",
1847 (long)arg->iargs[0], (long)obj->desc.line.x1,
1848 (long)obj->desc.line.y1, (long)obj->desc.line.x2,
1849 (long)obj->desc.line.y2 ) );
1850
1851 /* use 'GGAddObject' to draw the object */
1852 n = GGAddObject( arg->win->draw, obj );
1853 return ANSWER_GAP( "od", n, 0, 0, 0 );
1854 }
1855
1856
1857
1858 /****************************************************************************
1859 **
1860 *F FunDrawRectangle( <win>, <x1>, <y1>, <x2>, <y2> ) . . . draw a rectangle
1861 */
FunDrawRectangle(TypeArg * arg)1862 static Boolean FunDrawRectangle (
1863 TypeArg * arg )
1864 {
1865 TypeGapGraphicObject * obj;
1866 Int n;
1867 Int w;
1868
1869 /* create a line object */
1870 obj = (TypeGapGraphicObject*) XtMalloc( sizeof(TypeGapGraphicObject) );
1871
1872 /* convert <x> and <y> coordinates to X windows style */
1873 obj->type = T_RECT;
1874 obj->color = arg->win->color;
1875 obj->desc.rect.x1 = MIN( arg->iargs[1], arg->iargs[3] );
1876 obj->desc.rect.y1 = MIN( arg->iargs[2], arg->iargs[4] );
1877 obj->desc.rect.x2 = MAX( arg->iargs[1], arg->iargs[3] );
1878 obj->desc.rect.y2 = MAX( arg->iargs[2], arg->iargs[4] );
1879 w = obj->desc.rect.w = arg->win->line_width;
1880 obj->x = MIN( obj->desc.rect.x1, obj->desc.rect.x2 ) - w;
1881 obj->y = MIN( obj->desc.rect.y1, obj->desc.rect.y2 ) - w;
1882 obj->w = MAX( obj->desc.rect.x1, obj->desc.rect.x2 ) - obj->x + 1 + 2*w;
1883 obj->h = MAX( obj->desc.rect.y1, obj->desc.rect.y2 ) - obj->y + 1 + 2*w;
1884 CHECK_BBOX(obj);
1885 DEBUG( D_XCMD, ( "DrawRectangle( #%ld, %ld, %ld, %ld )\n",
1886 (long)arg->iargs[0], (long)arg->iargs[1],
1887 (long)arg->iargs[2], (long)arg->iargs[3] ) );
1888
1889 /* use 'GGAddObject' to draw the object */
1890 n = GGAddObject( arg->win->draw, obj );
1891 return ANSWER_GAP( "od", n, 0, 0, 0 );
1892 }
1893
1894
1895 /****************************************************************************
1896 **
1897 *F FunDrawText( <win>, <fid>, <x>, <y>, <str> ) . . . . . . draw text <str>
1898 */
FunDrawText(TypeArg * arg)1899 static Boolean FunDrawText (
1900 TypeArg * arg )
1901 {
1902 TypeGapGraphicObject * obj;
1903 XFontStruct * font = arg->font;
1904 Int n;
1905
1906 /* create a TEXT object */
1907 obj = (TypeGapGraphicObject*) XtMalloc( sizeof(TypeGapGraphicObject) );
1908
1909 /* convert <x> and <y> coordinates to X windows style */
1910 obj->type = T_TEXT;
1911 obj->color = arg->win->color;
1912 obj->desc.text.x = arg->iargs[2];
1913 obj->desc.text.y = arg->iargs[3];
1914 obj->desc.text.font = font->fid;
1915 obj->desc.text.len = strlen(arg->sargs[0]);
1916 obj->desc.text.str = XtMalloc(obj->desc.text.len+1);
1917 strcpy( obj->desc.text.str, arg->sargs[0] );
1918 obj->x = arg->iargs[2] - 1;
1919 obj->y = arg->iargs[3] - font->ascent - 1;
1920 obj->w = obj->desc.text.len*font->max_bounds.width + 2;
1921 obj->h = font->descent + font->ascent + 2;
1922 CHECK_BBOX(obj);
1923 DEBUG( D_XCMD, ( "DrawText( #%ld, %ld, %ld, %s )\n",
1924 (long)arg->iargs[0], (long)arg->iargs[1],
1925 (long)arg->iargs[2], arg->sargs[0] ) );
1926
1927 /* use 'GGAddObject' to draw the object */
1928 n = GGAddObject( arg->win->draw, obj );
1929 return ANSWER_GAP( "od", n, 0, 0, 0 );
1930 }
1931
1932
1933 /****************************************************************************
1934 **
1935
1936 *F FunPlaybackFile( <filename> ) . . . . . . . . . playback file <filename>
1937 */
FunPlaybackFile(TypeArg * arg)1938 static Boolean FunPlaybackFile (
1939 TypeArg * arg )
1940 {
1941 return PlaybackFile(arg->sargs[0]) ?
1942 ANSWER_GAP( "o", 0, 0, 0, 0 )
1943 : ANSWER_GAP( "es", "cannot open file", 0, 0, 0 );
1944 }
1945
1946
1947 /****************************************************************************
1948 **
1949 *F FunResumePlayback() . . . . . . . . . . . . . . . resume playback of file
1950 */
FunResumePlayback(TypeArg * arg)1951 static Boolean FunResumePlayback (
1952 TypeArg * arg )
1953 {
1954 return ResumePlayback() ?
1955 ANSWER_GAP( "o", 0, 0, 0, 0 )
1956 : ANSWER_GAP( "es", "no playback in progress", 0, 0, 0 );
1957 }
1958
1959
1960 /****************************************************************************
1961 **
1962
1963 *F * * * * * * * * * * interface to the main program * * * * * * * * * * *
1964 */
1965
1966
1967 /****************************************************************************
1968 **
1969
1970 *V WindowCommands[] . . . . . . . . . . . . . . . list of window commands
1971 */
1972 TypeWindowCommand WindowCommands[] =
1973 {
1974 { "XAT", "#S", FunAddTitle },
1975 { "XCA", "#", FunClearAll },
1976 { "XCL", "TS", FunChangeList },
1977 { "XCM", "#III", FunCheckMenuEntry },
1978 { "XCN", "", FunColorModel },
1979 { "XCO", "#I", FunSetColor },
1980 { "XCS", "T", FunCloseSelector },
1981 { "XCW", "#", FunCloseWindow },
1982 { "XDB", "#IIII", FunDrawBox },
1983 { "XDC", "#III", FunDrawCircle },
1984 { "XDD", "#III", FunDrawDisc },
1985 { "XDL", "#IIII", FunDrawLine },
1986 { "XDM", "#I", FunDeleteMenu },
1987 { "XDR", "#IIII", FunDrawRectangle },
1988 { "XDT", "#FIIS", FunDrawText },
1989 { "XEB", "TII", FunEnableButton },
1990 { "XEM", "#III", FunEnableMenuEntry },
1991 { "XFI", "F", FunFontInfo },
1992 { "XFU", "#I", FunFastUpdate },
1993 { "XLW", "#I", FunSetLineWidth },
1994 { "XME", "#SS", FunMenu },
1995 { "XOS", "SSS", FunOpenSelector },
1996 { "XOW", "SII", FunOpenWindow },
1997 { "XPF", "S", FunPlaybackFile },
1998 { "XPS", "SS" , FunPopupShell },
1999 { "XQP", "#", FunQueryPointer },
2000 { "XRE", "#II", FunResize },
2001 { "XRP", "", FunResumePlayback },
2002 { "XRO", "#*", FunRemoveObjects },
2003 { "XSD", "ISS", FunShowDialog },
2004 { "XSP", "I", FunShowPopup },
2005 { "XUS", "T", FunUnhighlihtSelector },
2006 { 0L, 0L, 0L }
2007 };
2008
2009
2010 /****************************************************************************
2011 **
2012 *V PrivateActions . . . . . . . . . . . . . . . . . . . . action functions
2013 */
2014 static XtActionsRec PrivateActions[] =
2015 {
2016 { "NotifyClick", NotifyClick },
2017 { "WmDeleteWindow", WmDeleteWindow }
2018 };
2019
2020
2021 /****************************************************************************
2022 **
2023 *F InitXCMDS() . . . . . . . . . . . . . . . initalize all global variables
2024 */
InitXCMDS()2025 void InitXCMDS ()
2026 {
2027
2028 /* get the fonts form the database for <GapTalk> */
2029 XtVaGetValues( GapTalk,
2030 XtNtinyFont, (XtArgVal)&TinyFont,
2031 XtNsmallFont, (XtArgVal)&SmallFont,
2032 XtNnormalFont, (XtArgVal)&NormalFont,
2033 XtNlargeFont, (XtArgVal)&LargeFont,
2034 XtNhugeFont, (XtArgVal)&HugeFont,
2035 (String)NULL );
2036
2037 /* create lists for windows, popups, and selectors */
2038 GapWindows = List(0);
2039 PopupMenus = List(0);
2040 TextSelectors = List(0);
2041
2042 /* create cursors */
2043 SleepCursor = XCreateFontCursor( GapDisplay, XC_watch );
2044 RunCursor = XCreateFontCursor( GapDisplay, XC_top_left_arrow );
2045
2046 /* create popup dialogs */
2047 DialogOkCancel = CreatePopupDialog( AppContext, XGap, "OkCancelDialog",
2048 PD_OK | PD_CANCEL, PD_OK, 0 );
2049
2050 /* register private actions */
2051 XtAppAddActions( AppContext, PrivateActions, XtNumber(PrivateActions) );
2052 }
2053
2054
2055 /****************************************************************************
2056 **
2057 *F UpdateXCMDS( <state> ) . . . . . . . . . . gap is/isn't accepting input
2058 */
UpdateXCMDS(state)2059 void UpdateXCMDS ( state )
2060 Boolean state;
2061 {
2062 TypeGapWindow * win;
2063 Int i;
2064
2065 /* GAP accepts input */
2066 if ( state )
2067 {
2068 for ( i = 0; i < LEN(GapWindows); i++ )
2069 {
2070 win = ELM( GapWindows, i );
2071 if ( win && win->used == True )
2072 XDefineCursor( GapDisplay, XtWindow(win->top), RunCursor );
2073 }
2074 }
2075
2076 /* GAP doesn't accept input */
2077 else
2078 {
2079 for ( i = 0; i < LEN(GapWindows); i++ )
2080 {
2081 win = ELM( GapWindows, i );
2082 if ( win && win->used == True )
2083 XDefineCursor( GapDisplay, XtWindow(win->top), SleepCursor );
2084 }
2085 }
2086 }
2087
2088
2089 /****************************************************************************
2090 **
2091 *F ExitXCMDS() . . . . . . . . . . . . . . . . . clear all global variables
2092 */
ExitXCMDS()2093 void ExitXCMDS ()
2094 {
2095 TypeArg arg;
2096 TypeMenu * menu;
2097 Int i;
2098 Int j;
2099
2100 /* clear list of windows and popups */
2101 for ( i = 0; i < LEN(GapWindows); i++ )
2102 {
2103 arg.win = ELM(GapWindows,i);
2104 if ( arg.win->used )
2105 FunCloseWindow(&arg);
2106 XtFree((char*)ELM(GapWindows,i));
2107 }
2108 XtFree((char*)GapWindows);
2109 for ( i = 0; i < LEN(TextSelectors); i++ )
2110 {
2111 arg.sel = ELM(TextSelectors,i);
2112 if ( arg.sel != 0 )
2113 {
2114 FunCloseSelector(&arg);
2115 XtFree((char*)ELM(TextSelectors,i));
2116 }
2117 }
2118 XtFree((char*)TextSelectors);
2119 for (i = 0; i < LEN(PopupMenus); i++ )
2120 if ( (menu = ELM(PopupMenus,i)) != 0 )
2121 {
2122 for ( j = 0; j < LEN(menu->entries); j++ )
2123 XtFree((char*)ELM(menu->entries,j));
2124 XtFree((char*)menu->entries);
2125 XtFree((char*)menu);
2126 }
2127 XtFree((char*)PopupMenus);
2128 }
2129
2130
2131 /****************************************************************************
2132 **
2133
2134 *E xcmds.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
2135 */
2136