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 }