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>
34 extern long *xmalloc();
37 #if defined (USE_LUCID)
38 #include "lwlib-Xlw.h"
40 #if defined (USE_MOTIF)
42 #else /* not USE_MOTIF */
43 #if defined (USE_LUCID)
45 #endif /* not USE_MOTIF && USE_LUCID */
47 #if defined (USE_OLIT)
48 #include "lwlib-Xol.h"
51 #include "lwlib-Xaw.h"
54 #if !defined (USE_LUCID) && !defined (USE_MOTIF) && !defined (USE_OLIT)
55 ERROR
! At least one of USE_LUCID
, USE_MOTIF
or USE_OLIT must be defined
.
58 #if defined (USE_MOTIF) && defined (USE_OLIT)
59 ERROR
! no more than one of USE_MOTIF
and USE_OLIT may be defined
.
63 #define max(x, y) ((x) > (y) ? (x) : (y))
66 /* List of all widgets managed by the library. */
68 all_widget_info
= NULL
;
71 char *lwlib_toolkit_type
= "motif";
73 char *lwlib_toolkit_type
= "lucid";
75 \f/* Forward declarations */
77 instanciate_widget_instance (/* widget_instance* instance */);
79 lwlib_memset (address
, value
, length
)
86 for (i
= 0; i
< length
; i
++)
90 lwlib_bcopy (from
, to
, length
)
97 for (i
= 0; i
< length
; i
++)
100 \f/* utility functions for widget_instance and widget_info */
107 result
= (char *) malloc (strlen (s
) + 1);
114 /* Like strcmp but ignore differences in case. */
117 my_strcasecmp (s1
, s2
)
129 return (c1
> c2
? 1 : -1);
142 static widget_value
*widget_value_free_list
= 0;
143 static int malloc_cpt
= 0;
146 malloc_widget_value ()
149 if (widget_value_free_list
)
151 wv
= widget_value_free_list
;
152 widget_value_free_list
= wv
->free_list
;
157 wv
= (widget_value
*) malloc (sizeof (widget_value
));
160 lwlib_memset (wv
, 0, sizeof (widget_value
));
164 /* this is analagous to free(). It frees only what was allocated
165 by malloc_widget_value(), and no substructures.
168 free_widget_value (wv
)
176 /* When the number of already allocated cells is too big,
183 wv
->free_list
= widget_value_free_list
;
184 widget_value_free_list
= wv
;
189 free_widget_value_tree (wv
)
195 if (wv
->name
) free (wv
->name
);
196 if (wv
->value
) free (wv
->value
);
197 if (wv
->key
) free (wv
->key
);
199 wv
->name
= wv
->value
= wv
->key
= (char *) 0xDEADBEEF;
201 if (wv
->toolkit_data
&& wv
->free_toolkit_data
)
203 free (wv
->toolkit_data
);
204 wv
->toolkit_data
= (void *) 0xDEADBEEF;
207 if (wv
->contents
&& (wv
->contents
!= (widget_value
*)1))
209 free_widget_value_tree (wv
->contents
);
210 wv
->contents
= (widget_value
*) 0xDEADBEEF;
214 free_widget_value_tree (wv
->next
);
215 wv
->next
= (widget_value
*) 0xDEADBEEF;
217 free_widget_value (wv
);
220 static widget_value
*
221 copy_widget_value_tree (val
, change
)
229 if (val
== (widget_value
*) 1)
232 copy
= malloc_widget_value ();
233 copy
->name
= safe_strdup (val
->name
);
234 copy
->value
= safe_strdup (val
->value
);
235 copy
->key
= safe_strdup (val
->key
);
236 copy
->enabled
= val
->enabled
;
237 copy
->selected
= val
->selected
;
238 copy
->edited
= False
;
239 copy
->change
= change
;
240 copy
->contents
= copy_widget_value_tree (val
->contents
, change
);
241 copy
->call_data
= val
->call_data
;
242 copy
->next
= copy_widget_value_tree (val
->next
, change
);
243 copy
->toolkit_data
= NULL
;
244 copy
->free_toolkit_data
= False
;
249 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
254 lw_callback pre_activate_cb
;
255 lw_callback selection_cb
;
256 lw_callback post_activate_cb
;
258 widget_info
* info
= (widget_info
*)malloc (sizeof (widget_info
));
259 info
->type
= safe_strdup (type
);
260 info
->name
= safe_strdup (name
);
262 info
->val
= copy_widget_value_tree (val
, STRUCTURAL_CHANGE
);
264 info
->pre_activate_cb
= pre_activate_cb
;
265 info
->selection_cb
= selection_cb
;
266 info
->post_activate_cb
= post_activate_cb
;
267 info
->instances
= NULL
;
269 info
->next
= all_widget_info
;
270 all_widget_info
= info
;
276 free_widget_info (info
)
279 safe_free_str (info
->type
);
280 safe_free_str (info
->name
);
281 free_widget_value_tree (info
->val
);
282 lwlib_memset ((void*)info
, 0xDEADBEEF, sizeof (widget_info
));
287 mark_widget_destroyed (widget
, closure
, call_data
)
292 widget_instance
* instance
= (widget_instance
*)closure
;
294 /* be very conservative */
295 if (instance
->widget
== widget
)
296 instance
->widget
= NULL
;
299 static widget_instance
*
300 allocate_widget_instance (info
, parent
, pop_up_p
)
305 widget_instance
* instance
=
306 (widget_instance
*)malloc (sizeof (widget_instance
));
307 instance
->parent
= parent
;
308 instance
->pop_up_p
= pop_up_p
;
309 instance
->info
= info
;
310 instance
->next
= info
->instances
;
311 info
->instances
= instance
;
313 instanciate_widget_instance (instance
);
315 XtAddCallback (instance
->widget
, XtNdestroyCallback
,
316 mark_widget_destroyed
, (XtPointer
)instance
);
321 free_widget_instance (instance
)
322 widget_instance
* instance
;
324 lwlib_memset ((void*)instance
, 0xDEADBEEF, sizeof (widget_instance
));
329 get_widget_info (id
, remove_p
)
335 for (prev
= NULL
, info
= all_widget_info
;
337 prev
= info
, info
= info
->next
)
343 prev
->next
= info
->next
;
345 all_widget_info
= info
->next
;
352 /* Internal function used by the library dependent implementation to get the
353 widget_value for a given widget in an instance */
355 lw_get_widget_info (id
)
358 return get_widget_info (id
, 0);
361 static widget_instance
*
362 get_widget_instance (widget
, remove_p
)
367 widget_instance
* instance
;
368 widget_instance
* prev
;
369 for (info
= all_widget_info
; info
; info
= info
->next
)
370 for (prev
= NULL
, instance
= info
->instances
;
372 prev
= instance
, instance
= instance
->next
)
373 if (instance
->widget
== widget
)
378 prev
->next
= instance
->next
;
380 info
->instances
= instance
->next
;
384 return (widget_instance
*) 0;
387 static widget_instance
*
388 find_instance (id
, parent
, pop_up_p
)
393 widget_info
* info
= get_widget_info (id
, False
);
394 widget_instance
* instance
;
397 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
398 if (instance
->parent
== parent
&& instance
->pop_up_p
== pop_up_p
)
405 /* utility function for widget_value */
411 if (!!s1
^ !!s2
) return True
;
412 return (s1
&& s2
) ? strcmp (s1
, s2
) : s1
? False
: !!s2
;
417 # define EXPLAIN(name, oc, nc, desc, a1, a2) \
418 printf ("Change: \"%s\"\tmax(%s=%d,%s=%d)\t%s %d %d\n", \
420 (oc == NO_CHANGE ? "none" : \
421 (oc == INVISIBLE_CHANGE ? "invisible" : \
422 (oc == VISIBLE_CHANGE ? "visible" : \
423 (oc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
425 (nc == NO_CHANGE ? "none" : \
426 (nc == INVISIBLE_CHANGE ? "invisible" : \
427 (nc == VISIBLE_CHANGE ? "visible" : \
428 (nc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
431 # define EXPLAIN(name, oc, nc, desc, a1, a2)
435 static widget_value
*
436 merge_widget_value (val1
, val2
, level
)
442 widget_value
* merged_next
;
443 widget_value
* merged_contents
;
448 return copy_widget_value_tree (val2
, STRUCTURAL_CHANGE
);
454 free_widget_value_tree (val1
);
460 if (safe_strcmp (val1
->name
, val2
->name
))
462 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "name change",
463 val1
->name
, val2
->name
);
464 change
= max (change
, STRUCTURAL_CHANGE
);
465 safe_free_str (val1
->name
);
466 val1
->name
= safe_strdup (val2
->name
);
468 if (safe_strcmp (val1
->value
, val2
->value
))
470 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "value change",
471 val1
->value
, val2
->value
);
472 change
= max (change
, VISIBLE_CHANGE
);
473 safe_free_str (val1
->value
);
474 val1
->value
= safe_strdup (val2
->value
);
476 if (safe_strcmp (val1
->key
, val2
->key
))
478 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "key change",
479 val1
->key
, val2
->key
);
480 change
= max (change
, VISIBLE_CHANGE
);
481 safe_free_str (val1
->key
);
482 val1
->key
= safe_strdup (val2
->key
);
484 if (val1
->enabled
!= val2
->enabled
)
486 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "enablement change",
487 val1
->enabled
, val2
->enabled
);
488 change
= max (change
, VISIBLE_CHANGE
);
489 val1
->enabled
= val2
->enabled
;
491 if (val1
->selected
!= val2
->selected
)
493 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "selection change",
494 val1
->selected
, val2
->selected
);
495 change
= max (change
, VISIBLE_CHANGE
);
496 val1
->selected
= val2
->selected
;
498 if (val1
->call_data
!= val2
->call_data
)
500 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "call-data change",
501 val1
->call_data
, val2
->call_data
);
502 change
= max (change
, INVISIBLE_CHANGE
);
503 val1
->call_data
= val2
->call_data
;
509 merge_widget_value (val1
->contents
, val2
->contents
, level
- 1);
511 if (val1
->contents
&& !merged_contents
)
513 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "(contents gone)",
515 change
= max (change
, INVISIBLE_CHANGE
);
517 else if (merged_contents
&& merged_contents
->change
!= NO_CHANGE
)
519 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "(contents change)",
521 change
= max (change
, INVISIBLE_CHANGE
);
524 val1
->contents
= merged_contents
;
527 merged_next
= merge_widget_value (val1
->next
, val2
->next
, level
);
529 if (val1
->next
&& !merged_next
)
531 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "(following gone)",
533 change
= max (change
, STRUCTURAL_CHANGE
);
535 else if (merged_next
)
537 if (merged_next
->change
)
538 EXPLAIN (val1
->name
, change
, merged_next
->change
, "(following change)",
540 change
= max (change
, merged_next
->change
);
543 val1
->next
= merged_next
;
545 val1
->change
= change
;
547 if (change
> NO_CHANGE
&& val1
->toolkit_data
)
549 if (val1
->free_toolkit_data
)
550 free (val1
->toolkit_data
);
551 val1
->toolkit_data
= NULL
;
558 /* modifying the widgets */
560 name_to_widget (instance
, name
)
561 widget_instance
* instance
;
564 Widget widget
= NULL
;
566 if (!instance
->widget
)
569 if (!strcmp (XtName (instance
->widget
), name
))
570 widget
= instance
->widget
;
573 int length
= strlen (name
) + 2;
574 char* real_name
= (char *) xmalloc (length
);
576 strcpy (real_name
+ 1, name
);
578 widget
= XtNameToWidget (instance
->widget
, real_name
);
586 set_one_value (instance
, val
, deep_p
)
587 widget_instance
* instance
;
591 Widget widget
= name_to_widget (instance
, val
->name
);
595 #if defined (USE_LUCID)
596 if (lw_lucid_widget_p (instance
->widget
))
597 xlw_update_one_widget (instance
, widget
, val
, deep_p
);
599 #if defined (USE_MOTIF)
600 if (lw_motif_widget_p (instance
->widget
))
601 xm_update_one_widget (instance
, widget
, val
, deep_p
);
603 #if defined (USE_OLIT)
604 if (lw_olit_widget_p (instance
->widget
))
605 xol_update_one_widget (instance
, widget
, val
, deep_p
);
607 #if defined (USE_XAW)
608 if (lw_xaw_widget_p (instance
->widget
))
609 xaw_update_one_widget (instance
, widget
, val
, deep_p
);
615 update_one_widget_instance (instance
, deep_p
)
616 widget_instance
* instance
;
621 if (!instance
->widget
)
622 /* the widget was destroyed */
625 for (val
= instance
->info
->val
; val
; val
= val
->next
)
626 if (val
->change
!= NO_CHANGE
)
627 set_one_value (instance
, val
, deep_p
);
631 update_all_widget_values (info
, deep_p
)
635 widget_instance
* instance
;
638 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
639 update_one_widget_instance (instance
, deep_p
);
641 for (val
= info
->val
; val
; val
= val
->next
)
642 val
->change
= NO_CHANGE
;
646 lw_modify_all_widgets (id
, val
, deep_p
)
651 widget_info
* info
= get_widget_info (id
, False
);
652 widget_value
* new_val
;
653 widget_value
* next_new_val
;
662 for (new_val
= val
; new_val
; new_val
= new_val
->next
)
664 next_new_val
= new_val
->next
;
665 new_val
->next
= NULL
;
667 for (prev
= NULL
, cur
= info
->val
; cur
; prev
= cur
, cur
= cur
->next
)
668 if (!strcmp (cur
->name
, new_val
->name
))
673 cur
= merge_widget_value (cur
, new_val
, deep_p
? 1000 : 1);
675 prev
->next
= cur
? cur
: next
;
677 info
->val
= cur
? cur
: next
;
684 /* Could not find it, add it */
686 prev
->next
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
688 info
->val
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
690 new_val
->next
= next_new_val
;
693 update_all_widget_values (info
, deep_p
);
697 /* creating the widgets */
700 initialize_widget_instance (instance
)
701 widget_instance
* instance
;
705 for (val
= instance
->info
->val
; val
; val
= val
->next
)
706 val
->change
= STRUCTURAL_CHANGE
;
708 update_one_widget_instance (instance
, True
);
710 for (val
= instance
->info
->val
; val
; val
= val
->next
)
711 val
->change
= NO_CHANGE
;
715 static widget_creation_function
716 find_in_table (type
, table
)
718 widget_creation_entry
* table
;
720 widget_creation_entry
* cur
;
721 for (cur
= table
; cur
->type
; cur
++)
722 if (!my_strcasecmp (type
, cur
->type
))
723 return cur
->function
;
731 /* return True if name matches [EILPQeilpq][1-9][Bb] or
732 [EILPQeilpq][1-9][Bb][Rr][1-9] */
738 case 'E': case 'I': case 'L': case 'P': case 'Q':
739 case 'e': case 'i': case 'l': case 'p': case 'q':
740 if (name
[1] >= '0' && name
[1] <= '9')
742 if (name
[2] != 'B' && name
[2] != 'b')
746 if ((name
[3] == 'T' || name
[3] == 't') && !name
[4])
748 if ((name
[3] == 'R' || name
[3] == 'r')
749 && name
[4] >= '0' && name
[4] <= '9' && !name
[5])
762 instanciate_widget_instance (instance
)
763 widget_instance
* instance
;
765 widget_creation_function function
= NULL
;
767 #if defined (USE_LUCID)
769 function
= find_in_table (instance
->info
->type
, xlw_creation_table
);
771 #if defined(USE_MOTIF)
773 function
= find_in_table (instance
->info
->type
, xm_creation_table
);
775 #if defined (USE_OLIT)
777 function
= find_in_table (instance
->info
->type
, xol_creation_table
);
779 #if defined (USE_XAW)
781 function
= find_in_table (instance
->info
->type
, xaw_creation_table
);
786 if (dialog_spec_p (instance
->info
->type
))
788 #if defined (USE_LUCID)
791 #if defined(USE_MOTIF)
793 function
= xm_create_dialog
;
795 #if defined (USE_XAW)
797 function
= xaw_create_dialog
;
799 #if defined (USE_OLIT)
807 printf ("No creation function for widget type %s\n",
808 instance
->info
->type
);
812 instance
->widget
= (*function
) (instance
);
814 if (!instance
->widget
)
817 /* XtRealizeWidget (instance->widget);*/
821 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
826 lw_callback pre_activate_cb
;
827 lw_callback selection_cb
;
828 lw_callback post_activate_cb
;
830 if (!get_widget_info (id
, False
))
831 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
836 lw_get_widget (id
, parent
, pop_up_p
)
841 widget_instance
* instance
;
843 instance
= find_instance (id
, parent
, pop_up_p
);
844 return instance
? instance
->widget
: NULL
;
848 lw_make_widget (id
, parent
, pop_up_p
)
853 widget_instance
* instance
;
856 instance
= find_instance (id
, parent
, pop_up_p
);
859 info
= get_widget_info (id
, False
);
862 instance
= allocate_widget_instance (info
, parent
, pop_up_p
);
863 initialize_widget_instance (instance
);
865 if (!instance
->widget
)
867 return instance
->widget
;
871 lw_create_widget (type
, name
, id
, val
, parent
, pop_up_p
, pre_activate_cb
, selection_cb
, post_activate_cb
)
878 lw_callback pre_activate_cb
;
879 lw_callback selection_cb
;
880 lw_callback post_activate_cb
;
882 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
884 return lw_make_widget (id
, parent
, pop_up_p
);
888 /* destroying the widgets */
890 destroy_one_instance (instance
)
891 widget_instance
* instance
;
893 /* Remove the destroy callback on the widget; that callback will try to
894 dereference the instance object (to set its widget slot to 0, since the
895 widget is dead.) Since the instance is now dead, we don't have to worry
896 about the fact that its widget is dead too.
898 This happens in the Phase2Destroy of the widget, so this callback would
899 not have been run until arbitrarily long after the instance was freed.
901 if (instance
->widget
)
902 XtRemoveCallback (instance
->widget
, XtNdestroyCallback
,
903 mark_widget_destroyed
, (XtPointer
)instance
);
905 if (instance
->widget
)
907 /* The else are pretty tricky here, including the empty statement
908 at the end because it would be very bad to destroy a widget
910 #if defined (USE_LUCID)
911 if (lw_lucid_widget_p (instance
->widget
))
912 xlw_destroy_instance (instance
);
915 #if defined (USE_MOTIF)
916 if (lw_motif_widget_p (instance
->widget
))
917 xm_destroy_instance (instance
);
920 #if defined (USE_OLIT)
921 if (lw_olit_widget_p (instance
->widget
))
922 xol_destroy_instance (instance
);
925 #if defined (USE_XAW)
926 if (lw_xaw_widget_p (instance
->widget
))
927 xaw_destroy_instance (instance
);
930 /* do not remove the empty statement */
934 free_widget_instance (instance
);
938 lw_destroy_widget (w
)
941 widget_instance
* instance
= get_widget_instance (w
, True
);
945 widget_info
*info
= instance
->info
;
946 /* instance has already been removed from the list; free it */
947 destroy_one_instance (instance
);
948 /* if there are no instances left, free the info too */
949 if (!info
->instances
)
950 lw_destroy_all_widgets (info
->id
);
955 lw_destroy_all_widgets (id
)
958 widget_info
* info
= get_widget_info (id
, True
);
959 widget_instance
* instance
;
960 widget_instance
* next
;
964 for (instance
= info
->instances
; instance
; )
966 next
= instance
->next
;
967 destroy_one_instance (instance
);
970 free_widget_info (info
);
975 lw_destroy_everything ()
977 while (all_widget_info
)
978 lw_destroy_all_widgets (all_widget_info
->id
);
982 lw_destroy_all_pop_ups ()
986 widget_instance
* instance
;
988 for (info
= all_widget_info
; info
; info
= next
)
991 instance
= info
->instances
;
992 if (instance
&& instance
->pop_up_p
)
993 lw_destroy_all_widgets (info
->id
);
998 extern Widget
first_child (/* Widget */); /* garbage */
1002 lw_raise_all_pop_up_widgets ()
1005 widget_instance
* instance
;
1006 Widget result
= NULL
;
1008 for (info
= all_widget_info
; info
; info
= info
->next
)
1009 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1010 if (instance
->pop_up_p
)
1012 Widget widget
= instance
->widget
;
1015 if (XtIsManaged (widget
)
1017 /* What a complete load of crap!!!!
1018 When a dialogShell is on the screen, it is not managed!
1020 || (lw_motif_widget_p (instance
->widget
) &&
1021 XtIsManaged (first_child (widget
)))
1027 XMapRaised (XtDisplay (widget
), XtWindow (widget
));
1035 lw_pop_all_widgets (id
, up
)
1039 widget_info
* info
= get_widget_info (id
, False
);
1040 widget_instance
* instance
;
1043 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1044 if (instance
->pop_up_p
&& instance
->widget
)
1046 #if defined (USE_LUCID)
1047 if (lw_lucid_widget_p (instance
->widget
))
1049 XtRealizeWidget (instance
->widget
);
1050 xlw_pop_instance (instance
, up
);
1053 #if defined (USE_MOTIF)
1054 if (lw_motif_widget_p (instance
->widget
))
1056 XtRealizeWidget (instance
->widget
);
1057 xm_pop_instance (instance
, up
);
1060 #if defined (USE_OLIT)
1061 if (lw_olit_widget_p (instance
->widget
))
1063 XtRealizeWidget (instance
->widget
);
1064 xol_pop_instance (instance
, up
);
1067 #if defined (USE_XAW)
1068 if (lw_xaw_widget_p (instance
->widget
))
1070 XtRealizeWidget (XtParent (instance
->widget
));
1071 XtRealizeWidget (instance
->widget
);
1072 xaw_pop_instance (instance
, up
);
1079 lw_pop_up_all_widgets (id
)
1082 lw_pop_all_widgets (id
, True
);
1086 lw_pop_down_all_widgets (id
)
1089 lw_pop_all_widgets (id
, False
);
1093 lw_popup_menu (widget
)
1096 #if defined (USE_LUCID)
1097 if (lw_lucid_widget_p (widget
))
1098 xlw_popup_menu (widget
);
1100 #if defined (USE_MOTIF)
1101 if (lw_motif_widget_p (widget
))
1102 xm_popup_menu (widget
);
1104 #if defined (USE_OLIT)
1105 if (lw_olit_widget_p (widget
))
1106 xol_popup_menu (widget
);
1108 #if defined (USE_XAW)
1109 if (lw_xaw_widget_p (widget
))
1110 xaw_popup_menu (widget
);
1114 \f/* get the values back */
1116 get_one_value (instance
, val
)
1117 widget_instance
* instance
;
1120 Widget widget
= name_to_widget (instance
, val
->name
);
1124 #if defined (USE_LUCID)
1125 if (lw_lucid_widget_p (instance
->widget
))
1126 xlw_update_one_value (instance
, widget
, val
);
1128 #if defined (USE_MOTIF)
1129 if (lw_motif_widget_p (instance
->widget
))
1130 xm_update_one_value (instance
, widget
, val
);
1132 #if defined (USE_OLIT)
1133 if (lw_olit_widget_p (instance
->widget
))
1134 xol_update_one_value (instance
, widget
, val
);
1136 #if defined (USE_XAW)
1137 if (lw_xaw_widget_p (instance
->widget
))
1138 xaw_update_one_value (instance
, widget
, val
);
1147 lw_get_some_values (id
, val_out
)
1149 widget_value
* val_out
;
1151 widget_info
* info
= get_widget_info (id
, False
);
1152 widget_instance
* instance
;
1154 Boolean result
= False
;
1159 instance
= info
->instances
;
1163 for (val
= val_out
; val
; val
= val
->next
)
1164 if (get_one_value (instance
, val
))
1171 lw_get_all_values (id
)
1174 widget_info
* info
= get_widget_info (id
, False
);
1175 widget_value
* val
= info
->val
;
1176 if (lw_get_some_values (id
, val
))
1182 /* internal function used by the library dependent implementation to get the
1183 widget_value for a given widget in an instance */
1185 lw_get_widget_value_for_widget (instance
, w
)
1186 widget_instance
* instance
;
1189 char* name
= XtName (w
);
1191 for (cur
= instance
->info
->val
; cur
; cur
= cur
->next
)
1192 if (!strcmp (cur
->name
, name
))
1197 \f/* update other instances value when one thing changed */
1198 /* This function can be used as a an XtCallback for the widgets that get
1199 modified to update other instances of the widgets. Closure should be the
1202 lw_internal_update_other_instances (widget
, closure
, call_data
)
1205 XtPointer call_data
;
1207 /* To forbid recursive calls */
1208 static Boolean updating
;
1210 widget_instance
* instance
= (widget_instance
*)closure
;
1211 char* name
= XtName (widget
);
1213 widget_instance
* cur
;
1216 /* never recurse as this could cause infinite recursions. */
1220 /* protect against the widget being destroyed */
1221 if (XtWidgetBeingDestroyedP (widget
))
1224 /* Return immediately if there are no other instances */
1225 info
= instance
->info
;
1226 if (!info
->instances
->next
)
1231 for (val
= info
->val
; val
&& strcmp (val
->name
, name
); val
= val
->next
);
1233 if (val
&& get_one_value (instance
, val
))
1234 for (cur
= info
->instances
; cur
; cur
= cur
->next
)
1235 if (cur
!= instance
)
1236 set_one_value (cur
, val
, True
);
1245 lw_get_widget_id (w
)
1248 widget_instance
* instance
= get_widget_instance (w
, False
);
1250 return instance
? instance
->info
->id
: 0;
1253 \f/* set the keyboard focus */
1255 lw_set_keyboard_focus (parent
, w
)
1259 #if defined (USE_MOTIF)
1260 xm_set_keyboard_focus (parent
, w
);
1262 XtSetKeyboardFocus (parent
, w
);
1268 show_one_widget_busy (w
, flag
)
1272 Pixel foreground
= 0;
1273 Pixel background
= 1;
1274 Widget widget_to_invert
= XtNameToWidget (w
, "*sheet");
1275 if (!widget_to_invert
)
1276 widget_to_invert
= w
;
1278 XtVaGetValues (widget_to_invert
,
1279 XtNforeground
, &foreground
,
1280 XtNbackground
, &background
,
1282 XtVaSetValues (widget_to_invert
,
1283 XtNforeground
, background
,
1284 XtNbackground
, foreground
,
1289 lw_show_busy (w
, busy
)
1293 widget_instance
* instance
= get_widget_instance (w
, False
);
1295 widget_instance
* next
;
1299 info
= instance
->info
;
1300 if (info
->busy
!= busy
)
1302 for (next
= info
->instances
; next
; next
= next
->next
)
1304 show_one_widget_busy (next
->widget
, busy
);
1310 /* This hack exists because Lucid/Athena need to execute the strange
1311 function below to support geometry management. */
1313 lw_refigure_widget (w
, doit
)
1317 #if defined (USE_XAW)
1318 XawPanedSetRefigureMode (w
, doit
);
1320 #if defined (USE_MOTIF)
1324 XtUnmanageChild (w
);
1328 /* Toolkit independent way of determining if an event window is in the
1331 lw_window_is_in_menubar (win
, menubar_widget
)
1333 Widget menubar_widget
;
1335 return menubar_widget
1336 #if defined (USE_LUCID)
1337 && XtWindow (menubar_widget
) == win
;
1339 #if defined (USE_MOTIF)
1340 && XtWindowToWidget (XtDisplay (menubar_widget
), win
)
1341 && (XtParent (XtWindowToWidget (XtDisplay (menubar_widget
), win
))
1346 /* Motif hack to set the main window areas. */
1348 lw_set_main_areas (parent
, menubar
, work_area
)
1353 #if defined (USE_MOTIF)
1354 xm_set_main_areas (parent
, menubar
, work_area
);
1358 /* Manage resizing for Motif. This disables resizing when the menubar
1359 is about to be modified. */
1361 lw_allow_resizing (w
, flag
)
1365 #if defined (USE_MOTIF)
1366 xm_manage_resizing (w
, flag
);