Mercurial > hg > xemacs-beta
comparison src/gui-x.c @ 406:b8cc9ab3f761 r21-2-33
Import from CVS: tag r21-2-33
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:17:09 +0200 |
parents | 2f8bb876ab1d |
children | 501cfd01ee6d |
comparison
equal
deleted
inserted
replaced
405:0e08f63c74d2 | 406:b8cc9ab3f761 |
---|---|
31 #include <Xm/Xm.h> /* for XmVersion */ | 31 #include <Xm/Xm.h> /* for XmVersion */ |
32 #endif | 32 #endif |
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 "events.h" | |
36 #include "frame.h" | 37 #include "frame.h" |
37 #include "gui.h" | 38 #include "gui.h" |
39 #include "glyphs.h" | |
38 #include "redisplay.h" | 40 #include "redisplay.h" |
39 #include "opaque.h" | 41 #include "opaque.h" |
40 | 42 |
41 Lisp_Object Qmenu_no_selection_hook; | 43 Lisp_Object Qmenu_no_selection_hook; |
42 | 44 |
208 | 210 |
209 void | 211 void |
210 popup_selection_callback (Widget widget, LWLIB_ID ignored_id, | 212 popup_selection_callback (Widget widget, LWLIB_ID ignored_id, |
211 XtPointer client_data) | 213 XtPointer client_data) |
212 { | 214 { |
213 Lisp_Object fn, arg; | 215 Lisp_Object data, image_instance, callback, callback_ex; |
214 Lisp_Object data; | 216 Lisp_Object frame, event; |
215 Lisp_Object frame; | |
216 int update_subwindows_p = 0; | 217 int update_subwindows_p = 0; |
217 struct device *d = get_device_from_display (XtDisplay (widget)); | 218 struct device *d = get_device_from_display (XtDisplay (widget)); |
218 struct frame *f = x_any_widget_or_parent_to_frame (d, widget); | 219 struct frame *f = x_any_widget_or_parent_to_frame (d, widget); |
219 | 220 |
220 /* set in lwlib to the time stamp associated with the most recent menu | 221 /* set in lwlib to the time stamp associated with the most recent menu |
226 if (((EMACS_INT) client_data) == 0) | 227 if (((EMACS_INT) client_data) == 0) |
227 return; | 228 return; |
228 VOID_TO_LISP (data, client_data); | 229 VOID_TO_LISP (data, client_data); |
229 XSETFRAME (frame, f); | 230 XSETFRAME (frame, f); |
230 | 231 |
232 image_instance = XCAR (data); | |
233 callback = XCAR (XCDR (data)); | |
234 callback_ex = XCDR (XCDR (data)); | |
235 | |
231 #if 0 | 236 #if 0 |
232 /* #### What the hell? I can't understand why this call is here, | 237 /* #### What the hell? I can't understand why this call is here, |
233 and doing it is really courting disaster in the new event | 238 and doing it is really courting disaster in the new event |
234 model, since popup_selection_callback is called from | 239 model, since popup_selection_callback is called from |
235 within next_event_internal() and Faccept_process_output() | 240 within next_event_internal() and Faccept_process_output() |
239 Faccept_process_output (Qnil, Qnil, Qnil); | 244 Faccept_process_output (Qnil, Qnil, Qnil); |
240 #endif | 245 #endif |
241 | 246 |
242 if (((EMACS_INT) client_data) == -1) | 247 if (((EMACS_INT) client_data) == -1) |
243 { | 248 { |
244 fn = Qrun_hooks; | 249 event = Fmake_event (Qnil, Qnil); |
245 arg = Qmenu_no_selection_hook; | 250 |
251 XEVENT (event)->event_type = misc_user_event; | |
252 XEVENT (event)->channel = frame; | |
253 XEVENT (event)->event.eval.function = Qrun_hooks; | |
254 XEVENT (event)->event.eval.object = Qmenu_no_selection_hook; | |
246 } | 255 } |
247 else | 256 else |
248 { | 257 { |
249 update_subwindows_p = 1; | 258 update_subwindows_p = 1; |
250 get_gui_callback (data, &fn, &arg); | 259 |
260 if (!NILP (callback_ex) && !UNBOUNDP (callback_ex)) | |
261 { | |
262 event = Fmake_event (Qnil, Qnil); | |
263 | |
264 XEVENT (event)->event_type = misc_user_event; | |
265 XEVENT (event)->channel = frame; | |
266 XEVENT (event)->event.eval.function = Qeval; | |
267 XEVENT (event)->event.eval.object = | |
268 list4 (Qfuncall, callback_ex, image_instance, event); | |
269 } | |
270 else if (NILP (callback) || UNBOUNDP (callback)) | |
271 event = Qnil; | |
272 else | |
273 { | |
274 Lisp_Object fn, arg; | |
275 | |
276 event = Fmake_event (Qnil, Qnil); | |
277 | |
278 get_gui_callback (callback, &fn, &arg); | |
279 XEVENT (event)->event_type = misc_user_event; | |
280 XEVENT (event)->channel = frame; | |
281 XEVENT (event)->event.eval.function = fn; | |
282 XEVENT (event)->event.eval.object = arg; | |
283 } | |
251 } | 284 } |
252 | 285 |
253 /* This is the timestamp used for asserting focus so we need to get an | 286 /* This is the timestamp used for asserting focus so we need to get an |
254 up-to-date value event if no events has been dispatched to emacs | 287 up-to-date value event if no events has been dispatched to emacs |
255 */ | 288 */ |
256 #if defined(HAVE_MENUBARS) | 289 #if defined(HAVE_MENUBARS) |
257 DEVICE_X_MOUSE_TIMESTAMP (d) = x_focus_timestamp_really_sucks_fix_me_better; | 290 DEVICE_X_MOUSE_TIMESTAMP (d) = x_focus_timestamp_really_sucks_fix_me_better; |
258 #else | 291 #else |
259 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d); | 292 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d); |
260 #endif | 293 #endif |
261 signal_special_Xt_user_event (frame, fn, arg); | 294 if (!NILP (event)) |
295 enqueue_Xt_dispatch_event (event); | |
262 /* The result of this evaluation could cause other instances to change so | 296 /* The result of this evaluation could cause other instances to change so |
263 enqueue an update callback to check this. */ | 297 enqueue an update callback to check this. We also have to make sure that |
264 if (update_subwindows_p) | 298 the function does not appear in the command history. |
299 #### I'm sure someone can tell me how to optimize this. */ | |
300 if (update_subwindows_p && !NILP (event)) | |
265 signal_special_Xt_user_event (frame, Qeval, | 301 signal_special_Xt_user_event (frame, Qeval, |
266 list2 (Qupdate_widget_instances, frame)); | 302 list3 (Qlet, |
303 list2 (Qthis_command, | |
304 Qlast_command), | |
305 list2 (Qupdate_widget_instances, | |
306 frame))); | |
267 } | 307 } |
268 | 308 |
269 #if 1 | 309 #if 1 |
270 /* Eval the activep slot of the menu item */ | 310 /* Eval the activep slot of the menu item */ |
271 # define wv_set_evalable_slot(slot,form) do { \ | 311 # define wv_set_evalable_slot(slot,form) do { \ |
335 } | 375 } |
336 | 376 |
337 /* This does the dirty work. gc_currently_forbidden is 1 when this is called. | 377 /* This does the dirty work. gc_currently_forbidden is 1 when this is called. |
338 */ | 378 */ |
339 int | 379 int |
340 button_item_to_widget_value (Lisp_Object gui_item, widget_value *wv, | 380 button_item_to_widget_value (Lisp_Object gui_object_instance, |
341 int allow_text_field_p, int no_keys_p) | 381 Lisp_Object gui_item, widget_value *wv, |
382 int allow_text_field_p, int no_keys_p, | |
383 int menu_entry_p) | |
342 { | 384 { |
343 /* !!#### This function has not been Mule-ized */ | 385 /* !!#### This function has not been Mule-ized */ |
344 /* This function cannot GC because gc_currently_forbidden is set when | 386 /* This function cannot GC because gc_currently_forbidden is set when |
345 it's called */ | 387 it's called */ |
346 Lisp_Gui_Item* pgui = 0; | 388 Lisp_Gui_Item* pgui = 0; |
360 | 402 |
361 if (!NILP (pgui->filter)) | 403 if (!NILP (pgui->filter)) |
362 signal_simple_error(":filter keyword not permitted on leaf nodes", gui_item); | 404 signal_simple_error(":filter keyword not permitted on leaf nodes", gui_item); |
363 | 405 |
364 #ifdef HAVE_MENUBARS | 406 #ifdef HAVE_MENUBARS |
365 if (!gui_item_included_p (gui_item, Vmenubar_configuration)) | 407 if (menu_entry_p && !gui_item_included_p (gui_item, Vmenubar_configuration)) |
366 { | 408 { |
367 /* the include specification says to ignore this item. */ | 409 /* the include specification says to ignore this item. */ |
368 return 0; | 410 return 0; |
369 } | 411 } |
370 #endif /* HAVE_MENUBARS */ | 412 #endif /* HAVE_MENUBARS */ |
399 } | 441 } |
400 | 442 |
401 wv_set_evalable_slot (wv->enabled, pgui->active); | 443 wv_set_evalable_slot (wv->enabled, pgui->active); |
402 wv_set_evalable_slot (wv->selected, pgui->selected); | 444 wv_set_evalable_slot (wv->selected, pgui->selected); |
403 | 445 |
404 if (!NILP (pgui->callback)) | 446 if (!NILP (pgui->callback) || !NILP (pgui->callback_ex)) |
405 wv->call_data = LISP_TO_VOID (pgui->callback); | 447 wv->call_data = LISP_TO_VOID (cons3 (gui_object_instance, |
448 pgui->callback, | |
449 pgui->callback_ex)); | |
406 | 450 |
407 if (no_keys_p | 451 if (no_keys_p |
408 #ifdef HAVE_MENUBARS | 452 #ifdef HAVE_MENUBARS |
409 || !menubar_show_keybindings | 453 || (menu_entry_p && !menubar_show_keybindings) |
410 #endif | 454 #endif |
411 ) | 455 ) |
412 wv->key = 0; | 456 wv->key = 0; |
413 else if (!NILP (pgui->keys)) /* Use this string to generate key bindings */ | 457 else if (!NILP (pgui->keys)) /* Use this string to generate key bindings */ |
414 { | 458 { |
484 gui_item); | 528 gui_item); |
485 return 1; | 529 return 1; |
486 } | 530 } |
487 | 531 |
488 /* parse tree's of gui items into widget_value hierarchies */ | 532 /* parse tree's of gui items into widget_value hierarchies */ |
489 static void gui_item_children_to_widget_values (Lisp_Object items, widget_value* parent); | 533 static void gui_item_children_to_widget_values (Lisp_Object gui_object_instance, |
534 Lisp_Object items, | |
535 widget_value* parent); | |
490 | 536 |
491 static widget_value * | 537 static widget_value * |
492 gui_items_to_widget_values_1 (Lisp_Object items, widget_value* parent, | 538 gui_items_to_widget_values_1 (Lisp_Object gui_object_instance, |
539 Lisp_Object items, widget_value* parent, | |
493 widget_value* prev) | 540 widget_value* prev) |
494 { | 541 { |
495 widget_value* wv = 0; | 542 widget_value* wv = 0; |
496 | 543 |
497 assert ((parent || prev) && !(parent && prev)); | 544 assert ((parent || prev) && !(parent && prev)); |
501 wv = xmalloc_widget_value(); | 548 wv = xmalloc_widget_value(); |
502 if (parent) | 549 if (parent) |
503 parent->contents = wv; | 550 parent->contents = wv; |
504 else | 551 else |
505 prev->next = wv; | 552 prev->next = wv; |
506 if (!button_item_to_widget_value (items, wv, 0, 1)) | 553 if (!button_item_to_widget_value (gui_object_instance, |
554 items, wv, 0, 1, 0)) | |
507 { | 555 { |
508 free_widget_value_tree (wv); | 556 free_widget_value_tree (wv); |
509 if (parent) | 557 if (parent) |
510 parent->contents = 0; | 558 parent->contents = 0; |
511 else | 559 else |
521 /* first one is the parent */ | 569 /* first one is the parent */ |
522 if (CONSP (XCAR (items))) | 570 if (CONSP (XCAR (items))) |
523 signal_simple_error ("parent item must not be a list", XCAR (items)); | 571 signal_simple_error ("parent item must not be a list", XCAR (items)); |
524 | 572 |
525 if (parent) | 573 if (parent) |
526 wv = gui_items_to_widget_values_1 (XCAR (items), parent, 0); | 574 wv = gui_items_to_widget_values_1 (gui_object_instance, |
575 XCAR (items), parent, 0); | |
527 else | 576 else |
528 wv = gui_items_to_widget_values_1 (XCAR (items), 0, prev); | 577 wv = gui_items_to_widget_values_1 (gui_object_instance, |
578 XCAR (items), 0, prev); | |
529 /* the rest are the children */ | 579 /* the rest are the children */ |
530 gui_item_children_to_widget_values (XCDR (items), wv); | 580 gui_item_children_to_widget_values (gui_object_instance, |
581 XCDR (items), wv); | |
531 } | 582 } |
532 return wv; | 583 return wv; |
533 } | 584 } |
534 | 585 |
535 static void | 586 static void |
536 gui_item_children_to_widget_values (Lisp_Object items, widget_value* parent) | 587 gui_item_children_to_widget_values (Lisp_Object gui_object_instance, |
588 Lisp_Object items, widget_value* parent) | |
537 { | 589 { |
538 widget_value* wv = 0, *prev = 0; | 590 widget_value* wv = 0, *prev = 0; |
539 Lisp_Object rest; | 591 Lisp_Object rest; |
540 CHECK_CONS (items); | 592 CHECK_CONS (items); |
541 | 593 |
542 /* first one is master */ | 594 /* first one is master */ |
543 prev = gui_items_to_widget_values_1 (XCAR (items), parent, 0); | 595 prev = gui_items_to_widget_values_1 (gui_object_instance, XCAR (items), |
596 parent, 0); | |
544 /* the rest are the children */ | 597 /* the rest are the children */ |
545 LIST_LOOP (rest, XCDR (items)) | 598 LIST_LOOP (rest, XCDR (items)) |
546 { | 599 { |
547 Lisp_Object tab = XCAR (rest); | 600 Lisp_Object tab = XCAR (rest); |
548 wv = gui_items_to_widget_values_1 (tab, 0, prev); | 601 wv = gui_items_to_widget_values_1 (gui_object_instance, tab, 0, prev); |
549 prev = wv; | 602 prev = wv; |
550 } | 603 } |
551 } | 604 } |
552 | 605 |
553 widget_value * | 606 widget_value * |
554 gui_items_to_widget_values (Lisp_Object items) | 607 gui_items_to_widget_values (Lisp_Object gui_object_instance, Lisp_Object items) |
555 { | 608 { |
556 /* !!#### This function has not been Mule-ized */ | 609 /* !!#### This function has not been Mule-ized */ |
557 /* This function can GC */ | 610 /* This function can GC */ |
558 widget_value *control = 0, *tmp = 0; | 611 widget_value *control = 0, *tmp = 0; |
559 int count = specpdl_depth (); | 612 int count = specpdl_depth (); |
573 tree on Lisp error. */ | 626 tree on Lisp error. */ |
574 control = xmalloc_widget_value(); | 627 control = xmalloc_widget_value(); |
575 wv_closure = make_opaque_ptr (control); | 628 wv_closure = make_opaque_ptr (control); |
576 record_unwind_protect (widget_value_unwind, wv_closure); | 629 record_unwind_protect (widget_value_unwind, wv_closure); |
577 | 630 |
578 gui_items_to_widget_values_1 (items, control, 0); | 631 gui_items_to_widget_values_1 (gui_object_instance, items, control, 0); |
579 | 632 |
580 /* mess about getting the data we really want */ | 633 /* mess about getting the data we really want */ |
581 tmp = control; | 634 tmp = control; |
582 control = control->contents; | 635 control = control->contents; |
583 tmp->next = 0; | 636 tmp->next = 0; |