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;