/* most of these simple Motif routines are based on the ones in "Power Programming... MOTIF" by Eric F. Johnson and Kevin Reichard */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "motif.h" #ifdef __STDC__ static void really_quit( Widget, caddr_t, caddr_t ); static void present_help( Widget, caddr_t, caddr_t ); #else static void really_quit(); static void present_help(); #endif /* * Str2XmString() converts a standard C-style * null-terminated string into a Motif-style * compound string. Newline characters (\n) * in the C string become separators in the * Motif string, because we use * XmStringLtoRCreate(). */ XmString Str2XmString( string ) char *string; { XmString motif_string; motif_string = XmStringCreateLtoR( string, XmSTRING_DEFAULT_CHARSET ); return( motif_string ); } /* * Creates a simple pull-down menu. * Uses as few hard-coded resources * as possible. */ Widget simple_menu( menu_bar, name, mnemonic ) Widget menu_bar; /* parent */ char *name; int mnemonic; { Widget cascade_button; Widget menu_widget; Arg args[1]; char new_name[ 400 ]; XtSetArg( args[0], XmNmnemonic, mnemonic ); cascade_button = XmCreateCascadeButton( menu_bar, name, args, 1 ); XtManageChild( cascade_button ); /* * Check if Help, if so then * set up this widget for the * menu bar's help. */ if ( strcmp( name, "Help" ) == 0 ) { XtSetArg( args[0], XmNmenuHelpWidget, cascade_button ); XtSetValues( menu_bar, args, 1 ); } /* * Create a new name for the * actual menu. */ strcpy( new_name, name ); strcat( new_name, "Menu" ); menu_widget = XmCreatePulldownMenu( menu_bar, new_name, args, 0 ); XtSetArg( args[0], XmNsubMenuId, menu_widget ); XtSetValues( cascade_button, args, 1 ); return( menu_widget ); } /* simple_menu */ /* * Creates a push button gadget and optionally * a separator gadget (if NeedsSeparator == True) * to add to a simple menu. */ Widget simple_menu_item( menu_widget, name, mnemonic, NeedsSeparator ) Widget menu_widget; char *name; int mnemonic; Boolean NeedsSeparator; /* == True if you want a leading separator */ { Widget widget, sep; Arg args[1]; if ( NeedsSeparator == True ) { sep = XmCreateSeparatorGadget( menu_widget, "sep", NULL, 0 ); XtManageChild( sep ); } XtSetArg( args[0], XmNmnemonic, mnemonic ); widget = XmCreatePushButton( menu_widget, name, args, 1 ); XtManageChild( widget ); return( widget ); } /* simple_menu_item */ /* * Creates a push button gadget and optionally * a separator gadget (if NeedsSeparator == True), * using simple_menu_item(). Then, this routine * adds in a callback function for the menu choice. */ Widget simple_menu_call( menu_widget, name, mnemonic, NeedsSeparator, callback ) Widget menu_widget; char *name; int mnemonic; Boolean NeedsSeparator; /* == True if you want a leading separator */ void (*callback)(); { Widget widget; widget = simple_menu_item( menu_widget, name, mnemonic, NeedsSeparator ); XtAddCallback( widget, XmNactivateCallback, callback, NULL ); return( widget ); } /* simple_menu_call */ /* * CreateHelpWidget() takes a parent (menu bar) * widget and a help message (C text string) and * then creates a help widget and button in the * given menu bar. */ Widget CreateHelpWidget( parent, message ) Widget parent; char message[]; { Widget help_widget; Arg args[ 1 ]; /* * Set Meta-H as a short-cut for calling * up help. */ XtSetArg( args[0], XmNmnemonic, 'H' ); help_widget = XmCreateCascadeButton( parent, "Help", args, 1); XtManageChild( help_widget ); /* * Add a help call-back, * to pop up help on cue. */ XtAddCallback( help_widget, XmNactivateCallback, present_help, message ); /* * Set our help widget as the * default Motif help widget */ XtSetArg( args[0], XmNmenuHelpWidget, help_widget ); XtSetValues( parent, args, 1 ); return( help_widget ); } /* * quit_callback() is called when the user * chooses a quit choice. It creates * and pops up a Dialog widget to * ask the user "Are you sure?". */ void quit_callback( widget, client_data, call_data ) Widget widget; caddr_t client_data; caddr_t call_data; { Widget quit_dialog; quit_dialog = WarningDialog( widget, "QUIT", "Are you sure you\n want to quit?", really_quit ); /* callback function */ } /* quit_callback */ /* * really_quit() quits a Motif program. */ static void really_quit( widget, client_data, call_data ) Widget widget; caddr_t client_data; caddr_t call_data; { XtCloseDisplay( XtDisplay( widget ) ); exit( 0 ); } /* really_quit */ /* * CreateQuitButton() creates a quit button * as a menu choice on a Motif menu bar. */ Widget CreateQuitButton( parent ) Widget parent; { Widget quit_widget; Arg args[ 1 ]; /* * Create a quit button. Meta-Q * will also call the quit button. */ XtSetArg( args[0], XmNmnemonic, 'Q' ); quit_widget = XmCreateCascadeButton( parent, "Quit", args, 1 ); XtManageChild( quit_widget ); XtAddCallback( quit_widget, XmNactivateCallback, quit_callback, /* callback function */ NULL ); return( quit_widget ); } /* -- CreateQuitButton */ Widget CreatePulldownMenu( parent, name_on_bar, title, mnemonic ) Widget parent; char name_on_bar[]; char title[]; int mnemonic; { Widget cascade_widget, menu_widget; Arg args[ 1 ]; char new_name[ 256 ]; XtSetArg( args[0], XmNmnemonic, mnemonic ); cascade_widget = XmCreateCascadeButton( parent, name_on_bar, args, 1 ); XtManageChild( cascade_widget ); /* * Create the menu */ strcpy( new_name, title ); strcat( new_name, "-menu" ); menu_widget = XmCreatePulldownMenu( parent, new_name, NULL, 0 ); /* * Fill in a title in the menu */ CreateLabelWidget( menu_widget, title, title, args, 0 ); /* * Add in a separator */ XtCreateManagedWidget( "sep", xmSeparatorWidgetClass, menu_widget, NULL, 0 ); /* * Set up button on menu bar to * pull down our menu. */ XtSetArg( args[0], XmNsubMenuId, menu_widget ); XtSetValues( cascade_widget, args, 1 ); return( menu_widget ); } /* CreatePulldownMenu */ Widget FillMenu( menu_widget, name, callback_func ) Widget menu_widget; char name[]; void (*callback_func)(); { Widget menu_item; menu_item = XtCreateManagedWidget( name, xmPushButtonWidgetClass, menu_widget, NULL, 0 ); XtAddCallback( menu_item, XmNactivateCallback, callback_func, name ); return( menu_item ); } /* FillMenu */ /* * AddToList() adds a text string to a list * widget at a given position in the list. */ void AddToList( widget, string, position ) Widget widget; char string[]; int position; { XmString motif_string; motif_string = XmStringCreateSimple( string ); XmListAddItemUnselected( widget, motif_string, position ); XmStringFree( motif_string ); } /* AddToList */ /* * Creates a scrolled list widget. */ Widget CreateScrolledList( parent, name, args, n, list_callback ) Widget parent; char name[]; Arg *args; int n; void (*list_callback)(); /* call back function */ { Widget list_widget; /* * Set up size. Note that * n is passed as a parameter to * CreateScrolledList(). */ XtSetArg( args[n], XmNitemCount, 0 ); n++; XtSetArg( args[n], XmNselectionPolicy, XmSINGLE_SELECT ); n++; list_widget = XmCreateScrolledList( parent, name, args, n ); XtManageChild( list_widget ); XtAddCallback( list_widget, XmNsingleSelectionCallback, list_callback, NULL ); return( list_widget ); } /* CreateScrolledList */ /* * ErrorDialog() creates an XmErrorDialog * widget. This widget has no callback set up. * We use this widget to present a simple error * message (with no hope of un-doing the error). * * parent = parent widget * name = name of the ErrorDialog widget * message = text string to be displayed. */ Widget ErrorDialog( parent, name, message ) Widget parent; char name[]; char message[]; { Arg args[1]; Widget widget; XmString motif_string; motif_string = Str2XmString( message ); XtSetArg( args[0], XmNmessageString, motif_string ); widget = XmCreateErrorDialog( parent, name, args, 1 ); /* * Get rid of "Help" * push button. */ RemoveDialButton( widget, XmDIALOG_HELP_BUTTON ); RemoveDialButton( widget, XmDIALOG_CANCEL_BUTTON ); XtManageChild( widget ); XmStringFree( motif_string ); return( widget ); } /* ErrorDialog */ /* * present_help() creates * a help_widget. */ static void present_help( widget, client_data, call_data ) Widget widget; caddr_t client_data; caddr_t call_data; { Widget help_widget, SetUpHelp(); help_widget = SetUpHelp( widget, "Application Help", /* name */ client_data ); /* message */ } /* present_help */ /* * SetUpHelp creates a dialog * widget with your help message. */ Widget SetUpHelp( parent, name, message ) Widget parent; char name[]; char message[]; { Arg args[1]; Widget help_widget; XmString motif_string; motif_string = Str2XmString( message ); XtSetArg( args[0], XmNmessageString, motif_string ); help_widget = XmCreateInformationDialog( parent, name, args, 1 ); /* * Normally, an Information dialog * has three buttons: OK, Cancel * and Help. Since this is the * help dialog, we get rid of the * Cancel and Help buttons, by * making them unmanageable. */ RemoveDialButton( help_widget, XmDIALOG_CANCEL_BUTTON ); RemoveDialButton( help_widget, XmDIALOG_HELP_BUTTON ); XtManageChild( help_widget ); XmStringFree( motif_string ); return( help_widget ); } /* SetUphelp */ /* * Removes (unmanages) the "Help" * push button from a Motif * dialog widget, or other buttons. * which_button should be one of: * XmDIALOG_CANCEL_BUTTON * XmDIALOG_OK_BUTTON * XmDIALOG_HELP_BUTTON */ void RemoveDialButton( widget, which_button ) Widget widget; int which_button; { Widget dead_widget; /* * Normally, an Information dialog * has three buttons: OK, Cancel * and Help. Here, we get rid of * a button. */ dead_widget = XmMessageBoxGetChild( widget, which_button ); XtUnmanageChild( dead_widget ); } /* RemoveDialButton */ /* * PromptDialog() is a convenience routine used to * create a Motif Prompt Dialog. */ Widget PromptDialog( parent, name, message, callback_func ) Widget parent; char name[]; char message[]; void (*callback_func)(); { Arg args[1]; Widget widget; XmString motif_string; motif_string = Str2XmString( message ); XtSetArg( args[0], XmNselectionLabelString, motif_string ); widget = XmCreatePromptDialog( parent, name, args, 1 ); /* * Set up callback for activation, * Just for OK button. */ XtAddCallback( widget, XmNokCallback, callback_func, NULL ); XtManageChild( widget ); XmStringFree( motif_string ); return( widget ); } /* PromptDialog */ /* * WarningDialog() creates a warning dialog widget. * It has Ok and Cancel buttons. callback_func() * is called if Ok is pressed. */ Widget WarningDialog( parent, name, message, callback_func ) Widget parent; char name[]; char message[]; void (*callback_func)(); { Arg args[1]; Widget widget; XmString motif_string; motif_string = Str2XmString( message ); XtSetArg( args[0], XmNmessageString, motif_string ); widget = XmCreateWarningDialog( parent, name, args, 1 ); /* * Get rid of "Help" * push button. */ RemoveDialButton( widget, XmDIALOG_HELP_BUTTON ); /* * Set up callback on OK * button. */ XtAddCallback( widget, XmNokCallback, callback_func, NULL ); XtManageChild( widget ); XmStringFree( motif_string ); return( widget ); } /* WarningDialog */ /* * CreateLabelWidget() creates a simple Motif * label widget, with the given parent, name * and message. */ Widget CreateLabelWidget( parent, name, message, args, n ) Widget parent; char name[]; char message[]; Arg *args; int n; { Widget label_widget; XmString label_text; label_text = XmStringCreateSimple( message ); /* * Set label_text as text for a label widget. * Note that n already has a value when * passed to CreateLabelWidget(), so * we don't initialize n to zero here. */ XtSetArg( args[n], XmNlabelString, label_text ); n++; /* * Create label widget */ label_widget = XtCreateManagedWidget( name, xmLabelWidgetClass, parent, args, n ); XmStringFree( label_text ); return( label_widget ); } /* CreateLabelWidget */ /* * Sets the given label widget to * have the given string */ void SetLabel( widget, string ) Widget widget; char string[]; { XmString label_text; Arg args[ 1 ]; label_text = XmStringCreateSimple( string ); /* * Set label_text as text for a label widget */ XtSetArg( args[0], XmNlabelString, label_text ); XtSetValues( widget, args, 1 ); XmStringFree( label_text ); } Widget CreatePushButton( parent, name, label, args, n, callback_func ) Widget parent; char name[]; char label[]; Arg *args; int n; void (*callback_func)(); { Widget push_widget; XmString motif_string; motif_string = XmStringCreateSimple(label); XtSetArg( args[n], XmNlabelString, motif_string ); n++; push_widget = XtCreateManagedWidget( name, xmPushButtonWidgetClass, parent, args, n ); XtAddCallback( push_widget, XmNactivateCallback, callback_func, NULL ); XmStringFree(motif_string); return( push_widget ); } /* function CreatePushButton */ Widget CreateSimpleButton( parent, label, callback_func, data ) Widget parent; char label[]; void (*callback_func)(); caddr_t data; { Widget push_widget; XmString motif_string; Arg args[1]; motif_string = XmStringCreateSimple(label); XtSetArg( args[0], XmNlabelString, motif_string ); push_widget = XtCreateManagedWidget( "simplePB", xmPushButtonWidgetClass, parent, args, 1 ); XtAddCallback( push_widget, XmNactivateCallback, callback_func, data ); XmStringFree(motif_string); return( push_widget ); } /* * BulletinDefaultButton() sets the given bulletin board * dialog to have the given push button as its default * button (the one that is triggered when the user presses * the Return key). */ void BulletinDefaultButton( bulletin, button ) Widget bulletin; Widget button; { Arg args[1]; XtSetArg( args[0], XmNdefaultButton, button ); XtSetValues( bulletin, args, 1 ); } /* * Creates and manages a toggle button widget. The initial * state of the toggle button is set to state. When the * state changes, callback_func() will be called. The * type specifies the radio button diamond XmONE_OF_MANY or the * square XmN_OF_MANY shape for the toggle button. */ Widget CreateToggle( parent, name, message, state, type, callback_func ) Widget parent; char name[]; char message[]; /* text to appear next to toggle */ Boolean state; /* initial state */ int type; /* XmN_OF_MANY or XmONE_OF_MANY */ void (*callback_func)(); /* state change callback */ { Widget toggle_widget; Arg args[5]; int n=0; XmString motif_string; motif_string = XmStringCreateSimple( message ); XtSetArg( args[n], XmNlabelString, motif_string ); n++; XtSetArg( args[n], XmNindicatorType, type ); n++; XtSetArg( args[n], XmNindicatorOn, True ); n++; XtSetArg( args[n], XmNset, state ); n++; /* on or off */ toggle_widget = XmCreateToggleButton( parent, name, args, n ); XtManageChild( toggle_widget ); XtAddCallback( toggle_widget, XmNvalueChangedCallback, callback_func, NULL ); XmStringFree( motif_string ); return( toggle_widget ); } /* CreateToggle */ Widget CreateSimpleToggle( parent, name, state, type, callback_func, data ) Widget parent; char name[]; Boolean state; /* initial state */ int type; /* XmN_OF_MANY or XmONE_OF_MANY */ void (*callback_func)(); /* state change callback */ caddr_t data; { Widget toggle_widget; Arg args[5]; int n=0; XmString motif_string; motif_string = XmStringCreateSimple( name ); XtSetArg( args[n], XmNlabelString, motif_string ); n++; XtSetArg( args[n], XmNindicatorType, type ); n++; XtSetArg( args[n], XmNindicatorOn, True ); n++; XtSetArg( args[n], XmNset, state ); n++; /* on or off */ toggle_widget = XmCreateToggleButton( parent, name, args, n ); XtManageChild( toggle_widget ); XtAddCallback( toggle_widget, XmNvalueChangedCallback, callback_func, data ); XmStringFree( motif_string ); return( toggle_widget ); } /* * Sets the value of a toggle button to * True of False, depending on the * value of state. If state != 0, * then the toggle is set to True. * If state == 0, then the toggle is * set to False. */ void SetToggle( widget, state ) Widget widget; int state; { Arg args[1]; Boolean on = True; if ( state == 0 ) on = False; XtSetArg( args[0], XmNset, on ); XtSetValues( widget, args, 1 ); } /* * Creates a RowColumn widget to oversee a group * of radio buttons. */ Widget CreateRadioBox( parent, name ) Widget parent; char name[]; { Widget radio; Arg args[3]; int n=0; XtSetArg( args[n], XmNradioBehavior, True ); n++; XtSetArg( args[n], XmNradioAlwaysOne, True ); n++; radio = XmCreateRowColumn( parent, name, args, n ); XtManageChild( radio ); return( radio ); }