Mercurial > hg > xemacs-beta
comparison src/gui-x.c @ 442:abe6d1db359e r21-2-36
Import from CVS: tag r21-2-36
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:35:02 +0200 |
parents | 8de8e3f6228a |
children | 576fb035e263 |
comparison
equal
deleted
inserted
replaced
441:72a7cfa4a488 | 442:abe6d1db359e |
---|---|
1 /* General GUI code -- X-specific. (menubars, scrollbars, toolbars, dialogs) | 1 /* General GUI code -- X-specific. (menubars, scrollbars, toolbars, dialogs) |
2 Copyright (C) 1995 Board of Trustees, University of Illinois. | 2 Copyright (C) 1995 Board of Trustees, University of Illinois. |
3 Copyright (C) 1995, 1996 Ben Wing. | 3 Copyright (C) 1995, 1996, 2000 Ben Wing. |
4 Copyright (C) 1995 Sun Microsystems, Inc. | 4 Copyright (C) 1995 Sun Microsystems, Inc. |
5 Copyright (C) 1998 Free Software Foundation, Inc. | 5 Copyright (C) 1998 Free Software Foundation, Inc. |
6 | 6 |
7 This file is part of XEmacs. | 7 This file is part of XEmacs. |
8 | 8 |
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
22 Boston, MA 02111-1307, USA. */ | 22 Boston, MA 02111-1307, USA. */ |
23 | 23 |
24 /* Synched up with: Not in FSF. */ | 24 /* Synched up with: Not in FSF. */ |
25 | 25 |
26 /* This file Mule-ized by Ben Wing, 7-8-00. */ | |
27 | |
26 #include <config.h> | 28 #include <config.h> |
27 #include "lisp.h" | 29 #include "lisp.h" |
28 | 30 |
29 #include "console-x.h" | 31 #include "console-x.h" |
30 #ifdef LWLIB_USES_MOTIF | 32 #ifdef LWLIB_USES_MOTIF |
31 #include <Xm/Xm.h> /* for XmVersion */ | 33 #include <Xm/Xm.h> /* for XmVersion */ |
32 #endif | 34 #endif |
33 #include "gui-x.h" | 35 #include "gui-x.h" |
34 #include "buffer.h" | 36 #include "buffer.h" |
35 #include "device.h" | 37 #include "device.h" |
38 #include "events.h" | |
36 #include "frame.h" | 39 #include "frame.h" |
37 #include "gui.h" | 40 #include "gui.h" |
41 #include "glyphs.h" | |
38 #include "redisplay.h" | 42 #include "redisplay.h" |
39 #include "opaque.h" | 43 #include "opaque.h" |
40 | |
41 Lisp_Object Qmenu_no_selection_hook; | |
42 | 44 |
43 /* we need a unique id for each popup menu, dialog box, and scrollbar */ | 45 /* we need a unique id for each popup menu, dialog box, and scrollbar */ |
44 static unsigned int lwlib_id_tick; | 46 static unsigned int lwlib_id_tick; |
45 | 47 |
46 LWLIB_ID | 48 LWLIB_ID |
149 | 151 |
150 #if 0 | 152 #if 0 |
151 static void | 153 static void |
152 print_widget_value (widget_value *wv, int depth) | 154 print_widget_value (widget_value *wv, int depth) |
153 { | 155 { |
154 /* !!#### This function has not been Mule-ized */ | 156 /* strings in wv are in external format; use printf not stdout_out |
155 char d [200]; | 157 because the latter takes internal-format strings */ |
158 Extbyte d [200]; | |
156 int i; | 159 int i; |
157 for (i = 0; i < depth; i++) d[i] = ' '; | 160 for (i = 0; i < depth; i++) d[i] = ' '; |
158 d[depth]=0; | 161 d[depth]=0; |
159 /* #### - print type field */ | 162 /* #### - print type field */ |
160 printf ("%sname: %s\n", d, (wv->name ? wv->name : "(null)")); | 163 printf ("%sname: %s\n", d, (wv->name ? wv->name : "(null)")); |
208 | 211 |
209 void | 212 void |
210 popup_selection_callback (Widget widget, LWLIB_ID ignored_id, | 213 popup_selection_callback (Widget widget, LWLIB_ID ignored_id, |
211 XtPointer client_data) | 214 XtPointer client_data) |
212 { | 215 { |
213 Lisp_Object fn, arg; | 216 Lisp_Object data, image_instance, callback, callback_ex; |
214 Lisp_Object data; | 217 Lisp_Object frame, event; |
215 Lisp_Object frame; | 218 int update_subwindows_p = 0; |
216 struct device *d = get_device_from_display (XtDisplay (widget)); | 219 struct device *d = get_device_from_display (XtDisplay (widget)); |
217 struct frame *f = x_any_widget_or_parent_to_frame (d, widget); | 220 struct frame *f = x_any_widget_or_parent_to_frame (d, widget); |
218 | 221 |
219 /* set in lwlib to the time stamp associated with the most recent menu | 222 /* set in lwlib to the time stamp associated with the most recent menu |
220 operation */ | 223 operation */ |
238 Faccept_process_output (Qnil, Qnil, Qnil); | 241 Faccept_process_output (Qnil, Qnil, Qnil); |
239 #endif | 242 #endif |
240 | 243 |
241 if (((EMACS_INT) client_data) == -1) | 244 if (((EMACS_INT) client_data) == -1) |
242 { | 245 { |
243 fn = Qrun_hooks; | 246 event = Fmake_event (Qnil, Qnil); |
244 arg = Qmenu_no_selection_hook; | 247 |
248 XEVENT (event)->event_type = misc_user_event; | |
249 XEVENT (event)->channel = frame; | |
250 XEVENT (event)->event.eval.function = Qrun_hooks; | |
251 XEVENT (event)->event.eval.object = Qmenu_no_selection_hook; | |
245 } | 252 } |
246 else | 253 else |
247 { | 254 { |
248 MARK_SUBWINDOWS_STATE_CHANGED; | 255 image_instance = XCAR (data); |
249 get_gui_callback (data, &fn, &arg); | 256 callback = XCAR (XCDR (data)); |
257 callback_ex = XCDR (XCDR (data)); | |
258 update_subwindows_p = 1; | |
259 /* It is possible for a widget action to cause it to get out of | |
260 sync with its instantiator. Thus it is necessary to signal | |
261 this possibility. */ | |
262 if (IMAGE_INSTANCEP (image_instance)) | |
263 XIMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (image_instance) = 1; | |
264 | |
265 if (!NILP (callback_ex) && !UNBOUNDP (callback_ex)) | |
266 { | |
267 event = Fmake_event (Qnil, Qnil); | |
268 | |
269 XEVENT (event)->event_type = misc_user_event; | |
270 XEVENT (event)->channel = frame; | |
271 XEVENT (event)->event.eval.function = Qeval; | |
272 XEVENT (event)->event.eval.object = | |
273 list4 (Qfuncall, callback_ex, image_instance, event); | |
274 } | |
275 else if (NILP (callback) || UNBOUNDP (callback)) | |
276 event = Qnil; | |
277 else | |
278 { | |
279 Lisp_Object fn, arg; | |
280 | |
281 event = Fmake_event (Qnil, Qnil); | |
282 | |
283 get_gui_callback (callback, &fn, &arg); | |
284 XEVENT (event)->event_type = misc_user_event; | |
285 XEVENT (event)->channel = frame; | |
286 XEVENT (event)->event.eval.function = fn; | |
287 XEVENT (event)->event.eval.object = arg; | |
288 } | |
250 } | 289 } |
251 | 290 |
252 /* This is the timestamp used for asserting focus so we need to get an | 291 /* This is the timestamp used for asserting focus so we need to get an |
253 up-to-date value event if no events has been dispatched to emacs | 292 up-to-date value event if no events has been dispatched to emacs |
254 */ | 293 */ |
255 #if defined(HAVE_MENUBARS) | 294 #if defined(HAVE_MENUBARS) |
256 DEVICE_X_MOUSE_TIMESTAMP (d) = x_focus_timestamp_really_sucks_fix_me_better; | 295 DEVICE_X_MOUSE_TIMESTAMP (d) = x_focus_timestamp_really_sucks_fix_me_better; |
257 #else | 296 #else |
258 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d); | 297 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d); |
259 #endif | 298 #endif |
260 signal_special_Xt_user_event (frame, fn, arg); | 299 if (!NILP (event)) |
300 enqueue_Xt_dispatch_event (event); | |
301 /* The result of this evaluation could cause other instances to change so | |
302 enqueue an update callback to check this. */ | |
303 if (update_subwindows_p && !NILP (event)) | |
304 enqueue_magic_eval_event (update_widget_instances, frame); | |
261 } | 305 } |
262 | 306 |
263 #if 1 | 307 #if 1 |
264 /* Eval the activep slot of the menu item */ | 308 /* Eval the activep slot of the menu item */ |
265 # define wv_set_evalable_slot(slot,form) do { \ | 309 # define wv_set_evalable_slot(slot,form) do { \ |
272 /* Treat the activep slot of the menu item as a boolean */ | 316 /* Treat the activep slot of the menu item as a boolean */ |
273 # define wv_set_evalable_slot(slot,form) \ | 317 # define wv_set_evalable_slot(slot,form) \ |
274 ((void) (slot = (!NILP (form)))) | 318 ((void) (slot = (!NILP (form)))) |
275 #endif | 319 #endif |
276 | 320 |
277 char * | 321 Extbyte * |
278 menu_separator_style (CONST char *s) | 322 menu_separator_style_and_to_external (const Bufbyte *s) |
279 { | 323 { |
280 CONST char *p; | 324 const Bufbyte *p; |
281 char first; | 325 Bufbyte first; |
282 | 326 |
283 if (!s || s[0] == '\0') | 327 if (!s || s[0] == '\0') |
284 return NULL; | 328 return NULL; |
285 first = s[0]; | 329 first = s[0]; |
286 if (first != '-' && first != '=') | 330 if (first != '-' && first != '=') |
296 if (*p == '!' || *p == '\0') | 340 if (*p == '!' || *p == '\0') |
297 return ((first == '-') | 341 return ((first == '-') |
298 ? NULL /* single etched is the default */ | 342 ? NULL /* single etched is the default */ |
299 : xstrdup ("shadowDoubleEtchedIn")); | 343 : xstrdup ("shadowDoubleEtchedIn")); |
300 else if (*p == ':') | 344 else if (*p == ':') |
301 return xstrdup (p+1); | 345 { |
346 Extbyte *retval; | |
347 | |
348 C_STRING_TO_EXTERNAL_MALLOC (p + 1, retval, Qlwlib_encoding); | |
349 return retval; | |
350 } | |
302 | 351 |
303 return NULL; | 352 return NULL; |
304 } | 353 } |
305 | 354 |
355 Extbyte * | |
356 add_accel_and_to_external (Lisp_Object string) | |
357 { | |
358 int i; | |
359 int found_accel = 0; | |
360 Extbyte *retval; | |
361 Bufbyte *name = XSTRING_DATA (string); | |
362 | |
363 for (i = 0; name[i]; ++i) | |
364 if (name[i] == '%' && name[i+1] == '_') | |
365 { | |
366 found_accel = 1; | |
367 break; | |
368 } | |
369 | |
370 if (found_accel) | |
371 LISP_STRING_TO_EXTERNAL_MALLOC (string, retval, Qlwlib_encoding); | |
372 else | |
373 { | |
374 size_t namelen = XSTRING_LENGTH (string); | |
375 Bufbyte *chars = (Bufbyte *) alloca (namelen + 3); | |
376 chars[0] = '%'; | |
377 chars[1] = '_'; | |
378 memcpy (chars + 2, name, namelen + 1); | |
379 C_STRING_TO_EXTERNAL_MALLOC (chars, retval, Qlwlib_encoding); | |
380 } | |
381 | |
382 return retval; | |
383 } | |
306 | 384 |
307 /* This does the dirty work. gc_currently_forbidden is 1 when this is called. | 385 /* This does the dirty work. gc_currently_forbidden is 1 when this is called. |
308 */ | 386 */ |
309 int | 387 int |
310 button_item_to_widget_value (Lisp_Object gui_item, widget_value *wv, | 388 button_item_to_widget_value (Lisp_Object gui_object_instance, |
311 int allow_text_field_p, int no_keys_p) | 389 Lisp_Object gui_item, widget_value *wv, |
312 { | 390 int allow_text_field_p, int no_keys_p, |
313 /* !!#### This function has not been Mule-ized */ | 391 int menu_entry_p, int accel_p) |
392 { | |
314 /* This function cannot GC because gc_currently_forbidden is set when | 393 /* This function cannot GC because gc_currently_forbidden is set when |
315 it's called */ | 394 it's called */ |
316 Lisp_Gui_Item* pgui = 0; | 395 Lisp_Gui_Item* pgui = 0; |
317 | 396 |
318 /* degenerate case */ | 397 /* degenerate case */ |
319 if (STRINGP (gui_item)) | 398 if (STRINGP (gui_item)) |
320 { | 399 { |
321 wv->type = TEXT_TYPE; | 400 wv->type = TEXT_TYPE; |
322 wv->name = (char *) XSTRING_DATA (gui_item); | 401 if (accel_p) |
323 wv->name = xstrdup (wv->name); | 402 wv->name = add_accel_and_to_external (gui_item); |
403 else | |
404 LISP_STRING_TO_EXTERNAL_MALLOC (gui_item, wv->name, Qlwlib_encoding); | |
324 return 1; | 405 return 1; |
325 } | 406 } |
326 else if (!GUI_ITEMP (gui_item)) | 407 else if (!GUI_ITEMP (gui_item)) |
327 signal_simple_error("need a string or a gui_item here", gui_item); | 408 syntax_error ("need a string or a gui_item here", gui_item); |
328 | 409 |
329 pgui = XGUI_ITEM (gui_item); | 410 pgui = XGUI_ITEM (gui_item); |
330 | 411 |
331 if (!NILP (pgui->filter)) | 412 if (!NILP (pgui->filter)) |
332 signal_simple_error(":filter keyword not permitted on leaf nodes", gui_item); | 413 syntax_error (":filter keyword not permitted on leaf nodes", gui_item); |
333 | 414 |
334 #ifdef HAVE_MENUBARS | 415 #ifdef HAVE_MENUBARS |
335 if (!gui_item_included_p (gui_item, Vmenubar_configuration)) | 416 if (menu_entry_p && !gui_item_included_p (gui_item, Vmenubar_configuration)) |
336 { | 417 { |
337 /* the include specification says to ignore this item. */ | 418 /* the include specification says to ignore this item. */ |
338 return 0; | 419 return 0; |
339 } | 420 } |
340 #endif /* HAVE_MENUBARS */ | 421 #endif /* HAVE_MENUBARS */ |
341 | 422 |
423 if (!STRINGP (pgui->name)) | |
424 pgui->name = Feval (pgui->name); | |
425 | |
342 CHECK_STRING (pgui->name); | 426 CHECK_STRING (pgui->name); |
343 wv->name = (char *) XSTRING_DATA (pgui->name); | 427 if (accel_p) |
344 wv->name = xstrdup (wv->name); | 428 { |
345 wv->accel = LISP_TO_VOID (gui_item_accelerator (gui_item)); | 429 wv->name = add_accel_and_to_external (pgui->name); |
430 wv->accel = LISP_TO_VOID (gui_item_accelerator (gui_item)); | |
431 } | |
432 else | |
433 { | |
434 LISP_STRING_TO_EXTERNAL_MALLOC (pgui->name, wv->name, Qlwlib_encoding); | |
435 wv->accel = LISP_TO_VOID (Qnil); | |
436 } | |
346 | 437 |
347 if (!NILP (pgui->suffix)) | 438 if (!NILP (pgui->suffix)) |
348 { | 439 { |
349 CONST char *const_bogosity; | |
350 Lisp_Object suffix2; | 440 Lisp_Object suffix2; |
351 | 441 |
352 /* Shortcut to avoid evaluating suffix each time */ | 442 /* Shortcut to avoid evaluating suffix each time */ |
353 if (STRINGP (pgui->suffix)) | 443 if (STRINGP (pgui->suffix)) |
354 suffix2 = pgui->suffix; | 444 suffix2 = pgui->suffix; |
356 { | 446 { |
357 suffix2 = Feval (pgui->suffix); | 447 suffix2 = Feval (pgui->suffix); |
358 CHECK_STRING (suffix2); | 448 CHECK_STRING (suffix2); |
359 } | 449 } |
360 | 450 |
361 TO_EXTERNAL_FORMAT (LISP_STRING, suffix2, | 451 LISP_STRING_TO_EXTERNAL_MALLOC (suffix2, wv->value, Qlwlib_encoding); |
362 C_STRING_ALLOCA, const_bogosity, | |
363 Qfile_name); | |
364 wv->value = (char *) const_bogosity; | |
365 wv->value = xstrdup (wv->value); | |
366 } | 452 } |
367 | 453 |
368 wv_set_evalable_slot (wv->enabled, pgui->active); | 454 wv_set_evalable_slot (wv->enabled, pgui->active); |
369 wv_set_evalable_slot (wv->selected, pgui->selected); | 455 wv_set_evalable_slot (wv->selected, pgui->selected); |
370 | 456 |
371 if (!NILP (pgui->callback)) | 457 if (!NILP (pgui->callback) || !NILP (pgui->callback_ex)) |
372 wv->call_data = LISP_TO_VOID (pgui->callback); | 458 wv->call_data = LISP_TO_VOID (cons3 (gui_object_instance, |
459 pgui->callback, | |
460 pgui->callback_ex)); | |
373 | 461 |
374 if (no_keys_p | 462 if (no_keys_p |
375 #ifdef HAVE_MENUBARS | 463 #ifdef HAVE_MENUBARS |
376 || !menubar_show_keybindings | 464 || (menu_entry_p && !menubar_show_keybindings) |
377 #endif | 465 #endif |
378 ) | 466 ) |
379 wv->key = 0; | 467 wv->key = 0; |
380 else if (!NILP (pgui->keys)) /* Use this string to generate key bindings */ | 468 else if (!NILP (pgui->keys)) /* Use this string to generate key bindings */ |
381 { | 469 { |
382 CHECK_STRING (pgui->keys); | 470 CHECK_STRING (pgui->keys); |
383 pgui->keys = Fsubstitute_command_keys (pgui->keys); | 471 pgui->keys = Fsubstitute_command_keys (pgui->keys); |
384 if (XSTRING_LENGTH (pgui->keys) > 0) | 472 if (XSTRING_LENGTH (pgui->keys) > 0) |
385 wv->key = xstrdup ((char *) XSTRING_DATA (pgui->keys)); | 473 LISP_STRING_TO_EXTERNAL_MALLOC (pgui->keys, wv->key, Qlwlib_encoding); |
386 else | 474 else |
387 wv->key = 0; | 475 wv->key = 0; |
388 } | 476 } |
389 else if (SYMBOLP (pgui->callback)) /* Show the binding of this command. */ | 477 else if (SYMBOLP (pgui->callback)) /* Show the binding of this command. */ |
390 { | 478 { |
391 char buf [1024]; | 479 char buf[1024]; /* #### */ |
392 /* #### Warning, dependency here on current_buffer and point */ | 480 /* #### Warning, dependency here on current_buffer and point */ |
393 where_is_to_char (pgui->callback, buf); | 481 where_is_to_char (pgui->callback, buf); |
394 if (buf [0]) | 482 if (buf [0]) |
395 wv->key = xstrdup (buf); | 483 C_STRING_TO_EXTERNAL_MALLOC (buf, wv->key, Qlwlib_encoding); |
396 else | 484 else |
397 wv->key = 0; | 485 wv->key = 0; |
398 } | 486 } |
399 | 487 |
400 CHECK_SYMBOL (pgui->style); | 488 CHECK_SYMBOL (pgui->style); |
401 if (NILP (pgui->style)) | 489 if (NILP (pgui->style)) |
402 { | 490 { |
491 Bufbyte *intname; | |
403 /* If the callback is nil, treat this item like unselectable text. | 492 /* If the callback is nil, treat this item like unselectable text. |
404 This way, dashes will show up as a separator. */ | 493 This way, dashes will show up as a separator. */ |
405 if (!wv->enabled) | 494 if (!wv->enabled) |
406 wv->type = BUTTON_TYPE; | 495 wv->type = BUTTON_TYPE; |
407 if (separator_string_p (wv->name)) | 496 EXTERNAL_TO_C_STRING (wv->name, intname, Qlwlib_encoding); |
497 if (separator_string_p (intname)) | |
408 { | 498 { |
409 wv->type = SEPARATOR_TYPE; | 499 wv->type = SEPARATOR_TYPE; |
410 wv->value = menu_separator_style (wv->name); | 500 wv->value = menu_separator_style_and_to_external (intname); |
411 } | 501 } |
412 else | 502 else |
413 { | 503 { |
414 #if 0 | 504 #if 0 |
415 /* #### - this is generally desirable for menubars, but it breaks | 505 /* #### - this is generally desirable for menubars, but it breaks |
438 wv->value = wv->name; | 528 wv->value = wv->name; |
439 wv->name = "value"; | 529 wv->name = "value"; |
440 #endif | 530 #endif |
441 } | 531 } |
442 else | 532 else |
443 signal_simple_error_2 ("Unknown style", pgui->style, gui_item); | 533 syntax_error_2 ("Unknown style", pgui->style, gui_item); |
444 | 534 |
445 if (!allow_text_field_p && (wv->type == TEXT_TYPE)) | 535 if (!allow_text_field_p && (wv->type == TEXT_TYPE)) |
446 signal_simple_error ("Text field not allowed in this context", gui_item); | 536 syntax_error ("Text field not allowed in this context", gui_item); |
447 | 537 |
448 if (!NILP (pgui->selected) && EQ (pgui->style, Qtext)) | 538 if (!NILP (pgui->selected) && EQ (pgui->style, Qtext)) |
449 signal_simple_error ( | 539 syntax_error |
450 ":selected only makes sense with :style toggle, radio or button", | 540 (":selected only makes sense with :style toggle, radio or button", |
451 gui_item); | 541 gui_item); |
452 return 1; | 542 return 1; |
453 } | 543 } |
454 | 544 |
455 /* parse tree's of gui items into widget_value hierarchies */ | 545 /* parse tree's of gui items into widget_value hierarchies */ |
456 static void gui_item_children_to_widget_values (Lisp_Object items, widget_value* parent); | 546 static void gui_item_children_to_widget_values (Lisp_Object |
547 gui_object_instance, | |
548 Lisp_Object items, | |
549 widget_value* parent, | |
550 int accel_p); | |
457 | 551 |
458 static widget_value * | 552 static widget_value * |
459 gui_items_to_widget_values_1 (Lisp_Object items, widget_value* parent, | 553 gui_items_to_widget_values_1 (Lisp_Object gui_object_instance, |
460 widget_value* prev) | 554 Lisp_Object items, widget_value* parent, |
555 widget_value* prev, int accel_p) | |
461 { | 556 { |
462 widget_value* wv = 0; | 557 widget_value* wv = 0; |
463 | 558 |
464 assert ((parent || prev) && !(parent && prev)); | 559 assert ((parent || prev) && !(parent && prev)); |
465 /* now walk the tree creating widget_values as appropriate */ | 560 /* now walk the tree creating widget_values as appropriate */ |
466 if (!CONSP (items)) | 561 if (!CONSP (items)) |
467 { | 562 { |
468 wv = xmalloc_widget_value(); | 563 wv = xmalloc_widget_value (); |
469 if (parent) | 564 if (parent) |
470 parent->contents = wv; | 565 parent->contents = wv; |
471 else | 566 else |
472 prev->next = wv; | 567 prev->next = wv; |
473 if (!button_item_to_widget_value (items, wv, 0, 1)) | 568 if (!button_item_to_widget_value (gui_object_instance, |
569 items, wv, 0, 1, 0, accel_p)) | |
474 { | 570 { |
475 free_widget_value_tree (wv); | 571 free_widget_value_tree (wv); |
476 if (parent) | 572 if (parent) |
477 parent->contents = 0; | 573 parent->contents = 0; |
478 else | 574 else |
479 prev->next = 0; | 575 prev->next = 0; |
480 } | 576 } |
481 else | 577 else |
482 { | 578 wv->value = xstrdup (wv->name); /* what a mess... */ |
483 wv->value = xstrdup (wv->name); /* what a mess... */ | |
484 } | |
485 } | 579 } |
486 else | 580 else |
487 { | 581 { |
488 /* first one is the parent */ | 582 /* first one is the parent */ |
489 if (CONSP (XCAR (items))) | 583 if (CONSP (XCAR (items))) |
490 signal_simple_error ("parent item must not be a list", XCAR (items)); | 584 syntax_error ("parent item must not be a list", XCAR (items)); |
491 | 585 |
492 if (parent) | 586 if (parent) |
493 wv = gui_items_to_widget_values_1 (XCAR (items), parent, 0); | 587 wv = gui_items_to_widget_values_1 (gui_object_instance, |
494 else | 588 XCAR (items), parent, 0, accel_p); |
495 wv = gui_items_to_widget_values_1 (XCAR (items), 0, prev); | 589 else |
590 wv = gui_items_to_widget_values_1 (gui_object_instance, | |
591 XCAR (items), 0, prev, accel_p); | |
496 /* the rest are the children */ | 592 /* the rest are the children */ |
497 gui_item_children_to_widget_values (XCDR (items), wv); | 593 gui_item_children_to_widget_values (gui_object_instance, |
594 XCDR (items), wv, accel_p); | |
498 } | 595 } |
499 return wv; | 596 return wv; |
500 } | 597 } |
501 | 598 |
502 static void | 599 static void |
503 gui_item_children_to_widget_values (Lisp_Object items, widget_value* parent) | 600 gui_item_children_to_widget_values (Lisp_Object gui_object_instance, |
601 Lisp_Object items, widget_value* parent, | |
602 int accel_p) | |
504 { | 603 { |
505 widget_value* wv = 0, *prev = 0; | 604 widget_value* wv = 0, *prev = 0; |
506 Lisp_Object rest; | 605 Lisp_Object rest; |
507 CHECK_CONS (items); | 606 CHECK_CONS (items); |
508 | 607 |
509 /* first one is master */ | 608 /* first one is master */ |
510 prev = gui_items_to_widget_values_1 (XCAR (items), parent, 0); | 609 prev = gui_items_to_widget_values_1 (gui_object_instance, XCAR (items), |
610 parent, 0, accel_p); | |
511 /* the rest are the children */ | 611 /* the rest are the children */ |
512 LIST_LOOP (rest, XCDR (items)) | 612 LIST_LOOP (rest, XCDR (items)) |
513 { | 613 { |
514 Lisp_Object tab = XCAR (rest); | 614 Lisp_Object tab = XCAR (rest); |
515 wv = gui_items_to_widget_values_1 (tab, 0, prev); | 615 wv = gui_items_to_widget_values_1 (gui_object_instance, tab, 0, prev, |
616 accel_p); | |
516 prev = wv; | 617 prev = wv; |
517 } | 618 } |
518 } | 619 } |
519 | 620 |
520 widget_value * | 621 widget_value * |
521 gui_items_to_widget_values (Lisp_Object items) | 622 gui_items_to_widget_values (Lisp_Object gui_object_instance, Lisp_Object items, |
522 { | 623 int accel_p) |
523 /* !!#### This function has not been Mule-ized */ | 624 { |
524 /* This function can GC */ | 625 /* This function can GC */ |
525 widget_value *control = 0, *tmp = 0; | 626 widget_value *control = 0, *tmp = 0; |
526 int count = specpdl_depth (); | 627 int count = specpdl_depth (); |
527 Lisp_Object wv_closure; | 628 Lisp_Object wv_closure; |
528 | 629 |
529 if (NILP (items)) | 630 if (NILP (items)) |
530 signal_simple_error ("must have some items", items); | 631 syntax_error ("must have some items", items); |
531 | 632 |
532 /* Inhibit GC during this conversion. The reasons for this are | 633 /* Inhibit GC during this conversion. The reasons for this are |
533 the same as in menu_item_descriptor_to_widget_value(); see | 634 the same as in menu_item_descriptor_to_widget_value(); see |
534 the large comment above that function. */ | 635 the large comment above that function. */ |
535 record_unwind_protect (restore_gc_inhibit, | 636 record_unwind_protect (restore_gc_inhibit, |
536 make_int (gc_currently_forbidden)); | 637 make_int (gc_currently_forbidden)); |
537 gc_currently_forbidden = 1; | 638 gc_currently_forbidden = 1; |
538 | 639 |
539 /* Also make sure that we free the partially-created widget_value | 640 /* Also make sure that we free the partially-created widget_value |
540 tree on Lisp error. */ | 641 tree on Lisp error. */ |
541 control = xmalloc_widget_value(); | 642 control = xmalloc_widget_value (); |
542 wv_closure = make_opaque_ptr (control); | 643 wv_closure = make_opaque_ptr (control); |
543 record_unwind_protect (widget_value_unwind, wv_closure); | 644 record_unwind_protect (widget_value_unwind, wv_closure); |
544 | 645 |
545 gui_items_to_widget_values_1 (items, control, 0); | 646 gui_items_to_widget_values_1 (gui_object_instance, items, control, 0, |
647 accel_p); | |
546 | 648 |
547 /* mess about getting the data we really want */ | 649 /* mess about getting the data we really want */ |
548 tmp = control; | 650 tmp = control; |
549 control = control->contents; | 651 control = control->contents; |
550 tmp->next = 0; | 652 tmp->next = 0; |
617 } | 719 } |
618 | 720 |
619 void | 721 void |
620 syms_of_gui_x (void) | 722 syms_of_gui_x (void) |
621 { | 723 { |
622 defsymbol (&Qmenu_no_selection_hook, "menu-no-selection-hook"); | 724 INIT_LRECORD_IMPLEMENTATION (popup_data); |
623 } | 725 } |
624 | 726 |
625 void | 727 void |
626 reinit_vars_of_gui_x (void) | 728 reinit_vars_of_gui_x (void) |
627 { | 729 { |
639 { | 741 { |
640 reinit_vars_of_gui_x (); | 742 reinit_vars_of_gui_x (); |
641 | 743 |
642 Vpopup_callbacks = Qnil; | 744 Vpopup_callbacks = Qnil; |
643 staticpro (&Vpopup_callbacks); | 745 staticpro (&Vpopup_callbacks); |
644 | 746 } |
645 #if 0 | |
646 /* This DEFVAR_LISP is just for the benefit of make-docfile. */ | |
647 /* #### misnamed */ | |
648 DEFVAR_LISP ("menu-no-selection-hook", &Vmenu_no_selection_hook /* | |
649 Function or functions to call when a menu or dialog box is dismissed | |
650 without a selection having been made. | |
651 */ ); | |
652 #endif | |
653 Fset (Qmenu_no_selection_hook, Qnil); | |
654 } |