comparison src/gui-x.c @ 424:11054d720c21 r21-2-20

Import from CVS: tag r21-2-20
author cvs
date Mon, 13 Aug 2007 11:26:11 +0200
parents 41dbb7a9d5f2
children
comparison
equal deleted inserted replaced
423:28d9c139be4c 424:11054d720c21
56 if (!tmp) memory_full (); 56 if (!tmp) memory_full ();
57 return tmp; 57 return tmp;
58 } 58 }
59 59
60 60
61 struct mark_widget_value_closure
62 {
63 void (*markobj) (Lisp_Object);
64 };
65
66 static int 61 static int
67 mark_widget_value_mapper (widget_value *val, void *closure) 62 mark_widget_value_mapper (widget_value *val, void *closure)
68 { 63 {
69 Lisp_Object markee; 64 Lisp_Object markee;
70
71 struct mark_widget_value_closure *cl =
72 (struct mark_widget_value_closure *) closure;
73 if (val->call_data) 65 if (val->call_data)
74 { 66 {
75 VOID_TO_LISP (markee, val->call_data); 67 VOID_TO_LISP (markee, val->call_data);
76 (cl->markobj) (markee); 68 mark_object (markee);
77 } 69 }
78 70
79 if (val->accel) 71 if (val->accel)
80 { 72 {
81 VOID_TO_LISP (markee, val->accel); 73 VOID_TO_LISP (markee, val->accel);
82 (cl->markobj) (markee); 74 mark_object (markee);
83 } 75 }
84 return 0; 76 return 0;
85 } 77 }
86 78
87 static Lisp_Object 79 static Lisp_Object
88 mark_popup_data (Lisp_Object obj, void (*markobj) (Lisp_Object)) 80 mark_popup_data (Lisp_Object obj)
89 { 81 {
90 struct popup_data *data = (struct popup_data *) XPOPUP_DATA (obj); 82 struct popup_data *data = (struct popup_data *) XPOPUP_DATA (obj);
91 83
92 /* 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
93 call-data */ 85 call-data */
94 86
95 if (data->id) 87 if (data->id)
96 { 88 lw_map_widget_values (data->id, mark_widget_value_mapper, 0);
97 struct mark_widget_value_closure closure;
98
99 closure.markobj = markobj;
100 lw_map_widget_values (data->id, mark_widget_value_mapper, &closure);
101 }
102 89
103 return data->last_menubar_buffer; 90 return data->last_menubar_buffer;
104 } 91 }
105 92
106 DEFINE_LRECORD_IMPLEMENTATION ("popup-data", popup_data, 93 DEFINE_LRECORD_IMPLEMENTATION ("popup-data", popup_data,
255 fn = Qrun_hooks; 242 fn = Qrun_hooks;
256 arg = Qmenu_no_selection_hook; 243 arg = Qmenu_no_selection_hook;
257 } 244 }
258 else 245 else
259 { 246 {
260 MARK_SUBWINDOWS_CHANGED; 247 MARK_SUBWINDOWS_STATE_CHANGED;
261 get_gui_callback (data, &fn, &arg); 248 get_gui_callback (data, &fn, &arg);
262 } 249 }
263 250
264 /* This is the timestamp used for asserting focus so we need to get an 251 /* 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 252 up-to-date value event if no events has been dispatched to emacs
323 int allow_text_field_p, int no_keys_p) 310 int allow_text_field_p, int no_keys_p)
324 { 311 {
325 /* !!#### This function has not been Mule-ized */ 312 /* !!#### This function has not been Mule-ized */
326 /* This function cannot GC because gc_currently_forbidden is set when 313 /* This function cannot GC because gc_currently_forbidden is set when
327 it's called */ 314 it's called */
328 struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui_item); 315 struct Lisp_Gui_Item* pgui = 0;
316
317 /* degenerate case */
318 if (STRINGP (gui_item))
319 {
320 wv->type = TEXT_TYPE;
321 wv->name = (char *) XSTRING_DATA (gui_item);
322 wv->name = xstrdup (wv->name);
323 return 1;
324 }
325 else if (!GUI_ITEMP (gui_item))
326 signal_simple_error("need a string or a gui_item here", gui_item);
327
328 pgui = XGUI_ITEM (gui_item);
329 329
330 if (!NILP (pgui->filter)) 330 if (!NILP (pgui->filter))
331 signal_simple_error(":filter keyword not permitted on leaf nodes", gui_item); 331 signal_simple_error(":filter keyword not permitted on leaf nodes", gui_item);
332 332
333 #ifdef HAVE_MENUBARS 333 #ifdef HAVE_MENUBARS
338 } 338 }
339 #endif /* HAVE_MENUBARS */ 339 #endif /* HAVE_MENUBARS */
340 340
341 CHECK_STRING (pgui->name); 341 CHECK_STRING (pgui->name);
342 wv->name = (char *) XSTRING_DATA (pgui->name); 342 wv->name = (char *) XSTRING_DATA (pgui->name);
343 wv->name = xstrdup (wv->name);
343 wv->accel = LISP_TO_VOID (gui_item_accelerator (gui_item)); 344 wv->accel = LISP_TO_VOID (gui_item_accelerator (gui_item));
344 345
345 if (!NILP (pgui->suffix)) 346 if (!NILP (pgui->suffix))
346 { 347 {
347 CONST char *const_bogosity; 348 CONST char *const_bogosity;
446 ":selected only makes sense with :style toggle, radio or button", 447 ":selected only makes sense with :style toggle, radio or button",
447 gui_item); 448 gui_item);
448 return 1; 449 return 1;
449 } 450 }
450 451
452 /* parse tree's of gui items into widget_value hierarchies */
453 static void gui_item_children_to_widget_values (Lisp_Object items, widget_value* parent);
454
455 static widget_value *
456 gui_items_to_widget_values_1 (Lisp_Object items, widget_value* parent,
457 widget_value* prev)
458 {
459 widget_value* wv = 0;
460
461 assert ((parent || prev) && !(parent && prev));
462 /* now walk the tree creating widget_values as appropriate */
463 if (!CONSP (items))
464 {
465 wv = xmalloc_widget_value();
466 if (parent)
467 parent->contents = wv;
468 else
469 prev->next = wv;
470 if (!button_item_to_widget_value (items, wv, 0, 1))
471 {
472 free_widget_value (wv);
473 if (parent)
474 parent->contents = 0;
475 else
476 prev->next = 0;
477 }
478 else
479 {
480 wv->value = xstrdup (wv->name); /* what a mess... */
481 }
482 }
483 else
484 {
485 /* first one is the parent */
486 if (CONSP (XCAR (items)))
487 signal_simple_error ("parent item must not be a list", XCAR (items));
488
489 if (parent)
490 wv = gui_items_to_widget_values_1 (XCAR (items), parent, 0);
491 else
492 wv = gui_items_to_widget_values_1 (XCAR (items), 0, prev);
493 /* the rest are the children */
494 gui_item_children_to_widget_values (XCDR (items), wv);
495 }
496 return wv;
497 }
498
499 static void
500 gui_item_children_to_widget_values (Lisp_Object items, widget_value* parent)
501 {
502 widget_value* wv = 0, *prev = 0;
503 Lisp_Object rest;
504 CHECK_CONS (items);
505
506 /* first one is master */
507 prev = gui_items_to_widget_values_1 (XCAR (items), parent, 0);
508 /* the rest are the children */
509 LIST_LOOP (rest, XCDR (items))
510 {
511 Lisp_Object tab = XCAR (rest);
512 wv = gui_items_to_widget_values_1 (tab, 0, prev);
513 prev = wv;
514 }
515 }
516
517 widget_value *
518 gui_items_to_widget_values (Lisp_Object items)
519 {
520 /* !!#### This function has not been Mule-ized */
521 /* This function can GC */
522 widget_value *control = 0, *tmp = 0;
523 int count = specpdl_depth ();
524 Lisp_Object wv_closure;
525
526 if (NILP (items))
527 signal_simple_error ("must have some items", items);
528
529 /* Inhibit GC during this conversion. The reasons for this are
530 the same as in menu_item_descriptor_to_widget_value(); see
531 the large comment above that function. */
532 record_unwind_protect (restore_gc_inhibit,
533 make_int (gc_currently_forbidden));
534 gc_currently_forbidden = 1;
535
536 /* Also make sure that we free the partially-created widget_value
537 tree on Lisp error. */
538 control = xmalloc_widget_value();
539 wv_closure = make_opaque_ptr (control);
540 record_unwind_protect (widget_value_unwind, wv_closure);
541
542 gui_items_to_widget_values_1 (items, control, 0);
543
544 /* mess about getting the data we really want */
545 tmp = control;
546 control = control->contents;
547 tmp->next = 0;
548 tmp->contents = 0;
549 free_widget_value (tmp);
550
551 /* No more need to free the half-filled-in structures. */
552 set_opaque_ptr (wv_closure, 0);
553 unbind_to (count, Qnil);
554
555 return control;
556 }
451 557
452 /* This is a kludge to make sure emacs can only link against a version of 558 /* This is a kludge to make sure emacs can only link against a version of
453 lwlib that was compiled in the right way. Emacs references symbols which 559 lwlib that was compiled in the right way. Emacs references symbols which
454 correspond to the way it thinks lwlib was compiled, and if lwlib wasn't 560 correspond to the way it thinks lwlib was compiled, and if lwlib wasn't
455 compiled in that way, then somewhat meaningful link errors will result. 561 compiled in that way, then somewhat meaningful link errors will result.
496 #ifdef LWLIB_DIALOGS_MOTIF 602 #ifdef LWLIB_DIALOGS_MOTIF
497 MACROLET (lwlib_dialogs_motif); 603 MACROLET (lwlib_dialogs_motif);
498 #elif defined (HAVE_DIALOGS) 604 #elif defined (HAVE_DIALOGS)
499 MACROLET (lwlib_dialogs_athena); 605 MACROLET (lwlib_dialogs_athena);
500 #endif 606 #endif
607 #ifdef LWLIB_WIDGETS_MOTIF
608 MACROLET (lwlib_widgets_motif);
609 #elif defined (HAVE_WIDGETS)
610 MACROLET (lwlib_widgets_athena);
611 #endif
501 612
502 #undef MACROLET 613 #undef MACROLET
503 } 614 }
504 615
505 void 616 void
507 { 618 {
508 defsymbol (&Qmenu_no_selection_hook, "menu-no-selection-hook"); 619 defsymbol (&Qmenu_no_selection_hook, "menu-no-selection-hook");
509 } 620 }
510 621
511 void 622 void
623 reinit_vars_of_gui_x (void)
624 {
625 lwlib_id_tick = (1<<16); /* start big, to not conflict with Energize */
626 #ifdef HAVE_POPUPS
627 popup_up_p = 0;
628 #endif
629
630 /* this makes only safe calls as in emacs.c */
631 sanity_check_lwlib ();
632 }
633
634 void
512 vars_of_gui_x (void) 635 vars_of_gui_x (void)
513 { 636 {
514 lwlib_id_tick = (1<<16); /* start big, to not conflict with Energize */ 637 reinit_vars_of_gui_x ();
515
516 popup_up_p = 0;
517 638
518 Vpopup_callbacks = Qnil; 639 Vpopup_callbacks = Qnil;
519 staticpro (&Vpopup_callbacks); 640 staticpro (&Vpopup_callbacks);
520 641
521 #if 0 642 #if 0
525 Function or functions to call when a menu or dialog box is dismissed 646 Function or functions to call when a menu or dialog box is dismissed
526 without a selection having been made. 647 without a selection having been made.
527 */ ); 648 */ );
528 #endif 649 #endif
529 Fset (Qmenu_no_selection_hook, Qnil); 650 Fset (Qmenu_no_selection_hook, Qnil);
530 651 }
531 /* this makes only safe calls as in emacs.c */
532 sanity_check_lwlib ();
533 }