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
.
56 /* List of all widgets managed by the library. */
58 all_widget_info
= NULL
;
60 \f/* Forward declarations */
62 instanciate_widget_instance (/* widget_instance* instance */);
64 lwlib_memset (address
, value
, length
)
71 for (i
= 0; i
< length
; i
++)
75 lwlib_bcopy (from
, to
, length
)
82 for (i
= 0; i
< length
; i
++)
85 \f/* utility functions for widget_instance and widget_info */
92 result
= (char *) malloc (strlen (s
) + 1);
99 /* Like strcmp but ignore differences in case. */
102 my_strcasecmp (s1
, s2
)
114 return (c1
> c2
? 1 : -1);
127 static widget_value
*widget_value_free_list
= 0;
128 static int malloc_cpt
= 0;
131 malloc_widget_value ()
134 if (widget_value_free_list
)
136 wv
= widget_value_free_list
;
137 widget_value_free_list
= wv
->free_list
;
142 wv
= (widget_value
*) malloc (sizeof (widget_value
));
145 lwlib_memset (wv
, 0, sizeof (widget_value
));
149 /* this is analagous to free(). It frees only what was allocated
150 by malloc_widget_value(), and no substructures.
153 free_widget_value (wv
)
161 /* When the number of already allocated cells is too big,
168 wv
->free_list
= widget_value_free_list
;
169 widget_value_free_list
= wv
;
174 free_widget_value_tree (wv
)
180 if (wv
->name
) free (wv
->name
);
181 if (wv
->value
) free (wv
->value
);
182 if (wv
->key
) free (wv
->key
);
184 wv
->name
= wv
->value
= wv
->key
= (char *) 0xDEADBEEF;
186 if (wv
->toolkit_data
&& wv
->free_toolkit_data
)
188 free (wv
->toolkit_data
);
189 wv
->toolkit_data
= (void *) 0xDEADBEEF;
192 if (wv
->contents
&& (wv
->contents
!= (widget_value
*)1))
194 free_widget_value_tree (wv
->contents
);
195 wv
->contents
= (widget_value
*) 0xDEADBEEF;
199 free_widget_value_tree (wv
->next
);
200 wv
->next
= (widget_value
*) 0xDEADBEEF;
202 free_widget_value (wv
);
205 static widget_value
*
206 copy_widget_value_tree (val
, change
)
214 if (val
== (widget_value
*) 1)
217 copy
= malloc_widget_value ();
218 copy
->name
= safe_strdup (val
->name
);
219 copy
->value
= safe_strdup (val
->value
);
220 copy
->key
= safe_strdup (val
->key
);
221 copy
->enabled
= val
->enabled
;
222 copy
->selected
= val
->selected
;
223 copy
->edited
= False
;
224 copy
->change
= change
;
225 copy
->contents
= copy_widget_value_tree (val
->contents
, change
);
226 copy
->call_data
= val
->call_data
;
227 copy
->next
= copy_widget_value_tree (val
->next
, change
);
228 copy
->toolkit_data
= NULL
;
229 copy
->free_toolkit_data
= False
;
234 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
239 lw_callback pre_activate_cb
;
240 lw_callback selection_cb
;
241 lw_callback post_activate_cb
;
243 widget_info
* info
= (widget_info
*)malloc (sizeof (widget_info
));
244 info
->type
= safe_strdup (type
);
245 info
->name
= safe_strdup (name
);
247 info
->val
= copy_widget_value_tree (val
, STRUCTURAL_CHANGE
);
249 info
->pre_activate_cb
= pre_activate_cb
;
250 info
->selection_cb
= selection_cb
;
251 info
->post_activate_cb
= post_activate_cb
;
252 info
->instances
= NULL
;
254 info
->next
= all_widget_info
;
255 all_widget_info
= info
;
261 free_widget_info (info
)
264 safe_free_str (info
->type
);
265 safe_free_str (info
->name
);
266 free_widget_value_tree (info
->val
);
267 lwlib_memset ((void*)info
, 0xDEADBEEF, sizeof (widget_info
));
272 mark_widget_destroyed (widget
, closure
, call_data
)
277 widget_instance
* instance
= (widget_instance
*)closure
;
279 /* be very conservative */
280 if (instance
->widget
== widget
)
281 instance
->widget
= NULL
;
284 static widget_instance
*
285 allocate_widget_instance (info
, parent
, pop_up_p
)
290 widget_instance
* instance
=
291 (widget_instance
*)malloc (sizeof (widget_instance
));
292 instance
->parent
= parent
;
293 instance
->pop_up_p
= pop_up_p
;
294 instance
->info
= info
;
295 instance
->next
= info
->instances
;
296 info
->instances
= instance
;
298 instanciate_widget_instance (instance
);
300 XtAddCallback (instance
->widget
, XtNdestroyCallback
,
301 mark_widget_destroyed
, (XtPointer
)instance
);
306 free_widget_instance (instance
)
307 widget_instance
* instance
;
309 lwlib_memset ((void*)instance
, 0xDEADBEEF, sizeof (widget_instance
));
314 get_widget_info (id
, remove_p
)
320 for (prev
= NULL
, info
= all_widget_info
;
322 prev
= info
, info
= info
->next
)
328 prev
->next
= info
->next
;
330 all_widget_info
= info
->next
;
337 /* Internal function used by the library dependent implementation to get the
338 widget_value for a given widget in an instance */
340 lw_get_widget_info (id
)
343 return get_widget_info (id
, 0);
346 static widget_instance
*
347 get_widget_instance (widget
, remove_p
)
352 widget_instance
* instance
;
353 widget_instance
* prev
;
354 for (info
= all_widget_info
; info
; info
= info
->next
)
355 for (prev
= NULL
, instance
= info
->instances
;
357 prev
= instance
, instance
= instance
->next
)
358 if (instance
->widget
== widget
)
363 prev
->next
= instance
->next
;
365 info
->instances
= instance
->next
;
369 return (widget_instance
*) 0;
372 static widget_instance
*
373 find_instance (id
, parent
, pop_up_p
)
378 widget_info
* info
= get_widget_info (id
, False
);
379 widget_instance
* instance
;
382 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
383 if (instance
->parent
== parent
&& instance
->pop_up_p
== pop_up_p
)
390 /* utility function for widget_value */
396 if (!!s1
^ !!s2
) return True
;
397 return (s1
&& s2
) ? strcmp (s1
, s2
) : s1
? False
: !!s2
;
405 return i1
> i2
? i1
: i2
;
410 # define EXPLAIN(name, oc, nc, desc, a1, a2) \
411 printf ("Change: \"%s\"\tmax(%s=%d,%s=%d)\t%s %d %d\n", \
413 (oc == NO_CHANGE ? "none" : \
414 (oc == INVISIBLE_CHANGE ? "invisible" : \
415 (oc == VISIBLE_CHANGE ? "visible" : \
416 (oc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
418 (nc == NO_CHANGE ? "none" : \
419 (nc == INVISIBLE_CHANGE ? "invisible" : \
420 (nc == VISIBLE_CHANGE ? "visible" : \
421 (nc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
424 # define EXPLAIN(name, oc, nc, desc, a1, a2)
428 static widget_value
*
429 merge_widget_value (val1
, val2
, level
)
435 widget_value
* merged_next
;
436 widget_value
* merged_contents
;
441 return copy_widget_value_tree (val2
, STRUCTURAL_CHANGE
);
447 free_widget_value_tree (val1
);
453 if (safe_strcmp (val1
->name
, val2
->name
))
455 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "name change",
456 val1
->name
, val2
->name
);
457 change
= max (change
, STRUCTURAL_CHANGE
);
458 safe_free_str (val1
->name
);
459 val1
->name
= safe_strdup (val2
->name
);
461 if (safe_strcmp (val1
->value
, val2
->value
))
463 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "value change",
464 val1
->value
, val2
->value
);
465 change
= max (change
, VISIBLE_CHANGE
);
466 safe_free_str (val1
->value
);
467 val1
->value
= safe_strdup (val2
->value
);
469 if (safe_strcmp (val1
->key
, val2
->key
))
471 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "key change",
472 val1
->key
, val2
->key
);
473 change
= max (change
, VISIBLE_CHANGE
);
474 safe_free_str (val1
->key
);
475 val1
->key
= safe_strdup (val2
->key
);
477 if (val1
->enabled
!= val2
->enabled
)
479 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "enablement change",
480 val1
->enabled
, val2
->enabled
);
481 change
= max (change
, VISIBLE_CHANGE
);
482 val1
->enabled
= val2
->enabled
;
484 if (val1
->selected
!= val2
->selected
)
486 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "selection change",
487 val1
->selected
, val2
->selected
);
488 change
= max (change
, VISIBLE_CHANGE
);
489 val1
->selected
= val2
->selected
;
491 if (val1
->call_data
!= val2
->call_data
)
493 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "call-data change",
494 val1
->call_data
, val2
->call_data
);
495 change
= max (change
, INVISIBLE_CHANGE
);
496 val1
->call_data
= val2
->call_data
;
502 merge_widget_value (val1
->contents
, val2
->contents
, level
- 1);
504 if (val1
->contents
&& !merged_contents
)
506 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "(contents gone)",
508 change
= max (change
, INVISIBLE_CHANGE
);
510 else if (merged_contents
&& merged_contents
->change
!= NO_CHANGE
)
512 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "(contents change)",
514 change
= max (change
, INVISIBLE_CHANGE
);
517 val1
->contents
= merged_contents
;
520 merged_next
= merge_widget_value (val1
->next
, val2
->next
, level
);
522 if (val1
->next
&& !merged_next
)
524 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "(following gone)",
526 change
= max (change
, STRUCTURAL_CHANGE
);
528 else if (merged_next
)
530 if (merged_next
->change
)
531 EXPLAIN (val1
->name
, change
, merged_next
->change
, "(following change)",
533 change
= max (change
, merged_next
->change
);
536 val1
->next
= merged_next
;
538 val1
->change
= change
;
540 if (change
> NO_CHANGE
&& val1
->toolkit_data
)
542 if (val1
->free_toolkit_data
)
543 free (val1
->toolkit_data
);
544 val1
->toolkit_data
= NULL
;
551 /* modifying the widgets */
553 name_to_widget (instance
, name
)
554 widget_instance
* instance
;
557 Widget widget
= NULL
;
559 if (!instance
->widget
)
562 if (!strcmp (XtName (instance
->widget
), name
))
563 widget
= instance
->widget
;
566 int length
= strlen (name
) + 2;
567 char* real_name
= (char *) xmalloc (length
);
569 strcpy (real_name
+ 1, name
);
571 widget
= XtNameToWidget (instance
->widget
, real_name
);
579 set_one_value (instance
, val
, deep_p
)
580 widget_instance
* instance
;
584 Widget widget
= name_to_widget (instance
, val
->name
);
588 #if defined (USE_LUCID)
589 if (lw_lucid_widget_p (instance
->widget
))
590 xlw_update_one_widget (instance
, widget
, val
, deep_p
);
592 #if defined (USE_MOTIF)
593 if (lw_motif_widget_p (instance
->widget
))
594 xm_update_one_widget (instance
, widget
, val
, deep_p
);
596 #if defined (USE_OLIT)
597 if (lw_olit_widget_p (instance
->widget
))
598 xol_update_one_widget (instance
, widget
, val
, deep_p
);
600 #if defined (USE_XAW)
601 if (lw_xaw_widget_p (instance
->widget
))
602 xaw_update_one_widget (instance
, widget
, val
, deep_p
);
608 update_one_widget_instance (instance
, deep_p
)
609 widget_instance
* instance
;
614 if (!instance
->widget
)
615 /* the widget was destroyed */
618 for (val
= instance
->info
->val
; val
; val
= val
->next
)
619 if (val
->change
!= NO_CHANGE
)
620 set_one_value (instance
, val
, deep_p
);
624 update_all_widget_values (info
, deep_p
)
628 widget_instance
* instance
;
631 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
632 update_one_widget_instance (instance
, deep_p
);
634 for (val
= info
->val
; val
; val
= val
->next
)
635 val
->change
= NO_CHANGE
;
639 lw_modify_all_widgets (id
, val
, deep_p
)
644 widget_info
* info
= get_widget_info (id
, False
);
645 widget_value
* new_val
;
646 widget_value
* next_new_val
;
655 for (new_val
= val
; new_val
; new_val
= new_val
->next
)
657 next_new_val
= new_val
->next
;
658 new_val
->next
= NULL
;
660 for (prev
= NULL
, cur
= info
->val
; cur
; prev
= cur
, cur
= cur
->next
)
661 if (!strcmp (cur
->name
, new_val
->name
))
666 cur
= merge_widget_value (cur
, new_val
, deep_p
? 1000 : 1);
668 prev
->next
= cur
? cur
: next
;
670 info
->val
= cur
? cur
: next
;
677 /* Could not find it, add it */
679 prev
->next
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
681 info
->val
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
683 new_val
->next
= next_new_val
;
686 update_all_widget_values (info
, deep_p
);
690 /* creating the widgets */
693 initialize_widget_instance (instance
)
694 widget_instance
* instance
;
698 for (val
= instance
->info
->val
; val
; val
= val
->next
)
699 val
->change
= STRUCTURAL_CHANGE
;
701 update_one_widget_instance (instance
, True
);
703 for (val
= instance
->info
->val
; val
; val
= val
->next
)
704 val
->change
= NO_CHANGE
;
708 static widget_creation_function
709 find_in_table (type
, table
)
711 widget_creation_entry
* table
;
713 widget_creation_entry
* cur
;
714 for (cur
= table
; cur
->type
; cur
++)
715 if (!my_strcasecmp (type
, cur
->type
))
716 return cur
->function
;
724 /* return True if name matches [EILPQeilpq][1-9][Bb] or
725 [EILPQeilpq][1-9][Bb][Rr][1-9] */
731 case 'E': case 'I': case 'L': case 'P': case 'Q':
732 case 'e': case 'i': case 'l': case 'p': case 'q':
733 if (name
[1] >= '0' && name
[1] <= '9')
735 if (name
[2] != 'B' && name
[2] != 'b')
739 if ((name
[3] == 'T' || name
[3] == 't') && !name
[4])
741 if ((name
[3] == 'R' || name
[3] == 'r')
742 && name
[4] >= '0' && name
[4] <= '9' && !name
[5])
755 instanciate_widget_instance (instance
)
756 widget_instance
* instance
;
758 widget_creation_function function
= NULL
;
760 #if defined (USE_LUCID)
762 function
= find_in_table (instance
->info
->type
, xlw_creation_table
);
764 #if defined(USE_MOTIF)
766 function
= find_in_table (instance
->info
->type
, xm_creation_table
);
768 #if defined (USE_OLIT)
770 function
= find_in_table (instance
->info
->type
, xol_creation_table
);
772 #if defined (USE_XAW)
774 function
= find_in_table (instance
->info
->type
, xaw_creation_table
);
779 if (dialog_spec_p (instance
->info
->type
))
781 #if defined (USE_LUCID)
784 #if defined(USE_MOTIF)
786 function
= xm_create_dialog
;
788 #if defined (USE_XAW)
790 function
= xaw_create_dialog
;
792 #if defined (USE_OLIT)
800 printf ("No creation function for widget type %s\n",
801 instance
->info
->type
);
805 instance
->widget
= (*function
) (instance
);
807 if (!instance
->widget
)
810 /* XtRealizeWidget (instance->widget);*/
814 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
819 lw_callback pre_activate_cb
;
820 lw_callback selection_cb
;
821 lw_callback post_activate_cb
;
823 if (!get_widget_info (id
, False
))
824 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
829 lw_get_widget (id
, parent
, pop_up_p
)
834 widget_instance
* instance
;
836 instance
= find_instance (id
, parent
, pop_up_p
);
837 return instance
? instance
->widget
: NULL
;
841 lw_make_widget (id
, parent
, pop_up_p
)
846 widget_instance
* instance
;
849 instance
= find_instance (id
, parent
, pop_up_p
);
852 info
= get_widget_info (id
, False
);
855 instance
= allocate_widget_instance (info
, parent
, pop_up_p
);
856 initialize_widget_instance (instance
);
858 if (!instance
->widget
)
860 return instance
->widget
;
864 lw_create_widget (type
, name
, id
, val
, parent
, pop_up_p
, pre_activate_cb
, selection_cb
, post_activate_cb
)
871 lw_callback pre_activate_cb
;
872 lw_callback selection_cb
;
873 lw_callback post_activate_cb
;
875 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
877 return lw_make_widget (id
, parent
, pop_up_p
);
881 /* destroying the widgets */
883 destroy_one_instance (instance
)
884 widget_instance
* instance
;
886 /* Remove the destroy callback on the widget; that callback will try to
887 dereference the instance object (to set its widget slot to 0, since the
888 widget is dead.) Since the instance is now dead, we don't have to worry
889 about the fact that its widget is dead too.
891 This happens in the Phase2Destroy of the widget, so this callback would
892 not have been run until arbitrarily long after the instance was freed.
894 if (instance
->widget
)
895 XtRemoveCallback (instance
->widget
, XtNdestroyCallback
,
896 mark_widget_destroyed
, (XtPointer
)instance
);
898 if (instance
->widget
)
900 /* The else are pretty tricky here, including the empty statement
901 at the end because it would be very bad to destroy a widget
903 #if defined (USE_LUCID)
904 if (lw_lucid_widget_p (instance
->widget
))
905 xlw_destroy_instance (instance
);
908 #if defined (USE_MOTIF)
909 if (lw_motif_widget_p (instance
->widget
))
910 xm_destroy_instance (instance
);
913 #if defined (USE_OLIT)
914 if (lw_olit_widget_p (instance
->widget
))
915 xol_destroy_instance (instance
);
918 #if defined (USE_XAW)
919 if (lw_xaw_widget_p (instance
->widget
))
920 xaw_destroy_instance (instance
);
923 /* do not remove the empty statement */
927 free_widget_instance (instance
);
931 lw_destroy_widget (w
)
934 widget_instance
* instance
= get_widget_instance (w
, True
);
938 widget_info
*info
= instance
->info
;
939 /* instance has already been removed from the list; free it */
940 destroy_one_instance (instance
);
941 /* if there are no instances left, free the info too */
942 if (!info
->instances
)
943 lw_destroy_all_widgets (info
->id
);
948 lw_destroy_all_widgets (id
)
951 widget_info
* info
= get_widget_info (id
, True
);
952 widget_instance
* instance
;
953 widget_instance
* next
;
957 for (instance
= info
->instances
; instance
; )
959 next
= instance
->next
;
960 destroy_one_instance (instance
);
963 free_widget_info (info
);
968 lw_destroy_everything ()
970 while (all_widget_info
)
971 lw_destroy_all_widgets (all_widget_info
->id
);
975 lw_destroy_all_pop_ups ()
979 widget_instance
* instance
;
981 for (info
= all_widget_info
; info
; info
= next
)
984 instance
= info
->instances
;
985 if (instance
&& instance
->pop_up_p
)
986 lw_destroy_all_widgets (info
->id
);
991 extern Widget
first_child (Widget
); /* garbage */
995 lw_raise_all_pop_up_widgets ()
998 widget_instance
* instance
;
999 Widget result
= NULL
;
1001 for (info
= all_widget_info
; info
; info
= info
->next
)
1002 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1003 if (instance
->pop_up_p
)
1005 Widget widget
= instance
->widget
;
1008 if (XtIsManaged (widget
)
1010 /* What a complete load of crap!!!!
1011 When a dialogShell is on the screen, it is not managed!
1013 || (lw_motif_widget_p (instance
->widget
) &&
1014 XtIsManaged (first_child (widget
)))
1020 XMapRaised (XtDisplay (widget
), XtWindow (widget
));
1028 lw_pop_all_widgets (id
, up
)
1032 widget_info
* info
= get_widget_info (id
, False
);
1033 widget_instance
* instance
;
1036 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1037 if (instance
->pop_up_p
&& instance
->widget
)
1039 #if defined (USE_LUCID)
1040 if (lw_lucid_widget_p (instance
->widget
))
1042 XtRealizeWidget (instance
->widget
);
1043 xlw_pop_instance (instance
, up
);
1046 #if defined (USE_MOTIF)
1047 if (lw_motif_widget_p (instance
->widget
))
1049 XtRealizeWidget (instance
->widget
);
1050 xm_pop_instance (instance
, up
);
1053 #if defined (USE_OLIT)
1054 if (lw_olit_widget_p (instance
->widget
))
1056 XtRealizeWidget (instance
->widget
);
1057 xol_pop_instance (instance
, up
);
1060 #if defined (USE_XAW)
1061 if (lw_xaw_widget_p (instance
->widget
))
1063 XtRealizeWidget (XtParent (instance
->widget
));
1064 XtRealizeWidget (instance
->widget
);
1065 xaw_pop_instance (instance
, up
);
1072 lw_pop_up_all_widgets (id
)
1075 lw_pop_all_widgets (id
, True
);
1079 lw_pop_down_all_widgets (id
)
1082 lw_pop_all_widgets (id
, False
);
1086 lw_popup_menu (widget
)
1089 #if defined (USE_LUCID)
1090 if (lw_lucid_widget_p (widget
))
1091 xlw_popup_menu (widget
);
1093 #if defined (USE_MOTIF)
1094 if (lw_motif_widget_p (widget
))
1095 xm_popup_menu (widget
);
1097 #if defined (USE_OLIT)
1098 if (lw_olit_widget_p (widget
))
1099 xol_popup_menu (widget
);
1101 #if defined (USE_XAW)
1102 if (lw_xaw_widget_p (widget
))
1103 xaw_popup_menu (widget
);
1107 \f/* get the values back */
1109 get_one_value (instance
, val
)
1110 widget_instance
* instance
;
1113 Widget widget
= name_to_widget (instance
, val
->name
);
1117 #if defined (USE_LUCID)
1118 if (lw_lucid_widget_p (instance
->widget
))
1119 xlw_update_one_value (instance
, widget
, val
);
1121 #if defined (USE_MOTIF)
1122 if (lw_motif_widget_p (instance
->widget
))
1123 xm_update_one_value (instance
, widget
, val
);
1125 #if defined (USE_OLIT)
1126 if (lw_olit_widget_p (instance
->widget
))
1127 xol_update_one_value (instance
, widget
, val
);
1129 #if defined (USE_XAW)
1130 if (lw_xaw_widget_p (instance
->widget
))
1131 xaw_update_one_value (instance
, widget
, val
);
1140 lw_get_some_values (id
, val_out
)
1142 widget_value
* val_out
;
1144 widget_info
* info
= get_widget_info (id
, False
);
1145 widget_instance
* instance
;
1147 Boolean result
= False
;
1152 instance
= info
->instances
;
1156 for (val
= val_out
; val
; val
= val
->next
)
1157 if (get_one_value (instance
, val
))
1164 lw_get_all_values (id
)
1167 widget_info
* info
= get_widget_info (id
, False
);
1168 widget_value
* val
= info
->val
;
1169 if (lw_get_some_values (id
, val
))
1175 /* internal function used by the library dependent implementation to get the
1176 widget_value for a given widget in an instance */
1178 lw_get_widget_value_for_widget (instance
, w
)
1179 widget_instance
* instance
;
1182 char* name
= XtName (w
);
1184 for (cur
= instance
->info
->val
; cur
; cur
= cur
->next
)
1185 if (!strcmp (cur
->name
, name
))
1190 \f/* update other instances value when one thing changed */
1191 /* This function can be used as a an XtCallback for the widgets that get
1192 modified to update other instances of the widgets. Closure should be the
1195 lw_internal_update_other_instances (widget
, closure
, call_data
)
1198 XtPointer call_data
;
1200 /* To forbid recursive calls */
1201 static Boolean updating
;
1203 widget_instance
* instance
= (widget_instance
*)closure
;
1204 char* name
= XtName (widget
);
1206 widget_instance
* cur
;
1209 /* never recurse as this could cause infinite recursions. */
1213 /* protect against the widget being destroyed */
1214 if (XtWidgetBeingDestroyedP (widget
))
1217 /* Return immediately if there are no other instances */
1218 info
= instance
->info
;
1219 if (!info
->instances
->next
)
1224 for (val
= info
->val
; val
&& strcmp (val
->name
, name
); val
= val
->next
);
1226 if (val
&& get_one_value (instance
, val
))
1227 for (cur
= info
->instances
; cur
; cur
= cur
->next
)
1228 if (cur
!= instance
)
1229 set_one_value (cur
, val
, True
);
1238 lw_get_widget_id (w
)
1241 widget_instance
* instance
= get_widget_instance (w
, False
);
1243 return instance
? instance
->info
->id
: 0;
1246 \f/* set the keyboard focus */
1248 lw_set_keyboard_focus (parent
, w
)
1252 #if defined (USE_MOTIF)
1253 xm_set_keyboard_focus (parent
, w
);
1255 XtSetKeyboardFocus (parent
, w
);
1261 show_one_widget_busy (w
, flag
)
1265 Pixel foreground
= 0;
1266 Pixel background
= 1;
1267 Widget widget_to_invert
= XtNameToWidget (w
, "*sheet");
1268 if (!widget_to_invert
)
1269 widget_to_invert
= w
;
1271 XtVaGetValues (widget_to_invert
,
1272 XtNforeground
, &foreground
,
1273 XtNbackground
, &background
,
1275 XtVaSetValues (widget_to_invert
,
1276 XtNforeground
, background
,
1277 XtNbackground
, foreground
,
1282 lw_show_busy (w
, busy
)
1286 widget_instance
* instance
= get_widget_instance (w
, False
);
1288 widget_instance
* next
;
1292 info
= instance
->info
;
1293 if (info
->busy
!= busy
)
1295 for (next
= info
->instances
; next
; next
= next
->next
)
1297 show_one_widget_busy (next
->widget
, busy
);