This source file includes following definitions.
- x_print_complete_resource_name
- make_destroyed_instance
- free_destroyed_instance
- first_child
- lw_motif_widget_p
- resource_motif_string
- destroy_all_children
- xm_arm_callback
- xm_update_label
- xm_update_list
- xm_update_pushbutton
- xm_update_cascadebutton
- xm_update_toggle
- xm_update_radiobox
- make_menu_in_widget
- update_one_menu_entry
- xm_update_menu
- xm_update_text
- xm_update_text_field
- xm_update_one_widget
- xm_update_one_value
- activate_button
- dialog_key_cb
- make_dialog
- find_matching_instance
- mark_dead_instance_destroyed
- recenter_widget
- recycle_instance
- xm_create_dialog
- make_menubar
- remove_grabs
- make_popup_menu
- make_main
- make_one
- make_project_p_sheet
- make_debugger_p_sheet
- make_breaklist_p_sheet
- make_le_browser_p_sheet
- make_class_browser_p_sheet
- make_call_browser_p_sheet
- make_build_dialog
- make_editmode_dialog
- make_search_dialog
- make_project_display_dialog
- xm_destroy_instance
- xm_popup_menu
- set_min_dialog_size
- xm_pop_instance
- do_call
- xm_internal_update_other_instances
- xm_generic_callback
- xm_nosel_callback
- xm_pull_down_callback
- xm_pop_down_callback
- xm_pop_up_callback
- xm_set_keyboard_focus
- xm_set_main_areas
- xm_manage_resizing
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <config.h>
22
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <setjmp.h>
26
27 #include <X11/StringDefs.h>
28 #include <X11/IntrinsicP.h>
29 #include <X11/ObjectP.h>
30 #include <X11/CoreP.h>
31 #include <X11/CompositeP.h>
32
33 #include <lisp.h>
34
35 #include "lwlib-Xm.h"
36 #include "lwlib-utils.h"
37
38 #include <Xm/BulletinB.h>
39 #include <Xm/CascadeB.h>
40 #include <Xm/CascadeBG.h>
41 #include <Xm/DrawingA.h>
42 #include <Xm/FileSB.h>
43 #include <Xm/Label.h>
44 #include <Xm/List.h>
45 #include <Xm/MainW.h>
46 #include <Xm/MenuShell.h>
47 #include <Xm/MessageB.h>
48 #include <Xm/PanedW.h>
49 #include <Xm/PushB.h>
50 #include <Xm/PushBG.h>
51 #include <Xm/ArrowB.h>
52 #include <Xm/SelectioB.h>
53 #include <Xm/Text.h>
54 #include <Xm/TextF.h>
55 #include <Xm/ToggleB.h>
56 #include <Xm/ToggleBG.h>
57 #include <Xm/RowColumn.h>
58 #include <Xm/ScrolledW.h>
59 #include <Xm/Separator.h>
60 #include <Xm/DialogS.h>
61 #include <Xm/Form.h>
62
63 enum do_call_type { pre_activate, selection, no_selection, post_activate };
64
65
66
67 typedef struct _destroyed_instance
68 {
69 char* name;
70 char* type;
71 Widget widget;
72 Widget parent;
73 Boolean pop_up_p;
74 struct _destroyed_instance* next;
75 } destroyed_instance;
76
77 static destroyed_instance *make_destroyed_instance (char *, char *,
78 Widget, Widget,
79 Boolean);
80 static void free_destroyed_instance (destroyed_instance*);
81 Widget first_child (Widget);
82 static XmString resource_motif_string (Widget, char *);
83 static void destroy_all_children (Widget, int);
84 static void xm_update_label (widget_instance *, Widget, widget_value *);
85 static void xm_update_list (widget_instance *, Widget, widget_value *);
86 static void xm_update_pushbutton (widget_instance *, Widget,
87 widget_value *);
88 static void xm_update_cascadebutton (widget_instance *, Widget,
89 widget_value *);
90 static void xm_update_toggle (widget_instance *, Widget, widget_value *);
91 static void xm_update_radiobox (widget_instance *, Widget, widget_value *);
92 static void make_menu_in_widget (widget_instance *, Widget,
93 widget_value *, int);
94 static void update_one_menu_entry (widget_instance *, Widget,
95 widget_value *, Boolean);
96 static void xm_update_menu (widget_instance *, Widget, widget_value *,
97 Boolean);
98 static void xm_update_text (widget_instance *, Widget, widget_value *);
99 static void xm_update_text_field (widget_instance *, Widget,
100 widget_value *);
101 static void activate_button (Widget, XtPointer, XtPointer);
102 static Widget make_dialog (char *, Widget, Boolean, char *, char *,
103 Boolean, Boolean, Boolean, int, int);
104 static destroyed_instance* find_matching_instance (widget_instance*);
105 static void mark_dead_instance_destroyed (Widget, XtPointer, XtPointer);
106 static void recenter_widget (Widget);
107 static Widget recycle_instance (destroyed_instance*);
108 static Widget make_menubar (widget_instance*);
109 static void remove_grabs (Widget, XtPointer, XtPointer);
110 static Widget make_popup_menu (widget_instance*);
111 static Widget make_main (widget_instance*);
112 static void set_min_dialog_size (Widget);
113 static void do_call (Widget, XtPointer, enum do_call_type);
114 static void xm_generic_callback (Widget, XtPointer, XtPointer);
115 static void xm_nosel_callback (Widget, XtPointer, XtPointer);
116 static void xm_pull_down_callback (Widget, XtPointer, XtPointer);
117 static void xm_pop_down_callback (Widget, XtPointer, XtPointer);
118 static void xm_pop_up_callback (Widget, XtPointer, XtPointer);
119 static void xm_internal_update_other_instances (Widget, XtPointer,
120 XtPointer);
121 static void xm_arm_callback (Widget, XtPointer, XtPointer);
122
123 #if 0
124 void xm_update_one_widget (widget_instance *, Widget, widget_value *,
125 Boolean);
126 void xm_pop_instance (widget_instance*, Boolean);
127 void xm_manage_resizing (Widget, Boolean);
128 #endif
129
130
131 #if 0
132
133
134
135
136 void
137 x_print_complete_resource_name (Widget widget)
138 {
139 int i;
140 String names[100];
141
142 for (i = 0; i < 100 && widget != NULL; ++i)
143 {
144 names[i] = XtName (widget);
145 widget = XtParent (widget);
146 }
147
148 for (--i; i >= 1; --i)
149 fprintf (stderr, "%s.", names[i]);
150 fprintf (stderr, "%s\n", names[0]);
151 }
152
153 #endif
154
155
156 static destroyed_instance *all_destroyed_instances = NULL;
157
158 static destroyed_instance*
159 make_destroyed_instance (char* name,
160 char* type,
161 Widget widget,
162 Widget parent,
163 Boolean pop_up_p)
164 {
165 destroyed_instance* instance =
166 (destroyed_instance*) xmalloc (sizeof (destroyed_instance));
167 instance->name = xstrdup (name);
168 instance->type = xstrdup (type);
169 instance->widget = widget;
170 instance->parent = parent;
171 instance->pop_up_p = pop_up_p;
172 instance->next = NULL;
173 return instance;
174 }
175
176 static void
177 free_destroyed_instance (destroyed_instance* instance)
178 {
179 xfree (instance->name);
180 xfree (instance->type);
181 xfree (instance);
182 }
183
184
185 Widget
186 first_child (Widget widget)
187 {
188 return ((CompositeWidget)widget)->composite.children [0];
189 }
190
191 Boolean
192 lw_motif_widget_p (Widget widget)
193 {
194 return
195 XtClass (widget) == xmDialogShellWidgetClass
196 || XmIsPrimitive (widget) || XmIsManager (widget) || XmIsGadget (widget);
197 }
198
199 static XmString
200 resource_motif_string (Widget widget,
201 char* name)
202 {
203 XtResource resource;
204 XmString result = 0;
205
206 resource.resource_name = name;
207 resource.resource_class = XmCXmString;
208 resource.resource_type = XmRXmString;
209 resource.resource_size = sizeof (XmString);
210 resource.resource_offset = 0;
211 resource.default_type = XtRImmediate;
212 resource.default_addr = 0;
213
214 XtGetSubresources (widget, (XtPointer)&result, "dialogString",
215 "DialogString", &resource, 1, NULL, 0);
216 return result;
217 }
218
219
220
221
222 static void
223 destroy_all_children (Widget widget,
224 int first_child_to_destroy)
225 {
226 Widget* children;
227 unsigned int number;
228 int i;
229
230 children = XtCompositeChildren (widget, &number);
231 if (children)
232 {
233 XtUnmanageChildren (children + first_child_to_destroy,
234 number - first_child_to_destroy);
235
236
237
238 for (i = first_child_to_destroy; i < number; i++)
239 {
240 Arg al[2];
241 Widget submenu = 0;
242
243
244
245
246
247 XtSetArg (al[0], XmNsubMenuId, &submenu);
248 XtGetValues (children[i], al, 1);
249 if (submenu)
250 {
251 destroy_all_children (submenu, 0);
252 XtDestroyWidget (submenu);
253 }
254 XtDestroyWidget (children[i]);
255 }
256
257 XtFree ((char *) children);
258 }
259 }
260
261
262
263
264
265
266
267
268
269 static void
270 xm_arm_callback (Widget w, XtPointer client_data, XtPointer call_data)
271 {
272 XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *) call_data;
273 widget_value *wv = NULL;
274 widget_instance *instance = client_data;
275 XtPointer user_data;
276 Arg al[2];
277 int ac = 0;
278
279 XtSetArg (al[ac], XmNuserData, &user_data); ac++;
280 XtGetValues (w, al, ac);
281 wv = user_data;
282
283 if (wv != NULL)
284 {
285 if (instance->info->highlight_cb
286 && (cbs->reason == XmCR_DISARM
287 || (cbs->event
288 && (cbs->event->type == EnterNotify
289 || cbs->event->type == MotionNotify))))
290 {
291 call_data = cbs->reason == XmCR_DISARM ? NULL : wv;
292 instance->info->highlight_cb (w, instance->info->id, call_data);
293 }
294 }
295 }
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316 static void
317 xm_update_label (widget_instance* instance,
318 Widget widget,
319 widget_value* val)
320 {
321 XmString res_string = 0;
322 XmString built_string = 0;
323 XmString key_string = 0;
324 Arg al [256];
325 int ac;
326
327 ac = 0;
328
329 if (val->value)
330 {
331
332
333 res_string = resource_motif_string (widget, val->value);
334
335 if (res_string)
336 {
337 XtSetArg (al [ac], XmNlabelString, res_string); ac++;
338 }
339 else
340 {
341 built_string =
342 XmStringCreateLocalized (val->value);
343 XtSetArg (al [ac], XmNlabelString, built_string); ac++;
344 }
345
346 XtSetArg (al [ac], XmNlabelType, XmSTRING); ac++;
347 }
348
349 if (val->key)
350 {
351 key_string = XmStringCreateLocalized (val->key);
352 XtSetArg (al [ac], XmNacceleratorText, key_string); ac++;
353 }
354
355 if (ac)
356 XtSetValues (widget, al, ac);
357
358 if (built_string)
359 XmStringFree (built_string);
360
361 if (key_string)
362 XmStringFree (key_string);
363 }
364
365
366 static void
367 xm_update_list (widget_instance* instance,
368 Widget widget,
369 widget_value* val)
370 {
371 widget_value* cur;
372 int i;
373 XtRemoveAllCallbacks (widget, XmNsingleSelectionCallback);
374 XtAddCallback (widget, XmNsingleSelectionCallback, xm_generic_callback,
375 instance);
376 for (cur = val->contents, i = 0; cur; cur = cur->next)
377 if (cur->value)
378 {
379 XmString xmstr = XmStringCreateLocalized (cur->value);
380 i += 1;
381 XmListAddItem (widget, xmstr, 0);
382 if (cur->selected)
383 XmListSelectPos (widget, i, False);
384 XmStringFree (xmstr);
385 }
386 }
387
388
389 static void
390 xm_update_pushbutton (widget_instance* instance,
391 Widget widget,
392 widget_value* val)
393 {
394 XtVaSetValues (widget, XmNalignment, XmALIGNMENT_CENTER, NULL);
395 XtRemoveAllCallbacks (widget, XmNactivateCallback);
396 XtAddCallback (widget, XmNactivateCallback, xm_generic_callback, instance);
397 }
398
399 static void
400 xm_update_cascadebutton (widget_instance* instance,
401 Widget widget,
402 widget_value* val)
403 {
404
405 XtRemoveAllCallbacks (widget, XmNcascadingCallback);
406 XtAddCallback (widget, XmNcascadingCallback, xm_pull_down_callback,
407 instance);
408 }
409
410
411 static void
412 xm_update_toggle (widget_instance* instance,
413 Widget widget,
414 widget_value* val)
415 {
416 XtRemoveAllCallbacks (widget, XmNvalueChangedCallback);
417 XtAddCallback (widget, XmNvalueChangedCallback,
418 xm_generic_callback, instance);
419 XtVaSetValues (widget, XmNset, val->selected,
420 XmNalignment, XmALIGNMENT_BEGINNING, NULL);
421 }
422
423 static void
424 xm_update_radiobox (widget_instance* instance,
425 Widget widget,
426 widget_value* val)
427
428 {
429 Widget toggle;
430 widget_value* cur;
431
432
433 XtRemoveAllCallbacks (widget, XmNentryCallback);
434 XtAddCallback (widget, XmNentryCallback, xm_generic_callback, instance);
435
436
437
438
439
440
441
442 for (cur = val->contents; cur; cur = cur->next)
443 {
444 toggle = XtNameToWidget (widget, cur->value);
445 if (toggle)
446 {
447 XtSetSensitive (toggle, cur->enabled);
448 if (!val->value && cur->selected)
449 XtVaSetValues (toggle, XmNset, cur->selected, NULL);
450 if (val->value && strcmp (val->value, cur->value))
451 XtVaSetValues (toggle, XmNset, False, NULL);
452 }
453 }
454
455
456 if (val->value)
457 {
458 toggle = XtNameToWidget (widget, val->value);
459 if (toggle)
460 XtVaSetValues (toggle, XmNset, True, NULL);
461 }
462 }
463
464
465
466
467
468
469 static void
470 make_menu_in_widget (widget_instance* instance,
471 Widget widget,
472 widget_value* val,
473 int keep_first_children)
474 {
475 Widget* children = 0;
476 int num_children;
477 int child_index;
478 widget_value* cur;
479 Widget button = 0;
480 Widget menu;
481 Arg al [256];
482 int ac;
483 Boolean menubar_p;
484 unsigned char type;
485
486 Widget* old_children;
487 unsigned int old_num_children;
488
489
490 static char overrideTrans[] = "<Btn2Down>: Noop()";
491 XtTranslations override = XtParseTranslationTable (overrideTrans);
492
493 old_children = XtCompositeChildren (widget, &old_num_children);
494
495
496 for (num_children = 0, cur = val; cur; num_children++, cur = cur->next)
497 ;
498 children = (Widget*)(void*)XtMalloc (num_children * sizeof (Widget));
499
500 #ifndef LESSTIF_VERSION
501
502 if (!XmIsRowColumn (widget))
503 emacs_abort ();
504 #endif
505
506
507 type = -1;
508 XtSetArg (al[0], XmNrowColumnType, &type);
509 XtGetValues (widget, al, 1);
510 if (type != XmMENU_BAR && type != XmMENU_PULLDOWN && type != XmMENU_POPUP)
511 emacs_abort ();
512 menubar_p = type == XmMENU_BAR;
513
514
515
516 if (!menubar_p)
517 {
518 XtAddCallback (XtParent (widget), XmNpopdownCallback,
519 xm_pop_down_callback, (XtPointer) instance);
520 XtAddCallback (XtParent (widget), XmNpopupCallback,
521 xm_pop_up_callback, (XtPointer) instance);
522 }
523
524
525 for (child_index = 0, cur = val; child_index < keep_first_children;
526 child_index++, cur = cur->next)
527 children[child_index] = old_children[child_index];
528
529
530
531 if (old_num_children != keep_first_children)
532 emacs_abort ();
533
534
535 for (child_index = keep_first_children; cur; child_index++, cur = cur->next)
536 {
537 enum menu_separator separator;
538
539 ac = 0;
540 XtSetArg (al[ac], XmNsensitive, cur->enabled); ac++;
541 XtSetArg (al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
542 XtSetArg (al[ac], XmNuserData, cur); ac++;
543
544 if (instance->pop_up_p && !cur->contents && !cur->call_data
545 && !lw_separator_p (cur->name, &separator, 1))
546 {
547 ac = 0;
548 XtSetArg (al[ac], XmNalignment, XmALIGNMENT_CENTER); ac++;
549 button = XmCreateLabel (widget, cur->name, al, ac);
550 }
551 else if (lw_separator_p (cur->name, &separator, 1))
552 {
553 ac = 0;
554 XtSetArg (al[ac], XmNseparatorType, separator); ++ac;
555 button = XmCreateSeparator (widget, cur->name, al, ac);
556 }
557 else if (!cur->contents)
558 {
559 if (menubar_p)
560 button = XmCreateCascadeButton (widget, cur->name, al, ac);
561 else if (!cur->call_data)
562 button = XmCreateLabel (widget, cur->name, al, ac);
563 else if (cur->button_type == BUTTON_TYPE_TOGGLE
564 || cur->button_type == BUTTON_TYPE_RADIO)
565 {
566 XtSetArg (al[ac], XmNset, cur->selected); ++ac;
567 XtSetArg (al[ac], XmNvisibleWhenOff, True); ++ac;
568 XtSetArg (al[ac], XmNindicatorType,
569 (cur->button_type == BUTTON_TYPE_TOGGLE
570 ? XmN_OF_MANY : XmONE_OF_MANY));
571 ++ac;
572 button = XmCreateToggleButton (widget, cur->name, al, ac);
573 XtAddCallback (button, XmNarmCallback, xm_arm_callback,
574 (XtPointer) instance);
575 XtAddCallback (button, XmNdisarmCallback, xm_arm_callback,
576 (XtPointer) instance);
577 }
578 else
579 {
580 button = XmCreatePushButton (widget, cur->name, al, ac);
581 XtAddCallback (button, XmNarmCallback, xm_arm_callback,
582 (XtPointer) instance);
583 XtAddCallback (button, XmNdisarmCallback, xm_arm_callback,
584 (XtPointer) instance);
585 }
586
587 xm_update_label (instance, button, cur);
588
589
590
591
592
593 if (cur->button_type)
594 xm_update_toggle (instance, button, cur);
595 else if (cur->call_data)
596 XtAddCallback (button, XmNactivateCallback, xm_generic_callback,
597 (XtPointer)instance);
598 }
599 else
600 {
601 menu = XmCreatePulldownMenu (widget, cur->name, NULL, 0);
602
603 make_menu_in_widget (instance, menu, cur->contents, 0);
604 XtSetArg (al[ac], XmNsubMenuId, menu); ac++;
605 button = XmCreateCascadeButton (widget, cur->name, al, ac);
606
607 xm_update_label (instance, button, cur);
608
609 XtAddCallback (button, XmNcascadingCallback, xm_pull_down_callback,
610 (XtPointer)instance);
611 XtOverrideTranslations (button, override);
612
613 }
614
615 children[child_index] = button;
616 }
617
618
619
620
621
622
623 if (button)
624 XtVaSetValues (widget, XmNmenuHelpWidget, button, NULL);
625
626 if (num_children)
627 XtManageChildren (children, num_children);
628
629 XtFree ((char *) children);
630 if (old_children)
631 XtFree ((char *) old_children);
632 }
633
634 static void
635 update_one_menu_entry (widget_instance* instance,
636 Widget widget,
637 widget_value* val,
638 Boolean deep_p)
639 {
640 Arg al [256];
641 int ac;
642 Widget menu;
643 widget_value* contents;
644
645 if (val->this_one_change == NO_CHANGE)
646 return;
647
648
649
650 XtSetSensitive (widget, val->enabled);
651 XtVaSetValues (widget, XmNuserData, val, NULL);
652
653
654 if (val->this_one_change >= VISIBLE_CHANGE)
655 {
656 xm_update_label (instance, widget, val);
657 if (val->button_type)
658 xm_update_toggle (instance, widget, val);
659 }
660
661
662 ac = 0;
663 menu = NULL;
664 XtSetArg (al [ac], XmNsubMenuId, &menu); ac++;
665 XtGetValues (widget, al, ac);
666
667 contents = val->contents;
668
669 if (!menu)
670 {
671 if (contents)
672 {
673 unsigned int old_num_children, i;
674 Widget parent;
675 Widget *widget_list;
676
677 parent = XtParent (widget);
678 widget_list = XtCompositeChildren (parent, &old_num_children);
679
680
681 for (i = 0; i < old_num_children; i++)
682 if (strcmp (XtName (widget_list[i]), XtName (widget)) == 0)
683 break;
684 if (i == old_num_children)
685 emacs_abort ();
686 if (XmIsCascadeButton (widget_list[i]))
687 {
688 menu = XmCreatePulldownMenu (parent, XtName(widget), NULL, 0);
689 make_menu_in_widget (instance, menu, contents, 0);
690 ac = 0;
691 XtSetArg (al [ac], XmNsubMenuId, menu); ac++;
692 XtSetValues (widget, al, ac);
693 }
694 else
695 {
696 Widget button;
697
698
699
700 XtDestroyWidget (widget_list[i]);
701 menu = XmCreatePulldownMenu (parent, val->name, NULL, 0);
702 make_menu_in_widget (instance, menu, contents, 0);
703 ac = 0;
704 XtSetArg (al [ac], XmNsubMenuId, menu); ac++;
705
706
707 XtSetArg (al [ac], XmNmappingDelay, 0); ac++;
708 #ifdef XmNpositionIndex
709
710 XtSetArg (al [ac], XmNpositionIndex , i); ac++;
711 #endif
712 button = XmCreateCascadeButton (parent, val->name, al, ac);
713 xm_update_label (instance, button, val);
714
715 XtAddCallback (button, XmNcascadingCallback, xm_pull_down_callback,
716 (XtPointer)instance);
717 XtManageChild (button);
718 }
719
720 if (widget_list)
721 XtFree ((char*) widget_list);
722 }
723 }
724 else if (!contents)
725 {
726 ac = 0;
727 XtSetArg (al [ac], XmNsubMenuId, NULL); ac++;
728 XtSetValues (widget, al, ac);
729 XtDestroyWidget (menu);
730 }
731 else if (deep_p && contents->change != NO_CHANGE)
732 xm_update_menu (instance, menu, val, 1);
733 }
734
735 static void
736 xm_update_menu (widget_instance* instance,
737 Widget widget,
738 widget_value* val,
739 Boolean deep_p)
740 {
741 Widget* children;
742 unsigned int num_children;
743 int num_children_to_keep = 0;
744 int i;
745 widget_value* cur;
746
747 children = XtCompositeChildren (widget, &num_children);
748
749
750
751
752
753
754 if (val->contents == 0)
755 num_children_to_keep = 0;
756 else if (val->contents->change == STRUCTURAL_CHANGE)
757 {
758 if (children)
759 {
760 for (i = 0, cur = val->contents;
761 (i < num_children
762 && cur);
763 i++, cur = cur->next)
764 {
765 if (cur->this_one_change == STRUCTURAL_CHANGE)
766 break;
767 }
768
769 num_children_to_keep = i;
770 }
771 }
772 else
773 num_children_to_keep = num_children;
774
775
776
777 if (children)
778 {
779 for (i = 0, cur = val->contents; i < num_children_to_keep; i++)
780 {
781 if (!cur)
782 {
783 num_children_to_keep = i;
784 break;
785 }
786 if (children [i]->core.being_destroyed
787 || strcmp (XtName (children [i]), cur->name))
788 continue;
789 update_one_menu_entry (instance, children [i], cur, deep_p);
790 cur = cur->next;
791 }
792 }
793
794
795
796 if (val->contents && val->contents->change == STRUCTURAL_CHANGE)
797 {
798 destroy_all_children (widget, num_children_to_keep);
799 make_menu_in_widget (instance, widget, val->contents,
800 num_children_to_keep);
801 }
802
803 XtFree ((char *) children);
804 }
805
806
807
808
809 static void
810 xm_update_text (widget_instance* instance,
811 Widget widget,
812 widget_value* val)
813 {
814 XmTextSetString (widget, val->value ? val->value : "");
815 XtRemoveAllCallbacks (widget, XmNactivateCallback);
816 XtAddCallback (widget, XmNactivateCallback, xm_generic_callback, instance);
817 XtRemoveAllCallbacks (widget, XmNvalueChangedCallback);
818 XtAddCallback (widget, XmNvalueChangedCallback,
819 xm_internal_update_other_instances, instance);
820 }
821
822 static void
823 xm_update_text_field (widget_instance* instance,
824 Widget widget,
825 widget_value* val)
826 {
827 XmTextFieldSetString (widget, val->value ? val->value : "");
828 XtRemoveAllCallbacks (widget, XmNactivateCallback);
829 XtAddCallback (widget, XmNactivateCallback, xm_generic_callback, instance);
830 XtRemoveAllCallbacks (widget, XmNvalueChangedCallback);
831 XtAddCallback (widget, XmNvalueChangedCallback,
832 xm_internal_update_other_instances, instance);
833 }
834
835
836
837
838 void
839 xm_update_one_widget (widget_instance* instance,
840 Widget widget,
841 widget_value* val,
842 Boolean deep_p)
843 {
844 WidgetClass class;
845
846
847 val->edited = False;
848
849
850 XtSetSensitive (widget, val->enabled);
851 XtVaSetValues (widget, XmNuserData, val, NULL);
852
853
854 if (XtIsSubclass (widget, xmLabelWidgetClass))
855 xm_update_label (instance, widget, val);
856
857 class = XtClass (widget);
858
859 if (class == xmPushButtonWidgetClass ||
860 class == xmArrowButtonWidgetClass)
861 {
862 xm_update_pushbutton (instance, widget, val);
863 }
864 else if (class == xmCascadeButtonWidgetClass)
865 {
866 xm_update_cascadebutton (instance, widget, val);
867 }
868 else if (class == xmToggleButtonWidgetClass
869 || class == xmToggleButtonGadgetClass)
870 {
871 xm_update_toggle (instance, widget, val);
872 }
873 else if (class == xmRowColumnWidgetClass)
874 {
875 Boolean radiobox = 0;
876 int ac = 0;
877 Arg al [1];
878
879 XtSetArg (al [ac], XmNradioBehavior, &radiobox); ac++;
880 XtGetValues (widget, al, ac);
881
882 if (radiobox)
883 xm_update_radiobox (instance, widget, val);
884 else
885 xm_update_menu (instance, widget, val, deep_p);
886 }
887 else if (class == xmTextWidgetClass)
888 {
889 xm_update_text (instance, widget, val);
890 }
891 else if (class == xmTextFieldWidgetClass)
892 {
893 xm_update_text_field (instance, widget, val);
894 }
895 else if (class == xmListWidgetClass)
896 {
897 xm_update_list (instance, widget, val);
898 }
899 }
900
901
902 void
903 xm_update_one_value (widget_instance* instance,
904 Widget widget,
905 widget_value* val)
906 {
907 WidgetClass class = XtClass (widget);
908 widget_value *old_wv;
909
910
911 for (old_wv = instance->info->val->contents; old_wv; old_wv = old_wv->next)
912 if (!strcmp (val->name, old_wv->name))
913 {
914 val->call_data = old_wv->call_data;
915 break;
916 }
917
918 if (class == xmToggleButtonWidgetClass || class == xmToggleButtonGadgetClass)
919 {
920 XtVaGetValues (widget, XmNset, &val->selected, NULL);
921 val->edited = True;
922 }
923 else if (class == xmTextWidgetClass)
924 {
925 xfree (val->value);
926 val->value = XmTextGetString (widget);
927 val->edited = True;
928 }
929 else if (class == xmTextFieldWidgetClass)
930 {
931 xfree (val->value);
932 val->value = XmTextFieldGetString (widget);
933 val->edited = True;
934 }
935 else if (class == xmRowColumnWidgetClass)
936 {
937 Boolean radiobox = 0;
938 int ac = 0;
939 Arg al [1];
940
941 XtSetArg (al [ac], XmNradioBehavior, &radiobox); ac++;
942 XtGetValues (widget, al, ac);
943
944 if (radiobox)
945 {
946 CompositeWidget radio = (CompositeWidget)widget;
947 int i;
948 for (i = 0; i < radio->composite.num_children; i++)
949 {
950 int set = False;
951 Widget toggle = radio->composite.children [i];
952
953 XtVaGetValues (toggle, XmNset, &set, NULL);
954 if (set)
955 dupstring (&val->value, XtName (toggle));
956 }
957 val->edited = True;
958 }
959 }
960 else if (class == xmListWidgetClass)
961 {
962 int pos_cnt;
963 int* pos_list;
964 if (XmListGetSelectedPos (widget, &pos_list, &pos_cnt))
965 {
966 int i;
967 widget_value* cur;
968 for (cur = val->contents, i = 0; cur; cur = cur->next)
969 if (cur->value)
970 {
971 int j;
972 cur->selected = False;
973 i += 1;
974 for (j = 0; j < pos_cnt; j++)
975 if (pos_list [j] == i)
976 {
977 cur->selected = True;
978 val->value = xstrdup (cur->name);
979 }
980 }
981 val->edited = 1;
982 XtFree ((char *) pos_list);
983 }
984 }
985 }
986
987
988
989
990
991
992
993
994 static void
995 activate_button (Widget widget,
996 XtPointer closure,
997 XtPointer call_data)
998 {
999 Widget button = (Widget)closure;
1000 XtCallCallbacks (button, XmNactivateCallback, NULL);
1001 }
1002
1003
1004
1005
1006 static void
1007 dialog_key_cb (Widget widget,
1008 XtPointer closure,
1009 XEvent *event,
1010 Boolean *continue_to_dispatch)
1011 {
1012 KeySym sym = 0;
1013 Modifiers modif_ret;
1014
1015 XtTranslateKeycode (event->xkey.display, event->xkey.keycode, 0,
1016 &modif_ret, &sym);
1017
1018 if (sym == osfXK_Cancel)
1019 {
1020 Widget w = *((Widget *) closure);
1021
1022 while (w && ! XtIsShell (w))
1023 w = XtParent (w);
1024
1025 if (XtIsShell (w)) XtPopdown (w);
1026 }
1027
1028 *continue_to_dispatch = TRUE;
1029 }
1030
1031
1032 static Widget
1033 make_dialog (char* name,
1034 Widget parent,
1035 Boolean pop_up_p,
1036 char* shell_title,
1037 char* icon_name,
1038 Boolean text_input_slot,
1039 Boolean radio_box,
1040 Boolean list,
1041 int left_buttons,
1042 int right_buttons)
1043 {
1044 Widget result;
1045 Widget form;
1046 Widget row;
1047 Widget icon;
1048 Widget icon_separator;
1049 Widget message_label;
1050 Widget value = 0;
1051 Widget separator;
1052 Widget button = 0;
1053 Widget children [16];
1054 int n_children;
1055 Arg al[64];
1056 int ac;
1057 int i;
1058
1059 if (pop_up_p)
1060 {
1061 ac = 0;
1062 XtSetArg(al[ac], XmNtitle, shell_title); ac++;
1063 XtSetArg(al[ac], XtNallowShellResize, True); ac++;
1064 XtSetArg(al[ac], XmNdeleteResponse, XmUNMAP); ac++;
1065 result = XmCreateDialogShell (parent, "dialog", al, ac);
1066 ac = 0;
1067 XtSetArg(al[ac], XmNautoUnmanage, FALSE); ac++;
1068
1069 XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
1070 form = XmCreateForm (result, shell_title, al, ac);
1071 }
1072 else
1073 {
1074 ac = 0;
1075 XtSetArg(al[ac], XmNautoUnmanage, FALSE); ac++;
1076 XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
1077 form = XmCreateForm (parent, shell_title, al, ac);
1078 result = form;
1079 }
1080
1081 n_children = left_buttons + right_buttons + 1;
1082 ac = 0;
1083 XtSetArg(al[ac], XmNpacking, n_children == 3?
1084 XmPACK_COLUMN: XmPACK_TIGHT); ac++;
1085 XtSetArg(al[ac], XmNorientation, n_children == 3?
1086 XmVERTICAL: XmHORIZONTAL); ac++;
1087 XtSetArg(al[ac], XmNnumColumns, left_buttons + right_buttons + 1); ac++;
1088 XtSetArg(al[ac], XmNmarginWidth, 0); ac++;
1089 XtSetArg(al[ac], XmNmarginHeight, 0); ac++;
1090 XtSetArg(al[ac], XmNspacing, 13); ac++;
1091 XtSetArg(al[ac], XmNadjustLast, False); ac++;
1092 XtSetArg(al[ac], XmNalignment, XmALIGNMENT_CENTER); ac++;
1093 XtSetArg(al[ac], XmNisAligned, True); ac++;
1094 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
1095 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
1096 XtSetArg(al[ac], XmNbottomOffset, 13); ac++;
1097 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1098 XtSetArg(al[ac], XmNleftOffset, 13); ac++;
1099 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1100 XtSetArg(al[ac], XmNrightOffset, 13); ac++;
1101 row = XmCreateRowColumn (form, "row", al, ac);
1102
1103 n_children = 0;
1104 for (i = 0; i < left_buttons; i++)
1105 {
1106 char button_name [16];
1107 sprintf (button_name, "button%d", i + 1);
1108 ac = 0;
1109 if (i == 0)
1110 {
1111 XtSetArg(al[ac], XmNhighlightThickness, 1); ac++;
1112 XtSetArg(al[ac], XmNshowAsDefault, TRUE); ac++;
1113 }
1114 XtSetArg(al[ac], XmNmarginWidth, 10); ac++;
1115 XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
1116 children [n_children] = XmCreatePushButton (row, button_name, al, ac);
1117 XtAddEventHandler (children [n_children],
1118 KeyPressMask, False, dialog_key_cb, result);
1119
1120 if (i == 0)
1121 {
1122 button = children [n_children];
1123 ac = 0;
1124 XtSetArg(al[ac], XmNdefaultButton, button); ac++;
1125 XtSetValues (row, al, ac);
1126 }
1127
1128 n_children++;
1129 }
1130
1131
1132 ac = 0;
1133 XtSetArg (al[ac], XmNmappedWhenManaged, FALSE); ac++;
1134 children [n_children] = XmCreateLabel (row, "separator_button", al, ac);
1135 n_children++;
1136
1137 for (i = 0; i < right_buttons; i++)
1138 {
1139 char button_name [16];
1140 sprintf (button_name, "button%d", left_buttons + i + 1);
1141 ac = 0;
1142 XtSetArg(al[ac], XmNmarginWidth, 10); ac++;
1143 XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
1144 children [n_children] = XmCreatePushButton (row, button_name, al, ac);
1145 XtAddEventHandler (children [n_children],
1146 KeyPressMask, False, dialog_key_cb, result);
1147
1148 if (! button) button = children [n_children];
1149 n_children++;
1150 }
1151
1152 XtManageChildren (children, n_children);
1153
1154 ac = 0;
1155 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
1156 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
1157 XtSetArg(al[ac], XmNbottomOffset, 13); ac++;
1158 XtSetArg(al[ac], XmNbottomWidget, row); ac++;
1159 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1160 XtSetArg(al[ac], XmNleftOffset, 0); ac++;
1161 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1162 XtSetArg(al[ac], XmNrightOffset, 0); ac++;
1163 separator = XmCreateSeparator (form, "", al, ac);
1164
1165 ac = 0;
1166 XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
1167 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1168 XtSetArg(al[ac], XmNtopOffset, 13); ac++;
1169 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
1170 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1171 XtSetArg(al[ac], XmNleftOffset, 13); ac++;
1172 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE); ac++;
1173 icon = XmCreateLabel (form, icon_name, al, ac);
1174
1175 ac = 0;
1176 XtSetArg(al[ac], XmNmappedWhenManaged, FALSE); ac++;
1177 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
1178 XtSetArg(al[ac], XmNtopOffset, 6); ac++;
1179 XtSetArg(al[ac], XmNtopWidget, icon); ac++;
1180 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
1181 XtSetArg(al[ac], XmNbottomOffset, 6); ac++;
1182 XtSetArg(al[ac], XmNbottomWidget, separator); ac++;
1183 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_NONE); ac++;
1184 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_NONE); ac++;
1185 icon_separator = XmCreateLabel (form, "", al, ac);
1186
1187 if (text_input_slot)
1188 {
1189 ac = 0;
1190 XtSetArg(al[ac], XmNcolumns, 50); ac++;
1191 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
1192 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
1193 XtSetArg(al[ac], XmNbottomOffset, 13); ac++;
1194 XtSetArg(al[ac], XmNbottomWidget, separator); ac++;
1195 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
1196 XtSetArg(al[ac], XmNleftOffset, 13); ac++;
1197 XtSetArg(al[ac], XmNleftWidget, icon); ac++;
1198 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1199 XtSetArg(al[ac], XmNrightOffset, 13); ac++;
1200 value = XmCreateTextField (form, "value", al, ac);
1201 }
1202 else if (radio_box)
1203 {
1204 Widget radio_butt;
1205 ac = 0;
1206 XtSetArg(al[ac], XmNmarginWidth, 0); ac++;
1207 XtSetArg(al[ac], XmNmarginHeight, 0); ac++;
1208 XtSetArg(al[ac], XmNspacing, 13); ac++;
1209 XtSetArg(al[ac], XmNalignment, XmALIGNMENT_CENTER); ac++;
1210 XtSetArg(al[ac], XmNorientation, XmHORIZONTAL); ac++;
1211 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
1212 XtSetArg(al[ac], XmNbottomOffset, 13); ac++;
1213 XtSetArg(al[ac], XmNbottomWidget, separator); ac++;
1214 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
1215 XtSetArg(al[ac], XmNleftOffset, 13); ac++;
1216 XtSetArg(al[ac], XmNleftWidget, icon); ac++;
1217 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1218 XtSetArg(al[ac], XmNrightOffset, 13); ac++;
1219 value = XmCreateRadioBox (form, "radiobutton1", al, ac);
1220 ac = 0;
1221 i = 0;
1222 radio_butt = XmCreateToggleButtonGadget (value, "radio1", al, ac);
1223 children [i++] = radio_butt;
1224 radio_butt = XmCreateToggleButtonGadget (value, "radio2", al, ac);
1225 children [i++] = radio_butt;
1226 radio_butt = XmCreateToggleButtonGadget (value, "radio3", al, ac);
1227 children [i++] = radio_butt;
1228 XtManageChildren (children, i);
1229 }
1230 else if (list)
1231 {
1232 ac = 0;
1233 XtSetArg(al[ac], XmNvisibleItemCount, 5); ac++;
1234 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
1235 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
1236 XtSetArg(al[ac], XmNbottomOffset, 13); ac++;
1237 XtSetArg(al[ac], XmNbottomWidget, separator); ac++;
1238 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
1239 XtSetArg(al[ac], XmNleftOffset, 13); ac++;
1240 XtSetArg(al[ac], XmNleftWidget, icon); ac++;
1241 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1242 XtSetArg(al[ac], XmNrightOffset, 13); ac++;
1243 value = XmCreateScrolledList (form, "list", al, ac);
1244
1245
1246
1247 XtAddCallback (value, XmNdefaultActionCallback, activate_button, button);
1248 }
1249
1250 ac = 0;
1251 XtSetArg(al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
1252 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1253 XtSetArg(al[ac], XmNtopOffset, 13); ac++;
1254 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
1255 XtSetArg(al[ac], XmNbottomOffset, 13); ac++;
1256 XtSetArg(al[ac], XmNbottomWidget,
1257 text_input_slot || radio_box || list ? value : separator); ac++;
1258 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
1259 XtSetArg(al[ac], XmNleftOffset, 13); ac++;
1260 XtSetArg(al[ac], XmNleftWidget, icon); ac++;
1261 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1262 XtSetArg(al[ac], XmNrightOffset, 13); ac++;
1263 message_label = XmCreateLabel (form, "message", al, ac);
1264
1265 if (list)
1266 XtManageChild (value);
1267
1268 i = 0;
1269 children [i] = row; i++;
1270 children [i] = separator; i++;
1271 if (text_input_slot || radio_box)
1272 {
1273 children [i] = value; i++;
1274 }
1275 children [i] = message_label; i++;
1276 children [i] = icon; i++;
1277 children [i] = icon_separator; i++;
1278 XtManageChildren (children, i);
1279
1280 if (text_input_slot || list)
1281 {
1282 XtInstallAccelerators (value, button);
1283 XtSetKeyboardFocus (result, value);
1284 }
1285 else
1286 {
1287 XtInstallAccelerators (form, button);
1288 XtSetKeyboardFocus (result, button);
1289 }
1290
1291 return result;
1292 }
1293
1294 static destroyed_instance*
1295 find_matching_instance (widget_instance* instance)
1296 {
1297 destroyed_instance* cur;
1298 destroyed_instance* prev;
1299 char* type = instance->info->type;
1300 char* name = instance->info->name;
1301
1302 for (prev = NULL, cur = all_destroyed_instances;
1303 cur;
1304 prev = cur, cur = cur->next)
1305 {
1306 if (!strcmp (cur->name, name)
1307 && !strcmp (cur->type, type)
1308 && cur->parent == instance->parent
1309 && cur->pop_up_p == instance->pop_up_p)
1310 {
1311 if (prev)
1312 prev->next = cur->next;
1313 else
1314 all_destroyed_instances = cur->next;
1315 return cur;
1316 }
1317
1318 else if (!cur->widget)
1319 {
1320 if (prev)
1321 prev->next = cur->next;
1322 else
1323 all_destroyed_instances = cur->next;
1324 free_destroyed_instance (cur);
1325 cur = prev ? prev : all_destroyed_instances;
1326 }
1327 }
1328 return NULL;
1329 }
1330
1331 static void
1332 mark_dead_instance_destroyed (Widget widget,
1333 XtPointer closure,
1334 XtPointer call_data)
1335 {
1336 destroyed_instance* instance = (destroyed_instance*)closure;
1337 instance->widget = NULL;
1338 }
1339
1340 static void
1341 recenter_widget (Widget widget)
1342 {
1343 Widget parent = XtParent (widget);
1344 Screen* screen = XtScreen (widget);
1345 Dimension screen_width = WidthOfScreen (screen);
1346 Dimension screen_height = HeightOfScreen (screen);
1347 Dimension parent_width = 0;
1348 Dimension parent_height = 0;
1349 Dimension child_width = 0;
1350 Dimension child_height = 0;
1351 Position x;
1352 Position y;
1353
1354 XtVaGetValues (widget, XtNwidth, &child_width, XtNheight, &child_height, NULL);
1355 XtVaGetValues (parent, XtNwidth, &parent_width, XtNheight, &parent_height,
1356 NULL);
1357
1358 x = (((Position)parent_width) - ((Position)child_width)) / 2;
1359 y = (((Position)parent_height) - ((Position)child_height)) / 2;
1360
1361 XtTranslateCoords (parent, x, y, &x, &y);
1362
1363 if (x + child_width > screen_width)
1364 x = screen_width - child_width;
1365 if (x < 0)
1366 x = 0;
1367
1368 if (y + child_height > screen_height)
1369 y = screen_height - child_height;
1370 if (y < 0)
1371 y = 0;
1372
1373 XtVaSetValues (widget, XtNx, x, XtNy, y, NULL);
1374 }
1375
1376 static Widget
1377 recycle_instance (destroyed_instance* instance)
1378 {
1379 Widget widget = instance->widget;
1380
1381
1382 if (widget)
1383 {
1384 Widget focus;
1385 Widget separator;
1386
1387
1388
1389 XtRemoveCallback (instance->parent, XtNdestroyCallback,
1390 mark_dead_instance_destroyed,
1391 (XtPointer)instance);
1392
1393
1394 focus = XtNameToWidget (widget, "*value");
1395 if (!focus)
1396 focus = XtNameToWidget (widget, "*button1");
1397 if (focus)
1398 XtSetKeyboardFocus (widget, focus);
1399
1400
1401 separator = XtNameToWidget (widget, "*separator_button");
1402 if (separator)
1403 XtVaSetValues (separator, XtNwidth, 5, XtNheight, 5, NULL);
1404
1405
1406 recenter_widget (widget);
1407 }
1408 free_destroyed_instance (instance);
1409 return widget;
1410 }
1411
1412 Widget
1413 xm_create_dialog (widget_instance* instance)
1414 {
1415 char* name = instance->info->type;
1416 Widget parent = instance->parent;
1417 Widget widget;
1418 Boolean pop_up_p = instance->pop_up_p;
1419 char* shell_name = 0;
1420 char* icon_name = 0;
1421 Boolean text_input_slot = False;
1422 Boolean radio_box = False;
1423 Boolean list = False;
1424 int total_buttons;
1425 int left_buttons = 0;
1426 int right_buttons = 1;
1427 destroyed_instance* dead_one;
1428
1429
1430 dead_one = find_matching_instance (instance);
1431 if (dead_one)
1432 {
1433 Widget recycled_widget = recycle_instance (dead_one);
1434 if (recycled_widget)
1435 return recycled_widget;
1436 }
1437
1438 switch (name [0]){
1439 case 'E': case 'e':
1440 icon_name = "dbox-error";
1441 shell_name = "Error";
1442 break;
1443
1444 case 'I': case 'i':
1445 icon_name = "dbox-info";
1446 shell_name = "Information";
1447 break;
1448
1449 case 'L': case 'l':
1450 list = True;
1451 icon_name = "dbox-question";
1452 shell_name = "Prompt";
1453 break;
1454
1455 case 'P': case 'p':
1456 text_input_slot = True;
1457 icon_name = "dbox-question";
1458 shell_name = "Prompt";
1459 break;
1460
1461 case 'Q': case 'q':
1462 icon_name = "dbox-question";
1463 shell_name = "Question";
1464 break;
1465 }
1466
1467 total_buttons = name [1] - '0';
1468
1469 if (name [3] == 'T' || name [3] == 't')
1470 {
1471 text_input_slot = False;
1472 radio_box = True;
1473 }
1474 else if (name [3])
1475 right_buttons = name [4] - '0';
1476
1477 left_buttons = total_buttons - right_buttons;
1478
1479 widget = make_dialog (name, parent, pop_up_p,
1480 shell_name, icon_name, text_input_slot, radio_box,
1481 list, left_buttons, right_buttons);
1482
1483 XtAddCallback (widget, XmNpopdownCallback, xm_nosel_callback,
1484 (XtPointer) instance);
1485
1486 return widget;
1487 }
1488
1489
1490
1491
1492 static Widget
1493 make_menubar (widget_instance* instance)
1494 {
1495 Arg al[3];
1496 int ac;
1497
1498 ac = 0;
1499 XtSetArg(al[ac], XmNmenuAccelerator, 0); ++ac;
1500 return XmCreateMenuBar (instance->parent, instance->info->name, al, ac);
1501 }
1502
1503 static void
1504 remove_grabs (Widget shell,
1505 XtPointer closure,
1506 XtPointer call_data)
1507 {
1508 Widget menu = (Widget) closure;
1509 XmRemoveFromPostFromList (menu, XtParent (XtParent (menu)));
1510 }
1511
1512 static Widget
1513 make_popup_menu (widget_instance* instance)
1514 {
1515 Widget parent = instance->parent;
1516 Window parent_window = parent->core.window;
1517 Widget result;
1518
1519
1520 parent->core.window = 0;
1521 result = XmCreatePopupMenu (parent, instance->info->name, NULL, 0);
1522 XtAddCallback (XtParent (result), XmNpopdownCallback, remove_grabs,
1523 (XtPointer)result);
1524 parent->core.window = parent_window;
1525 return result;
1526 }
1527
1528 static Widget
1529 make_main (widget_instance* instance)
1530 {
1531 Widget parent = instance->parent;
1532 Widget result;
1533 Arg al[2];
1534 int ac;
1535
1536 ac = 0;
1537 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
1538 XtSetArg (al[ac], XmNspacing, 0); ac++;
1539 result = XmCreateMainWindow (parent, instance->info->name, al, ac);
1540 return result;
1541 }
1542
1543
1544
1545 #ifdef ENERGIZE
1546
1547
1548 typedef Widget (*widget_maker) (Widget);
1549 extern Widget create_project_p_sheet (Widget parent);
1550 extern Widget create_debugger_p_sheet (Widget parent);
1551 extern Widget create_breaklist_p_sheet (Widget parent);
1552 extern Widget create_le_browser_p_sheet (Widget parent);
1553 extern Widget create_class_browser_p_sheet (Widget parent);
1554 extern Widget create_call_browser_p_sheet (Widget parent);
1555 extern Widget create_build_dialog (Widget parent);
1556 extern Widget create_editmode_dialog (Widget parent);
1557 extern Widget create_search_dialog (Widget parent);
1558 extern Widget create_project_display_dialog (Widget parent);
1559
1560 static Widget
1561 make_one (widget_instance* instance, widget_maker fn)
1562 {
1563 Widget result;
1564 Arg al [64];
1565 int ac = 0;
1566
1567 if (instance->pop_up_p)
1568 {
1569 XtSetArg (al [ac], XmNallowShellResize, TRUE); ac++;
1570 result = XmCreateDialogShell (instance->parent, "dialog", NULL, 0);
1571 XtAddCallback (result, XmNpopdownCallback, &xm_nosel_callback,
1572 (XtPointer) instance);
1573 (*fn) (result);
1574 }
1575 else
1576 {
1577 result = (*fn) (instance->parent);
1578 XtRealizeWidget (result);
1579 }
1580 return result;
1581 }
1582
1583 static Widget
1584 make_project_p_sheet (widget_instance* instance)
1585 {
1586 return make_one (instance, create_project_p_sheet);
1587 }
1588
1589 static Widget
1590 make_debugger_p_sheet (widget_instance* instance)
1591 {
1592 return make_one (instance, create_debugger_p_sheet);
1593 }
1594
1595 static Widget
1596 make_breaklist_p_sheet (widget_instance* instance)
1597 {
1598 return make_one (instance, create_breaklist_p_sheet);
1599 }
1600
1601 static Widget
1602 make_le_browser_p_sheet (widget_instance* instance)
1603 {
1604 return make_one (instance, create_le_browser_p_sheet);
1605 }
1606
1607 static Widget
1608 make_class_browser_p_sheet (widget_instance* instance)
1609 {
1610 return make_one (instance, create_class_browser_p_sheet);
1611 }
1612
1613 static Widget
1614 make_call_browser_p_sheet (widget_instance* instance)
1615 {
1616 return make_one (instance, create_call_browser_p_sheet);
1617 }
1618
1619 static Widget
1620 make_build_dialog (widget_instance* instance)
1621 {
1622 return make_one (instance, create_build_dialog);
1623 }
1624
1625 static Widget
1626 make_editmode_dialog (widget_instance* instance)
1627 {
1628 return make_one (instance, create_editmode_dialog);
1629 }
1630
1631 static Widget
1632 make_search_dialog (widget_instance* instance)
1633 {
1634 return make_one (instance, create_search_dialog);
1635 }
1636
1637 static Widget
1638 make_project_display_dialog (widget_instance* instance)
1639 {
1640 return make_one (instance, create_project_display_dialog);
1641 }
1642
1643 #endif
1644
1645 widget_creation_entry
1646 xm_creation_table [] =
1647 {
1648 {"menubar", make_menubar},
1649 {"popup", make_popup_menu},
1650 {"main", make_main},
1651 #ifdef ENERGIZE
1652 {"project_p_sheet", make_project_p_sheet},
1653 {"debugger_p_sheet", make_debugger_p_sheet},
1654 {"breaklist_psheet", make_breaklist_p_sheet},
1655 {"leb_psheet", make_le_browser_p_sheet},
1656 {"class_browser_psheet", make_class_browser_p_sheet},
1657 {"ctree_browser_psheet", make_call_browser_p_sheet},
1658 {"build", make_build_dialog},
1659 {"editmode", make_editmode_dialog},
1660 {"search", make_search_dialog},
1661 {"project_display", make_project_display_dialog},
1662 #endif
1663 {NULL, NULL}
1664 };
1665
1666
1667 void
1668 xm_destroy_instance ( widget_instance* instance)
1669 {
1670 Widget widget = instance->widget;
1671
1672
1673
1674 if (0
1675 && XtClass (widget) == xmDialogShellWidgetClass)
1676 {
1677 destroyed_instance* dead_instance =
1678 make_destroyed_instance (instance->info->name,
1679 instance->info->type,
1680 instance->widget,
1681 instance->parent,
1682 instance->pop_up_p);
1683 dead_instance->next = all_destroyed_instances;
1684 all_destroyed_instances = dead_instance;
1685 XtUnmanageChild (first_child (instance->widget));
1686 XFlush (XtDisplay (instance->widget));
1687 XtAddCallback (instance->parent, XtNdestroyCallback,
1688 mark_dead_instance_destroyed, (XtPointer)dead_instance);
1689 }
1690 else
1691 {
1692
1693
1694 XtRemoveCallback (instance->widget, XtNdestroyCallback,
1695 xm_nosel_callback, (XtPointer)instance);
1696 XtDestroyWidget (instance->widget);
1697 }
1698 }
1699
1700
1701 void
1702 xm_popup_menu (Widget widget, XEvent *event)
1703 {
1704 XButtonPressedEvent dummy;
1705
1706 if (event == 0)
1707 {
1708 dummy.type = ButtonPress;
1709 dummy.serial = 0;
1710 dummy.send_event = 0;
1711 dummy.display = XtDisplay (widget);
1712 dummy.window = XtWindow (XtParent (widget));
1713 dummy.time = 0;
1714 dummy.button = 0;
1715 XQueryPointer (dummy.display, dummy.window, &dummy.root,
1716 &dummy.subwindow, &dummy.x_root, &dummy.y_root,
1717 &dummy.x, &dummy.y, &dummy.state);
1718 event = (XEvent *) &dummy;
1719 }
1720
1721 if (event->type == ButtonPress || event->type == ButtonRelease)
1722 {
1723
1724
1725
1726
1727 #if XmVersion < 1002 || (defined LESSTIF_VERSION && LESSTIF_VERSION < 84)
1728 {
1729
1730
1731
1732
1733 char *trans = 0;
1734 if (event->xbutton.state & Button5Mask) trans = "<Btn5Down>";
1735 else if (event->xbutton.state & Button4Mask) trans = "<Btn4Down>";
1736 else if (event->xbutton.state & Button3Mask) trans = "<Btn3Down>";
1737 else if (event->xbutton.state & Button2Mask) trans = "<Btn2Down>";
1738 else if (event->xbutton.state & Button1Mask) trans = "<Btn1Down>";
1739 if (trans) XtVaSetValues (widget, XmNmenuPost, trans, NULL);
1740 }
1741 #endif
1742
1743 XmMenuPosition (widget, (XButtonPressedEvent *) event);
1744 }
1745
1746 XtManageChild (widget);
1747 }
1748
1749 static void
1750 set_min_dialog_size (Widget w)
1751 {
1752 short width;
1753 short height;
1754 XtVaGetValues (w, XmNwidth, &width, XmNheight, &height, NULL);
1755 XtVaSetValues (w, XmNminWidth, width, XmNminHeight, height, NULL);
1756 }
1757
1758 void
1759 xm_pop_instance (widget_instance* instance, Boolean up)
1760 {
1761 Widget widget = instance->widget;
1762
1763 if (XtClass (widget) == xmDialogShellWidgetClass)
1764 {
1765 Widget widget_to_manage = first_child (widget);
1766 if (up)
1767 {
1768 XtManageChild (widget_to_manage);
1769 set_min_dialog_size (widget);
1770 XtSetKeyboardFocus (instance->parent, widget);
1771 }
1772 else
1773 XtUnmanageChild (widget_to_manage);
1774 }
1775 else
1776 {
1777 if (up)
1778 XtManageChild (widget);
1779 else
1780 XtUnmanageChild (widget);
1781 }
1782 }
1783
1784
1785
1786
1787 static void
1788 do_call (Widget widget,
1789 XtPointer closure,
1790 enum do_call_type type)
1791 {
1792 Arg al [256];
1793 int ac;
1794 XtPointer user_data;
1795 widget_instance* instance = (widget_instance*)closure;
1796 widget_value *wv;
1797 Widget instance_widget;
1798 LWLIB_ID id;
1799
1800 if (!instance)
1801 return;
1802 if (widget->core.being_destroyed)
1803 return;
1804
1805 instance_widget = instance->widget;
1806 if (!instance_widget)
1807 return;
1808
1809 id = instance->info->id;
1810 ac = 0;
1811 user_data = NULL;
1812 XtSetArg (al [ac], XmNuserData, &user_data); ac++;
1813 XtGetValues (widget, al, ac);
1814 wv = user_data;
1815
1816 switch (type)
1817 {
1818 case pre_activate:
1819 if (instance->info->pre_activate_cb)
1820 instance->info->pre_activate_cb (widget, id, wv ? wv->call_data : NULL);
1821 break;
1822
1823 case selection:
1824 if (instance->info->selection_cb)
1825 instance->info->selection_cb (widget, id, wv ? wv->call_data : NULL);
1826 break;
1827
1828 case no_selection:
1829 if (instance->info->selection_cb)
1830 instance->info->selection_cb (widget, id, (XtPointer) -1);
1831 break;
1832
1833 case post_activate:
1834 if (instance->info->post_activate_cb)
1835 instance->info->post_activate_cb (widget, id, wv ? wv->call_data : NULL);
1836 break;
1837
1838 default:
1839 emacs_abort ();
1840 }
1841 }
1842
1843
1844
1845
1846
1847
1848 static void
1849 xm_internal_update_other_instances (Widget widget,
1850 XtPointer closure,
1851 XtPointer call_data)
1852 {
1853 Widget parent;
1854 for (parent = widget; parent; parent = XtParent (parent))
1855 if (XtIsShell (parent))
1856 break;
1857 else if (!XtIsManaged (parent))
1858 return;
1859 lw_internal_update_other_instances (widget, closure, call_data);
1860 }
1861
1862 static void
1863 xm_generic_callback (Widget widget,
1864 XtPointer closure,
1865 XtPointer call_data)
1866 {
1867 lw_internal_update_other_instances (widget, closure, call_data);
1868 do_call (widget, closure, selection);
1869 }
1870
1871 static void
1872 xm_nosel_callback (Widget widget,
1873 XtPointer closure,
1874 XtPointer call_data)
1875 {
1876
1877
1878
1879
1880
1881
1882
1883
1884 do_call (widget, closure, no_selection);
1885 XtDestroyWidget (widget);
1886 }
1887
1888 static void
1889 xm_pull_down_callback (Widget widget,
1890 XtPointer closure,
1891 XtPointer call_data)
1892 {
1893 Widget parent = XtParent (widget);
1894
1895 if (XmIsRowColumn (parent))
1896 {
1897 unsigned char type = 0xff;
1898 XtVaGetValues (parent, XmNrowColumnType, &type, NULL);
1899 if (type == XmMENU_BAR)
1900 do_call (widget, closure, pre_activate);
1901 }
1902 }
1903
1904
1905
1906
1907
1908
1909
1910
1911 static void
1912 xm_pop_down_callback (Widget widget,
1913 XtPointer closure,
1914 XtPointer call_data)
1915 {
1916 widget_instance *instance = (widget_instance *) closure;
1917
1918 if ((!instance->pop_up_p && XtParent (widget) == instance->widget)
1919 || XtParent (widget) == instance->parent)
1920 do_call (widget, closure, post_activate);
1921 }
1922
1923 static void
1924 xm_pop_up_callback (Widget widget,
1925 XtPointer closure,
1926 XtPointer call_data)
1927 {
1928 widget_instance *instance = (widget_instance *) closure;
1929
1930 if ((!instance->pop_up_p && XtParent (widget) == instance->widget)
1931 || XtParent (widget) == instance->parent)
1932 do_call (widget, closure, pre_activate);
1933 }
1934
1935
1936
1937 void
1938 xm_set_keyboard_focus (Widget parent, Widget w)
1939 {
1940 XmProcessTraversal (w, 0);
1941 XtSetKeyboardFocus (parent, w);
1942 }
1943
1944
1945 void
1946 xm_set_main_areas (Widget parent,
1947 Widget menubar,
1948 Widget work_area)
1949 {
1950 XmMainWindowSetAreas (parent,
1951 menubar,
1952 0,
1953 0,
1954 0,
1955 work_area);
1956 }
1957
1958
1959 void
1960 xm_manage_resizing (Widget w, Boolean flag)
1961 {
1962 XtVaSetValues (w, XtNallowShellResize, flag, NULL);
1963 }