1 /* A general interface to the widgets of different toolkits.
2 Copyright (C) 1992, 1993 Lucid, Inc.
4 This file is part of the Lucid Widget Library.
6 The Lucid Widget Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 The Lucid Widget Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #undef __STRICT_BSD__ /* ick */
24 #include <sys/types.h>
27 #include "lwlib-int.h"
28 #include "lwlib-utils.h"
29 #include <X11/StringDefs.h>
31 #if defined (USE_LUCID)
32 #include "lwlib-Xlw.h"
34 #if defined (USE_MOTIF)
36 #else /* not USE_MOTIF */
37 #if defined (USE_LUCID)
39 #endif /* not USE_MOTIF && USE_LUCID */
41 #if defined (USE_OLIT)
42 #include "lwlib-Xol.h"
45 #include "lwlib-Xaw.h"
48 #if !defined (USE_LUCID) && !defined (USE_MOTIF) && !defined (USE_OLIT)
49 ERROR
! At least one of USE_LUCID
, USE_MOTIF
or USE_OLIT must be defined
.
52 #if defined (USE_MOTIF) && defined (USE_OLIT)
53 ERROR
! no more than one of USE_MOTIF
and USE_OLIT may be defined
.
57 #define max(x, y) ((x) > (y) ? (x) : (y))
60 /* List of all widgets managed by the library. */
62 all_widget_info
= NULL
;
64 \f/* Forward declarations */
66 instanciate_widget_instance (/* widget_instance* instance */);
68 lwlib_memset (address
, value
, length
)
75 for (i
= 0; i
< length
; i
++)
79 lwlib_bcopy (from
, to
, length
)
86 for (i
= 0; i
< length
; i
++)
89 \f/* utility functions for widget_instance and widget_info */
96 result
= (char *) malloc (strlen (s
) + 1);
103 /* Like strcmp but ignore differences in case. */
106 my_strcasecmp (s1
, s2
)
118 return (c1
> c2
? 1 : -1);
131 static widget_value
*widget_value_free_list
= 0;
132 static int malloc_cpt
= 0;
135 malloc_widget_value ()
138 if (widget_value_free_list
)
140 wv
= widget_value_free_list
;
141 widget_value_free_list
= wv
->free_list
;
146 wv
= (widget_value
*) malloc (sizeof (widget_value
));
149 lwlib_memset (wv
, 0, sizeof (widget_value
));
153 /* this is analagous to free(). It frees only what was allocated
154 by malloc_widget_value(), and no substructures.
157 free_widget_value (wv
)
165 /* When the number of already allocated cells is too big,
172 wv
->free_list
= widget_value_free_list
;
173 widget_value_free_list
= wv
;
178 free_widget_value_tree (wv
)
184 if (wv
->name
) free (wv
->name
);
185 if (wv
->value
) free (wv
->value
);
186 if (wv
->key
) free (wv
->key
);
188 wv
->name
= wv
->value
= wv
->key
= (char *) 0xDEADBEEF;
190 if (wv
->toolkit_data
&& wv
->free_toolkit_data
)
192 free (wv
->toolkit_data
);
193 wv
->toolkit_data
= (void *) 0xDEADBEEF;
196 if (wv
->contents
&& (wv
->contents
!= (widget_value
*)1))
198 free_widget_value_tree (wv
->contents
);
199 wv
->contents
= (widget_value
*) 0xDEADBEEF;
203 free_widget_value_tree (wv
->next
);
204 wv
->next
= (widget_value
*) 0xDEADBEEF;
206 free_widget_value (wv
);
209 static widget_value
*
210 copy_widget_value_tree (val
, change
)
218 if (val
== (widget_value
*) 1)
221 copy
= malloc_widget_value ();
222 copy
->name
= safe_strdup (val
->name
);
223 copy
->value
= safe_strdup (val
->value
);
224 copy
->key
= safe_strdup (val
->key
);
225 copy
->enabled
= val
->enabled
;
226 copy
->selected
= val
->selected
;
227 copy
->edited
= False
;
228 copy
->change
= change
;
229 copy
->contents
= copy_widget_value_tree (val
->contents
, change
);
230 copy
->call_data
= val
->call_data
;
231 copy
->next
= copy_widget_value_tree (val
->next
, change
);
232 copy
->toolkit_data
= NULL
;
233 copy
->free_toolkit_data
= False
;
238 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
243 lw_callback pre_activate_cb
;
244 lw_callback selection_cb
;
245 lw_callback post_activate_cb
;
247 widget_info
* info
= (widget_info
*)malloc (sizeof (widget_info
));
248 info
->type
= safe_strdup (type
);
249 info
->name
= safe_strdup (name
);
251 info
->val
= copy_widget_value_tree (val
, STRUCTURAL_CHANGE
);
253 info
->pre_activate_cb
= pre_activate_cb
;
254 info
->selection_cb
= selection_cb
;
255 info
->post_activate_cb
= post_activate_cb
;
256 info
->instances
= NULL
;
258 info
->next
= all_widget_info
;
259 all_widget_info
= info
;
265 free_widget_info (info
)
268 safe_free_str (info
->type
);
269 safe_free_str (info
->name
);
270 free_widget_value_tree (info
->val
);
271 lwlib_memset ((void*)info
, 0xDEADBEEF, sizeof (widget_info
));
276 mark_widget_destroyed (widget
, closure
, call_data
)
281 widget_instance
* instance
= (widget_instance
*)closure
;
283 /* be very conservative */
284 if (instance
->widget
== widget
)
285 instance
->widget
= NULL
;
288 static widget_instance
*
289 allocate_widget_instance (info
, parent
, pop_up_p
)
294 widget_instance
* instance
=
295 (widget_instance
*)malloc (sizeof (widget_instance
));
296 instance
->parent
= parent
;
297 instance
->pop_up_p
= pop_up_p
;
298 instance
->info
= info
;
299 instance
->next
= info
->instances
;
300 info
->instances
= instance
;
302 instanciate_widget_instance (instance
);
304 XtAddCallback (instance
->widget
, XtNdestroyCallback
,
305 mark_widget_destroyed
, (XtPointer
)instance
);
310 free_widget_instance (instance
)
311 widget_instance
* instance
;
313 lwlib_memset ((void*)instance
, 0xDEADBEEF, sizeof (widget_instance
));
318 get_widget_info (id
, remove_p
)
324 for (prev
= NULL
, info
= all_widget_info
;
326 prev
= info
, info
= info
->next
)
332 prev
->next
= info
->next
;
334 all_widget_info
= info
->next
;
341 /* Internal function used by the library dependent implementation to get the
342 widget_value for a given widget in an instance */
344 lw_get_widget_info (id
)
347 return get_widget_info (id
, 0);
350 static widget_instance
*
351 get_widget_instance (widget
, remove_p
)
356 widget_instance
* instance
;
357 widget_instance
* prev
;
358 for (info
= all_widget_info
; info
; info
= info
->next
)
359 for (prev
= NULL
, instance
= info
->instances
;
361 prev
= instance
, instance
= instance
->next
)
362 if (instance
->widget
== widget
)
367 prev
->next
= instance
->next
;
369 info
->instances
= instance
->next
;
373 return (widget_instance
*) 0;
376 static widget_instance
*
377 find_instance (id
, parent
, pop_up_p
)
382 widget_info
* info
= get_widget_info (id
, False
);
383 widget_instance
* instance
;
386 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
387 if (instance
->parent
== parent
&& instance
->pop_up_p
== pop_up_p
)
394 /* utility function for widget_value */
400 if (!!s1
^ !!s2
) return True
;
401 return (s1
&& s2
) ? strcmp (s1
, s2
) : s1
? False
: !!s2
;
406 # define EXPLAIN(name, oc, nc, desc, a1, a2) \
407 printf ("Change: \"%s\"\tmax(%s=%d,%s=%d)\t%s %d %d\n", \
409 (oc == NO_CHANGE ? "none" : \
410 (oc == INVISIBLE_CHANGE ? "invisible" : \
411 (oc == VISIBLE_CHANGE ? "visible" : \
412 (oc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
414 (nc == NO_CHANGE ? "none" : \
415 (nc == INVISIBLE_CHANGE ? "invisible" : \
416 (nc == VISIBLE_CHANGE ? "visible" : \
417 (nc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
420 # define EXPLAIN(name, oc, nc, desc, a1, a2)
424 static widget_value
*
425 merge_widget_value (val1
, val2
, level
)
431 widget_value
* merged_next
;
432 widget_value
* merged_contents
;
437 return copy_widget_value_tree (val2
, STRUCTURAL_CHANGE
);
443 free_widget_value_tree (val1
);
449 if (safe_strcmp (val1
->name
, val2
->name
))
451 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "name change",
452 val1
->name
, val2
->name
);
453 change
= max (change
, STRUCTURAL_CHANGE
);
454 safe_free_str (val1
->name
);
455 val1
->name
= safe_strdup (val2
->name
);
457 if (safe_strcmp (val1
->value
, val2
->value
))
459 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "value change",
460 val1
->value
, val2
->value
);
461 change
= max (change
, VISIBLE_CHANGE
);
462 safe_free_str (val1
->value
);
463 val1
->value
= safe_strdup (val2
->value
);
465 if (safe_strcmp (val1
->key
, val2
->key
))
467 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "key change",
468 val1
->key
, val2
->key
);
469 change
= max (change
, VISIBLE_CHANGE
);
470 safe_free_str (val1
->key
);
471 val1
->key
= safe_strdup (val2
->key
);
473 if (val1
->enabled
!= val2
->enabled
)
475 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "enablement change",
476 val1
->enabled
, val2
->enabled
);
477 change
= max (change
, VISIBLE_CHANGE
);
478 val1
->enabled
= val2
->enabled
;
480 if (val1
->selected
!= val2
->selected
)
482 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "selection change",
483 val1
->selected
, val2
->selected
);
484 change
= max (change
, VISIBLE_CHANGE
);
485 val1
->selected
= val2
->selected
;
487 if (val1
->call_data
!= val2
->call_data
)
489 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "call-data change",
490 val1
->call_data
, val2
->call_data
);
491 change
= max (change
, INVISIBLE_CHANGE
);
492 val1
->call_data
= val2
->call_data
;
498 merge_widget_value (val1
->contents
, val2
->contents
, level
- 1);
500 if (val1
->contents
&& !merged_contents
)
502 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "(contents gone)",
504 change
= max (change
, INVISIBLE_CHANGE
);
506 else if (merged_contents
&& merged_contents
->change
!= NO_CHANGE
)
508 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "(contents change)",
510 change
= max (change
, INVISIBLE_CHANGE
);
513 val1
->contents
= merged_contents
;
516 merged_next
= merge_widget_value (val1
->next
, val2
->next
, level
);
518 if (val1
->next
&& !merged_next
)
520 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "(following gone)",
522 change
= max (change
, STRUCTURAL_CHANGE
);
524 else if (merged_next
)
526 if (merged_next
->change
)
527 EXPLAIN (val1
->name
, change
, merged_next
->change
, "(following change)",
529 change
= max (change
, merged_next
->change
);
532 val1
->next
= merged_next
;
534 val1
->change
= change
;
536 if (change
> NO_CHANGE
&& val1
->toolkit_data
)
538 if (val1
->free_toolkit_data
)
539 free (val1
->toolkit_data
);
540 val1
->toolkit_data
= NULL
;
547 /* modifying the widgets */
549 name_to_widget (instance
, name
)
550 widget_instance
* instance
;
553 Widget widget
= NULL
;
555 if (!instance
->widget
)
558 if (!strcmp (XtName (instance
->widget
), name
))
559 widget
= instance
->widget
;
562 int length
= strlen (name
) + 2;
563 char* real_name
= (char *) xmalloc (length
);
565 strcpy (real_name
+ 1, name
);
567 widget
= XtNameToWidget (instance
->widget
, real_name
);
575 set_one_value (instance
, val
, deep_p
)
576 widget_instance
* instance
;
580 Widget widget
= name_to_widget (instance
, val
->name
);
584 #if defined (USE_LUCID)
585 if (lw_lucid_widget_p (instance
->widget
))
586 xlw_update_one_widget (instance
, widget
, val
, deep_p
);
588 #if defined (USE_MOTIF)
589 if (lw_motif_widget_p (instance
->widget
))
590 xm_update_one_widget (instance
, widget
, val
, deep_p
);
592 #if defined (USE_OLIT)
593 if (lw_olit_widget_p (instance
->widget
))
594 xol_update_one_widget (instance
, widget
, val
, deep_p
);
596 #if defined (USE_XAW)
597 if (lw_xaw_widget_p (instance
->widget
))
598 xaw_update_one_widget (instance
, widget
, val
, deep_p
);
604 update_one_widget_instance (instance
, deep_p
)
605 widget_instance
* instance
;
610 if (!instance
->widget
)
611 /* the widget was destroyed */
614 for (val
= instance
->info
->val
; val
; val
= val
->next
)
615 if (val
->change
!= NO_CHANGE
)
616 set_one_value (instance
, val
, deep_p
);
620 update_all_widget_values (info
, deep_p
)
624 widget_instance
* instance
;
627 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
628 update_one_widget_instance (instance
, deep_p
);
630 for (val
= info
->val
; val
; val
= val
->next
)
631 val
->change
= NO_CHANGE
;
635 lw_modify_all_widgets (id
, val
, deep_p
)
640 widget_info
* info
= get_widget_info (id
, False
);
641 widget_value
* new_val
;
642 widget_value
* next_new_val
;
651 for (new_val
= val
; new_val
; new_val
= new_val
->next
)
653 next_new_val
= new_val
->next
;
654 new_val
->next
= NULL
;
656 for (prev
= NULL
, cur
= info
->val
; cur
; prev
= cur
, cur
= cur
->next
)
657 if (!strcmp (cur
->name
, new_val
->name
))
662 cur
= merge_widget_value (cur
, new_val
, deep_p
? 1000 : 1);
664 prev
->next
= cur
? cur
: next
;
666 info
->val
= cur
? cur
: next
;
673 /* Could not find it, add it */
675 prev
->next
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
677 info
->val
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
679 new_val
->next
= next_new_val
;
682 update_all_widget_values (info
, deep_p
);
686 /* creating the widgets */
689 initialize_widget_instance (instance
)
690 widget_instance
* instance
;
694 for (val
= instance
->info
->val
; val
; val
= val
->next
)
695 val
->change
= STRUCTURAL_CHANGE
;
697 update_one_widget_instance (instance
, True
);
699 for (val
= instance
->info
->val
; val
; val
= val
->next
)
700 val
->change
= NO_CHANGE
;
704 static widget_creation_function
705 find_in_table (type
, table
)
707 widget_creation_entry
* table
;
709 widget_creation_entry
* cur
;
710 for (cur
= table
; cur
->type
; cur
++)
711 if (!my_strcasecmp (type
, cur
->type
))
712 return cur
->function
;
720 /* return True if name matches [EILPQeilpq][1-9][Bb] or
721 [EILPQeilpq][1-9][Bb][Rr][1-9] */
727 case 'E': case 'I': case 'L': case 'P': case 'Q':
728 case 'e': case 'i': case 'l': case 'p': case 'q':
729 if (name
[1] >= '0' && name
[1] <= '9')
731 if (name
[2] != 'B' && name
[2] != 'b')
735 if ((name
[3] == 'T' || name
[3] == 't') && !name
[4])
737 if ((name
[3] == 'R' || name
[3] == 'r')
738 && name
[4] >= '0' && name
[4] <= '9' && !name
[5])
751 instanciate_widget_instance (instance
)
752 widget_instance
* instance
;
754 widget_creation_function function
= NULL
;
756 #if defined (USE_LUCID)
758 function
= find_in_table (instance
->info
->type
, xlw_creation_table
);
760 #if defined(USE_MOTIF)
762 function
= find_in_table (instance
->info
->type
, xm_creation_table
);
764 #if defined (USE_OLIT)
766 function
= find_in_table (instance
->info
->type
, xol_creation_table
);
768 #if defined (USE_XAW)
770 function
= find_in_table (instance
->info
->type
, xaw_creation_table
);
775 if (dialog_spec_p (instance
->info
->type
))
777 #if defined (USE_LUCID)
780 #if defined(USE_MOTIF)
782 function
= xm_create_dialog
;
784 #if defined (USE_XAW)
786 function
= xaw_create_dialog
;
788 #if defined (USE_OLIT)
796 printf ("No creation function for widget type %s\n",
797 instance
->info
->type
);
801 instance
->widget
= (*function
) (instance
);
803 if (!instance
->widget
)
806 /* XtRealizeWidget (instance->widget);*/
810 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
815 lw_callback pre_activate_cb
;
816 lw_callback selection_cb
;
817 lw_callback post_activate_cb
;
819 if (!get_widget_info (id
, False
))
820 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
825 lw_get_widget (id
, parent
, pop_up_p
)
830 widget_instance
* instance
;
832 instance
= find_instance (id
, parent
, pop_up_p
);
833 return instance
? instance
->widget
: NULL
;
837 lw_make_widget (id
, parent
, pop_up_p
)
842 widget_instance
* instance
;
845 instance
= find_instance (id
, parent
, pop_up_p
);
848 info
= get_widget_info (id
, False
);
851 instance
= allocate_widget_instance (info
, parent
, pop_up_p
);
852 initialize_widget_instance (instance
);
854 if (!instance
->widget
)
856 return instance
->widget
;
860 lw_create_widget (type
, name
, id
, val
, parent
, pop_up_p
, pre_activate_cb
, selection_cb
, post_activate_cb
)
867 lw_callback pre_activate_cb
;
868 lw_callback selection_cb
;
869 lw_callback post_activate_cb
;
871 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
873 return lw_make_widget (id
, parent
, pop_up_p
);
877 /* destroying the widgets */
879 destroy_one_instance (instance
)
880 widget_instance
* instance
;
882 /* Remove the destroy callback on the widget; that callback will try to
883 dereference the instance object (to set its widget slot to 0, since the
884 widget is dead.) Since the instance is now dead, we don't have to worry
885 about the fact that its widget is dead too.
887 This happens in the Phase2Destroy of the widget, so this callback would
888 not have been run until arbitrarily long after the instance was freed.
890 if (instance
->widget
)
891 XtRemoveCallback (instance
->widget
, XtNdestroyCallback
,
892 mark_widget_destroyed
, (XtPointer
)instance
);
894 if (instance
->widget
)
896 /* The else are pretty tricky here, including the empty statement
897 at the end because it would be very bad to destroy a widget
899 #if defined (USE_LUCID)
900 if (lw_lucid_widget_p (instance
->widget
))
901 xlw_destroy_instance (instance
);
904 #if defined (USE_MOTIF)
905 if (lw_motif_widget_p (instance
->widget
))
906 xm_destroy_instance (instance
);
909 #if defined (USE_OLIT)
910 if (lw_olit_widget_p (instance
->widget
))
911 xol_destroy_instance (instance
);
914 #if defined (USE_XAW)
915 if (lw_xaw_widget_p (instance
->widget
))
916 xaw_destroy_instance (instance
);
919 /* do not remove the empty statement */
923 free_widget_instance (instance
);
927 lw_destroy_widget (w
)
930 widget_instance
* instance
= get_widget_instance (w
, True
);
934 widget_info
*info
= instance
->info
;
935 /* instance has already been removed from the list; free it */
936 destroy_one_instance (instance
);
937 /* if there are no instances left, free the info too */
938 if (!info
->instances
)
939 lw_destroy_all_widgets (info
->id
);
944 lw_destroy_all_widgets (id
)
947 widget_info
* info
= get_widget_info (id
, True
);
948 widget_instance
* instance
;
949 widget_instance
* next
;
953 for (instance
= info
->instances
; instance
; )
955 next
= instance
->next
;
956 destroy_one_instance (instance
);
959 free_widget_info (info
);
964 lw_destroy_everything ()
966 while (all_widget_info
)
967 lw_destroy_all_widgets (all_widget_info
->id
);
971 lw_destroy_all_pop_ups ()
975 widget_instance
* instance
;
977 for (info
= all_widget_info
; info
; info
= next
)
980 instance
= info
->instances
;
981 if (instance
&& instance
->pop_up_p
)
982 lw_destroy_all_widgets (info
->id
);
987 extern Widget
first_child (Widget
); /* garbage */
991 lw_raise_all_pop_up_widgets ()
994 widget_instance
* instance
;
995 Widget result
= NULL
;
997 for (info
= all_widget_info
; info
; info
= info
->next
)
998 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
999 if (instance
->pop_up_p
)
1001 Widget widget
= instance
->widget
;
1004 if (XtIsManaged (widget
)
1006 /* What a complete load of crap!!!!
1007 When a dialogShell is on the screen, it is not managed!
1009 || (lw_motif_widget_p (instance
->widget
) &&
1010 XtIsManaged (first_child (widget
)))
1016 XMapRaised (XtDisplay (widget
), XtWindow (widget
));
1024 lw_pop_all_widgets (id
, up
)
1028 widget_info
* info
= get_widget_info (id
, False
);
1029 widget_instance
* instance
;
1032 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1033 if (instance
->pop_up_p
&& instance
->widget
)
1035 #if defined (USE_LUCID)
1036 if (lw_lucid_widget_p (instance
->widget
))
1038 XtRealizeWidget (instance
->widget
);
1039 xlw_pop_instance (instance
, up
);
1042 #if defined (USE_MOTIF)
1043 if (lw_motif_widget_p (instance
->widget
))
1045 XtRealizeWidget (instance
->widget
);
1046 xm_pop_instance (instance
, up
);
1049 #if defined (USE_OLIT)
1050 if (lw_olit_widget_p (instance
->widget
))
1052 XtRealizeWidget (instance
->widget
);
1053 xol_pop_instance (instance
, up
);
1056 #if defined (USE_XAW)
1057 if (lw_xaw_widget_p (instance
->widget
))
1059 XtRealizeWidget (XtParent (instance
->widget
));
1060 XtRealizeWidget (instance
->widget
);
1061 xaw_pop_instance (instance
, up
);
1068 lw_pop_up_all_widgets (id
)
1071 lw_pop_all_widgets (id
, True
);
1075 lw_pop_down_all_widgets (id
)
1078 lw_pop_all_widgets (id
, False
);
1082 lw_popup_menu (widget
)
1085 #if defined (USE_LUCID)
1086 if (lw_lucid_widget_p (widget
))
1087 xlw_popup_menu (widget
);
1089 #if defined (USE_MOTIF)
1090 if (lw_motif_widget_p (widget
))
1091 xm_popup_menu (widget
);
1093 #if defined (USE_OLIT)
1094 if (lw_olit_widget_p (widget
))
1095 xol_popup_menu (widget
);
1097 #if defined (USE_XAW)
1098 if (lw_xaw_widget_p (widget
))
1099 xaw_popup_menu (widget
);
1103 \f/* get the values back */
1105 get_one_value (instance
, val
)
1106 widget_instance
* instance
;
1109 Widget widget
= name_to_widget (instance
, val
->name
);
1113 #if defined (USE_LUCID)
1114 if (lw_lucid_widget_p (instance
->widget
))
1115 xlw_update_one_value (instance
, widget
, val
);
1117 #if defined (USE_MOTIF)
1118 if (lw_motif_widget_p (instance
->widget
))
1119 xm_update_one_value (instance
, widget
, val
);
1121 #if defined (USE_OLIT)
1122 if (lw_olit_widget_p (instance
->widget
))
1123 xol_update_one_value (instance
, widget
, val
);
1125 #if defined (USE_XAW)
1126 if (lw_xaw_widget_p (instance
->widget
))
1127 xaw_update_one_value (instance
, widget
, val
);
1136 lw_get_some_values (id
, val_out
)
1138 widget_value
* val_out
;
1140 widget_info
* info
= get_widget_info (id
, False
);
1141 widget_instance
* instance
;
1143 Boolean result
= False
;
1148 instance
= info
->instances
;
1152 for (val
= val_out
; val
; val
= val
->next
)
1153 if (get_one_value (instance
, val
))
1160 lw_get_all_values (id
)
1163 widget_info
* info
= get_widget_info (id
, False
);
1164 widget_value
* val
= info
->val
;
1165 if (lw_get_some_values (id
, val
))
1171 /* internal function used by the library dependent implementation to get the
1172 widget_value for a given widget in an instance */
1174 lw_get_widget_value_for_widget (instance
, w
)
1175 widget_instance
* instance
;
1178 char* name
= XtName (w
);
1180 for (cur
= instance
->info
->val
; cur
; cur
= cur
->next
)
1181 if (!strcmp (cur
->name
, name
))
1186 \f/* update other instances value when one thing changed */
1187 /* This function can be used as a an XtCallback for the widgets that get
1188 modified to update other instances of the widgets. Closure should be the
1191 lw_internal_update_other_instances (widget
, closure
, call_data
)
1194 XtPointer call_data
;
1196 /* To forbid recursive calls */
1197 static Boolean updating
;
1199 widget_instance
* instance
= (widget_instance
*)closure
;
1200 char* name
= XtName (widget
);
1202 widget_instance
* cur
;
1205 /* never recurse as this could cause infinite recursions. */
1209 /* protect against the widget being destroyed */
1210 if (XtWidgetBeingDestroyedP (widget
))
1213 /* Return immediately if there are no other instances */
1214 info
= instance
->info
;
1215 if (!info
->instances
->next
)
1220 for (val
= info
->val
; val
&& strcmp (val
->name
, name
); val
= val
->next
);
1222 if (val
&& get_one_value (instance
, val
))
1223 for (cur
= info
->instances
; cur
; cur
= cur
->next
)
1224 if (cur
!= instance
)
1225 set_one_value (cur
, val
, True
);
1234 lw_get_widget_id (w
)
1237 widget_instance
* instance
= get_widget_instance (w
, False
);
1239 return instance
? instance
->info
->id
: 0;
1242 \f/* set the keyboard focus */
1244 lw_set_keyboard_focus (parent
, w
)
1248 #if defined (USE_MOTIF)
1249 xm_set_keyboard_focus (parent
, w
);
1251 XtSetKeyboardFocus (parent
, w
);
1257 show_one_widget_busy (w
, flag
)
1261 Pixel foreground
= 0;
1262 Pixel background
= 1;
1263 Widget widget_to_invert
= XtNameToWidget (w
, "*sheet");
1264 if (!widget_to_invert
)
1265 widget_to_invert
= w
;
1267 XtVaGetValues (widget_to_invert
,
1268 XtNforeground
, &foreground
,
1269 XtNbackground
, &background
,
1271 XtVaSetValues (widget_to_invert
,
1272 XtNforeground
, background
,
1273 XtNbackground
, foreground
,
1278 lw_show_busy (w
, busy
)
1282 widget_instance
* instance
= get_widget_instance (w
, False
);
1284 widget_instance
* next
;
1288 info
= instance
->info
;
1289 if (info
->busy
!= busy
)
1291 for (next
= info
->instances
; next
; next
= next
->next
)
1293 show_one_widget_busy (next
->widget
, busy
);
1299 /* This hack exists because Lucid/Athena need to execute the strange
1300 function below to support geometry management. */
1302 lw_refigure_widget (w
, doit
)
1306 #if defined (USE_XAW)
1307 XawPanedSetRefigureMode (w
, doit
);
1309 #if defined (USE_MOTIF)
1311 XtUnmanageChild (w
);
1317 /* Toolkit independent way of determining if an event window is in the
1320 lw_window_is_in_menubar (win
, menubar_widget
)
1322 Widget menubar_widget
;
1324 return menubar_widget
1325 #if defined (USE_LUCID)
1326 && XtWindow (menubar_widget
) == win
;
1328 #if defined (USE_MOTIF)
1329 && XtWindowToWidget (XtDisplay (menubar_widget
), win
)
1330 && (XtParent (XtWindowToWidget (XtDisplay (menubar_widget
), win
))
1335 /* Motif hack to set the main window areas. */
1337 lw_set_main_areas (parent
, menubar
, work_area
)
1342 #if defined (USE_MOTIF)
1343 xm_set_main_areas (parent
, menubar
, work_area
);
1347 /* Manage resizing for Motif. This disables resizing when the menubar
1348 is about to be modified. */
1350 lw_allow_resizing (w
, flag
)
1354 #if defined (USE_MOTIF)
1355 xm_manage_resizing (w
, flag
);