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)
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.
#include <X11/CoreP.h>
#include <X11/CompositeP.h>
+#include "../src/lisp.h"
+
#include "lwlib-Xm.h"
#include "lwlib-utils.h"
#include <Xm/DialogS.h>
#include <Xm/Form.h>
+#undef P_
#if defined __STDC__ || defined PROTOTYPES
#define P_(X) X
#else
\f/* Structures to keep destroyed instances */
-typedef struct _destroyed_instance
+typedef struct _destroyed_instance
{
char* name;
char* type;
#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*
instance->next = NULL;
return instance;
}
-
+
static void
free_destroyed_instance (instance)
destroyed_instance* instance;
lw_motif_widget_p (widget)
Widget widget;
{
- return
+ return
XtClass (widget) == xmDialogShellWidgetClass
|| XmIsPrimitive (widget) || XmIsManager (widget) || XmIsGadget (widget);
}
{
XtResource resource;
XmString result = 0;
-
+
resource.resource_name = name;
resource.resource_class = XmCXmString;
resource.resource_type = XmRXmString;
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++)
{
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]);
}
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
XmStringCreateLtoR (val->value, XmSTRING_DEFAULT_CHARSET);
XtSetArg (al [ac], XmNlabelString, built_string); ac++;
}
-
+
XtSetArg (al [ac], XmNlabelType, XmSTRING); ac++;
}
-
+
if (val->key)
{
key_string = XmStringCreateLtoR (val->key, XmSTRING_DEFAULT_CHARSET);
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))
{
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
menu = NULL;
XtSetArg (al [ac], XmNsubMenuId, &menu); ac++;
XtGetValues (widget, al, ac);
-
+
contents = val->contents;
if (!menu)
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);
#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)
{
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)
{
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);
Boolean deep_p;
{
WidgetClass class;
-
+
/* Mark as not edited */
val->edited = False;
/* Common to all widget types */
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 ||
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
val->call_data = old_wv->call_data;
break;
}
-
+
if (class == xmToggleButtonWidgetClass || class == xmToggleButtonGadgetClass)
{
XtVaGetValues (widget, XmNset, &val->selected, NULL);
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;
{
int set = False;
Widget toggle = radio->composite.children [i];
-
+
XtVaGetValues (toggle, XmNset, &set, NULL);
if (set)
{
/* 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
Arg al[64]; /* Arg List */
int ac; /* Arg Count */
int i;
-
+
if (pop_up_p)
{
ac = 0;
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++;
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++)
{
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];
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++;
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++;
XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
XtSetArg(al[ac], XmNrightOffset, 13); ac++;
message = XmCreateLabel (form, "message", al, ac);
-
+
if (list)
XtManageChild (value);
children [i] = icon; i++;
children [i] = icon_separator; i++;
XtManageChildren (children, i);
-
+
if (text_input_slot || list)
{
XtInstallAccelerators (value, button);
XtInstallAccelerators (form, button);
XtSetKeyboardFocus (result, button);
}
-
+
return result;
}
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)
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)
shell_name = "Question";
break;
}
-
+
total_buttons = name [1] - '0';
if (name [3] == 'T' || name [3] == 't')
}
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);
#endif /* ENERGIZE */
widget_creation_entry
-xm_creation_table [] =
+xm_creation_table [] =
{
{"menubar", make_menubar},
{"popup", make_popup_menu},
/* 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 = "<Btn5Down>";
else if (event->xbutton.state & Button4Mask) trans = "<Btn4Down>";
if (trans) XtVaSetValues (widget, XmNmenuPost, trans, NULL);
}
#endif
-
+
XmMenuPosition (widget, (XButtonPressedEvent *) event);
}
-
+
XtManageChild (widget);
}
if (up)
XtManageChild (widget);
else
- XtUnmanageChild (widget);
+ XtUnmanageChild (widget);
}
}
\f
-/* motif callback */
+/* motif callback */
static void
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 */
/* XmNpopdownCallback for MenuShell widgets. WIDGET is the MenuShell,
- CLOSURE is a pointer to the widget_instance of the shell,
+ CLOSURE is a pointer to the widget_instance of the shell,
Note that this callback is called for each cascade button in a
menu, whether or not its submenu is visible. */