X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/566f7ec8587d8cdbbf71fe51ec3acb516d685fc5..03da5d089a8ed035cec443a27259e7d21487a22e:/lwlib/lwlib-Xm.c diff --git a/lwlib/lwlib-Xm.c b/lwlib/lwlib-Xm.c index ca9898b513..32abbca760 100644 --- a/lwlib/lwlib-Xm.c +++ b/lwlib/lwlib-Xm.c @@ -1,22 +1,24 @@ /* The lwlib interface to Motif widgets. + Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003, + 2004, 2005 Free Software Foundation, Inc. Copyright (C) 1992 Lucid, Inc. This file is part of the Lucid Widget Library. -The Lucid Widget Library is free software; you can redistribute it and/or +The Lucid Widget Library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) +the Free Software Foundation; either version 2, or (at your option) any later version. The Lucid Widget Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of +but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include @@ -31,6 +33,8 @@ Boston, MA 02111-1307, USA. */ #include #include +#include "../src/lisp.h" + #include "lwlib-Xm.h" #include "lwlib-utils.h" @@ -59,7 +63,8 @@ Boston, MA 02111-1307, USA. */ #include #include -#ifdef __STDC__ +#undef P_ +#if defined __STDC__ || defined PROTOTYPES #define P_(X) X #else #define P_(X) () @@ -69,7 +74,7 @@ enum do_call_type { pre_activate, selection, no_selection, post_activate }; /* Structures to keep destroyed instances */ -typedef struct _destroyed_instance +typedef struct _destroyed_instance { char* name; char* type; @@ -125,7 +130,6 @@ static void xm_generic_callback P_ ((Widget, XtPointer, XtPointer)); static void xm_nosel_callback P_ ((Widget, XtPointer, XtPointer)); static void xm_pull_down_callback P_ ((Widget, XtPointer, XtPointer)); static void xm_pop_down_callback P_ ((Widget, XtPointer, XtPointer)); -static void xm_unmap_callback P_ ((Widget, XtPointer, XtPointer)); void xm_set_keyboard_focus P_ ((Widget, Widget)); void xm_set_main_areas P_ ((Widget, Widget, Widget)); static void xm_internal_update_other_instances P_ ((Widget, XtPointer, @@ -140,6 +144,32 @@ void xm_manage_resizing P_ ((Widget, Boolean)); #endif +#if 0 + +/* Print the complete X resource name of widget WIDGET to stderr. + This is sometimes handy to have available. */ + +void +x_print_complete_resource_name (widget) + Widget widget; +{ + int i; + String names[100]; + + for (i = 0; i < 100 && widget != NULL; ++i) + { + names[i] = XtName (widget); + widget = XtParent (widget); + } + + for (--i; i >= 1; --i) + fprintf (stderr, "%s.", names[i]); + fprintf (stderr, "%s\n", names[0]); +} + +#endif /* 0 */ + + static destroyed_instance *all_destroyed_instances = NULL; static destroyed_instance* @@ -160,7 +190,7 @@ make_destroyed_instance (name, type, widget, parent, pop_up_p) instance->next = NULL; return instance; } - + static void free_destroyed_instance (instance) destroyed_instance* instance; @@ -182,7 +212,7 @@ Boolean lw_motif_widget_p (widget) Widget widget; { - return + return XtClass (widget) == xmDialogShellWidgetClass || XmIsPrimitive (widget) || XmIsManager (widget) || XmIsGadget (widget); } @@ -194,7 +224,7 @@ resource_motif_string (widget, name) { XtResource resource; XmString result = 0; - + resource.resource_name = name; resource.resource_class = XmCXmString; resource.resource_type = XmRXmString; @@ -226,7 +256,7 @@ destroy_all_children (widget, first_child_to_destroy) XtUnmanageChildren (children + first_child_to_destroy, number - first_child_to_destroy); - /* Unmanage all children and destroy them. They will only be + /* Unmanage all children and destroy them. They will only be really destroyed when we get out of DispatchEvent. */ for (i = first_child_to_destroy; i < number; i++) { @@ -237,10 +267,13 @@ destroy_all_children (widget, first_child_to_destroy) XtCompositeChildren. So get it out of the cascade button and free it. If this child is not a cascade button, then submenu should remain unchanged. */ - XtSetArg (al[0], XmNsubMenuId, &submenu); + XtSetArg (al[0], XmNsubMenuId, &submenu); XtGetValues (children[i], al, 1); if (submenu) - XtDestroyWidget (submenu); + { + destroy_all_children (submenu, 0); + XtDestroyWidget (submenu); + } XtDestroyWidget (children[i]); } @@ -266,7 +299,7 @@ xm_arm_callback (w, client_data, call_data) widget_instance *instance; /* Get the id of the menu bar or popup menu this widget is in. */ - while (1) + while (w != NULL) { if (XmIsRowColumn (w)) { @@ -280,11 +313,14 @@ xm_arm_callback (w, client_data, call_data) w = XtParent (w); } - instance = lw_get_widget_instance (w); - if (instance && instance->info->highlight_cb) + if (w != NULL) { - call_data = cbs->reason == XmCR_DISARM ? NULL : wv; - instance->info->highlight_cb (w, instance->info->id, call_data); + instance = lw_get_widget_instance (w); + if (instance && instance->info->highlight_cb) + { + call_data = cbs->reason == XmCR_DISARM ? NULL : wv; + instance->info->highlight_cb (w, instance->info->id, call_data); + } } } @@ -295,7 +331,7 @@ xm_arm_callback (w, client_data, call_data) the value to update. Menus: - + Emacs fills VAL->name with the text to display in the menu, and sets VAL->value to null. Function make_menu_in_widget creates widgets with VAL->name as resource name. This works because the @@ -334,16 +370,16 @@ xm_update_label (instance, widget, val) else { built_string = - XmStringCreateLtoR (val->value, XmSTRING_DEFAULT_CHARSET); + XmStringCreateLocalized (val->value); XtSetArg (al [ac], XmNlabelString, built_string); ac++; } - + XtSetArg (al [ac], XmNlabelType, XmSTRING); ac++; } - + if (val->key) { - key_string = XmStringCreateLtoR (val->key, XmSTRING_DEFAULT_CHARSET); + key_string = XmStringCreateLocalized (val->key); XtSetArg (al [ac], XmNacceleratorText, key_string); ac++; } @@ -372,7 +408,7 @@ xm_update_list (instance, widget, val) for (cur = val->contents, i = 0; cur; cur = cur->next) if (cur->value) { - XmString xmstr = XmStringCreate (cur->value, XmSTRING_DEFAULT_CHARSET); + XmString xmstr = XmStringCreateLocalized (cur->value); i += 1; XmListAddItem (widget, xmstr, 0); if (cur->selected) @@ -388,7 +424,7 @@ xm_update_pushbutton (instance, widget, val) Widget widget; widget_value* val; { - XtVaSetValues (widget, XmNalignment, XmALIGNMENT_CENTER, 0); + XtVaSetValues (widget, XmNalignment, XmALIGNMENT_CENTER, NULL); XtRemoveAllCallbacks (widget, XmNactivateCallback); XtAddCallback (widget, XmNactivateCallback, xm_generic_callback, instance); } @@ -416,7 +452,7 @@ xm_update_toggle (instance, widget, val) XtAddCallback (widget, XmNvalueChangedCallback, xm_generic_callback, instance); XtVaSetValues (widget, XmNset, val->selected, - XmNalignment, XmALIGNMENT_BEGINNING, 0); + XmNalignment, XmALIGNMENT_BEGINNING, NULL); } static void @@ -444,11 +480,11 @@ xm_update_radiobox (instance, widget, val) toggle = XtNameToWidget (widget, cur->value); if (toggle) { - XtVaSetValues (toggle, XmNsensitive, cur->enabled, 0); + XtSetSensitive (toggle, cur->enabled); if (!val->value && cur->selected) - XtVaSetValues (toggle, XmNset, cur->selected, 0); + XtVaSetValues (toggle, XmNset, cur->selected, NULL); if (val->value && strcmp (val->value, cur->value)) - XtVaSetValues (toggle, XmNset, False, 0); + XtVaSetValues (toggle, XmNset, False, NULL); } } @@ -457,7 +493,7 @@ xm_update_radiobox (instance, widget, val) { toggle = XtNameToWidget (widget, val->value); if (toggle) - XtVaSetValues (toggle, XmNset, True, 0); + XtVaSetValues (toggle, XmNset, True, NULL); } } @@ -488,10 +524,15 @@ make_menu_in_widget (instance, widget, val, keep_first_children) Widget* old_children; unsigned int old_num_children; + /* Disable drag and drop for labels in menu bar. */ + static char overrideTrans[] = ": Noop()"; + XtTranslations override = XtParseTranslationTable (overrideTrans); + old_children = XtCompositeChildren (widget, &old_num_children); /* Allocate the children array */ - for (num_children = 0, cur = val; cur; num_children++, cur = cur->next); + for (num_children = 0, cur = val; cur; num_children++, cur = cur->next) + ; children = (Widget*)XtMalloc (num_children * sizeof (Widget)); /* WIDGET should be a RowColumn. */ @@ -506,18 +547,11 @@ make_menu_in_widget (instance, widget, val, keep_first_children) abort (); menubar_p = type == XmMENU_BAR; -#if 0 /* This can't be used in LessTif as of 2000-01-24 because it's - impossible to decide from this plus the cascading callback if a - popup is still posted or not. When selecting cascade button A, - then B, then clicking on the frame, the sequence of callbacks is - `cascading A', cascading B', `popdown for all cascade buttons in - the menu bar. */ /* Add a callback to popups and pulldowns that is called when it is made invisible again. */ if (!menubar_p) XtAddCallback (XtParent (widget), XmNpopdownCallback, xm_pop_down_callback, (XtPointer)instance); -#endif /* Preserve the first KEEP_FIRST_CHILDREN old children. */ for (child_index = 0, cur = val; child_index < keep_first_children; @@ -538,7 +572,7 @@ make_menu_in_widget (instance, widget, val, keep_first_children) XtSetArg (al[ac], XmNsensitive, cur->enabled); ac++; XtSetArg (al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; XtSetArg (al[ac], XmNuserData, cur->call_data); ac++; - + if (instance->pop_up_p && !cur->contents && !cur->call_data && !lw_separator_p (cur->name, &separator, 1)) { @@ -577,9 +611,9 @@ make_menu_in_widget (instance, widget, val, keep_first_children) XtAddCallback (button, XmNarmCallback, xm_arm_callback, cur); XtAddCallback (button, XmNdisarmCallback, xm_arm_callback, cur); } - + xm_update_label (instance, button, cur); - + /* Add a callback that is called when the button is selected. Toggle buttons don't support XmNactivateCallback, we use XmNvalueChangedCallback in @@ -594,12 +628,6 @@ make_menu_in_widget (instance, widget, val, keep_first_children) { menu = XmCreatePulldownMenu (widget, cur->name, NULL, 0); - /* XmNpopdownCallback is working strangely under LessTif. - Using XmNunmapCallback is the only way to go there. */ - if (menubar_p) - XtAddCallback (menu, XmNunmapCallback, xm_unmap_callback, - (XtPointer) instance); - make_menu_in_widget (instance, menu, cur->contents, 0); XtSetArg (al[ac], XmNsubMenuId, menu); ac++; button = XmCreateCascadeButton (widget, cur->name, al, ac); @@ -608,6 +636,8 @@ make_menu_in_widget (instance, widget, val, keep_first_children) XtAddCallback (button, XmNcascadingCallback, xm_pull_down_callback, (XtPointer)instance); + XtOverrideTranslations (button, override); + } children[child_index] = button; @@ -619,13 +649,7 @@ make_menu_in_widget (instance, widget, val, keep_first_children) XmNmenuHelpWidget work, we need to set it before managing the children.. --gerd. */ if (button) - XtVaSetValues (widget, XmNmenuHelpWidget, button, 0); - - /* LessTif apparently doesn't recompute centered text when more - widgets are added. So, do it after all widgets have been - created. */ - if (title) - XtVaSetValues (title, XmNalignment, XmALIGNMENT_CENTER, 0); + XtVaSetValues (widget, XmNmenuHelpWidget, button, NULL); if (num_children) XtManageChildren (children, num_children); @@ -652,10 +676,8 @@ update_one_menu_entry (instance, widget, val, deep_p) /* update the sensitivity and userdata */ /* Common to all widget types */ - XtVaSetValues (widget, - XmNsensitive, val->enabled, - XmNuserData, val->call_data, - 0); + XtSetSensitive (widget, val->enabled); + XtVaSetValues (widget, XmNuserData, val->call_data, NULL); /* update the menu button as a label. */ if (val->this_one_change >= VISIBLE_CHANGE) @@ -670,7 +692,7 @@ update_one_menu_entry (instance, widget, val, deep_p) menu = NULL; XtSetArg (al [ac], XmNsubMenuId, &menu); ac++; XtGetValues (widget, al, ac); - + contents = val->contents; if (!menu) @@ -701,8 +723,8 @@ update_one_menu_entry (instance, widget, val, deep_p) else { Widget button; - - /* The current menuitem is a XmPushButtonGadget, it + + /* The current menuitem is a XmPushButtonGadget, it needs to be replaced by a CascadeButtonGadget */ XtDestroyWidget (widget_list[i]); menu = XmCreatePulldownMenu (parent, val->name, NULL, 0); @@ -718,11 +740,14 @@ update_one_menu_entry (instance, widget, val, deep_p) #endif button = XmCreateCascadeButton (parent, val->name, al, ac); xm_update_label (instance, button, val); - + XtAddCallback (button, XmNcascadingCallback, xm_pull_down_callback, (XtPointer)instance); XtManageChild (button); } + + if (widget_list) + XtFree ((char*) widget_list); } } else if (!contents) @@ -762,7 +787,7 @@ xm_update_menu (instance, widget, val, deep_p) { if (children) { - for (i = 0, cur = val->contents; + for (i = 0, cur = val->contents; (i < num_children && cur); /* how else to ditch unwanted children ?? - mgd */ i++, cur = cur->next) @@ -802,7 +827,7 @@ xm_update_menu (instance, widget, val, deep_p) { destroy_all_children (widget, num_children_to_keep); make_menu_in_widget (instance, widget, val->contents, - num_children_to_keep); + num_children_to_keep); } XtFree ((char *) children); @@ -850,20 +875,18 @@ xm_update_one_widget (instance, widget, val, deep_p) Boolean deep_p; { WidgetClass class; - + /* Mark as not edited */ val->edited = False; /* Common to all widget types */ - XtVaSetValues (widget, - XmNsensitive, val->enabled, - XmNuserData, val->call_data, - 0); - + XtSetSensitive (widget, val->enabled); + XtVaSetValues (widget, XmNuserData, val->call_data, NULL); + /* Common to all label like widgets */ if (XtIsSubclass (widget, xmLabelWidgetClass)) xm_update_label (instance, widget, val); - + class = XtClass (widget); /* Class specific things */ if (class == xmPushButtonWidgetClass || @@ -885,10 +908,10 @@ xm_update_one_widget (instance, widget, val, deep_p) Boolean radiobox = 0; int ac = 0; Arg al [1]; - + XtSetArg (al [ac], XmNradioBehavior, &radiobox); ac++; XtGetValues (widget, al, ac); - + if (radiobox) xm_update_radiobox (instance, widget, val); else @@ -925,10 +948,10 @@ xm_update_one_value (instance, widget, val) val->call_data = old_wv->call_data; break; } - + if (class == xmToggleButtonWidgetClass || class == xmToggleButtonGadgetClass) { - XtVaGetValues (widget, XmNset, &val->selected, 0); + XtVaGetValues (widget, XmNset, &val->selected, NULL); val->edited = True; } else if (class == xmTextWidgetClass) @@ -950,10 +973,10 @@ xm_update_one_value (instance, widget, val) Boolean radiobox = 0; int ac = 0; Arg al [1]; - + XtSetArg (al [ac], XmNradioBehavior, &radiobox); ac++; XtGetValues (widget, al, ac); - + if (radiobox) { CompositeWidget radio = (CompositeWidget)widget; @@ -962,8 +985,8 @@ xm_update_one_value (instance, widget, val) { int set = False; Widget toggle = radio->composite.children [i]; - - XtVaGetValues (toggle, XmNset, &set, 0); + + XtVaGetValues (toggle, XmNset, &set, NULL); if (set) { if (val->value) @@ -1005,7 +1028,7 @@ xm_update_one_value (instance, widget, val) /* This function is for activating a button from a program. It's wrong because we pass a NULL argument in the call_data which is not Motif compatible. This is used from the XmNdefaultAction callback of the List widgets to - have a double-click put down a dialog box like the button would do. + have a double-click put down a dialog box like the button would do. I could not find a way to do that with accelerators. */ static void @@ -1020,6 +1043,33 @@ activate_button (widget, closure, call_data) /* creation functions */ +/* Called for key press in dialogs. Used to pop down dialog on ESC. */ +static void +dialog_key_cb (widget, closure, event, continue_to_dispatch) + Widget widget; + XtPointer closure; + XEvent *event; + Boolean *continue_to_dispatch; +{ + KeySym sym = 0; + Modifiers modif_ret; + + XtTranslateKeycode (event->xkey.display, event->xkey.keycode, 0, + &modif_ret, &sym); + + if (sym == osfXK_Cancel) + { + Widget w = *((Widget *) closure); + + while (w && ! XtIsShell (w)) + w = XtParent (w); + + if (XtIsShell (w)) XtPopdown (w); + } + + *continue_to_dispatch = TRUE; +} + /* dialogs */ static Widget make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, @@ -1049,7 +1099,7 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, Arg al[64]; /* Arg List */ int ac; /* Arg Count */ int i; - + if (pop_up_p) { ac = 0; @@ -1074,9 +1124,9 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, n_children = left_buttons + right_buttons + 1; ac = 0; - XtSetArg(al[ac], XmNpacking, n_children == 3? + XtSetArg(al[ac], XmNpacking, n_children == 3? XmPACK_COLUMN: XmPACK_TIGHT); ac++; - XtSetArg(al[ac], XmNorientation, n_children == 3? + XtSetArg(al[ac], XmNorientation, n_children == 3? XmVERTICAL: XmHORIZONTAL); ac++; XtSetArg(al[ac], XmNnumColumns, left_buttons + right_buttons + 1); ac++; XtSetArg(al[ac], XmNmarginWidth, 0); ac++; @@ -1093,7 +1143,7 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNrightOffset, 13); ac++; row = XmCreateRowColumn (form, "row", al, ac); - + n_children = 0; for (i = 0; i < left_buttons; i++) { @@ -1108,6 +1158,8 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, XtSetArg(al[ac], XmNmarginWidth, 10); ac++; XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++; children [n_children] = XmCreatePushButton (row, button_name, al, ac); + XtAddEventHandler (children [n_children], + KeyPressMask, False, dialog_key_cb, result); if (i == 0) { @@ -1125,7 +1177,7 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, XtSetArg (al[ac], XmNmappedWhenManaged, FALSE); ac++; children [n_children] = XmCreateLabel (row, "separator_button", al, ac); n_children++; - + for (i = 0; i < right_buttons; i++) { char button_name [16]; @@ -1134,12 +1186,15 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, XtSetArg(al[ac], XmNmarginWidth, 10); ac++; XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++; children [n_children] = XmCreatePushButton (row, button_name, al, ac); + XtAddEventHandler (children [n_children], + KeyPressMask, False, dialog_key_cb, result); + if (! button) button = children [n_children]; n_children++; } - + XtManageChildren (children, n_children); - + ac = 0; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE); ac++; XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++; @@ -1235,7 +1290,7 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, list activate the default button */ XtAddCallback (value, XmNdefaultActionCallback, activate_button, button); } - + ac = 0; XtSetArg(al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++; @@ -1250,7 +1305,7 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNrightOffset, 13); ac++; message = XmCreateLabel (form, "message", al, ac); - + if (list) XtManageChild (value); @@ -1265,7 +1320,7 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, children [i] = icon; i++; children [i] = icon_separator; i++; XtManageChildren (children, i); - + if (text_input_slot || list) { XtInstallAccelerators (value, button); @@ -1276,7 +1331,7 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, XtInstallAccelerators (form, button); XtSetKeyboardFocus (result, button); } - + return result; } @@ -1343,13 +1398,13 @@ recenter_widget (widget) Position x; Position y; - XtVaGetValues (widget, XtNwidth, &child_width, XtNheight, &child_height, 0); + XtVaGetValues (widget, XtNwidth, &child_width, XtNheight, &child_height, NULL); XtVaGetValues (parent, XtNwidth, &parent_width, XtNheight, &parent_height, - 0); + NULL); x = (((Position)parent_width) - ((Position)child_width)) / 2; y = (((Position)parent_height) - ((Position)child_height)) / 2; - + XtTranslateCoords (parent, x, y, &x, &y); if (x + child_width > screen_width) @@ -1362,7 +1417,7 @@ recenter_widget (widget) if (y < 0) y = 0; - XtVaSetValues (widget, XtNx, x, XtNy, y, 0); + XtVaSetValues (widget, XtNx, x, XtNy, y, NULL); } static Widget @@ -1389,11 +1444,11 @@ recycle_instance (instance) focus = XtNameToWidget (widget, "*button1"); if (focus) XtSetKeyboardFocus (widget, focus); - + /* shrink the separator label back to their original size */ separator = XtNameToWidget (widget, "*separator_button"); if (separator) - XtVaSetValues (separator, XtNwidth, 5, XtNheight, 5, 0); + XtVaSetValues (separator, XtNwidth, 5, XtNheight, 5, NULL); /* Center the dialog in its parent */ recenter_widget (widget); @@ -1411,7 +1466,7 @@ xm_create_dialog (instance) Widget widget; Boolean pop_up_p = instance->pop_up_p; char* shell_name = 0; - char* icon_name; + char* icon_name = 0; Boolean text_input_slot = False; Boolean radio_box = False; Boolean list = False; @@ -1457,7 +1512,7 @@ xm_create_dialog (instance) shell_name = "Question"; break; } - + total_buttons = name [1] - '0'; if (name [3] == 'T' || name [3] == 't') @@ -1467,15 +1522,16 @@ xm_create_dialog (instance) } else if (name [3]) right_buttons = name [4] - '0'; - + left_buttons = total_buttons - right_buttons; - + widget = make_dialog (name, parent, pop_up_p, shell_name, icon_name, text_input_slot, radio_box, list, left_buttons, right_buttons); XtAddCallback (widget, XmNpopdownCallback, xm_nosel_callback, (XtPointer) instance); + return widget; } @@ -1491,13 +1547,6 @@ make_menubar (instance) ac = 0; XtSetArg(al[ac], XmNmenuAccelerator, 0); ++ac; - - /* As of 2000-01-17, the LessTif menu bar resizes to height 0 when - all its children are removed, causing an annoying flickering - behavior. Prevent that by not allowing resizing. */ - XtSetArg(al[ac], XmNresizeHeight, False); ++ac; - XtSetArg(al[ac], XmNresizeWidth, False); ++ac; - return XmCreateMenuBar (instance->parent, instance->info->name, al, ac); } @@ -1647,7 +1696,7 @@ make_project_display_dialog (widget_instance* instance) #endif /* ENERGIZE */ widget_creation_entry -xm_creation_table [] = +xm_creation_table [] = { {"menubar", make_menubar}, {"popup", make_popup_menu}, @@ -1727,19 +1776,29 @@ xm_popup_menu (widget, event) if (event->type == ButtonPress || event->type == ButtonRelease) { - /* This is so totally ridiculous: there's NO WAY to tell Motif - that *any* button can select a menu item. Only one button - can have that honor. - */ - char *trans = 0; - if (event->xbutton.state & Button5Mask) trans = ""; - else if (event->xbutton.state & Button4Mask) trans = ""; - else if (event->xbutton.state & Button3Mask) trans = ""; - else if (event->xbutton.state & Button2Mask) trans = ""; - else if (event->xbutton.state & Button1Mask) trans = ""; - if (trans) XtVaSetValues (widget, XmNmenuPost, trans, 0); + /* Setting the menuPost resource only required by Motif 1.1 and + LessTif 0.84 and earlier. With later versions of LessTif, + setting menuPost is unnecessary and may cause problems, so + don't do it. */ +#if XmVersion < 1002 || (defined LESSTIF_VERSION && LESSTIF_VERSION < 84) + { + /* This is so totally ridiculous: there's NO WAY to tell Motif + that *any* button can select a menu item. Only one button + can have that honor. */ + + char *trans = 0; + if (event->xbutton.state & Button5Mask) trans = ""; + else if (event->xbutton.state & Button4Mask) trans = ""; + else if (event->xbutton.state & Button3Mask) trans = ""; + else if (event->xbutton.state & Button2Mask) trans = ""; + else if (event->xbutton.state & Button1Mask) trans = ""; + if (trans) XtVaSetValues (widget, XmNmenuPost, trans, NULL); + } +#endif + XmMenuPosition (widget, (XButtonPressedEvent *) event); } + XtManageChild (widget); } @@ -1749,8 +1808,8 @@ set_min_dialog_size (w) { short width; short height; - XtVaGetValues (w, XmNwidth, &width, XmNheight, &height, 0); - XtVaSetValues (w, XmNminWidth, width, XmNminHeight, height, 0); + XtVaGetValues (w, XmNwidth, &width, XmNheight, &height, NULL); + XtVaSetValues (w, XmNminWidth, width, XmNminHeight, height, NULL); } void @@ -1777,12 +1836,12 @@ xm_pop_instance (instance, up) if (up) XtManageChild (widget); else - XtUnmanageChild (widget); + XtUnmanageChild (widget); } } -/* motif callback */ +/* motif callback */ static void do_call (widget, closure, type) @@ -1811,31 +1870,36 @@ do_call (widget, closure, type) user_data = NULL; XtSetArg (al [ac], XmNuserData, &user_data); ac++; XtGetValues (widget, al, ac); + switch (type) { case pre_activate: if (instance->info->pre_activate_cb) instance->info->pre_activate_cb (widget, id, user_data); break; + case selection: if (instance->info->selection_cb) instance->info->selection_cb (widget, id, user_data); break; + case no_selection: if (instance->info->selection_cb) instance->info->selection_cb (widget, id, (XtPointer) -1); break; + case post_activate: if (instance->info->post_activate_cb) instance->info->post_activate_cb (widget, id, user_data); break; + default: abort (); } } /* Like lw_internal_update_other_instances except that it does not do - anything if its shell parent is not managed. This is to protect + anything if its shell parent is not managed. This is to protect lw_internal_update_other_instances to dereference freed memory if the widget was ``destroyed'' by caching it in the all_destroyed_instances list */ @@ -1870,14 +1934,14 @@ xm_nosel_callback (widget, closure, call_data) XtPointer closure; XtPointer call_data; { - /* This callback is only called when a dialog box is dismissed with the wm's - destroy button (WM_DELETE_WINDOW.) We want the dialog box to be destroyed - in that case, not just unmapped, so that it releases its keyboard grabs. - But there are problems with running our callbacks while the widget is in - the process of being destroyed, so we set XmNdeleteResponse to XmUNMAP - instead of XmDESTROY and then destroy it ourself after having run the - callback. - */ + /* This callback is only called when a dialog box is dismissed with + the wm's destroy button (WM_DELETE_WINDOW.) We want the dialog + box to be destroyed in that case, not just unmapped, so that it + releases its keyboard grabs. But there are problems with running + our callbacks while the widget is in the process of being + destroyed, so we set XmNdeleteResponse to XmUNMAP instead of + XmDESTROY and then destroy it ourself after having run the + callback. */ do_call (widget, closure, no_selection); XtDestroyWidget (widget); } @@ -1901,11 +1965,10 @@ xm_pull_down_callback (widget, closure, call_data) /* XmNpopdownCallback for MenuShell widgets. WIDGET is the MenuShell, - CLOSURE is a pointer to the widget_instance of the shell, CALL_DATA - is always null under LessTif. + CLOSURE is a pointer to the widget_instance of the shell, - 2000-01-23: This callback is called for each cascade button in - a menu, whether or not its submenu is visible. */ + Note that this callback is called for each cascade button in a + menu, whether or not its submenu is visible. */ static void xm_pop_down_callback (widget, closure, call_data) @@ -1915,19 +1978,8 @@ xm_pop_down_callback (widget, closure, call_data) { widget_instance *instance = (widget_instance *) closure; - if ((!instance->pop_up_p && (XtParent (widget) == instance->widget)) - || (XtParent (widget) == instance->parent)) - do_call (widget, closure, post_activate); -} - -static void -xm_unmap_callback (widget, closure, call_data) - Widget widget; - XtPointer closure; - XtPointer call_data; -{ - widget_instance *instance = (widget_instance *) closure; - if (!instance->pop_up_p) + if ((!instance->pop_up_p && XtParent (widget) == instance->widget) + || XtParent (widget) == instance->parent) do_call (widget, closure, post_activate); } @@ -1965,3 +2017,6 @@ xm_manage_resizing (w, flag) { XtVaSetValues (w, XtNallowShellResize, flag, NULL); } + +/* arch-tag: 73976f64-73b2-4600-aa13-d9ede20ee965 + (do not change this comment) */