Mercurial > hg > xemacs-beta
comparison src/gui-x.c @ 398:74fd4e045ea6 r21-2-29
Import from CVS: tag r21-2-29
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:13:30 +0200 |
parents | 8626e4521993 |
children | a86b2b5e0111 |
comparison
equal
deleted
inserted
replaced
397:f4aeb21a5bad | 398:74fd4e045ea6 |
---|---|
33 #include "gui-x.h" | 33 #include "gui-x.h" |
34 #include "buffer.h" | 34 #include "buffer.h" |
35 #include "device.h" | 35 #include "device.h" |
36 #include "frame.h" | 36 #include "frame.h" |
37 #include "gui.h" | 37 #include "gui.h" |
38 #include "redisplay.h" | |
38 #include "opaque.h" | 39 #include "opaque.h" |
39 | 40 |
40 #ifdef HAVE_POPUPS | |
41 Lisp_Object Qmenu_no_selection_hook; | 41 Lisp_Object Qmenu_no_selection_hook; |
42 #endif | |
43 | 42 |
44 /* we need a unique id for each popup menu, dialog box, and scrollbar */ | 43 /* we need a unique id for each popup menu, dialog box, and scrollbar */ |
45 static unsigned int lwlib_id_tick; | 44 static unsigned int lwlib_id_tick; |
46 | 45 |
47 LWLIB_ID | 46 LWLIB_ID |
57 if (!tmp) memory_full (); | 56 if (!tmp) memory_full (); |
58 return tmp; | 57 return tmp; |
59 } | 58 } |
60 | 59 |
61 | 60 |
62 #ifdef HAVE_POPUPS | |
63 | |
64 struct mark_widget_value_closure | |
65 { | |
66 void (*markobj) (Lisp_Object); | |
67 }; | |
68 | |
69 static int | 61 static int |
70 mark_widget_value_mapper (widget_value *val, void *closure) | 62 mark_widget_value_mapper (widget_value *val, void *closure) |
71 { | 63 { |
72 Lisp_Object markee; | 64 Lisp_Object markee; |
73 | |
74 struct mark_widget_value_closure *cl = | |
75 (struct mark_widget_value_closure *) closure; | |
76 if (val->call_data) | 65 if (val->call_data) |
77 { | 66 { |
78 VOID_TO_LISP (markee, val->call_data); | 67 VOID_TO_LISP (markee, val->call_data); |
79 (cl->markobj) (markee); | 68 mark_object (markee); |
80 } | 69 } |
81 | 70 |
82 if (val->accel) | 71 if (val->accel) |
83 { | 72 { |
84 VOID_TO_LISP (markee, val->accel); | 73 VOID_TO_LISP (markee, val->accel); |
85 (cl->markobj) (markee); | 74 mark_object (markee); |
86 } | 75 } |
87 return 0; | 76 return 0; |
88 } | 77 } |
89 | 78 |
90 static Lisp_Object | 79 static Lisp_Object |
91 mark_popup_data (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 80 mark_popup_data (Lisp_Object obj) |
92 { | 81 { |
93 struct popup_data *data = (struct popup_data *) XPOPUP_DATA (obj); | 82 struct popup_data *data = (struct popup_data *) XPOPUP_DATA (obj); |
94 | 83 |
95 /* Now mark the callbacks and such that are hidden in the lwlib | 84 /* Now mark the callbacks and such that are hidden in the lwlib |
96 call-data */ | 85 call-data */ |
97 | 86 |
98 if (data->id) | 87 if (data->id) |
99 { | 88 lw_map_widget_values (data->id, mark_widget_value_mapper, 0); |
100 struct mark_widget_value_closure closure; | |
101 | |
102 closure.markobj = markobj; | |
103 lw_map_widget_values (data->id, mark_widget_value_mapper, &closure); | |
104 } | |
105 | 89 |
106 return data->last_menubar_buffer; | 90 return data->last_menubar_buffer; |
107 } | 91 } |
108 | 92 |
109 DEFINE_LRECORD_IMPLEMENTATION ("popup-data", popup_data, | 93 DEFINE_LRECORD_IMPLEMENTATION ("popup-data", popup_data, |
110 mark_popup_data, internal_object_printer, | 94 mark_popup_data, internal_object_printer, |
111 0, 0, 0, struct popup_data); | 95 0, 0, 0, 0, struct popup_data); |
112 | 96 |
113 /* This is like FRAME_MENUBAR_DATA (f), but contains an alist of | 97 /* This is like FRAME_MENUBAR_DATA (f), but contains an alist of |
114 (id . popup-data) for GCPRO'ing the callbacks of the popup menus | 98 (id . popup-data) for GCPRO'ing the callbacks of the popup menus |
115 and dialog boxes. */ | 99 and dialog boxes. */ |
116 static Lisp_Object Vpopup_callbacks; | 100 static Lisp_Object Vpopup_callbacks; |
121 struct popup_data *pdata; | 105 struct popup_data *pdata; |
122 Lisp_Object lid = make_int (id); | 106 Lisp_Object lid = make_int (id); |
123 Lisp_Object lpdata; | 107 Lisp_Object lpdata; |
124 | 108 |
125 assert (NILP (assq_no_quit (lid, Vpopup_callbacks))); | 109 assert (NILP (assq_no_quit (lid, Vpopup_callbacks))); |
126 pdata = alloc_lcrecord_type (struct popup_data, lrecord_popup_data); | 110 pdata = alloc_lcrecord_type (struct popup_data, &lrecord_popup_data); |
127 pdata->id = id; | 111 pdata->id = id; |
128 pdata->last_menubar_buffer = Qnil; | 112 pdata->last_menubar_buffer = Qnil; |
129 pdata->menubar_contents_up_to_date = 0; | 113 pdata->menubar_contents_up_to_date = 0; |
130 XSETPOPUP_DATA (lpdata, pdata); | 114 XSETPOPUP_DATA (lpdata, pdata); |
131 Vpopup_callbacks = Fcons (Fcons (lid, lpdata), Vpopup_callbacks); | 115 Vpopup_callbacks = Fcons (Fcons (lid, lpdata), Vpopup_callbacks); |
157 widget_value_unwind (Lisp_Object closure) | 141 widget_value_unwind (Lisp_Object closure) |
158 { | 142 { |
159 widget_value *wv = (widget_value *) get_opaque_ptr (closure); | 143 widget_value *wv = (widget_value *) get_opaque_ptr (closure); |
160 free_opaque_ptr (closure); | 144 free_opaque_ptr (closure); |
161 if (wv) | 145 if (wv) |
162 free_widget_value (wv); | 146 free_widget_value_tree (wv); |
163 return Qnil; | 147 return Qnil; |
164 } | 148 } |
165 | 149 |
166 #if 0 | 150 #if 0 |
167 static void | 151 static void |
200 free_popup_widget_value_tree (widget_value *wv) | 184 free_popup_widget_value_tree (widget_value *wv) |
201 { | 185 { |
202 if (! wv) return; | 186 if (! wv) return; |
203 if (wv->key) xfree (wv->key); | 187 if (wv->key) xfree (wv->key); |
204 if (wv->value) xfree (wv->value); | 188 if (wv->value) xfree (wv->value); |
189 if (wv->name) xfree (wv->name); | |
205 | 190 |
206 wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; | 191 wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; |
207 | 192 |
208 if (wv->contents && (wv->contents != (widget_value*)1)) | 193 if (wv->contents && (wv->contents != (widget_value*)1)) |
209 { | 194 { |
257 { | 242 { |
258 fn = Qrun_hooks; | 243 fn = Qrun_hooks; |
259 arg = Qmenu_no_selection_hook; | 244 arg = Qmenu_no_selection_hook; |
260 } | 245 } |
261 else | 246 else |
262 get_gui_callback (data, &fn, &arg); | 247 { |
248 MARK_SUBWINDOWS_STATE_CHANGED; | |
249 get_gui_callback (data, &fn, &arg); | |
250 } | |
263 | 251 |
264 /* This is the timestamp used for asserting focus so we need to get an | 252 /* This is the timestamp used for asserting focus so we need to get an |
265 up-to-date value event if no events has been dispatched to emacs | 253 up-to-date value event if no events has been dispatched to emacs |
266 */ | 254 */ |
267 #if defined(HAVE_MENUBARS) | 255 #if defined(HAVE_MENUBARS) |
285 # define wv_set_evalable_slot(slot,form) \ | 273 # define wv_set_evalable_slot(slot,form) \ |
286 ((void) (slot = (!NILP (form)))) | 274 ((void) (slot = (!NILP (form)))) |
287 #endif | 275 #endif |
288 | 276 |
289 char * | 277 char * |
290 menu_separator_style (CONST char *s) | 278 menu_separator_style (const char *s) |
291 { | 279 { |
292 CONST char *p; | 280 const char *p; |
293 char first; | 281 char first; |
294 | 282 |
295 if (!s || s[0] == '\0') | 283 if (!s || s[0] == '\0') |
296 return NULL; | 284 return NULL; |
297 first = s[0]; | 285 first = s[0]; |
313 return xstrdup (p+1); | 301 return xstrdup (p+1); |
314 | 302 |
315 return NULL; | 303 return NULL; |
316 } | 304 } |
317 | 305 |
318 /* set menu accelerator key to first underlined character in menu name */ | |
319 | |
320 Lisp_Object | |
321 menu_name_to_accelerator (char *name) | |
322 { | |
323 while (*name) { | |
324 if (*name=='%') { | |
325 ++name; | |
326 if (!(*name)) | |
327 return Qnil; | |
328 if (*name=='_' && *(name+1)) | |
329 { | |
330 int accelerator = (int) (unsigned char) (*(name+1)); | |
331 return make_char (tolower (accelerator)); | |
332 } | |
333 } | |
334 ++name; | |
335 } | |
336 return Qnil; | |
337 } | |
338 | 306 |
339 /* This does the dirty work. gc_currently_forbidden is 1 when this is called. | 307 /* This does the dirty work. gc_currently_forbidden is 1 when this is called. |
340 */ | 308 */ |
341 | |
342 int | 309 int |
343 button_item_to_widget_value (Lisp_Object desc, widget_value *wv, | 310 button_item_to_widget_value (Lisp_Object gui_item, widget_value *wv, |
344 int allow_text_field_p, int no_keys_p) | 311 int allow_text_field_p, int no_keys_p) |
345 { | 312 { |
346 /* !!#### This function has not been Mule-ized */ | 313 /* !!#### This function has not been Mule-ized */ |
347 /* This function cannot GC because gc_currently_forbidden is set when | 314 /* This function cannot GC because gc_currently_forbidden is set when |
348 it's called */ | 315 it's called */ |
349 Lisp_Object name = Qnil; | 316 Lisp_Gui_Item* pgui = 0; |
350 Lisp_Object callback = Qnil; | 317 |
351 Lisp_Object suffix = Qnil; | 318 /* degenerate case */ |
352 Lisp_Object active_p = Qt; | 319 if (STRINGP (gui_item)) |
353 Lisp_Object include_p = Qt; | 320 { |
354 Lisp_Object selected_p = Qnil; | 321 wv->type = TEXT_TYPE; |
355 Lisp_Object keys = Qnil; | 322 wv->name = (char *) XSTRING_DATA (gui_item); |
356 Lisp_Object style = Qnil; | 323 wv->name = xstrdup (wv->name); |
357 Lisp_Object config_tag = Qnil; | 324 return 1; |
358 Lisp_Object accel = Qnil; | 325 } |
359 int length = XVECTOR_LENGTH (desc); | 326 else if (!GUI_ITEMP (gui_item)) |
360 Lisp_Object *contents = XVECTOR_DATA (desc); | 327 signal_simple_error("need a string or a gui_item here", gui_item); |
361 int plist_p; | 328 |
362 int selected_spec = 0, included_spec = 0; | 329 pgui = XGUI_ITEM (gui_item); |
363 | 330 |
364 if (length < 2) | 331 if (!NILP (pgui->filter)) |
365 signal_simple_error ("Button descriptors must be at least 2 long", desc); | 332 signal_simple_error(":filter keyword not permitted on leaf nodes", gui_item); |
366 | |
367 /* length 2: [ "name" callback ] | |
368 length 3: [ "name" callback active-p ] | |
369 length 4: [ "name" callback active-p suffix ] | |
370 or [ "name" callback keyword value ] | |
371 length 5+: [ "name" callback [ keyword value ]+ ] | |
372 */ | |
373 plist_p = (length >= 5 || (length > 2 && KEYWORDP (contents [2]))); | |
374 | |
375 if (!plist_p && length > 2) | |
376 /* the old way */ | |
377 { | |
378 name = contents [0]; | |
379 callback = contents [1]; | |
380 active_p = contents [2]; | |
381 if (length == 4) | |
382 suffix = contents [3]; | |
383 } | |
384 else | |
385 { | |
386 /* the new way */ | |
387 int i; | |
388 if (length & 1) | |
389 signal_simple_error ( | |
390 "Button descriptor has an odd number of keywords and values", | |
391 desc); | |
392 | |
393 name = contents [0]; | |
394 callback = contents [1]; | |
395 for (i = 2; i < length;) | |
396 { | |
397 Lisp_Object key = contents [i++]; | |
398 Lisp_Object val = contents [i++]; | |
399 if (!KEYWORDP (key)) | |
400 signal_simple_error_2 ("Not a keyword", key, desc); | |
401 | |
402 if (EQ (key, Q_active)) active_p = val; | |
403 else if (EQ (key, Q_suffix)) suffix = val; | |
404 else if (EQ (key, Q_keys)) keys = val; | |
405 else if (EQ (key, Q_style)) style = val; | |
406 else if (EQ (key, Q_selected)) selected_p = val, selected_spec = 1; | |
407 else if (EQ (key, Q_included)) include_p = val, included_spec = 1; | |
408 else if (EQ (key, Q_config)) config_tag = val; | |
409 else if (EQ (key, Q_accelerator)) | |
410 { | |
411 if ( SYMBOLP (val) | |
412 || CHARP (val)) | |
413 accel = val; | |
414 else | |
415 signal_simple_error ("Bad keyboard accelerator", val); | |
416 } | |
417 else if (EQ (key, Q_filter)) | |
418 signal_simple_error(":filter keyword not permitted on leaf nodes", desc); | |
419 else | |
420 signal_simple_error_2 ("Unknown menu item keyword", key, desc); | |
421 } | |
422 } | |
423 | 333 |
424 #ifdef HAVE_MENUBARS | 334 #ifdef HAVE_MENUBARS |
425 if ((!NILP (config_tag) && NILP (Fmemq (config_tag, Vmenubar_configuration))) | 335 if (!gui_item_included_p (gui_item, Vmenubar_configuration)) |
426 || (included_spec && NILP (Feval (include_p)))) | |
427 { | 336 { |
428 /* the include specification says to ignore this item. */ | 337 /* the include specification says to ignore this item. */ |
429 return 0; | 338 return 0; |
430 } | 339 } |
431 #endif /* HAVE_MENUBARS */ | 340 #endif /* HAVE_MENUBARS */ |
432 | 341 |
433 CHECK_STRING (name); | 342 CHECK_STRING (pgui->name); |
434 wv->name = (char *) XSTRING_DATA (name); | 343 wv->name = (char *) XSTRING_DATA (pgui->name); |
435 | 344 wv->name = xstrdup (wv->name); |
436 if (NILP (accel)) | 345 wv->accel = LISP_TO_VOID (gui_item_accelerator (gui_item)); |
437 accel = menu_name_to_accelerator (wv->name); | 346 |
438 wv->accel = LISP_TO_VOID (accel); | 347 if (!NILP (pgui->suffix)) |
439 | 348 { |
440 if (!NILP (suffix)) | 349 const char *const_bogosity; |
441 { | |
442 CONST char *const_bogosity; | |
443 Lisp_Object suffix2; | 350 Lisp_Object suffix2; |
444 | 351 |
445 /* Shortcut to avoid evaluating suffix each time */ | 352 /* Shortcut to avoid evaluating suffix each time */ |
446 if (STRINGP (suffix)) | 353 if (STRINGP (pgui->suffix)) |
447 suffix2 = suffix; | 354 suffix2 = pgui->suffix; |
448 else | 355 else |
449 { | 356 { |
450 suffix2 = Feval (suffix); | 357 suffix2 = Feval (pgui->suffix); |
451 CHECK_STRING (suffix2); | 358 CHECK_STRING (suffix2); |
452 } | 359 } |
453 | 360 |
454 GET_C_STRING_FILENAME_DATA_ALLOCA (suffix2, const_bogosity); | 361 TO_EXTERNAL_FORMAT (LISP_STRING, suffix2, |
362 C_STRING_ALLOCA, const_bogosity, | |
363 Qfile_name); | |
455 wv->value = (char *) const_bogosity; | 364 wv->value = (char *) const_bogosity; |
456 wv->value = xstrdup (wv->value); | 365 wv->value = xstrdup (wv->value); |
457 } | 366 } |
458 | 367 |
459 wv_set_evalable_slot (wv->enabled, active_p); | 368 wv_set_evalable_slot (wv->enabled, pgui->active); |
460 wv_set_evalable_slot (wv->selected, selected_p); | 369 wv_set_evalable_slot (wv->selected, pgui->selected); |
461 | 370 |
462 wv->call_data = LISP_TO_VOID (callback); | 371 if (!NILP (pgui->callback)) |
372 wv->call_data = LISP_TO_VOID (pgui->callback); | |
463 | 373 |
464 if (no_keys_p | 374 if (no_keys_p |
465 #ifdef HAVE_MENUBARS | 375 #ifdef HAVE_MENUBARS |
466 || !menubar_show_keybindings | 376 || !menubar_show_keybindings |
467 #endif | 377 #endif |
468 ) | 378 ) |
469 wv->key = 0; | 379 wv->key = 0; |
470 else if (!NILP (keys)) /* Use this string to generate key bindings */ | 380 else if (!NILP (pgui->keys)) /* Use this string to generate key bindings */ |
471 { | 381 { |
472 CHECK_STRING (keys); | 382 CHECK_STRING (pgui->keys); |
473 keys = Fsubstitute_command_keys (keys); | 383 pgui->keys = Fsubstitute_command_keys (pgui->keys); |
474 if (XSTRING_LENGTH (keys) > 0) | 384 if (XSTRING_LENGTH (pgui->keys) > 0) |
475 wv->key = xstrdup ((char *) XSTRING_DATA (keys)); | 385 wv->key = xstrdup ((char *) XSTRING_DATA (pgui->keys)); |
476 else | 386 else |
477 wv->key = 0; | 387 wv->key = 0; |
478 } | 388 } |
479 else if (SYMBOLP (callback)) /* Show the binding of this command. */ | 389 else if (SYMBOLP (pgui->callback)) /* Show the binding of this command. */ |
480 { | 390 { |
481 char buf [1024]; | 391 char buf [1024]; |
482 /* #### Warning, dependency here on current_buffer and point */ | 392 /* #### Warning, dependency here on current_buffer and point */ |
483 where_is_to_char (callback, buf); | 393 where_is_to_char (pgui->callback, buf); |
484 if (buf [0]) | 394 if (buf [0]) |
485 wv->key = xstrdup (buf); | 395 wv->key = xstrdup (buf); |
486 else | 396 else |
487 wv->key = 0; | 397 wv->key = 0; |
488 } | 398 } |
489 | 399 |
490 CHECK_SYMBOL (style); | 400 CHECK_SYMBOL (pgui->style); |
491 if (NILP (style)) | 401 if (NILP (pgui->style)) |
492 { | 402 { |
493 /* If the callback is nil, treat this item like unselectable text. | 403 /* If the callback is nil, treat this item like unselectable text. |
494 This way, dashes will show up as a separator. */ | 404 This way, dashes will show up as a separator. */ |
495 if (!wv->enabled) | 405 if (!wv->enabled) |
496 wv->type = BUTTON_TYPE; | 406 wv->type = BUTTON_TYPE; |
513 else | 423 else |
514 #endif | 424 #endif |
515 wv->type = BUTTON_TYPE; | 425 wv->type = BUTTON_TYPE; |
516 } | 426 } |
517 } | 427 } |
518 else if (EQ (style, Qbutton)) | 428 else if (EQ (pgui->style, Qbutton)) |
519 wv->type = BUTTON_TYPE; | 429 wv->type = BUTTON_TYPE; |
520 else if (EQ (style, Qtoggle)) | 430 else if (EQ (pgui->style, Qtoggle)) |
521 wv->type = TOGGLE_TYPE; | 431 wv->type = TOGGLE_TYPE; |
522 else if (EQ (style, Qradio)) | 432 else if (EQ (pgui->style, Qradio)) |
523 wv->type = RADIO_TYPE; | 433 wv->type = RADIO_TYPE; |
524 else if (EQ (style, Qtext)) | 434 else if (EQ (pgui->style, Qtext)) |
525 { | 435 { |
526 wv->type = TEXT_TYPE; | 436 wv->type = TEXT_TYPE; |
527 #if 0 | 437 #if 0 |
528 wv->value = wv->name; | 438 wv->value = wv->name; |
529 wv->name = "value"; | 439 wv->name = "value"; |
530 #endif | 440 #endif |
531 } | 441 } |
532 else | 442 else |
533 signal_simple_error_2 ("Unknown style", style, desc); | 443 signal_simple_error_2 ("Unknown style", pgui->style, gui_item); |
534 | 444 |
535 if (!allow_text_field_p && (wv->type == TEXT_TYPE)) | 445 if (!allow_text_field_p && (wv->type == TEXT_TYPE)) |
536 signal_simple_error ("Text field not allowed in this context", desc); | 446 signal_simple_error ("Text field not allowed in this context", gui_item); |
537 | 447 |
538 if (selected_spec && EQ (style, Qtext)) | 448 if (!NILP (pgui->selected) && EQ (pgui->style, Qtext)) |
539 signal_simple_error ( | 449 signal_simple_error ( |
540 ":selected only makes sense with :style toggle, radio or button", | 450 ":selected only makes sense with :style toggle, radio or button", |
541 desc); | 451 gui_item); |
542 return 1; | 452 return 1; |
543 } | 453 } |
544 | 454 |
545 #endif /* HAVE_POPUPS */ | 455 /* 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); | |
457 | |
458 static widget_value * | |
459 gui_items_to_widget_values_1 (Lisp_Object items, widget_value* parent, | |
460 widget_value* prev) | |
461 { | |
462 widget_value* wv = 0; | |
463 | |
464 assert ((parent || prev) && !(parent && prev)); | |
465 /* now walk the tree creating widget_values as appropriate */ | |
466 if (!CONSP (items)) | |
467 { | |
468 wv = xmalloc_widget_value(); | |
469 if (parent) | |
470 parent->contents = wv; | |
471 else | |
472 prev->next = wv; | |
473 if (!button_item_to_widget_value (items, wv, 0, 1)) | |
474 { | |
475 free_widget_value_tree (wv); | |
476 if (parent) | |
477 parent->contents = 0; | |
478 else | |
479 prev->next = 0; | |
480 } | |
481 else | |
482 { | |
483 wv->value = xstrdup (wv->name); /* what a mess... */ | |
484 } | |
485 } | |
486 else | |
487 { | |
488 /* first one is the parent */ | |
489 if (CONSP (XCAR (items))) | |
490 signal_simple_error ("parent item must not be a list", XCAR (items)); | |
491 | |
492 if (parent) | |
493 wv = gui_items_to_widget_values_1 (XCAR (items), parent, 0); | |
494 else | |
495 wv = gui_items_to_widget_values_1 (XCAR (items), 0, prev); | |
496 /* the rest are the children */ | |
497 gui_item_children_to_widget_values (XCDR (items), wv); | |
498 } | |
499 return wv; | |
500 } | |
501 | |
502 static void | |
503 gui_item_children_to_widget_values (Lisp_Object items, widget_value* parent) | |
504 { | |
505 widget_value* wv = 0, *prev = 0; | |
506 Lisp_Object rest; | |
507 CHECK_CONS (items); | |
508 | |
509 /* first one is master */ | |
510 prev = gui_items_to_widget_values_1 (XCAR (items), parent, 0); | |
511 /* the rest are the children */ | |
512 LIST_LOOP (rest, XCDR (items)) | |
513 { | |
514 Lisp_Object tab = XCAR (rest); | |
515 wv = gui_items_to_widget_values_1 (tab, 0, prev); | |
516 prev = wv; | |
517 } | |
518 } | |
519 | |
520 widget_value * | |
521 gui_items_to_widget_values (Lisp_Object items) | |
522 { | |
523 /* !!#### This function has not been Mule-ized */ | |
524 /* This function can GC */ | |
525 widget_value *control = 0, *tmp = 0; | |
526 int count = specpdl_depth (); | |
527 Lisp_Object wv_closure; | |
528 | |
529 if (NILP (items)) | |
530 signal_simple_error ("must have some items", items); | |
531 | |
532 /* Inhibit GC during this conversion. The reasons for this are | |
533 the same as in menu_item_descriptor_to_widget_value(); see | |
534 the large comment above that function. */ | |
535 record_unwind_protect (restore_gc_inhibit, | |
536 make_int (gc_currently_forbidden)); | |
537 gc_currently_forbidden = 1; | |
538 | |
539 /* Also make sure that we free the partially-created widget_value | |
540 tree on Lisp error. */ | |
541 control = xmalloc_widget_value(); | |
542 wv_closure = make_opaque_ptr (control); | |
543 record_unwind_protect (widget_value_unwind, wv_closure); | |
544 | |
545 gui_items_to_widget_values_1 (items, control, 0); | |
546 | |
547 /* mess about getting the data we really want */ | |
548 tmp = control; | |
549 control = control->contents; | |
550 tmp->next = 0; | |
551 tmp->contents = 0; | |
552 free_widget_value_tree (tmp); | |
553 | |
554 /* No more need to free the half-filled-in structures. */ | |
555 set_opaque_ptr (wv_closure, 0); | |
556 unbind_to (count, Qnil); | |
557 | |
558 return control; | |
559 } | |
546 | 560 |
547 /* This is a kludge to make sure emacs can only link against a version of | 561 /* This is a kludge to make sure emacs can only link against a version of |
548 lwlib that was compiled in the right way. Emacs references symbols which | 562 lwlib that was compiled in the right way. Emacs references symbols which |
549 correspond to the way it thinks lwlib was compiled, and if lwlib wasn't | 563 correspond to the way it thinks lwlib was compiled, and if lwlib wasn't |
550 compiled in that way, then somewhat meaningful link errors will result. | 564 compiled in that way, then somewhat meaningful link errors will result. |
591 #ifdef LWLIB_DIALOGS_MOTIF | 605 #ifdef LWLIB_DIALOGS_MOTIF |
592 MACROLET (lwlib_dialogs_motif); | 606 MACROLET (lwlib_dialogs_motif); |
593 #elif defined (HAVE_DIALOGS) | 607 #elif defined (HAVE_DIALOGS) |
594 MACROLET (lwlib_dialogs_athena); | 608 MACROLET (lwlib_dialogs_athena); |
595 #endif | 609 #endif |
610 #ifdef LWLIB_WIDGETS_MOTIF | |
611 MACROLET (lwlib_widgets_motif); | |
612 #elif defined (HAVE_WIDGETS) | |
613 MACROLET (lwlib_widgets_athena); | |
614 #endif | |
596 | 615 |
597 #undef MACROLET | 616 #undef MACROLET |
598 } | 617 } |
599 | 618 |
600 void | 619 void |
601 syms_of_gui_x (void) | 620 syms_of_gui_x (void) |
602 { | 621 { |
622 defsymbol (&Qmenu_no_selection_hook, "menu-no-selection-hook"); | |
623 } | |
624 | |
625 void | |
626 reinit_vars_of_gui_x (void) | |
627 { | |
628 lwlib_id_tick = (1<<16); /* start big, to not conflict with Energize */ | |
603 #ifdef HAVE_POPUPS | 629 #ifdef HAVE_POPUPS |
604 defsymbol (&Qmenu_no_selection_hook, "menu-no-selection-hook"); | 630 popup_up_p = 0; |
605 #endif | 631 #endif |
632 | |
633 /* this makes only safe calls as in emacs.c */ | |
634 sanity_check_lwlib (); | |
606 } | 635 } |
607 | 636 |
608 void | 637 void |
609 vars_of_gui_x (void) | 638 vars_of_gui_x (void) |
610 { | 639 { |
611 lwlib_id_tick = (1<<16); /* start big, to not conflict with Energize */ | 640 reinit_vars_of_gui_x (); |
612 | |
613 #ifdef HAVE_POPUPS | |
614 popup_up_p = 0; | |
615 | 641 |
616 Vpopup_callbacks = Qnil; | 642 Vpopup_callbacks = Qnil; |
617 staticpro (&Vpopup_callbacks); | 643 staticpro (&Vpopup_callbacks); |
618 | 644 |
619 #if 0 | 645 #if 0 |
623 Function or functions to call when a menu or dialog box is dismissed | 649 Function or functions to call when a menu or dialog box is dismissed |
624 without a selection having been made. | 650 without a selection having been made. |
625 */ ); | 651 */ ); |
626 #endif | 652 #endif |
627 Fset (Qmenu_no_selection_hook, Qnil); | 653 Fset (Qmenu_no_selection_hook, Qnil); |
628 #endif /* HAVE_POPUPS */ | 654 } |
629 | |
630 /* this makes only safe calls as in emacs.c */ | |
631 sanity_check_lwlib (); | |
632 } |