This source file includes following definitions.
- free_widget_value_tree
- copy_widget_value_tree
- allocate_widget_info
- free_widget_info
- mark_widget_destroyed
- allocate_widget_instance
- free_widget_instance
- get_widget_info
- lw_get_widget_info
- get_widget_instance
- lw_get_widget_instance
- find_instance
- safe_strcmp
- merge_widget_value
- name_to_widget
- set_one_value
- update_one_widget_instance
- update_all_widget_values
- lw_modify_all_widgets
- initialize_widget_instance
- find_in_table
- dialog_spec_p
- instantiate_widget_instance
- lw_register_widget
- lw_get_widget
- lw_make_widget
- lw_create_widget
- destroy_one_instance
- lw_destroy_widget
- lw_destroy_all_widgets
- lw_destroy_everything
- lw_destroy_all_pop_ups
- lw_raise_all_pop_up_widgets
- lw_pop_all_widgets
- lw_pop_up_all_widgets
- lw_pop_down_all_widgets
- lw_popup_menu
- get_one_value
- lw_get_some_values
- lw_get_all_values
- lw_get_widget_value_for_widget
- lw_internal_update_other_instances
- lw_get_widget_id
- lw_set_keyboard_focus
- show_one_widget_busy
- lw_show_busy
- lw_refigure_widget
- lw_window_is_in_menubar
- lw_set_main_areas
- lw_allow_resizing
- lw_separator_p
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 <setjmp.h>
24 #include <lisp.h>
25 #include <c-strcase.h>
26
27 #include <sys/types.h>
28 #include <stdio.h>
29 #include "lwlib-int.h"
30 #include "lwlib-utils.h"
31 #include <X11/StringDefs.h>
32
33 #if defined (USE_LUCID)
34 #include "lwlib-Xlw.h"
35 #endif
36 #if defined (USE_MOTIF)
37 #include "lwlib-Xm.h"
38 #else
39 #if defined (USE_LUCID)
40 #define USE_XAW
41 #endif
42 #endif
43 #if defined (USE_XAW)
44 #ifdef HAVE_XAW3D
45 #include <X11/Xaw3d/Paned.h>
46 #else
47 #include <X11/Xaw/Paned.h>
48 #endif
49 #include "lwlib-Xaw.h"
50 #endif
51
52 #if !defined (USE_LUCID) && !defined (USE_MOTIF)
53 #error At least one of USE_LUCID or USE_MOTIF must be defined.
54 #endif
55
56 #ifndef max
57 #define max(x, y) ((x) > (y) ? (x) : (y))
58 #endif
59
60
61 static widget_info*
62 all_widget_info = NULL;
63
64 #ifdef USE_MOTIF
65 const char *lwlib_toolkit_type = "motif";
66 #else
67 const char *lwlib_toolkit_type = "lucid";
68 #endif
69
70 static widget_value *merge_widget_value (widget_value *,
71 widget_value *,
72 int, int *);
73 static void instantiate_widget_instance (widget_instance *);
74 static void free_widget_value_tree (widget_value *);
75 static widget_value *copy_widget_value_tree (widget_value *,
76 change_type);
77 static widget_info *allocate_widget_info (const char *, const char *, LWLIB_ID,
78 widget_value *,
79 lw_callback, lw_callback,
80 lw_callback, lw_callback);
81 static void free_widget_info (widget_info *);
82 static void mark_widget_destroyed (Widget, XtPointer, XtPointer);
83 static widget_instance *allocate_widget_instance (widget_info *,
84 Widget, Boolean);
85 static void free_widget_instance (widget_instance *);
86 static widget_info *get_widget_info (LWLIB_ID, Boolean);
87 static widget_instance *get_widget_instance (Widget, Boolean);
88 static widget_instance *find_instance (LWLIB_ID, Widget, Boolean);
89 static Boolean safe_strcmp (const char *, const char *);
90 static Widget name_to_widget (widget_instance *, const char *);
91 static void set_one_value (widget_instance *, widget_value *, Boolean);
92 static void update_one_widget_instance (widget_instance *, Boolean);
93 static void update_all_widget_values (widget_info *, Boolean);
94 static void initialize_widget_instance (widget_instance *);
95 static widget_creation_function find_in_table (const char *, const widget_creation_entry *);
96 static Boolean dialog_spec_p (const char *);
97 static void destroy_one_instance (widget_instance *);
98 static void lw_pop_all_widgets (LWLIB_ID, Boolean);
99 static Boolean get_one_value (widget_instance *, widget_value *);
100 static void show_one_widget_busy (Widget, Boolean);
101
102 static void
103 free_widget_value_tree (widget_value *wv)
104 {
105 if (!wv)
106 return;
107
108 xfree (wv->name);
109 xfree (wv->value);
110 xfree (wv->key);
111
112 wv->name = wv->value = wv->key = (char *) 0xDEADBEEF;
113
114 if (wv->toolkit_data && wv->free_toolkit_data)
115 {
116 XtFree (wv->toolkit_data);
117 wv->toolkit_data = (void *) 0xDEADBEEF;
118 }
119
120 if (wv->contents && (wv->contents != (widget_value*)1))
121 {
122 free_widget_value_tree (wv->contents);
123 wv->contents = (widget_value *) 0xDEADBEEF;
124 }
125 if (wv->next)
126 {
127 free_widget_value_tree (wv->next);
128 wv->next = (widget_value *) 0xDEADBEEF;
129 }
130 xfree (wv);
131 }
132
133 static widget_value *
134 copy_widget_value_tree (widget_value *val, change_type change)
135 {
136 widget_value* copy;
137
138 if (!val)
139 return NULL;
140 if (val == (widget_value *) 1)
141 return val;
142
143 copy = xmalloc (sizeof (widget_value));
144 copy->lname = copy->lkey = Qnil;
145 copy->name = xstrdup (val->name);
146 copy->value = val->value ? xstrdup (val->value) : NULL;
147 copy->key = val->key ? xstrdup (val->key) : NULL;
148 copy->help = val->help;
149 copy->enabled = val->enabled;
150 copy->button_type = val->button_type;
151 copy->selected = val->selected;
152 copy->edited = False;
153 copy->change = change;
154 copy->this_one_change = change;
155 copy->contents = copy_widget_value_tree (val->contents, change);
156 copy->call_data = val->call_data;
157 copy->next = copy_widget_value_tree (val->next, change);
158 copy->toolkit_data = NULL;
159 copy->free_toolkit_data = False;
160 return copy;
161 }
162
163 static widget_info *
164 allocate_widget_info (const char* type,
165 const char* name,
166 LWLIB_ID id,
167 widget_value* val,
168 lw_callback pre_activate_cb,
169 lw_callback selection_cb,
170 lw_callback post_activate_cb,
171 lw_callback highlight_cb)
172 {
173 widget_info* info = (widget_info*) xmalloc (sizeof (widget_info));
174 info->type = xstrdup (type);
175 info->name = xstrdup (name);
176 info->id = id;
177 info->val = copy_widget_value_tree (val, STRUCTURAL_CHANGE);
178 info->busy = False;
179 info->pre_activate_cb = pre_activate_cb;
180 info->selection_cb = selection_cb;
181 info->post_activate_cb = post_activate_cb;
182 info->highlight_cb = highlight_cb;
183 info->instances = NULL;
184
185 info->next = all_widget_info;
186 all_widget_info = info;
187
188 return info;
189 }
190
191 static void
192 free_widget_info (widget_info *info)
193 {
194 xfree (info->type);
195 xfree (info->name);
196 free_widget_value_tree (info->val);
197 memset ((void*)info, 0xDEADBEEF, sizeof (widget_info));
198 xfree (info);
199 }
200
201 static void
202 mark_widget_destroyed (Widget widget, XtPointer closure, XtPointer call_data)
203 {
204 widget_instance* instance = (widget_instance*)closure;
205
206
207 if (instance->widget == widget)
208 instance->widget = NULL;
209 }
210
211 static widget_instance *
212 allocate_widget_instance (widget_info* info, Widget parent, Boolean pop_up_p)
213 {
214 widget_instance* instance =
215 (widget_instance*) xmalloc (sizeof (widget_instance));
216 memset (instance, 0, sizeof *instance);
217 instance->parent = parent;
218 instance->pop_up_p = pop_up_p;
219 instance->info = info;
220 instance->next = info->instances;
221 info->instances = instance;
222
223 instantiate_widget_instance (instance);
224
225 XtAddCallback (instance->widget, XtNdestroyCallback,
226 mark_widget_destroyed, (XtPointer)instance);
227 return instance;
228 }
229
230 static void
231 free_widget_instance (widget_instance *instance)
232 {
233 memset ((void*)instance, 0xDEADBEEF, sizeof (widget_instance));
234 xfree (instance);
235 }
236
237 static widget_info *
238 get_widget_info (LWLIB_ID id, Boolean remove_p)
239 {
240 widget_info* info;
241 widget_info* prev;
242 for (prev = NULL, info = all_widget_info;
243 info;
244 prev = info, info = info->next)
245 if (info->id == id)
246 {
247 if (remove_p)
248 {
249 if (prev)
250 prev->next = info->next;
251 else
252 all_widget_info = info->next;
253 }
254 return info;
255 }
256 return NULL;
257 }
258
259
260
261 widget_info *
262 lw_get_widget_info (LWLIB_ID id)
263 {
264 return get_widget_info (id, 0);
265 }
266
267 static widget_instance *
268 get_widget_instance (Widget widget, Boolean remove_p)
269 {
270 widget_info* info;
271 widget_instance* instance;
272 widget_instance* prev;
273 for (info = all_widget_info; info; info = info->next)
274 for (prev = NULL, instance = info->instances;
275 instance;
276 prev = instance, instance = instance->next)
277 if (instance->widget == widget)
278 {
279 if (remove_p)
280 {
281 if (prev)
282 prev->next = instance->next;
283 else
284 info->instances = instance->next;
285 }
286 return instance;
287 }
288 return (widget_instance *) 0;
289 }
290
291
292
293
294 widget_instance *
295 lw_get_widget_instance (Widget widget)
296 {
297 return get_widget_instance (widget, False);
298 }
299
300 static widget_instance*
301 find_instance (LWLIB_ID id, Widget parent, Boolean pop_up_p)
302 {
303 widget_info* info = get_widget_info (id, False);
304 widget_instance* instance;
305
306 if (info)
307 for (instance = info->instances; instance; instance = instance->next)
308 if (instance->parent == parent && instance->pop_up_p == pop_up_p)
309 return instance;
310
311 return NULL;
312 }
313
314
315
316 static Boolean
317 safe_strcmp (const char *s1, const char *s2)
318 {
319 if (!!s1 ^ !!s2) return True;
320 return (s1 && s2) ? strcmp (s1, s2) : s1 ? False : !!s2;
321 }
322
323
324 #if 0
325 # define EXPLAIN(name, oc, nc, desc, a1, a2) \
326 printf ("Change: \"%s\"\tmax(%s=%d,%s=%d)\t%s %d %d\n", \
327 name, \
328 (oc == NO_CHANGE ? "none" : \
329 (oc == INVISIBLE_CHANGE ? "invisible" : \
330 (oc == VISIBLE_CHANGE ? "visible" : \
331 (oc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
332 oc, \
333 (nc == NO_CHANGE ? "none" : \
334 (nc == INVISIBLE_CHANGE ? "invisible" : \
335 (nc == VISIBLE_CHANGE ? "visible" : \
336 (nc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
337 nc, desc, a1, a2)
338 #else
339 # define EXPLAIN(name, oc, nc, desc, a1, a2) ((void) 0)
340 #endif
341
342
343 static widget_value *
344 merge_widget_value (widget_value *val1,
345 widget_value *val2,
346 int level,
347 int *change_p)
348 {
349 change_type change, this_one_change;
350 widget_value* merged_next;
351 widget_value* merged_contents;
352
353 if (!val1)
354 {
355 if (val2)
356 {
357 *change_p = 1;
358 return copy_widget_value_tree (val2, STRUCTURAL_CHANGE);
359 }
360 else
361 return NULL;
362 }
363 if (!val2)
364 {
365 *change_p = 1;
366 free_widget_value_tree (val1);
367 return NULL;
368 }
369
370 change = NO_CHANGE;
371
372 if (safe_strcmp (val1->name, val2->name))
373 {
374 EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "name change",
375 val1->name, val2->name);
376 change = max (change, STRUCTURAL_CHANGE);
377 dupstring (&val1->name, val2->name);
378 }
379 if (safe_strcmp (val1->value, val2->value))
380 {
381 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "value change",
382 val1->value, val2->value);
383 change = max (change, VISIBLE_CHANGE);
384 dupstring (&val1->value, val2->value);
385 }
386 if (safe_strcmp (val1->key, val2->key))
387 {
388 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "key change",
389 val1->key, val2->key);
390 change = max (change, VISIBLE_CHANGE);
391 dupstring (&val1->key, val2->key);
392 }
393 if (! EQ (val1->help, val2->help))
394 {
395 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "help change",
396 val1->help, val2->help);
397 change = max (change, VISIBLE_CHANGE);
398 val1->help = val2->help;
399 }
400 if (val1->enabled != val2->enabled)
401 {
402 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "enablement change",
403 val1->enabled, val2->enabled);
404 change = max (change, VISIBLE_CHANGE);
405 val1->enabled = val2->enabled;
406 }
407 if (val1->button_type != val2->button_type)
408 {
409 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "button type change",
410 val1->button_type, val2->button_type);
411 change = max (change, VISIBLE_CHANGE);
412 val1->button_type = val2->button_type;
413 }
414 if (val1->selected != val2->selected)
415 {
416 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "selection change",
417 val1->selected, val2->selected);
418 change = max (change, VISIBLE_CHANGE);
419 val1->selected = val2->selected;
420 }
421 if (val1->call_data != val2->call_data)
422 {
423 EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "call-data change",
424 val1->call_data, val2->call_data);
425 change = max (change, INVISIBLE_CHANGE);
426 val1->call_data = val2->call_data;
427 }
428
429 if (level > 0)
430 {
431 merged_contents =
432 merge_widget_value (val1->contents, val2->contents, level - 1,
433 change_p);
434
435 if (val1->contents && !merged_contents)
436 {
437
438
439
440
441
442 EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "(contents gone)",
443 0, 0);
444 change = max (change, STRUCTURAL_CHANGE);
445 }
446 else if (merged_contents && merged_contents->change != NO_CHANGE)
447 {
448 EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "(contents change)",
449 0, 0);
450 change = max (change, INVISIBLE_CHANGE);
451 #if 0
452 #ifdef USE_MOTIF
453 change = max (merged_contents->change, change);
454 #endif
455 #endif
456 }
457
458 val1->contents = merged_contents;
459 }
460
461 this_one_change = change;
462
463 merged_next = merge_widget_value (val1->next, val2->next, level, change_p);
464
465 if (val1->next && !merged_next)
466 {
467 EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "(following gone)",
468 0, 0);
469 change = max (change, STRUCTURAL_CHANGE);
470 }
471 else if (merged_next)
472 {
473 if (merged_next->change)
474 EXPLAIN (val1->name, change, merged_next->change, "(following change)",
475 0, 0);
476 change = max (change, merged_next->change);
477 }
478
479 val1->next = merged_next;
480
481 val1->this_one_change = this_one_change;
482 val1->change = change;
483
484 if (change > NO_CHANGE && val1->toolkit_data)
485 {
486 *change_p = 1;
487 if (val1->free_toolkit_data)
488 XtFree (val1->toolkit_data);
489 val1->toolkit_data = NULL;
490 }
491
492 return val1;
493 }
494
495
496
497 static Widget
498 name_to_widget (widget_instance *instance, const char *name)
499 {
500 Widget widget = NULL;
501
502 if (!instance->widget)
503 return NULL;
504
505 if (!strcmp (XtName (instance->widget), name))
506 widget = instance->widget;
507 else
508 {
509 int length = strlen (name) + 2;
510 char* real_name = (char *) xmalloc (length);
511 real_name [0] = '*';
512 strcpy (real_name + 1, name);
513
514 widget = XtNameToWidget (instance->widget, real_name);
515
516 xfree (real_name);
517 }
518 return widget;
519 }
520
521 static void
522 set_one_value (widget_instance* instance, widget_value* val, Boolean deep_p)
523 {
524 Widget widget = name_to_widget (instance, val->name);
525
526 if (widget)
527 {
528 #if defined (USE_LUCID)
529 if (lw_lucid_widget_p (instance->widget))
530 xlw_update_one_widget (instance, widget, val, deep_p);
531 #endif
532 #if defined (USE_MOTIF)
533 if (lw_motif_widget_p (instance->widget))
534 xm_update_one_widget (instance, widget, val, deep_p);
535 #endif
536 #if defined (USE_XAW)
537 if (lw_xaw_widget_p (instance->widget))
538 xaw_update_one_widget (instance, widget, val, deep_p);
539 #endif
540 }
541 }
542
543 static void
544 update_one_widget_instance (widget_instance* instance, Boolean deep_p)
545 {
546 widget_value *val;
547
548 if (!instance->widget)
549
550 return;
551
552 for (val = instance->info->val; val; val = val->next)
553 if (val->change != NO_CHANGE)
554 set_one_value (instance, val, deep_p);
555 }
556
557 static void
558 update_all_widget_values (widget_info* info, Boolean deep_p)
559 {
560 widget_instance* instance;
561 widget_value* val;
562
563 for (instance = info->instances; instance; instance = instance->next)
564 update_one_widget_instance (instance, deep_p);
565
566 for (val = info->val; val; val = val->next)
567 val->change = NO_CHANGE;
568 }
569
570 int
571 lw_modify_all_widgets (LWLIB_ID id, widget_value* val, Boolean deep_p)
572 {
573 widget_info* info = get_widget_info (id, False);
574 widget_value* new_val;
575 widget_value* next_new_val;
576 widget_value* cur;
577 widget_value* prev;
578 widget_value* next;
579 int found;
580 int change_p = 0;
581
582 if (!info)
583 return 0;
584
585 for (new_val = val; new_val; new_val = new_val->next)
586 {
587 next_new_val = new_val->next;
588 new_val->next = NULL;
589 found = False;
590 for (prev = NULL, cur = info->val; cur; prev = cur, cur = cur->next)
591 if (!strcmp (cur->name, new_val->name))
592 {
593 found = True;
594 next = cur->next;
595 cur->next = NULL;
596 cur = merge_widget_value (cur, new_val, deep_p ? 1000 : 1,
597 &change_p);
598 if (prev)
599 prev->next = cur ? cur : next;
600 else
601 info->val = cur ? cur : next;
602 if (cur)
603 cur->next = next;
604 break;
605 }
606 if (!found)
607 {
608
609 if (prev)
610 prev->next = copy_widget_value_tree (new_val, STRUCTURAL_CHANGE);
611 else
612 info->val = copy_widget_value_tree (new_val, STRUCTURAL_CHANGE);
613 change_p = 1;
614 }
615 new_val->next = next_new_val;
616 }
617
618 update_all_widget_values (info, deep_p);
619 return change_p;
620 }
621
622
623
624
625 static void
626 initialize_widget_instance (widget_instance *instance)
627 {
628 widget_value* val;
629
630 for (val = instance->info->val; val; val = val->next)
631 val->change = STRUCTURAL_CHANGE;
632
633 update_one_widget_instance (instance, True);
634
635 for (val = instance->info->val; val; val = val->next)
636 val->change = NO_CHANGE;
637 }
638
639
640 static widget_creation_function
641 find_in_table (const char *type, const widget_creation_entry *table)
642 {
643 const widget_creation_entry* cur;
644 for (cur = table; cur->type; cur++)
645 if (!c_strcasecmp (type, cur->type))
646 return cur->function;
647 return NULL;
648 }
649
650 static Boolean
651 dialog_spec_p (const char *name)
652 {
653
654
655 if (!name)
656 return False;
657
658 switch (name [0])
659 {
660 case 'E': case 'I': case 'L': case 'P': case 'Q':
661 case 'e': case 'i': case 'l': case 'p': case 'q':
662 if (name [1] >= '0' && name [1] <= '9')
663 {
664 if (name [2] != 'B' && name [2] != 'b')
665 return False;
666 if (!name [3])
667 return True;
668 if ((name [3] == 'T' || name [3] == 't') && !name [4])
669 return True;
670 if ((name [3] == 'R' || name [3] == 'r')
671 && name [4] >= '0' && name [4] <= '9' && !name [5])
672 return True;
673 return False;
674 }
675 else
676 return False;
677
678 default:
679 return False;
680 }
681 }
682
683 static void
684 instantiate_widget_instance (widget_instance *instance)
685 {
686 widget_creation_function function = NULL;
687
688 #if defined (USE_LUCID)
689 if (!function)
690 function = find_in_table (instance->info->type, xlw_creation_table);
691 #endif
692 #if defined(USE_MOTIF)
693 if (!function)
694 function = find_in_table (instance->info->type, xm_creation_table);
695 #endif
696 #if defined (USE_XAW)
697 if (!function)
698 function = find_in_table (instance->info->type, xaw_creation_table);
699 #endif
700
701 if (!function)
702 {
703 if (dialog_spec_p (instance->info->type))
704 {
705 #if defined (USE_LUCID)
706
707 #endif
708 #if defined(USE_MOTIF)
709 if (!function)
710 function = xm_create_dialog;
711 #endif
712 #if defined (USE_XAW)
713 if (!function)
714 function = xaw_create_dialog;
715 #endif
716 }
717 }
718
719 if (!function)
720 {
721 printf ("No creation function for widget type %s\n",
722 instance->info->type);
723 emacs_abort ();
724 }
725
726 instance->widget = (*function) (instance);
727
728 if (!instance->widget)
729 emacs_abort ();
730
731
732 }
733
734 void
735 lw_register_widget (const char* type,
736 const char* name,
737 LWLIB_ID id,
738 widget_value* val,
739 lw_callback pre_activate_cb,
740 lw_callback selection_cb,
741 lw_callback post_activate_cb,
742 lw_callback highlight_cb)
743 {
744 if (!get_widget_info (id, False))
745 allocate_widget_info (type, name, id, val, pre_activate_cb, selection_cb,
746 post_activate_cb, highlight_cb);
747 }
748
749 Widget
750 lw_get_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p)
751 {
752 widget_instance* instance;
753
754 instance = find_instance (id, parent, pop_up_p);
755 return instance ? instance->widget : NULL;
756 }
757
758 Widget
759 lw_make_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p)
760 {
761 widget_instance* instance;
762 widget_info* info;
763
764 instance = find_instance (id, parent, pop_up_p);
765 if (!instance)
766 {
767 info = get_widget_info (id, False);
768 if (!info)
769 return NULL;
770 instance = allocate_widget_instance (info, parent, pop_up_p);
771 initialize_widget_instance (instance);
772 }
773 if (!instance->widget)
774 emacs_abort ();
775 return instance->widget;
776 }
777
778 Widget
779 lw_create_widget (const char* type, const char* name, LWLIB_ID id, widget_value* val,
780 Widget parent, Boolean pop_up_p,
781 lw_callback pre_activate_cb, lw_callback selection_cb,
782 lw_callback post_activate_cb, lw_callback highlight_cb)
783 {
784 lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb,
785 post_activate_cb, highlight_cb);
786 return lw_make_widget (id, parent, pop_up_p);
787 }
788
789
790
791 static void
792 destroy_one_instance (widget_instance *instance)
793 {
794
795
796
797
798
799
800
801
802 if (instance->widget)
803 XtRemoveCallback (instance->widget, XtNdestroyCallback,
804 mark_widget_destroyed, (XtPointer)instance);
805
806 if (instance->widget)
807 {
808
809
810
811 #if defined (USE_LUCID)
812 if (lw_lucid_widget_p (instance->widget))
813 xlw_destroy_instance (instance);
814 else
815 #endif
816 #if defined (USE_MOTIF)
817 if (lw_motif_widget_p (instance->widget))
818 xm_destroy_instance (instance);
819 else
820 #endif
821 #if defined (USE_XAW)
822 if (lw_xaw_widget_p (instance->widget))
823 xaw_destroy_instance (instance);
824 else
825 #endif
826 {
827
828 }
829 }
830
831 free_widget_instance (instance);
832 }
833
834 void
835 lw_destroy_widget (Widget w)
836 {
837 widget_instance* instance = get_widget_instance (w, True);
838
839 if (instance)
840 {
841 widget_info *info = instance->info;
842
843 destroy_one_instance (instance);
844
845 if (!info->instances)
846 lw_destroy_all_widgets (info->id);
847 }
848 }
849
850 void
851 lw_destroy_all_widgets (LWLIB_ID id)
852 {
853 widget_info* info = get_widget_info (id, True);
854 widget_instance* instance;
855 widget_instance* next;
856
857 if (info)
858 {
859 for (instance = info->instances; instance; )
860 {
861 next = instance->next;
862 destroy_one_instance (instance);
863 instance = next;
864 }
865 free_widget_info (info);
866 }
867 }
868
869 void
870 lw_destroy_everything (void)
871 {
872 while (all_widget_info)
873 lw_destroy_all_widgets (all_widget_info->id);
874 }
875
876 void
877 lw_destroy_all_pop_ups (void)
878 {
879 widget_info* info;
880 widget_info* next;
881 widget_instance* instance;
882
883 for (info = all_widget_info; info; info = next)
884 {
885 next = info->next;
886 instance = info->instances;
887 if (instance && instance->pop_up_p)
888 lw_destroy_all_widgets (info->id);
889 }
890 }
891
892 #ifdef USE_MOTIF
893 extern Widget first_child (Widget);
894 #endif
895
896 Widget
897 lw_raise_all_pop_up_widgets (void)
898 {
899 widget_info* info;
900 widget_instance* instance;
901 Widget result = NULL;
902
903 for (info = all_widget_info; info; info = info->next)
904 for (instance = info->instances; instance; instance = instance->next)
905 if (instance->pop_up_p)
906 {
907 Widget widget = instance->widget;
908 if (widget)
909 {
910 if (XtIsManaged (widget)
911 #ifdef USE_MOTIF
912
913
914
915 || (lw_motif_widget_p (instance->widget) &&
916 XtIsManaged (first_child (widget)))
917 #endif
918 )
919 {
920 if (!result)
921 result = widget;
922 XMapRaised (XtDisplay (widget), XtWindow (widget));
923 }
924 }
925 }
926 return result;
927 }
928
929 static void
930 lw_pop_all_widgets (LWLIB_ID id, Boolean up)
931 {
932 widget_info* info = get_widget_info (id, False);
933 widget_instance* instance;
934
935 if (info)
936 for (instance = info->instances; instance; instance = instance->next)
937 if (instance->pop_up_p && instance->widget)
938 {
939 #if defined (USE_LUCID)
940 if (lw_lucid_widget_p (instance->widget))
941 {
942 XtRealizeWidget (instance->widget);
943 xlw_pop_instance (instance, up);
944 }
945 #endif
946 #if defined (USE_MOTIF)
947 if (lw_motif_widget_p (instance->widget))
948 {
949 XtRealizeWidget (instance->widget);
950 xm_pop_instance (instance, up);
951 }
952 #endif
953 #if defined (USE_XAW)
954 if (lw_xaw_widget_p (instance->widget))
955 {
956 XtRealizeWidget (XtParent (instance->widget));
957 XtRealizeWidget (instance->widget);
958 xaw_pop_instance (instance, up);
959 }
960 #endif
961 }
962 }
963
964 void
965 lw_pop_up_all_widgets (LWLIB_ID id)
966 {
967 lw_pop_all_widgets (id, True);
968 }
969
970 void
971 lw_pop_down_all_widgets (LWLIB_ID id)
972 {
973 lw_pop_all_widgets (id, False);
974 }
975
976 void
977 lw_popup_menu (Widget widget, XEvent *event)
978 {
979 #if defined (USE_LUCID)
980 if (lw_lucid_widget_p (widget))
981 xlw_popup_menu (widget, event);
982 #endif
983 #if defined (USE_MOTIF)
984 if (lw_motif_widget_p (widget))
985 xm_popup_menu (widget, event);
986 #endif
987 #if defined (USE_XAW)
988 if (lw_xaw_widget_p (widget))
989 xaw_popup_menu (widget, event);
990 #endif
991 }
992
993
994 static Boolean
995 get_one_value (widget_instance *instance, widget_value *val)
996 {
997 Widget widget = name_to_widget (instance, val->name);
998
999 if (widget)
1000 {
1001 #if defined (USE_LUCID)
1002 if (lw_lucid_widget_p (instance->widget))
1003 xlw_update_one_value (instance, widget, val);
1004 #endif
1005 #if defined (USE_MOTIF)
1006 if (lw_motif_widget_p (instance->widget))
1007 xm_update_one_value (instance, widget, val);
1008 #endif
1009 #if defined (USE_XAW)
1010 if (lw_xaw_widget_p (instance->widget))
1011 xaw_update_one_value (instance, widget, val);
1012 #endif
1013 return True;
1014 }
1015 else
1016 return False;
1017 }
1018
1019 Boolean
1020 lw_get_some_values (LWLIB_ID id, widget_value *val_out)
1021 {
1022 widget_info* info = get_widget_info (id, False);
1023 widget_instance* instance;
1024 widget_value* val;
1025 Boolean result = False;
1026
1027 if (!info)
1028 return False;
1029
1030 instance = info->instances;
1031 if (!instance)
1032 return False;
1033
1034 for (val = val_out; val; val = val->next)
1035 if (get_one_value (instance, val))
1036 result = True;
1037
1038 return result;
1039 }
1040
1041 widget_value*
1042 lw_get_all_values (LWLIB_ID id)
1043 {
1044 widget_info* info = get_widget_info (id, False);
1045 if (info)
1046 {
1047 widget_value* val = info->val;
1048 if (lw_get_some_values (id, val))
1049 return val;
1050 }
1051 return NULL;
1052 }
1053
1054
1055
1056 widget_value*
1057 lw_get_widget_value_for_widget (widget_instance *instance, Widget w)
1058 {
1059 char* name = XtName (w);
1060 widget_value* cur;
1061 for (cur = instance->info->val; cur; cur = cur->next)
1062 if (!strcmp (cur->name, name))
1063 return cur;
1064 return NULL;
1065 }
1066
1067
1068
1069
1070 static Boolean lwlib_updating;
1071
1072
1073
1074
1075 void
1076 lw_internal_update_other_instances (Widget widget,
1077 XtPointer closure,
1078 XtPointer call_data)
1079 {
1080 widget_instance* instance = (widget_instance*)closure;
1081 char* name = XtName (widget);
1082 widget_info* info;
1083 widget_instance* cur;
1084 widget_value* val;
1085
1086
1087 if (lwlib_updating)
1088 return;
1089
1090
1091 if (XtWidgetBeingDestroyedP (widget))
1092 return;
1093
1094
1095 info = instance->info;
1096 if (!info->instances->next)
1097 return;
1098
1099 lwlib_updating = True;
1100
1101 for (val = info->val; val && strcmp (val->name, name); val = val->next);
1102
1103 if (val && get_one_value (instance, val))
1104 for (cur = info->instances; cur; cur = cur->next)
1105 if (cur != instance)
1106 set_one_value (cur, val, True);
1107
1108 lwlib_updating = False;
1109 }
1110
1111
1112
1113
1114 LWLIB_ID
1115 lw_get_widget_id (Widget w)
1116 {
1117 widget_instance* instance = get_widget_instance (w, False);
1118
1119 return instance ? instance->info->id : 0;
1120 }
1121
1122
1123 void
1124 lw_set_keyboard_focus (Widget parent, Widget w)
1125 {
1126 #if defined (USE_MOTIF)
1127 xm_set_keyboard_focus (parent, w);
1128 #else
1129 XtSetKeyboardFocus (parent, w);
1130 #endif
1131 }
1132
1133
1134 static void
1135 show_one_widget_busy (Widget w, Boolean flag)
1136 {
1137 Pixel foreground = 0;
1138 Pixel background = 1;
1139 Widget widget_to_invert = XtNameToWidget (w, "*sheet");
1140 if (!widget_to_invert)
1141 widget_to_invert = w;
1142
1143 XtVaGetValues (widget_to_invert,
1144 XtNforeground, &foreground,
1145 XtNbackground, &background,
1146 NULL);
1147 XtVaSetValues (widget_to_invert,
1148 XtNforeground, background,
1149 XtNbackground, foreground,
1150 NULL);
1151 }
1152
1153 void
1154 lw_show_busy (Widget w, Boolean busy)
1155 {
1156 widget_instance* instance = get_widget_instance (w, False);
1157 widget_info* info;
1158 widget_instance* next;
1159
1160 if (instance)
1161 {
1162 info = instance->info;
1163 if (info->busy != busy)
1164 {
1165 for (next = info->instances; next; next = next->next)
1166 if (next->widget)
1167 show_one_widget_busy (next->widget, busy);
1168 info->busy = busy;
1169 }
1170 }
1171 }
1172
1173
1174
1175 void
1176 lw_refigure_widget (Widget w, Boolean doit)
1177 {
1178 #if defined (USE_XAW)
1179 XawPanedSetRefigureMode (w, doit);
1180 #endif
1181 #if defined (USE_MOTIF)
1182 if (doit)
1183 XtManageChild (w);
1184 else
1185 XtUnmanageChild (w);
1186 #endif
1187 }
1188
1189
1190
1191 Boolean
1192 lw_window_is_in_menubar (Window win, Widget menubar_widget)
1193 {
1194 return menubar_widget
1195 #if defined (USE_LUCID)
1196 && XtWindow (menubar_widget) == win;
1197 #endif
1198 #if defined (USE_MOTIF)
1199 && ((XtWindow (menubar_widget) == win)
1200 || (XtWindowToWidget (XtDisplay (menubar_widget), win)
1201 && (XtParent (XtWindowToWidget (XtDisplay (menubar_widget), win))
1202 == menubar_widget)));
1203 #endif
1204 }
1205
1206
1207 void
1208 lw_set_main_areas (Widget parent, Widget menubar, Widget work_area)
1209 {
1210 #if defined (USE_MOTIF)
1211 xm_set_main_areas (parent, menubar, work_area);
1212 #endif
1213 }
1214
1215
1216
1217 void
1218 lw_allow_resizing (Widget w, Boolean flag)
1219 {
1220 #if defined (USE_MOTIF)
1221 xm_manage_resizing (w, flag);
1222 #endif
1223 }
1224
1225
1226
1227
1228
1229
1230
1231 int
1232 lw_separator_p (const char *label, enum menu_separator *type, int motif_p)
1233 {
1234 int separator_p = 0;
1235
1236 if (strncmp (label, "--:", 3) == 0)
1237 {
1238 static struct separator_table
1239 {
1240 const char *name;
1241 enum menu_separator type;
1242 }
1243 separator_names[] =
1244 {
1245 {"space", SEPARATOR_NO_LINE},
1246 {"noLine", SEPARATOR_NO_LINE},
1247 {"singleLine", SEPARATOR_SINGLE_LINE},
1248 {"doubleLine", SEPARATOR_DOUBLE_LINE},
1249 {"singleDashedLine", SEPARATOR_SINGLE_DASHED_LINE},
1250 {"doubleDashedLine", SEPARATOR_DOUBLE_DASHED_LINE},
1251 {"shadowEtchedIn", SEPARATOR_SHADOW_ETCHED_IN},
1252 {"shadowEtchedOut", SEPARATOR_SHADOW_ETCHED_OUT},
1253 {"shadowEtchedInDash", SEPARATOR_SHADOW_ETCHED_IN_DASH},
1254 {"shadowEtchedOutDash", SEPARATOR_SHADOW_ETCHED_OUT_DASH},
1255 {"shadowDoubleEtchedIn", SEPARATOR_SHADOW_DOUBLE_ETCHED_IN},
1256 {"shadowDoubleEtchedOut", SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT},
1257 {"shadowDoubleEtchedInDash", SEPARATOR_SHADOW_DOUBLE_ETCHED_IN_DASH},
1258 {"shadowDoubleEtchedOutDash", SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT_DASH},
1259 {0,0}
1260 };
1261
1262 int i;
1263
1264 label += 3;
1265 for (i = 0; separator_names[i].name; ++i)
1266 if (strcmp (label, separator_names[i].name) == 0)
1267 {
1268 separator_p = 1;
1269 *type = separator_names[i].type;
1270
1271
1272
1273 if (motif_p && *type >= SEPARATOR_SHADOW_DOUBLE_ETCHED_IN)
1274 *type -= 4;
1275 break;
1276 }
1277 }
1278 else if (strnlen (label, 4) == 4
1279 && memcmp (label, "--", 2) == 0
1280 && label[2] != '-')
1281 {
1282
1283 static struct separator_table
1284 {
1285 const char *name;
1286 enum menu_separator type;
1287 }
1288 separator_names[] =
1289 {
1290 {"space", SEPARATOR_NO_LINE},
1291 {"no-line", SEPARATOR_NO_LINE},
1292 {"single-line", SEPARATOR_SINGLE_LINE},
1293 {"double-line", SEPARATOR_DOUBLE_LINE},
1294 {"single-dashed-line", SEPARATOR_SINGLE_DASHED_LINE},
1295 {"double-dashed-line", SEPARATOR_DOUBLE_DASHED_LINE},
1296 {"shadow-etched-in", SEPARATOR_SHADOW_ETCHED_IN},
1297 {"shadow-etched-out", SEPARATOR_SHADOW_ETCHED_OUT},
1298 {"shadow-etched-in-dash", SEPARATOR_SHADOW_ETCHED_IN_DASH},
1299 {"shadow-etched-out-dash", SEPARATOR_SHADOW_ETCHED_OUT_DASH},
1300 {"shadow-double-etched-in", SEPARATOR_SHADOW_DOUBLE_ETCHED_IN},
1301 {"shadow-double-etched-out", SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT},
1302 {"shadow-double-etched-in-dash", SEPARATOR_SHADOW_DOUBLE_ETCHED_IN_DASH},
1303 {"shadow-double-etched-out-dash",SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT_DASH},
1304 {0,0}
1305 };
1306
1307 int i;
1308
1309 label += 2;
1310 for (i = 0; separator_names[i].name; ++i)
1311 if (strcmp (label, separator_names[i].name) == 0)
1312 {
1313 separator_p = 1;
1314 *type = separator_names[i].type;
1315
1316
1317
1318 if (motif_p && *type >= SEPARATOR_SHADOW_DOUBLE_ETCHED_IN)
1319 *type -= 4;
1320 break;
1321 }
1322 }
1323 else
1324 {
1325
1326
1327 if (*label == '-')
1328 {
1329 while (*label == '-')
1330 ++label;
1331 separator_p = *label == 0;
1332
1333 *type = SEPARATOR_SHADOW_ETCHED_IN;
1334 }
1335 }
1336
1337 return separator_p;
1338 }