1 /* most of these simple Motif routines are based on the ones in
2 "Power Programming... MOTIF" by Eric F. Johnson and Kevin Reichard */
3
4 #include <X11/Intrinsic.h>
5 #include <X11/StringDefs.h>
6 #include <Xm/Xm.h>
7 #include <Xm/RowColumn.h>
8 #include <Xm/CascadeB.h>
9 #include <Xm/PushB.h>
10 #include <Xm/Separator.h>
11 #include <Xm/List.h>
12 #include <Xm/MessageB.h>
13 #include <Xm/SelectioB.h>
14 #include <Xm/Label.h>
15 #include <Xm/PushBG.h>
16 #include <Xm/SeparatoG.h>
17 #include <Xm/ToggleB.h>
18
19 #include "motif.h"
20
21 #ifdef __STDC__
22 static void really_quit( Widget, caddr_t, caddr_t );
23 static void present_help( Widget, caddr_t, caddr_t );
24 #else
25 static void really_quit();
26 static void present_help();
27 #endif
28
29 /*
30 * Str2XmString() converts a standard C-style
31 * null-terminated string into a Motif-style
32 * compound string. Newline characters (\n)
33 * in the C string become separators in the
34 * Motif string, because we use
35 * XmStringLtoRCreate().
36 */
37
Str2XmString(string)38 XmString Str2XmString( string )
39 char *string;
40 {
41 XmString motif_string;
42 motif_string = XmStringCreateLtoR( string, XmSTRING_DEFAULT_CHARSET );
43 return( motif_string );
44 }
45
46
47 /*
48 * Creates a simple pull-down menu.
49 * Uses as few hard-coded resources
50 * as possible.
51 */
simple_menu(menu_bar,name,mnemonic)52 Widget simple_menu( menu_bar, name, mnemonic )
53 Widget menu_bar; /* parent */
54 char *name;
55 int mnemonic;
56 {
57 Widget cascade_button;
58 Widget menu_widget;
59 Arg args[1];
60 char new_name[ 400 ];
61
62 XtSetArg( args[0], XmNmnemonic, mnemonic );
63 cascade_button = XmCreateCascadeButton( menu_bar, name, args, 1 );
64 XtManageChild( cascade_button );
65
66 /*
67 * Check if Help, if so then
68 * set up this widget for the
69 * menu bar's help.
70 */
71 if ( strcmp( name, "Help" ) == 0 ) {
72 XtSetArg( args[0], XmNmenuHelpWidget, cascade_button );
73 XtSetValues( menu_bar, args, 1 );
74 }
75
76 /*
77 * Create a new name for the
78 * actual menu.
79 */
80 strcpy( new_name, name );
81 strcat( new_name, "Menu" );
82
83 menu_widget = XmCreatePulldownMenu( menu_bar, new_name, args, 0 );
84 XtSetArg( args[0], XmNsubMenuId, menu_widget );
85 XtSetValues( cascade_button, args, 1 );
86 return( menu_widget );
87 } /* simple_menu */
88
89
90 /*
91 * Creates a push button gadget and optionally
92 * a separator gadget (if NeedsSeparator == True)
93 * to add to a simple menu.
94 */
simple_menu_item(menu_widget,name,mnemonic,NeedsSeparator)95 Widget simple_menu_item( menu_widget, name, mnemonic, NeedsSeparator )
96 Widget menu_widget;
97 char *name;
98 int mnemonic;
99 Boolean NeedsSeparator; /* == True if you want a leading separator */
100 {
101 Widget widget, sep;
102 Arg args[1];
103
104 if ( NeedsSeparator == True ) {
105 sep = XmCreateSeparatorGadget( menu_widget, "sep", NULL, 0 );
106 XtManageChild( sep );
107 }
108
109 XtSetArg( args[0], XmNmnemonic, mnemonic );
110 widget = XmCreatePushButton( menu_widget, name, args, 1 );
111 XtManageChild( widget );
112 return( widget );
113 } /* simple_menu_item */
114
115
116
117 /*
118 * Creates a push button gadget and optionally
119 * a separator gadget (if NeedsSeparator == True),
120 * using simple_menu_item(). Then, this routine
121 * adds in a callback function for the menu choice.
122 */
simple_menu_call(menu_widget,name,mnemonic,NeedsSeparator,callback)123 Widget simple_menu_call( menu_widget, name, mnemonic, NeedsSeparator, callback )
124 Widget menu_widget;
125 char *name;
126 int mnemonic;
127 Boolean NeedsSeparator; /* == True if you want a leading separator */
128 void (*callback)();
129 {
130 Widget widget;
131
132 widget = simple_menu_item( menu_widget, name,
133 mnemonic, NeedsSeparator );
134
135 XtAddCallback( widget,
136 XmNactivateCallback,
137 callback, NULL );
138
139 return( widget );
140 } /* simple_menu_call */
141
142
143 /*
144 * CreateHelpWidget() takes a parent (menu bar)
145 * widget and a help message (C text string) and
146 * then creates a help widget and button in the
147 * given menu bar.
148 */
149
CreateHelpWidget(parent,message)150 Widget CreateHelpWidget( parent, message )
151 Widget parent;
152 char message[];
153 {
154 Widget help_widget;
155 Arg args[ 1 ];
156
157 /*
158 * Set Meta-H as a short-cut for calling
159 * up help.
160 */
161 XtSetArg( args[0], XmNmnemonic, 'H' );
162 help_widget = XmCreateCascadeButton( parent, "Help", args, 1);
163 XtManageChild( help_widget );
164
165 /*
166 * Add a help call-back,
167 * to pop up help on cue.
168 */
169 XtAddCallback( help_widget,
170 XmNactivateCallback,
171 present_help,
172 message );
173
174
175 /*
176 * Set our help widget as the
177 * default Motif help widget
178 */
179 XtSetArg( args[0], XmNmenuHelpWidget, help_widget );
180 XtSetValues( parent, args, 1 );
181 return( help_widget );
182 }
183
184
185 /*
186 * quit_callback() is called when the user
187 * chooses a quit choice. It creates
188 * and pops up a Dialog widget to
189 * ask the user "Are you sure?".
190 */
191
quit_callback(widget,client_data,call_data)192 void quit_callback( widget, client_data, call_data )
193 Widget widget;
194 caddr_t client_data;
195 caddr_t call_data;
196 {
197 Widget quit_dialog;
198
199 quit_dialog = WarningDialog( widget,
200 "QUIT",
201 "Are you sure you\n want to quit?",
202 really_quit ); /* callback function */
203
204 } /* quit_callback */
205
206 /*
207 * really_quit() quits a Motif program.
208 */
209
really_quit(widget,client_data,call_data)210 static void really_quit( widget, client_data, call_data )
211 Widget widget;
212 caddr_t client_data;
213 caddr_t call_data;
214 {
215 XtCloseDisplay( XtDisplay( widget ) );
216 exit( 0 );
217 } /* really_quit */
218
219
220 /*
221 * CreateQuitButton() creates a quit button
222 * as a menu choice on a Motif menu bar.
223 */
224
CreateQuitButton(parent)225 Widget CreateQuitButton( parent )
226 Widget parent;
227 {
228 Widget quit_widget;
229 Arg args[ 1 ];
230
231 /*
232 * Create a quit button. Meta-Q
233 * will also call the quit button.
234 */
235 XtSetArg( args[0], XmNmnemonic, 'Q' );
236
237 quit_widget = XmCreateCascadeButton( parent, "Quit", args, 1 );
238 XtManageChild( quit_widget );
239
240 XtAddCallback( quit_widget,
241 XmNactivateCallback,
242 quit_callback, /* callback function */
243 NULL );
244
245 return( quit_widget );
246
247 } /* -- CreateQuitButton */
248
249
CreatePulldownMenu(parent,name_on_bar,title,mnemonic)250 Widget CreatePulldownMenu( parent, name_on_bar, title, mnemonic )
251 Widget parent;
252 char name_on_bar[];
253 char title[];
254 int mnemonic;
255 {
256 Widget cascade_widget, menu_widget;
257 Arg args[ 1 ];
258 char new_name[ 256 ];
259
260 XtSetArg( args[0], XmNmnemonic, mnemonic );
261 cascade_widget = XmCreateCascadeButton( parent,
262 name_on_bar,
263 args,
264 1 );
265
266 XtManageChild( cascade_widget );
267
268 /*
269 * Create the menu
270 */
271 strcpy( new_name, title );
272 strcat( new_name, "-menu" );
273
274 menu_widget = XmCreatePulldownMenu( parent,
275 new_name,
276 NULL,
277 0 );
278
279 /*
280 * Fill in a title in the menu
281 */
282 CreateLabelWidget( menu_widget, title, title, args, 0 );
283
284
285 /*
286 * Add in a separator
287 */
288 XtCreateManagedWidget( "sep",
289 xmSeparatorWidgetClass,
290 menu_widget,
291 NULL,
292 0 );
293
294 /*
295 * Set up button on menu bar to
296 * pull down our menu.
297 */
298 XtSetArg( args[0], XmNsubMenuId, menu_widget );
299 XtSetValues( cascade_widget, args, 1 );
300 return( menu_widget );
301
302 } /* CreatePulldownMenu */
303
304
FillMenu(menu_widget,name,callback_func)305 Widget FillMenu( menu_widget, name, callback_func )
306 Widget menu_widget;
307 char name[];
308 void (*callback_func)();
309
310 {
311 Widget menu_item;
312
313 menu_item = XtCreateManagedWidget( name,
314 xmPushButtonWidgetClass,
315 menu_widget,
316 NULL,
317 0 );
318
319 XtAddCallback( menu_item,
320 XmNactivateCallback,
321 callback_func,
322 name );
323
324 return( menu_item );
325
326 } /* FillMenu */
327
328 /*
329 * AddToList() adds a text string to a list
330 * widget at a given position in the list.
331 */
332
AddToList(widget,string,position)333 void AddToList( widget, string, position )
334 Widget widget;
335 char string[];
336 int position;
337 {
338 XmString motif_string;
339
340 motif_string = XmStringCreateSimple( string );
341 XmListAddItemUnselected( widget, motif_string, position );
342 XmStringFree( motif_string );
343 } /* AddToList */
344
345 /*
346 * Creates a scrolled list widget.
347 */
348
CreateScrolledList(parent,name,args,n,list_callback)349 Widget CreateScrolledList( parent, name, args, n, list_callback )
350 Widget parent;
351 char name[];
352 Arg *args;
353 int n;
354 void (*list_callback)(); /* call back function */
355 {
356 Widget list_widget;
357
358 /*
359 * Set up size. Note that
360 * n is passed as a parameter to
361 * CreateScrolledList().
362 */
363 XtSetArg( args[n], XmNitemCount, 0 ); n++;
364 XtSetArg( args[n], XmNselectionPolicy, XmSINGLE_SELECT ); n++;
365
366 list_widget = XmCreateScrolledList( parent, name, args, n );
367 XtManageChild( list_widget );
368
369 XtAddCallback( list_widget,
370 XmNsingleSelectionCallback,
371 list_callback,
372 NULL );
373
374 return( list_widget );
375 } /* CreateScrolledList */
376
377 /*
378 * ErrorDialog() creates an XmErrorDialog
379 * widget. This widget has no callback set up.
380 * We use this widget to present a simple error
381 * message (with no hope of un-doing the error).
382 *
383 * parent = parent widget
384 * name = name of the ErrorDialog widget
385 * message = text string to be displayed.
386 */
387
ErrorDialog(parent,name,message)388 Widget ErrorDialog( parent, name, message )
389 Widget parent;
390 char name[];
391 char message[];
392 {
393 Arg args[1];
394 Widget widget;
395 XmString motif_string;
396
397 motif_string = Str2XmString( message );
398 XtSetArg( args[0], XmNmessageString, motif_string );
399 widget = XmCreateErrorDialog( parent,
400 name,
401 args,
402 1 );
403 /*
404 * Get rid of "Help"
405 * push button.
406 */
407 RemoveDialButton( widget, XmDIALOG_HELP_BUTTON );
408 RemoveDialButton( widget, XmDIALOG_CANCEL_BUTTON );
409
410 XtManageChild( widget );
411
412 XmStringFree( motif_string );
413 return( widget );
414 } /* ErrorDialog */
415
416 /*
417 * present_help() creates
418 * a help_widget.
419 */
420
present_help(widget,client_data,call_data)421 static void present_help( widget, client_data, call_data )
422 Widget widget;
423 caddr_t client_data;
424 caddr_t call_data;
425 {
426 Widget help_widget, SetUpHelp();
427
428 help_widget = SetUpHelp( widget,
429 "Application Help", /* name */
430 client_data ); /* message */
431
432 } /* present_help */
433
434
435 /*
436 * SetUpHelp creates a dialog
437 * widget with your help message.
438 */
439
SetUpHelp(parent,name,message)440 Widget SetUpHelp( parent, name, message )
441 Widget parent;
442 char name[];
443 char message[];
444 {
445 Arg args[1];
446 Widget help_widget;
447 XmString motif_string;
448
449 motif_string = Str2XmString( message );
450
451 XtSetArg( args[0], XmNmessageString, motif_string );
452 help_widget = XmCreateInformationDialog( parent,
453 name,
454 args,
455 1 );
456 /*
457 * Normally, an Information dialog
458 * has three buttons: OK, Cancel
459 * and Help. Since this is the
460 * help dialog, we get rid of the
461 * Cancel and Help buttons, by
462 * making them unmanageable.
463 */
464 RemoveDialButton( help_widget, XmDIALOG_CANCEL_BUTTON );
465
466 RemoveDialButton( help_widget, XmDIALOG_HELP_BUTTON );
467
468 XtManageChild( help_widget );
469 XmStringFree( motif_string );
470 return( help_widget );
471
472 } /* SetUphelp */
473
474
475 /*
476 * Removes (unmanages) the "Help"
477 * push button from a Motif
478 * dialog widget, or other buttons.
479 * which_button should be one of:
480 * XmDIALOG_CANCEL_BUTTON
481 * XmDIALOG_OK_BUTTON
482 * XmDIALOG_HELP_BUTTON
483 */
484
RemoveDialButton(widget,which_button)485 void RemoveDialButton( widget, which_button )
486 Widget widget;
487 int which_button;
488 {
489 Widget dead_widget;
490
491 /*
492 * Normally, an Information dialog
493 * has three buttons: OK, Cancel
494 * and Help. Here, we get rid of
495 * a button.
496 */
497 dead_widget = XmMessageBoxGetChild( widget, which_button );
498 XtUnmanageChild( dead_widget );
499
500 } /* RemoveDialButton */
501
502
503 /*
504 * PromptDialog() is a convenience routine used to
505 * create a Motif Prompt Dialog.
506 */
PromptDialog(parent,name,message,callback_func)507 Widget PromptDialog( parent, name, message, callback_func )
508 Widget parent;
509 char name[];
510 char message[];
511 void (*callback_func)();
512 {
513 Arg args[1];
514 Widget widget;
515 XmString motif_string;
516
517 motif_string = Str2XmString( message );
518
519 XtSetArg( args[0], XmNselectionLabelString, motif_string );
520 widget = XmCreatePromptDialog( parent,
521 name,
522 args,
523 1 );
524
525 /*
526 * Set up callback for activation,
527 * Just for OK button.
528 */
529 XtAddCallback( widget,
530 XmNokCallback,
531 callback_func,
532 NULL );
533
534 XtManageChild( widget );
535 XmStringFree( motif_string );
536 return( widget );
537 } /* PromptDialog */
538
539
540 /*
541 * WarningDialog() creates a warning dialog widget.
542 * It has Ok and Cancel buttons. callback_func()
543 * is called if Ok is pressed.
544 */
545
WarningDialog(parent,name,message,callback_func)546 Widget WarningDialog( parent, name, message, callback_func )
547 Widget parent;
548 char name[];
549 char message[];
550 void (*callback_func)();
551 {
552 Arg args[1];
553 Widget widget;
554 XmString motif_string;
555
556
557 motif_string = Str2XmString( message );
558
559 XtSetArg( args[0], XmNmessageString, motif_string );
560 widget = XmCreateWarningDialog( parent,
561 name,
562 args,
563 1 );
564 /*
565 * Get rid of "Help"
566 * push button.
567 */
568 RemoveDialButton( widget, XmDIALOG_HELP_BUTTON );
569
570 /*
571 * Set up callback on OK
572 * button.
573 */
574 XtAddCallback( widget,
575 XmNokCallback,
576 callback_func,
577 NULL );
578
579 XtManageChild( widget );
580 XmStringFree( motif_string );
581 return( widget );
582 } /* WarningDialog */
583
584 /*
585 * CreateLabelWidget() creates a simple Motif
586 * label widget, with the given parent, name
587 * and message.
588 */
589
CreateLabelWidget(parent,name,message,args,n)590 Widget CreateLabelWidget( parent, name, message, args, n )
591 Widget parent;
592 char name[];
593 char message[];
594 Arg *args;
595 int n;
596 {
597 Widget label_widget;
598 XmString label_text;
599
600 label_text = XmStringCreateSimple( message );
601
602 /*
603 * Set label_text as text for a label widget.
604 * Note that n already has a value when
605 * passed to CreateLabelWidget(), so
606 * we don't initialize n to zero here.
607 */
608 XtSetArg( args[n], XmNlabelString, label_text ); n++;
609
610 /*
611 * Create label widget
612 */
613 label_widget = XtCreateManagedWidget( name,
614 xmLabelWidgetClass,
615 parent,
616 args,
617 n );
618
619 XmStringFree( label_text );
620 return( label_widget );
621 } /* CreateLabelWidget */
622
623 /*
624 * Sets the given label widget to
625 * have the given string
626 */
SetLabel(widget,string)627 void SetLabel( widget, string )
628 Widget widget;
629 char string[];
630 {
631 XmString label_text;
632 Arg args[ 1 ];
633
634 label_text = XmStringCreateSimple( string );
635
636 /*
637 * Set label_text as text for a label widget
638 */
639 XtSetArg( args[0], XmNlabelString, label_text );
640 XtSetValues( widget, args, 1 );
641
642 XmStringFree( label_text );
643
644 }
645
CreatePushButton(parent,name,label,args,n,callback_func)646 Widget CreatePushButton( parent, name, label, args, n, callback_func )
647 Widget parent;
648 char name[];
649 char label[];
650 Arg *args;
651 int n;
652 void (*callback_func)();
653 {
654 Widget push_widget;
655 XmString motif_string;
656
657 motif_string = XmStringCreateSimple(label);
658 XtSetArg( args[n], XmNlabelString, motif_string ); n++;
659 push_widget = XtCreateManagedWidget( name,
660 xmPushButtonWidgetClass,
661 parent,
662 args,
663 n );
664
665 XtAddCallback( push_widget,
666 XmNactivateCallback,
667 callback_func,
668 NULL );
669
670 XmStringFree(motif_string);
671 return( push_widget );
672
673 } /* function CreatePushButton */
674
CreateSimpleButton(parent,label,callback_func,data)675 Widget CreateSimpleButton( parent, label, callback_func, data )
676 Widget parent;
677 char label[];
678 void (*callback_func)();
679 caddr_t data;
680 {
681 Widget push_widget;
682 XmString motif_string;
683 Arg args[1];
684
685 motif_string = XmStringCreateSimple(label);
686 XtSetArg( args[0], XmNlabelString, motif_string );
687 push_widget = XtCreateManagedWidget( "simplePB",
688 xmPushButtonWidgetClass,
689 parent,
690 args,
691 1 );
692
693 XtAddCallback( push_widget,
694 XmNactivateCallback,
695 callback_func,
696 data );
697
698 XmStringFree(motif_string);
699 return( push_widget );
700
701 }
702
703 /*
704 * BulletinDefaultButton() sets the given bulletin board
705 * dialog to have the given push button as its default
706 * button (the one that is triggered when the user presses
707 * the Return key).
708 */
BulletinDefaultButton(bulletin,button)709 void BulletinDefaultButton( bulletin, button )
710 Widget bulletin;
711 Widget button;
712 {
713 Arg args[1];
714
715 XtSetArg( args[0], XmNdefaultButton, button );
716 XtSetValues( bulletin, args, 1 );
717 }
718
719
720
721 /*
722 * Creates and manages a toggle button widget. The initial
723 * state of the toggle button is set to state. When the
724 * state changes, callback_func() will be called. The
725 * type specifies the radio button diamond XmONE_OF_MANY or the
726 * square XmN_OF_MANY shape for the toggle button.
727 */
728
CreateToggle(parent,name,message,state,type,callback_func)729 Widget CreateToggle( parent, name, message, state, type, callback_func )
730 Widget parent;
731 char name[];
732 char message[]; /* text to appear next to toggle */
733 Boolean state; /* initial state */
734 int type; /* XmN_OF_MANY or XmONE_OF_MANY */
735 void (*callback_func)(); /* state change callback */
736 {
737 Widget toggle_widget;
738 Arg args[5];
739 int n=0;
740 XmString motif_string;
741
742 motif_string = XmStringCreateSimple( message );
743
744 XtSetArg( args[n], XmNlabelString, motif_string ); n++;
745 XtSetArg( args[n], XmNindicatorType, type ); n++;
746 XtSetArg( args[n], XmNindicatorOn, True ); n++;
747 XtSetArg( args[n], XmNset, state ); n++; /* on or off */
748
749 toggle_widget = XmCreateToggleButton( parent, name, args, n );
750
751 XtManageChild( toggle_widget );
752 XtAddCallback( toggle_widget,
753 XmNvalueChangedCallback,
754 callback_func,
755 NULL );
756
757 XmStringFree( motif_string );
758 return( toggle_widget );
759
760 } /* CreateToggle */
761
762
CreateSimpleToggle(parent,name,state,type,callback_func,data)763 Widget CreateSimpleToggle( parent, name, state, type, callback_func, data )
764 Widget parent;
765 char name[];
766 Boolean state; /* initial state */
767 int type; /* XmN_OF_MANY or XmONE_OF_MANY */
768 void (*callback_func)(); /* state change callback */
769 caddr_t data;
770 {
771 Widget toggle_widget;
772 Arg args[5];
773 int n=0;
774 XmString motif_string;
775
776 motif_string = XmStringCreateSimple( name );
777
778 XtSetArg( args[n], XmNlabelString, motif_string ); n++;
779 XtSetArg( args[n], XmNindicatorType, type ); n++;
780 XtSetArg( args[n], XmNindicatorOn, True ); n++;
781 XtSetArg( args[n], XmNset, state ); n++; /* on or off */
782
783 toggle_widget = XmCreateToggleButton( parent, name, args, n );
784
785 XtManageChild( toggle_widget );
786 XtAddCallback( toggle_widget,
787 XmNvalueChangedCallback,
788 callback_func,
789 data );
790
791 XmStringFree( motif_string );
792 return( toggle_widget );
793 }
794
795 /*
796 * Sets the value of a toggle button to
797 * True of False, depending on the
798 * value of state. If state != 0,
799 * then the toggle is set to True.
800 * If state == 0, then the toggle is
801 * set to False.
802 */
803
SetToggle(widget,state)804 void SetToggle( widget, state )
805 Widget widget;
806 int state;
807 {
808 Arg args[1];
809 Boolean on = True;
810
811 if ( state == 0 )
812 on = False;
813
814 XtSetArg( args[0], XmNset, on );
815 XtSetValues( widget, args, 1 );
816 }
817
818
819 /*
820 * Creates a RowColumn widget to oversee a group
821 * of radio buttons.
822 */
823
CreateRadioBox(parent,name)824 Widget CreateRadioBox( parent, name )
825 Widget parent;
826 char name[];
827 {
828 Widget radio;
829 Arg args[3];
830 int n=0;
831
832 XtSetArg( args[n], XmNradioBehavior, True ); n++;
833 XtSetArg( args[n], XmNradioAlwaysOne, True ); n++;
834 radio = XmCreateRowColumn( parent, name, args, n );
835 XtManageChild( radio );
836 return( radio );
837 }
838
839
840
841
842
843
844
845
846
847