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 */
26 #include <sys/types.h>
29 #include <X11/StringDefs.h>
30 #include "lwlib-internal.h"
31 #include "lwlib-utils.h"
33 #if defined(__GNUC__) && !defined(alloca)
34 #define alloca __builtin_alloca
37 #if ((!__GNUC__) && !defined(__hpux)) && !defined(AIXV3)
45 #if defined (USE_LUCID)
46 #include "lwlib-Xlw.h"
48 #if defined (USE_MOTIF)
51 #if defined (USE_OLIT)
52 #include "lwlib-Xol.h"
55 #if !defined (USE_LUCID) && !defined (USE_MOTIF) && !defined (USE_OLIT)
56 ERROR
! At least one of USE_LUCID
, USE_MOTIF
or USE_OLIT must be defined
.
59 #if defined (USE_MOTIF) && defined (USE_OLIT)
60 ERROR
! no more than one of USE_MOTIF
and USE_OLIT may be defined
.
63 /* List of all widgets managed by the library. */
65 all_widget_info
= NULL
;
67 \f/* Forward declarations */
69 instanciate_widget_instance (widget_instance
* instance
);
71 \f/* utility functions for widget_instance and widget_info */
77 result
= (char *) malloc (strlen (s
) + 1);
85 safe_free_str (char* s
)
90 static widget_value
*widget_value_free_list
= 0;
93 malloc_widget_value ()
96 if (widget_value_free_list
)
98 wv
= widget_value_free_list
;
99 widget_value_free_list
= wv
->free_list
;
104 wv
= (widget_value
*) malloc (sizeof (widget_value
));
106 memset (wv
, 0, sizeof (widget_value
));
110 /* this is analagous to free(). It frees only what was allocated
111 by malloc_widget_value(), and no substructures.
114 free_widget_value (wv
)
119 wv
->free_list
= widget_value_free_list
;
120 widget_value_free_list
= wv
;
124 free_widget_value_tree (widget_value
* wv
)
129 if (wv
->name
) free (wv
->name
);
130 if (wv
->value
) free (wv
->value
);
131 if (wv
->key
) free (wv
->key
);
133 wv
->name
= wv
->value
= wv
->key
= (char *) 0xDEADBEEF;
135 if (wv
->toolkit_data
&& wv
->free_toolkit_data
)
137 free (wv
->toolkit_data
);
138 wv
->toolkit_data
= (void *) 0xDEADBEEF;
141 if (wv
->contents
&& (wv
->contents
!= (widget_value
*)1))
143 free_widget_value_tree (wv
->contents
);
144 wv
->contents
= (widget_value
*) 0xDEADBEEF;
148 free_widget_value_tree (wv
->next
);
149 wv
->next
= (widget_value
*) 0xDEADBEEF;
151 free_widget_value (wv
);
154 static widget_value
*
155 copy_widget_value_tree (widget_value
* val
, change_type change
)
161 if (val
== (widget_value
*) 1)
164 copy
= malloc_widget_value ();
165 copy
->name
= safe_strdup (val
->name
);
166 copy
->value
= safe_strdup (val
->value
);
167 copy
->key
= safe_strdup (val
->key
);
168 copy
->enabled
= val
->enabled
;
169 copy
->selected
= val
->selected
;
170 copy
->edited
= False
;
171 copy
->change
= change
;
172 copy
->contents
= copy_widget_value_tree (val
->contents
, change
);
173 copy
->call_data
= val
->call_data
;
174 copy
->next
= copy_widget_value_tree (val
->next
, change
);
175 copy
->toolkit_data
= NULL
;
176 copy
->free_toolkit_data
= False
;
181 allocate_widget_info (char* type
, char* name
, LWLIB_ID id
, widget_value
* val
,
182 lw_callback pre_activate_cb
, lw_callback selection_cb
,
183 lw_callback post_activate_cb
)
185 widget_info
* info
= (widget_info
*)malloc (sizeof (widget_info
));
186 info
->type
= safe_strdup (type
);
187 info
->name
= safe_strdup (name
);
189 info
->val
= copy_widget_value_tree (val
, STRUCTURAL_CHANGE
);
191 info
->pre_activate_cb
= pre_activate_cb
;
192 info
->selection_cb
= selection_cb
;
193 info
->post_activate_cb
= post_activate_cb
;
194 info
->instances
= NULL
;
196 info
->next
= all_widget_info
;
197 all_widget_info
= info
;
203 free_widget_info (widget_info
* info
)
205 safe_free_str (info
->type
);
206 safe_free_str (info
->name
);
207 free_widget_value_tree (info
->val
);
208 memset ((void*)info
, 0xDEADBEEF, sizeof (widget_info
));
213 mark_widget_destroyed (Widget widget
, XtPointer closure
, XtPointer call_data
)
215 widget_instance
* instance
= (widget_instance
*)closure
;
217 /* be very conservative */
218 if (instance
->widget
== widget
)
219 instance
->widget
= NULL
;
222 static widget_instance
*
223 allocate_widget_instance (widget_info
* info
, Widget parent
, Boolean pop_up_p
)
225 widget_instance
* instance
=
226 (widget_instance
*)malloc (sizeof (widget_instance
));
227 instance
->parent
= parent
;
228 instance
->pop_up_p
= pop_up_p
;
229 instance
->info
= info
;
230 instance
->next
= info
->instances
;
231 info
->instances
= instance
;
233 instanciate_widget_instance (instance
);
235 XtAddCallback (instance
->widget
, XtNdestroyCallback
,
236 mark_widget_destroyed
, (XtPointer
)instance
);
241 free_widget_instance (widget_instance
* instance
)
243 memset ((void*)instance
, 0xDEADBEEF, sizeof (widget_instance
));
248 get_widget_info (LWLIB_ID id
, Boolean remove_p
)
252 for (prev
= NULL
, info
= all_widget_info
;
254 prev
= info
, info
= info
->next
)
260 prev
->next
= info
->next
;
262 all_widget_info
= info
->next
;
269 static widget_instance
*
270 get_widget_instance (Widget widget
, Boolean remove_p
)
273 widget_instance
* instance
;
274 widget_instance
* prev
;
275 for (info
= all_widget_info
; info
; info
= info
->next
)
276 for (prev
= NULL
, instance
= info
->instances
;
278 prev
= instance
, instance
= instance
->next
)
279 if (instance
->widget
== widget
)
284 prev
->next
= instance
->next
;
286 info
->instances
= instance
->next
;
290 return (widget_instance
*) 0;
293 static widget_instance
*
294 find_instance (LWLIB_ID id
, Widget parent
, Boolean pop_up_p
)
296 widget_info
* info
= get_widget_info (id
, False
);
297 widget_instance
* instance
;
300 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
301 if (instance
->parent
== parent
&& instance
->pop_up_p
== pop_up_p
)
308 /* utility function for widget_value */
310 safe_strcmp (char* s1
, char* s2
)
312 if (!!s1
^ !!s2
) return True
;
313 return (s1
&& s2
) ? strcmp (s1
, s2
) : s1
? False
: !!s2
;
319 return i1
> i2
? i1
: i2
;
324 # define EXPLAIN(name, oc, nc, desc, a1, a2) \
325 printf ("Change: \"%s\"\tmax(%s=%d,%s=%d)\t%s %d %d\n", \
327 (oc == NO_CHANGE ? "none" : \
328 (oc == INVISIBLE_CHANGE ? "invisible" : \
329 (oc == VISIBLE_CHANGE ? "visible" : \
330 (oc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
332 (nc == NO_CHANGE ? "none" : \
333 (nc == INVISIBLE_CHANGE ? "invisible" : \
334 (nc == VISIBLE_CHANGE ? "visible" : \
335 (nc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
338 # define EXPLAIN(name, oc, nc, desc, a1, a2)
342 static widget_value
*
343 merge_widget_value (widget_value
* val1
, widget_value
* val2
, int level
)
346 widget_value
* merged_next
;
347 widget_value
* merged_contents
;
352 return copy_widget_value_tree (val2
, STRUCTURAL_CHANGE
);
358 free_widget_value_tree (val1
);
364 if (safe_strcmp (val1
->name
, val2
->name
))
366 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "name change",
367 val1
->name
, val2
->name
);
368 change
= max (change
, STRUCTURAL_CHANGE
);
369 safe_free_str (val1
->name
);
370 val1
->name
= safe_strdup (val2
->name
);
372 if (safe_strcmp (val1
->value
, val2
->value
))
374 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "value change",
375 val1
->value
, val2
->value
);
376 change
= max (change
, VISIBLE_CHANGE
);
377 safe_free_str (val1
->value
);
378 val1
->value
= safe_strdup (val2
->value
);
380 if (safe_strcmp (val1
->key
, val2
->key
))
382 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "key change",
383 val1
->key
, val2
->key
);
384 change
= max (change
, VISIBLE_CHANGE
);
385 safe_free_str (val1
->key
);
386 val1
->key
= safe_strdup (val2
->key
);
388 if (val1
->enabled
!= val2
->enabled
)
390 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "enablement change",
391 val1
->enabled
, val2
->enabled
);
392 change
= max (change
, VISIBLE_CHANGE
);
393 val1
->enabled
= val2
->enabled
;
395 if (val1
->selected
!= val2
->selected
)
397 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "selection change",
398 val1
->selected
, val2
->selected
);
399 change
= max (change
, VISIBLE_CHANGE
);
400 val1
->selected
= val2
->selected
;
402 if (val1
->call_data
!= val2
->call_data
)
404 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "call-data change",
405 val1
->call_data
, val2
->call_data
);
406 change
= max (change
, INVISIBLE_CHANGE
);
407 val1
->call_data
= val2
->call_data
;
413 merge_widget_value (val1
->contents
, val2
->contents
, level
- 1);
415 if (val1
->contents
&& !merged_contents
)
417 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "(contents gone)",
419 change
= max (change
, INVISIBLE_CHANGE
);
421 else if (merged_contents
&& merged_contents
->change
!= NO_CHANGE
)
423 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "(contents change)",
425 change
= max (change
, INVISIBLE_CHANGE
);
428 val1
->contents
= merged_contents
;
431 merged_next
= merge_widget_value (val1
->next
, val2
->next
, level
);
433 if (val1
->next
&& !merged_next
)
435 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "(following gone)",
437 change
= max (change
, STRUCTURAL_CHANGE
);
439 else if (merged_next
)
441 if (merged_next
->change
)
442 EXPLAIN (val1
->name
, change
, merged_next
->change
, "(following change)",
444 change
= max (change
, merged_next
->change
);
447 val1
->next
= merged_next
;
449 val1
->change
= change
;
451 if (change
> NO_CHANGE
&& val1
->toolkit_data
)
453 if (val1
->free_toolkit_data
)
454 free (val1
->toolkit_data
);
455 val1
->toolkit_data
= NULL
;
462 /* modifying the widgets */
464 name_to_widget (widget_instance
* instance
, char* name
)
466 Widget widget
= NULL
;
468 if (!instance
->widget
)
471 if (!strcmp (XtName (instance
->widget
), name
))
472 widget
= instance
->widget
;
475 int length
= strlen (name
) + 2;
476 char* real_name
= (char *) alloca (length
);
478 strcpy (real_name
+ 1, name
);
480 widget
= XtNameToWidget (instance
->widget
, real_name
);
486 set_one_value (widget_instance
* instance
, widget_value
* val
, Boolean deep_p
)
488 Widget widget
= name_to_widget (instance
, val
->name
);
492 #if defined (USE_LUCID)
493 if (lw_lucid_widget_p (instance
->widget
))
494 xlw_update_one_widget (instance
, widget
, val
, deep_p
);
496 #if defined (USE_MOTIF)
497 if (lw_motif_widget_p (instance
->widget
))
498 xm_update_one_widget (instance
, widget
, val
, deep_p
);
500 #if defined (USE_OLIT)
501 if (lw_olit_widget_p (instance
->widget
))
502 xol_update_one_widget (instance
, widget
, val
, deep_p
);
508 update_one_widget_instance (widget_instance
* instance
, Boolean deep_p
)
512 if (!instance
->widget
)
513 /* the widget was destroyed */
516 for (val
= instance
->info
->val
; val
; val
= val
->next
)
517 if (val
->change
!= NO_CHANGE
)
518 set_one_value (instance
, val
, deep_p
);
522 update_all_widget_values (widget_info
* info
, Boolean deep_p
)
524 widget_instance
* instance
;
527 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
528 update_one_widget_instance (instance
, deep_p
);
530 for (val
= info
->val
; val
; val
= val
->next
)
531 val
->change
= NO_CHANGE
;
535 lw_modify_all_widgets (LWLIB_ID id
, widget_value
* val
, Boolean deep_p
)
537 widget_info
* info
= get_widget_info (id
, False
);
538 widget_value
* new_val
;
539 widget_value
* next_new_val
;
548 for (new_val
= val
; new_val
; new_val
= new_val
->next
)
550 next_new_val
= new_val
->next
;
551 new_val
->next
= NULL
;
553 for (prev
= NULL
, cur
= info
->val
; cur
; prev
= cur
, cur
= cur
->next
)
554 if (!strcmp (cur
->name
, new_val
->name
))
559 cur
= merge_widget_value (cur
, new_val
, deep_p
? 1000 : 1);
561 prev
->next
= cur
? cur
: next
;
563 info
->val
= cur
? cur
: next
;
570 /* Could not find it, add it */
572 prev
->next
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
574 info
->val
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
576 new_val
->next
= next_new_val
;
579 update_all_widget_values (info
, deep_p
);
583 /* creating the widgets */
586 initialize_widget_instance (widget_instance
* instance
)
590 for (val
= instance
->info
->val
; val
; val
= val
->next
)
591 val
->change
= STRUCTURAL_CHANGE
;
593 update_one_widget_instance (instance
, True
);
595 for (val
= instance
->info
->val
; val
; val
= val
->next
)
596 val
->change
= NO_CHANGE
;
600 static widget_creation_function
601 find_in_table (char* type
, widget_creation_entry
* table
)
603 widget_creation_entry
* cur
;
604 for (cur
= table
; cur
->type
; cur
++)
605 if (!strcasecmp (type
, cur
->type
))
606 return cur
->function
;
611 dialog_spec_p (char* name
)
613 /* return True if name matches [EILPQeilpq][1-9][Bb] or
614 [EILPQeilpq][1-9][Bb][Rr][1-9] */
620 case 'E': case 'I': case 'L': case 'P': case 'Q':
621 case 'e': case 'i': case 'l': case 'p': case 'q':
622 if (name
[1] >= '0' && name
[1] <= '9')
624 if (name
[2] != 'B' && name
[2] != 'b')
628 if ((name
[3] == 'T' || name
[3] == 't') && !name
[4])
630 if ((name
[3] == 'R' || name
[3] == 'r')
631 && name
[4] >= '0' && name
[4] <= '9' && !name
[5])
644 instanciate_widget_instance (widget_instance
* instance
)
646 widget_creation_function function
= NULL
;
648 #if defined (USE_LUCID)
650 function
= find_in_table (instance
->info
->type
, xlw_creation_table
);
652 #if defined(USE_MOTIF)
654 function
= find_in_table (instance
->info
->type
, xm_creation_table
);
656 #if defined (USE_OLIT)
658 function
= find_in_table (instance
->info
->type
, xol_creation_table
);
663 if (dialog_spec_p (instance
->info
->type
))
665 #if defined (USE_LUCID)
668 #if defined(USE_MOTIF)
670 function
= xm_create_dialog
;
672 #if defined (USE_OLIT)
680 printf ("No creation function for widget type %s\n",
681 instance
->info
->type
);
685 instance
->widget
= (*function
) (instance
);
687 if (!instance
->widget
)
690 /* XtRealizeWidget (instance->widget);*/
694 lw_register_widget (char* type
, char* name
, LWLIB_ID id
, widget_value
* val
,
695 lw_callback pre_activate_cb
, lw_callback selection_cb
,
696 lw_callback post_activate_cb
)
698 if (!get_widget_info (id
, False
))
699 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
704 lw_get_widget (LWLIB_ID id
, Widget parent
, Boolean pop_up_p
)
706 widget_instance
* instance
;
708 instance
= find_instance (id
, parent
, pop_up_p
);
709 return instance
? instance
->widget
: NULL
;
713 lw_make_widget (LWLIB_ID id
, Widget parent
, Boolean pop_up_p
)
715 widget_instance
* instance
;
718 instance
= find_instance (id
, parent
, pop_up_p
);
721 info
= get_widget_info (id
, False
);
724 instance
= allocate_widget_instance (info
, parent
, pop_up_p
);
725 initialize_widget_instance (instance
);
727 if (!instance
->widget
)
729 return instance
->widget
;
733 lw_create_widget (char* type
, char* name
, LWLIB_ID id
, widget_value
* val
,
734 Widget parent
, Boolean pop_up_p
, lw_callback pre_activate_cb
,
735 lw_callback selection_cb
, lw_callback post_activate_cb
)
737 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
739 return lw_make_widget (id
, parent
, pop_up_p
);
743 /* destroying the widgets */
745 destroy_one_instance (widget_instance
* instance
)
747 /* Remove the destroy callback on the widget; that callback will try to
748 dereference the instance object (to set its widget slot to 0, since the
749 widget is dead.) Since the instance is now dead, we don't have to worry
750 about the fact that its widget is dead too.
752 This happens in the Phase2Destroy of the widget, so this callback would
753 not have been run until arbitrarily long after the instance was freed.
755 if (instance
->widget
)
756 XtRemoveCallback (instance
->widget
, XtNdestroyCallback
,
757 mark_widget_destroyed
, (XtPointer
)instance
);
759 if (instance
->widget
)
761 /* The else are pretty tricky here, including the empty statement
762 at the end because it would be very bad to destroy a widget
764 #if defined (USE_LUCID)
765 if (lw_lucid_widget_p (instance
->widget
))
766 xlw_destroy_instance (instance
);
769 #if defined (USE_MOTIF)
770 if (lw_motif_widget_p (instance
->widget
))
771 xm_destroy_instance (instance
);
774 #if defined (USE_OLIT)
775 if (lw_olit_widget_p (instance
->widget
))
776 xol_destroy_instance (instance
);
779 /* do not remove the empty statement */
783 free_widget_instance (instance
);
787 lw_destroy_widget (Widget w
)
789 widget_instance
* instance
= get_widget_instance (w
, True
);
793 widget_info
*info
= instance
->info
;
794 /* instance has already been removed from the list; free it */
795 destroy_one_instance (instance
);
796 /* if there are no instances left, free the info too */
797 if (!info
->instances
)
798 lw_destroy_all_widgets (info
->id
);
803 lw_destroy_all_widgets (LWLIB_ID id
)
805 widget_info
* info
= get_widget_info (id
, True
);
806 widget_instance
* instance
;
807 widget_instance
* next
;
811 for (instance
= info
->instances
; instance
; )
813 next
= instance
->next
;
814 destroy_one_instance (instance
);
817 free_widget_info (info
);
822 lw_destroy_everything ()
824 while (all_widget_info
)
825 lw_destroy_all_widgets (all_widget_info
->id
);
829 lw_destroy_all_pop_ups ()
833 widget_instance
* instance
;
835 for (info
= all_widget_info
; info
; info
= next
)
838 instance
= info
->instances
;
839 if (instance
&& instance
->pop_up_p
)
840 lw_destroy_all_widgets (info
->id
);
845 extern Widget
first_child (Widget
); /* garbage */
849 lw_raise_all_pop_up_widgets ()
852 widget_instance
* instance
;
853 Widget result
= NULL
;
855 for (info
= all_widget_info
; info
; info
= info
->next
)
856 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
857 if (instance
->pop_up_p
)
859 Widget widget
= instance
->widget
;
862 if (XtIsManaged (widget
)
864 /* What a complete load of crap!!!!
865 When a dialogShell is on the screen, it is not managed!
867 || (lw_motif_widget_p (instance
->widget
) &&
868 XtIsManaged (first_child (widget
)))
874 XMapRaised (XtDisplay (widget
), XtWindow (widget
));
882 lw_pop_all_widgets (LWLIB_ID id
, Boolean up
)
884 widget_info
* info
= get_widget_info (id
, False
);
885 widget_instance
* instance
;
888 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
889 if (instance
->pop_up_p
&& instance
->widget
)
891 if (!XtIsRealized (instance
->widget
))
892 XtRealizeWidget (instance
->widget
);
893 #if defined (USE_LUCID)
894 if (lw_lucid_widget_p (instance
->widget
))
895 xlw_pop_instance (instance
, up
);
897 #if defined (USE_MOTIF)
898 if (lw_motif_widget_p (instance
->widget
))
899 xm_pop_instance (instance
, up
);
901 #if defined (USE_OLIT)
902 if (lw_olit_widget_p (instance
->widget
))
903 xol_pop_instance (instance
, up
);
909 lw_pop_up_all_widgets (LWLIB_ID id
)
911 lw_pop_all_widgets (id
, True
);
915 lw_pop_down_all_widgets (LWLIB_ID id
)
917 lw_pop_all_widgets (id
, False
);
921 lw_popup_menu (Widget widget
)
923 #if defined (USE_LUCID)
924 if (lw_lucid_widget_p (widget
))
925 xlw_popup_menu (widget
);
927 #if defined (USE_MOTIF)
928 if (lw_motif_widget_p (widget
))
929 xm_popup_menu (widget
);
931 #if defined (USE_OLIT)
932 if (lw_olit_widget_p (widget
))
933 xol_popup_menu (widget
);
937 \f/* get the values back */
939 get_one_value (widget_instance
* instance
, widget_value
* val
)
941 Widget widget
= name_to_widget (instance
, val
->name
);
945 #if defined (USE_LUCID)
946 if (lw_lucid_widget_p (instance
->widget
))
947 xlw_update_one_value (instance
, widget
, val
);
949 #if defined (USE_MOTIF)
950 if (lw_motif_widget_p (instance
->widget
))
951 xm_update_one_value (instance
, widget
, val
);
953 #if defined (USE_OLIT)
954 if (lw_olit_widget_p (instance
->widget
))
955 xol_update_one_value (instance
, widget
, val
);
964 lw_get_some_values (LWLIB_ID id
, widget_value
* val_out
)
966 widget_info
* info
= get_widget_info (id
, False
);
967 widget_instance
* instance
;
969 Boolean result
= False
;
974 instance
= info
->instances
;
978 for (val
= val_out
; val
; val
= val
->next
)
979 if (get_one_value (instance
, val
))
986 lw_get_all_values (LWLIB_ID id
)
988 widget_info
* info
= get_widget_info (id
, False
);
989 widget_value
* val
= info
->val
;
990 if (lw_get_some_values (id
, val
))
996 /* internal function used by the library dependent implementation to get the
997 widget_value for a given widget in an instance */
999 lw_get_widget_value_for_widget (widget_instance
* instance
, Widget w
)
1001 char* name
= XtName (w
);
1003 for (cur
= instance
->info
->val
; cur
; cur
= cur
->next
)
1004 if (!strcmp (cur
->name
, name
))
1009 \f/* update other instances value when one thing changed */
1010 /* This function can be used as a an XtCallback for the widgets that get
1011 modified to update other instances of the widgets. Closure should be the
1014 lw_internal_update_other_instances (Widget widget
, XtPointer closure
,
1015 XtPointer call_data
)
1017 /* To forbid recursive calls */
1018 static Boolean updating
;
1020 widget_instance
* instance
= (widget_instance
*)closure
;
1021 char* name
= XtName (widget
);
1023 widget_instance
* cur
;
1026 /* never recurse as this could cause infinite recursions. */
1030 /* protect against the widget being destroyed */
1031 if (XtWidgetBeingDestroyedP (widget
))
1034 /* Return immediately if there are no other instances */
1035 info
= instance
->info
;
1036 if (!info
->instances
->next
)
1041 for (val
= info
->val
; val
&& strcmp (val
->name
, name
); val
= val
->next
);
1043 if (val
&& get_one_value (instance
, val
))
1044 for (cur
= info
->instances
; cur
; cur
= cur
->next
)
1045 if (cur
!= instance
)
1046 set_one_value (cur
, val
, True
);
1055 lw_get_widget_id (Widget w
)
1057 widget_instance
* instance
= get_widget_instance (w
, False
);
1059 return instance
? instance
->info
->id
: 0;
1062 \f/* set the keyboard focus */
1064 lw_set_keyboard_focus (Widget parent
, Widget w
)
1066 #if defined (USE_MOTIF)
1067 xm_set_keyboard_focus (parent
, w
);
1069 XtSetKeyboardFocus (parent
, w
);
1075 show_one_widget_busy (Widget w
, Boolean flag
)
1077 Pixel foreground
= 0;
1078 Pixel background
= 1;
1079 Widget widget_to_invert
= XtNameToWidget (w
, "*sheet");
1080 if (!widget_to_invert
)
1081 widget_to_invert
= w
;
1083 XtVaGetValues (widget_to_invert
,
1084 XtNforeground
, &foreground
,
1085 XtNbackground
, &background
,
1087 XtVaSetValues (widget_to_invert
,
1088 XtNforeground
, background
,
1089 XtNbackground
, foreground
,
1094 lw_show_busy (Widget w
, Boolean busy
)
1096 widget_instance
* instance
= get_widget_instance (w
, False
);
1098 widget_instance
* next
;
1102 info
= instance
->info
;
1103 if (info
->busy
!= busy
)
1105 for (next
= info
->instances
; next
; next
= next
->next
)
1107 show_one_widget_busy (next
->widget
, busy
);