}
\f
-struct mark_widget_value_closure
-{
- void (*markobj) (Lisp_Object);
-};
-
static int
mark_widget_value_mapper (widget_value *val, void *closure)
{
Lisp_Object markee;
-
- struct mark_widget_value_closure *cl =
- (struct mark_widget_value_closure *) closure;
if (val->call_data)
{
VOID_TO_LISP (markee, val->call_data);
- (cl->markobj) (markee);
+ mark_object (markee);
}
if (val->accel)
{
VOID_TO_LISP (markee, val->accel);
- (cl->markobj) (markee);
+ mark_object (markee);
}
return 0;
}
static Lisp_Object
-mark_popup_data (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_popup_data (Lisp_Object obj)
{
struct popup_data *data = (struct popup_data *) XPOPUP_DATA (obj);
call-data */
if (data->id)
- {
- struct mark_widget_value_closure closure;
-
- closure.markobj = markobj;
- lw_map_widget_values (data->id, mark_widget_value_mapper, &closure);
- }
+ lw_map_widget_values (data->id, mark_widget_value_mapper, 0);
return data->last_menubar_buffer;
}
widget_value *wv = (widget_value *) get_opaque_ptr (closure);
free_opaque_ptr (closure);
if (wv)
- free_widget_value (wv);
+ free_widget_value_tree (wv);
return Qnil;
}
if (! wv) return;
if (wv->key) xfree (wv->key);
if (wv->value) xfree (wv->value);
+ if (wv->name) xfree (wv->name);
wv->name = wv->value = wv->key = (char *) 0xDEADBEEF;
Lisp_Object fn, arg;
Lisp_Object data;
Lisp_Object frame;
+ int update_subwindows_p = 0;
struct device *d = get_device_from_display (XtDisplay (widget));
struct frame *f = x_any_widget_or_parent_to_frame (d, widget);
}
else
{
- MARK_SUBWINDOWS_CHANGED;
+ update_subwindows_p = 1;
get_gui_callback (data, &fn, &arg);
}
DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d);
#endif
signal_special_Xt_user_event (frame, fn, arg);
+ /* The result of this evaluation could cause other instances to change so
+ enqueue an update callback to check this. */
+ if (update_subwindows_p)
+ signal_special_Xt_user_event (frame, Qeval,
+ list2 (Qupdate_widget_instances, frame));
}
#if 1
#endif
char *
-menu_separator_style (CONST char *s)
+menu_separator_style (const char *s)
{
- CONST char *p;
+ const char *p;
char first;
if (!s || s[0] == '\0')
return NULL;
}
+char *
+strdup_and_add_accel (char *name)
+{
+ int i;
+ int found_accel = 0;
+
+ for (i=0; name[i]; ++i)
+ if (name[i] == '%' && name[i+1] == '_')
+ {
+ found_accel = 1;
+ break;
+ }
+
+ if (found_accel)
+ return xstrdup (name);
+ else
+ {
+ char *chars = (char *) alloca (strlen (name) + 3);
+ chars[0] = '%';
+ chars[1] = '_';
+ memcpy (chars+2, name, strlen (name) + 1);
+ return xstrdup (chars);
+ }
+}
/* This does the dirty work. gc_currently_forbidden is 1 when this is called.
*/
/* !!#### This function has not been Mule-ized */
/* This function cannot GC because gc_currently_forbidden is set when
it's called */
- struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui_item);
+ Lisp_Gui_Item* pgui = 0;
+
+ /* degenerate case */
+ if (STRINGP (gui_item))
+ {
+ wv->type = TEXT_TYPE;
+ wv->name = (char *) XSTRING_DATA (gui_item);
+ wv->name = strdup_and_add_accel (wv->name);
+ return 1;
+ }
+ else if (!GUI_ITEMP (gui_item))
+ signal_simple_error("need a string or a gui_item here", gui_item);
+
+ pgui = XGUI_ITEM (gui_item);
if (!NILP (pgui->filter))
signal_simple_error(":filter keyword not permitted on leaf nodes", gui_item);
}
#endif /* HAVE_MENUBARS */
+ if (!STRINGP (pgui->name))
+ pgui->name = Feval (pgui->name);
+
CHECK_STRING (pgui->name);
wv->name = (char *) XSTRING_DATA (pgui->name);
+ wv->name = xstrdup (wv->name);
wv->accel = LISP_TO_VOID (gui_item_accelerator (gui_item));
if (!NILP (pgui->suffix))
{
- CONST char *const_bogosity;
+ const char *const_bogosity;
Lisp_Object suffix2;
/* Shortcut to avoid evaluating suffix each time */
CHECK_STRING (suffix2);
}
- GET_C_STRING_FILENAME_DATA_ALLOCA (suffix2, const_bogosity);
+ TO_EXTERNAL_FORMAT (LISP_STRING, suffix2,
+ C_STRING_ALLOCA, const_bogosity,
+ Qfile_name);
wv->value = (char *) const_bogosity;
wv->value = xstrdup (wv->value);
}
}
else if (SYMBOLP (pgui->callback)) /* Show the binding of this command. */
{
- char buf [1024];
+ char buf[1024]; /* #### */
/* #### Warning, dependency here on current_buffer and point */
where_is_to_char (pgui->callback, buf);
if (buf [0])
return 1;
}
+/* parse tree's of gui items into widget_value hierarchies */
+static void gui_item_children_to_widget_values (Lisp_Object items, widget_value* parent);
+
+static widget_value *
+gui_items_to_widget_values_1 (Lisp_Object items, widget_value* parent,
+ widget_value* prev)
+{
+ widget_value* wv = 0;
+
+ assert ((parent || prev) && !(parent && prev));
+ /* now walk the tree creating widget_values as appropriate */
+ if (!CONSP (items))
+ {
+ wv = xmalloc_widget_value();
+ if (parent)
+ parent->contents = wv;
+ else
+ prev->next = wv;
+ if (!button_item_to_widget_value (items, wv, 0, 1))
+ {
+ free_widget_value_tree (wv);
+ if (parent)
+ parent->contents = 0;
+ else
+ prev->next = 0;
+ }
+ else
+ {
+ wv->value = xstrdup (wv->name); /* what a mess... */
+ }
+ }
+ else
+ {
+ /* first one is the parent */
+ if (CONSP (XCAR (items)))
+ signal_simple_error ("parent item must not be a list", XCAR (items));
+
+ if (parent)
+ wv = gui_items_to_widget_values_1 (XCAR (items), parent, 0);
+ else
+ wv = gui_items_to_widget_values_1 (XCAR (items), 0, prev);
+ /* the rest are the children */
+ gui_item_children_to_widget_values (XCDR (items), wv);
+ }
+ return wv;
+}
+
+static void
+gui_item_children_to_widget_values (Lisp_Object items, widget_value* parent)
+{
+ widget_value* wv = 0, *prev = 0;
+ Lisp_Object rest;
+ CHECK_CONS (items);
+
+ /* first one is master */
+ prev = gui_items_to_widget_values_1 (XCAR (items), parent, 0);
+ /* the rest are the children */
+ LIST_LOOP (rest, XCDR (items))
+ {
+ Lisp_Object tab = XCAR (rest);
+ wv = gui_items_to_widget_values_1 (tab, 0, prev);
+ prev = wv;
+ }
+}
+
+widget_value *
+gui_items_to_widget_values (Lisp_Object items)
+{
+ /* !!#### This function has not been Mule-ized */
+ /* This function can GC */
+ widget_value *control = 0, *tmp = 0;
+ int count = specpdl_depth ();
+ Lisp_Object wv_closure;
+
+ if (NILP (items))
+ signal_simple_error ("must have some items", items);
+
+ /* Inhibit GC during this conversion. The reasons for this are
+ the same as in menu_item_descriptor_to_widget_value(); see
+ the large comment above that function. */
+ record_unwind_protect (restore_gc_inhibit,
+ make_int (gc_currently_forbidden));
+ gc_currently_forbidden = 1;
+
+ /* Also make sure that we free the partially-created widget_value
+ tree on Lisp error. */
+ control = xmalloc_widget_value();
+ wv_closure = make_opaque_ptr (control);
+ record_unwind_protect (widget_value_unwind, wv_closure);
+
+ gui_items_to_widget_values_1 (items, control, 0);
+
+ /* mess about getting the data we really want */
+ tmp = control;
+ control = control->contents;
+ tmp->next = 0;
+ tmp->contents = 0;
+ free_widget_value_tree (tmp);
+
+ /* No more need to free the half-filled-in structures. */
+ set_opaque_ptr (wv_closure, 0);
+ unbind_to (count, Qnil);
+
+ return control;
+}
/* This is a kludge to make sure emacs can only link against a version of
lwlib that was compiled in the right way. Emacs references symbols which
#elif defined (HAVE_DIALOGS)
MACROLET (lwlib_dialogs_athena);
#endif
+#ifdef LWLIB_WIDGETS_MOTIF
+ MACROLET (lwlib_widgets_motif);
+#elif defined (HAVE_WIDGETS)
+ MACROLET (lwlib_widgets_athena);
+#endif
#undef MACROLET
}
void
syms_of_gui_x (void)
{
+ INIT_LRECORD_IMPLEMENTATION (popup_data);
+
defsymbol (&Qmenu_no_selection_hook, "menu-no-selection-hook");
}
void
-vars_of_gui_x (void)
+reinit_vars_of_gui_x (void)
{
lwlib_id_tick = (1<<16); /* start big, to not conflict with Energize */
-
+#ifdef HAVE_POPUPS
popup_up_p = 0;
+#endif
+
+ /* this makes only safe calls as in emacs.c */
+ sanity_check_lwlib ();
+}
+
+void
+vars_of_gui_x (void)
+{
+ reinit_vars_of_gui_x ();
Vpopup_callbacks = Qnil;
staticpro (&Vpopup_callbacks);
*/ );
#endif
Fset (Qmenu_no_selection_hook, Qnil);
-
- /* this makes only safe calls as in emacs.c */
- sanity_check_lwlib ();
}