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>
30 #include "lwlib-int.h"
31 #include "lwlib-utils.h"
32 #include <X11/StringDefs.h>
34 #if defined(__GNUC__) && !defined(alloca)
35 #define alloca __builtin_alloca
38 #if ((!__GNUC__) && !defined(__hpux)) && !defined(_AIX)
46 #if defined (USE_LUCID)
47 #include "lwlib-Xlw.h"
49 #if defined (USE_MOTIF)
51 #else /* not USE_MOTIF */
52 #if defined (USE_LUCID)
54 #endif /* not USE_MOTIF && USE_LUCID */
56 #if defined (USE_OLIT)
57 #include "lwlib-Xol.h"
60 #include "lwlib-Xaw.h"
63 #if !defined (USE_LUCID) && !defined (USE_MOTIF) && !defined (USE_OLIT)
64 ERROR
! At least one of USE_LUCID
, USE_MOTIF
or USE_OLIT must be defined
.
67 #if defined (USE_MOTIF) && defined (USE_OLIT)
68 ERROR
! no more than one of USE_MOTIF
and USE_OLIT may be defined
.
71 /* List of all widgets managed by the library. */
73 all_widget_info
= NULL
;
75 \f/* Forward declarations */
77 instanciate_widget_instance (/* widget_instance* instance */);
79 \f/* utility functions for widget_instance and widget_info */
86 result
= (char *) malloc (strlen (s
) + 1);
93 /* Like strcmp but ignore differences in case. */
96 my_strcasecmp (s1
, s2
)
108 return (c1
> c2
? 1 : -1);
121 static widget_value
*widget_value_free_list
= 0;
122 static int malloc_cpt
= 0;
125 malloc_widget_value ()
128 if (widget_value_free_list
)
130 wv
= widget_value_free_list
;
131 widget_value_free_list
= wv
->free_list
;
136 wv
= (widget_value
*) malloc (sizeof (widget_value
));
139 memset (wv
, 0, sizeof (widget_value
));
143 /* this is analagous to free(). It frees only what was allocated
144 by malloc_widget_value(), and no substructures.
147 free_widget_value (wv
)
155 /* When the number of already allocated cells is too big,
162 wv
->free_list
= widget_value_free_list
;
163 widget_value_free_list
= wv
;
168 free_widget_value_tree (wv
)
174 if (wv
->name
) free (wv
->name
);
175 if (wv
->value
) free (wv
->value
);
176 if (wv
->key
) free (wv
->key
);
178 wv
->name
= wv
->value
= wv
->key
= (char *) 0xDEADBEEF;
180 if (wv
->toolkit_data
&& wv
->free_toolkit_data
)
182 free (wv
->toolkit_data
);
183 wv
->toolkit_data
= (void *) 0xDEADBEEF;
186 if (wv
->contents
&& (wv
->contents
!= (widget_value
*)1))
188 free_widget_value_tree (wv
->contents
);
189 wv
->contents
= (widget_value
*) 0xDEADBEEF;
193 free_widget_value_tree (wv
->next
);
194 wv
->next
= (widget_value
*) 0xDEADBEEF;
196 free_widget_value (wv
);
199 static widget_value
*
200 copy_widget_value_tree (val
, change
)
208 if (val
== (widget_value
*) 1)
211 copy
= malloc_widget_value ();
212 copy
->name
= safe_strdup (val
->name
);
213 copy
->value
= safe_strdup (val
->value
);
214 copy
->key
= safe_strdup (val
->key
);
215 copy
->enabled
= val
->enabled
;
216 copy
->selected
= val
->selected
;
217 copy
->edited
= False
;
218 copy
->change
= change
;
219 copy
->contents
= copy_widget_value_tree (val
->contents
, change
);
220 copy
->call_data
= val
->call_data
;
221 copy
->next
= copy_widget_value_tree (val
->next
, change
);
222 copy
->toolkit_data
= NULL
;
223 copy
->free_toolkit_data
= False
;
228 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
233 lw_callback pre_activate_cb
;
234 lw_callback selection_cb
;
235 lw_callback post_activate_cb
;
237 widget_info
* info
= (widget_info
*)malloc (sizeof (widget_info
));
238 info
->type
= safe_strdup (type
);
239 info
->name
= safe_strdup (name
);
241 info
->val
= copy_widget_value_tree (val
, STRUCTURAL_CHANGE
);
243 info
->pre_activate_cb
= pre_activate_cb
;
244 info
->selection_cb
= selection_cb
;
245 info
->post_activate_cb
= post_activate_cb
;
246 info
->instances
= NULL
;
248 info
->next
= all_widget_info
;
249 all_widget_info
= info
;
255 free_widget_info (info
)
258 safe_free_str (info
->type
);
259 safe_free_str (info
->name
);
260 free_widget_value_tree (info
->val
);
261 memset ((void*)info
, 0xDEADBEEF, sizeof (widget_info
));
266 mark_widget_destroyed (widget
, closure
, call_data
)
271 widget_instance
* instance
= (widget_instance
*)closure
;
273 /* be very conservative */
274 if (instance
->widget
== widget
)
275 instance
->widget
= NULL
;
278 static widget_instance
*
279 allocate_widget_instance (info
, parent
, pop_up_p
)
284 widget_instance
* instance
=
285 (widget_instance
*)malloc (sizeof (widget_instance
));
286 instance
->parent
= parent
;
287 instance
->pop_up_p
= pop_up_p
;
288 instance
->info
= info
;
289 instance
->next
= info
->instances
;
290 info
->instances
= instance
;
292 instanciate_widget_instance (instance
);
294 XtAddCallback (instance
->widget
, XtNdestroyCallback
,
295 mark_widget_destroyed
, (XtPointer
)instance
);
300 free_widget_instance (instance
)
301 widget_instance
* instance
;
303 memset ((void*)instance
, 0xDEADBEEF, sizeof (widget_instance
));
308 get_widget_info (id
, remove_p
)
314 for (prev
= NULL
, info
= all_widget_info
;
316 prev
= info
, info
= info
->next
)
322 prev
->next
= info
->next
;
324 all_widget_info
= info
->next
;
331 /* Internal function used by the library dependent implementation to get the
332 widget_value for a given widget in an instance */
334 lw_get_widget_info (id
)
337 return get_widget_info (id
, 0);
340 static widget_instance
*
341 get_widget_instance (widget
, remove_p
)
346 widget_instance
* instance
;
347 widget_instance
* prev
;
348 for (info
= all_widget_info
; info
; info
= info
->next
)
349 for (prev
= NULL
, instance
= info
->instances
;
351 prev
= instance
, instance
= instance
->next
)
352 if (instance
->widget
== widget
)
357 prev
->next
= instance
->next
;
359 info
->instances
= instance
->next
;
363 return (widget_instance
*) 0;
366 static widget_instance
*
367 find_instance (id
, parent
, pop_up_p
)
372 widget_info
* info
= get_widget_info (id
, False
);
373 widget_instance
* instance
;
376 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
377 if (instance
->parent
== parent
&& instance
->pop_up_p
== pop_up_p
)
384 /* utility function for widget_value */
390 if (!!s1
^ !!s2
) return True
;
391 return (s1
&& s2
) ? strcmp (s1
, s2
) : s1
? False
: !!s2
;
399 return i1
> i2
? i1
: i2
;
404 # define EXPLAIN(name, oc, nc, desc, a1, a2) \
405 printf ("Change: \"%s\"\tmax(%s=%d,%s=%d)\t%s %d %d\n", \
407 (oc == NO_CHANGE ? "none" : \
408 (oc == INVISIBLE_CHANGE ? "invisible" : \
409 (oc == VISIBLE_CHANGE ? "visible" : \
410 (oc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
412 (nc == NO_CHANGE ? "none" : \
413 (nc == INVISIBLE_CHANGE ? "invisible" : \
414 (nc == VISIBLE_CHANGE ? "visible" : \
415 (nc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
418 # define EXPLAIN(name, oc, nc, desc, a1, a2)
422 static widget_value
*
423 merge_widget_value (val1
, val2
, level
)
429 widget_value
* merged_next
;
430 widget_value
* merged_contents
;
435 return copy_widget_value_tree (val2
, STRUCTURAL_CHANGE
);
441 free_widget_value_tree (val1
);
447 if (safe_strcmp (val1
->name
, val2
->name
))
449 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "name change",
450 val1
->name
, val2
->name
);
451 change
= max (change
, STRUCTURAL_CHANGE
);
452 safe_free_str (val1
->name
);
453 val1
->name
= safe_strdup (val2
->name
);
455 if (safe_strcmp (val1
->value
, val2
->value
))
457 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "value change",
458 val1
->value
, val2
->value
);
459 change
= max (change
, VISIBLE_CHANGE
);
460 safe_free_str (val1
->value
);
461 val1
->value
= safe_strdup (val2
->value
);
463 if (safe_strcmp (val1
->key
, val2
->key
))
465 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "key change",
466 val1
->key
, val2
->key
);
467 change
= max (change
, VISIBLE_CHANGE
);
468 safe_free_str (val1
->key
);
469 val1
->key
= safe_strdup (val2
->key
);
471 if (val1
->enabled
!= val2
->enabled
)
473 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "enablement change",
474 val1
->enabled
, val2
->enabled
);
475 change
= max (change
, VISIBLE_CHANGE
);
476 val1
->enabled
= val2
->enabled
;
478 if (val1
->selected
!= val2
->selected
)
480 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "selection change",
481 val1
->selected
, val2
->selected
);
482 change
= max (change
, VISIBLE_CHANGE
);
483 val1
->selected
= val2
->selected
;
485 if (val1
->call_data
!= val2
->call_data
)
487 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "call-data change",
488 val1
->call_data
, val2
->call_data
);
489 change
= max (change
, INVISIBLE_CHANGE
);
490 val1
->call_data
= val2
->call_data
;
496 merge_widget_value (val1
->contents
, val2
->contents
, level
- 1);
498 if (val1
->contents
&& !merged_contents
)
500 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "(contents gone)",
502 change
= max (change
, INVISIBLE_CHANGE
);
504 else if (merged_contents
&& merged_contents
->change
!= NO_CHANGE
)
506 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "(contents change)",
508 change
= max (change
, INVISIBLE_CHANGE
);
511 val1
->contents
= merged_contents
;
514 merged_next
= merge_widget_value (val1
->next
, val2
->next
, level
);
516 if (val1
->next
&& !merged_next
)
518 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "(following gone)",
520 change
= max (change
, STRUCTURAL_CHANGE
);
522 else if (merged_next
)
524 if (merged_next
->change
)
525 EXPLAIN (val1
->name
, change
, merged_next
->change
, "(following change)",
527 change
= max (change
, merged_next
->change
);
530 val1
->next
= merged_next
;
532 val1
->change
= change
;
534 if (change
> NO_CHANGE
&& val1
->toolkit_data
)
536 if (val1
->free_toolkit_data
)
537 free (val1
->toolkit_data
);
538 val1
->toolkit_data
= NULL
;
545 /* modifying the widgets */
547 name_to_widget (instance
, name
)
548 widget_instance
* instance
;
551 Widget widget
= NULL
;
553 if (!instance
->widget
)
556 if (!strcmp (XtName (instance
->widget
), name
))
557 widget
= instance
->widget
;
560 int length
= strlen (name
) + 2;
561 char* real_name
= (char *) alloca (length
);
563 strcpy (real_name
+ 1, name
);
565 widget
= XtNameToWidget (instance
->widget
, real_name
);
571 set_one_value (instance
, val
, deep_p
)
572 widget_instance
* instance
;
576 Widget widget
= name_to_widget (instance
, val
->name
);
580 #if defined (USE_LUCID)
581 if (lw_lucid_widget_p (instance
->widget
))
582 xlw_update_one_widget (instance
, widget
, val
, deep_p
);
584 #if defined (USE_MOTIF)
585 if (lw_motif_widget_p (instance
->widget
))
586 xm_update_one_widget (instance
, widget
, val
, deep_p
);
588 #if defined (USE_OLIT)
589 if (lw_olit_widget_p (instance
->widget
))
590 xol_update_one_widget (instance
, widget
, val
, deep_p
);
592 #if defined (USE_XAW)
593 if (lw_xaw_widget_p (instance
->widget
))
594 xaw_update_one_widget (instance
, widget
, val
, deep_p
);
600 update_one_widget_instance (instance
, deep_p
)
601 widget_instance
* instance
;
606 if (!instance
->widget
)
607 /* the widget was destroyed */
610 for (val
= instance
->info
->val
; val
; val
= val
->next
)
611 if (val
->change
!= NO_CHANGE
)
612 set_one_value (instance
, val
, deep_p
);
616 update_all_widget_values (info
, deep_p
)
620 widget_instance
* instance
;
623 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
624 update_one_widget_instance (instance
, deep_p
);
626 for (val
= info
->val
; val
; val
= val
->next
)
627 val
->change
= NO_CHANGE
;
631 lw_modify_all_widgets (id
, val
, deep_p
)
636 widget_info
* info
= get_widget_info (id
, False
);
637 widget_value
* new_val
;
638 widget_value
* next_new_val
;
647 for (new_val
= val
; new_val
; new_val
= new_val
->next
)
649 next_new_val
= new_val
->next
;
650 new_val
->next
= NULL
;
652 for (prev
= NULL
, cur
= info
->val
; cur
; prev
= cur
, cur
= cur
->next
)
653 if (!strcmp (cur
->name
, new_val
->name
))
658 cur
= merge_widget_value (cur
, new_val
, deep_p
? 1000 : 1);
660 prev
->next
= cur
? cur
: next
;
662 info
->val
= cur
? cur
: next
;
669 /* Could not find it, add it */
671 prev
->next
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
673 info
->val
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
675 new_val
->next
= next_new_val
;
678 update_all_widget_values (info
, deep_p
);
682 /* creating the widgets */
685 initialize_widget_instance (instance
)
686 widget_instance
* instance
;
690 for (val
= instance
->info
->val
; val
; val
= val
->next
)
691 val
->change
= STRUCTURAL_CHANGE
;
693 update_one_widget_instance (instance
, True
);
695 for (val
= instance
->info
->val
; val
; val
= val
->next
)
696 val
->change
= NO_CHANGE
;
700 static widget_creation_function
701 find_in_table (type
, table
)
703 widget_creation_entry
* table
;
705 widget_creation_entry
* cur
;
706 for (cur
= table
; cur
->type
; cur
++)
707 if (!my_strcasecmp (type
, cur
->type
))
708 return cur
->function
;
716 /* return True if name matches [EILPQeilpq][1-9][Bb] or
717 [EILPQeilpq][1-9][Bb][Rr][1-9] */
723 case 'E': case 'I': case 'L': case 'P': case 'Q':
724 case 'e': case 'i': case 'l': case 'p': case 'q':
725 if (name
[1] >= '0' && name
[1] <= '9')
727 if (name
[2] != 'B' && name
[2] != 'b')
731 if ((name
[3] == 'T' || name
[3] == 't') && !name
[4])
733 if ((name
[3] == 'R' || name
[3] == 'r')
734 && name
[4] >= '0' && name
[4] <= '9' && !name
[5])
747 instanciate_widget_instance (instance
)
748 widget_instance
* instance
;
750 widget_creation_function function
= NULL
;
752 #if defined (USE_LUCID)
754 function
= find_in_table (instance
->info
->type
, xlw_creation_table
);
756 #if defined(USE_MOTIF)
758 function
= find_in_table (instance
->info
->type
, xm_creation_table
);
760 #if defined (USE_OLIT)
762 function
= find_in_table (instance
->info
->type
, xol_creation_table
);
764 #if defined (USE_XAW)
766 function
= find_in_table (instance
->info
->type
, xaw_creation_table
);
771 if (dialog_spec_p (instance
->info
->type
))
773 #if defined (USE_LUCID)
776 #if defined(USE_MOTIF)
778 function
= xm_create_dialog
;
780 #if defined (USE_XAW)
782 function
= xaw_create_dialog
;
784 #if defined (USE_OLIT)
792 printf ("No creation function for widget type %s\n",
793 instance
->info
->type
);
797 instance
->widget
= (*function
) (instance
);
799 if (!instance
->widget
)
802 /* XtRealizeWidget (instance->widget);*/
806 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
811 lw_callback pre_activate_cb
;
812 lw_callback selection_cb
;
813 lw_callback post_activate_cb
;
815 if (!get_widget_info (id
, False
))
816 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
821 lw_get_widget (id
, parent
, pop_up_p
)
826 widget_instance
* instance
;
828 instance
= find_instance (id
, parent
, pop_up_p
);
829 return instance
? instance
->widget
: NULL
;
833 lw_make_widget (id
, parent
, pop_up_p
)
838 widget_instance
* instance
;
841 instance
= find_instance (id
, parent
, pop_up_p
);
844 info
= get_widget_info (id
, False
);
847 instance
= allocate_widget_instance (info
, parent
, pop_up_p
);
848 initialize_widget_instance (instance
);
850 if (!instance
->widget
)
852 return instance
->widget
;
856 lw_create_widget (type
, name
, id
, val
, parent
, pop_up_p
, pre_activate_cb
, selection_cb
, post_activate_cb
)
863 lw_callback pre_activate_cb
;
864 lw_callback selection_cb
;
865 lw_callback post_activate_cb
;
867 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
869 return lw_make_widget (id
, parent
, pop_up_p
);
873 /* destroying the widgets */
875 destroy_one_instance (instance
)
876 widget_instance
* instance
;
878 /* Remove the destroy callback on the widget; that callback will try to
879 dereference the instance object (to set its widget slot to 0, since the
880 widget is dead.) Since the instance is now dead, we don't have to worry
881 about the fact that its widget is dead too.
883 This happens in the Phase2Destroy of the widget, so this callback would
884 not have been run until arbitrarily long after the instance was freed.
886 if (instance
->widget
)
887 XtRemoveCallback (instance
->widget
, XtNdestroyCallback
,
888 mark_widget_destroyed
, (XtPointer
)instance
);
890 if (instance
->widget
)
892 /* The else are pretty tricky here, including the empty statement
893 at the end because it would be very bad to destroy a widget
895 #if defined (USE_LUCID)
896 if (lw_lucid_widget_p (instance
->widget
))
897 xlw_destroy_instance (instance
);
900 #if defined (USE_MOTIF)
901 if (lw_motif_widget_p (instance
->widget
))
902 xm_destroy_instance (instance
);
905 #if defined (USE_OLIT)
906 if (lw_olit_widget_p (instance
->widget
))
907 xol_destroy_instance (instance
);
910 #if defined (USE_XAW)
911 if (lw_xaw_widget_p (instance
->widget
))
912 xaw_destroy_instance (instance
);
915 /* do not remove the empty statement */
919 free_widget_instance (instance
);
923 lw_destroy_widget (w
)
926 widget_instance
* instance
= get_widget_instance (w
, True
);
930 widget_info
*info
= instance
->info
;
931 /* instance has already been removed from the list; free it */
932 destroy_one_instance (instance
);
933 /* if there are no instances left, free the info too */
934 if (!info
->instances
)
935 lw_destroy_all_widgets (info
->id
);
940 lw_destroy_all_widgets (id
)
943 widget_info
* info
= get_widget_info (id
, True
);
944 widget_instance
* instance
;
945 widget_instance
* next
;
949 for (instance
= info
->instances
; instance
; )
951 next
= instance
->next
;
952 destroy_one_instance (instance
);
955 free_widget_info (info
);
960 lw_destroy_everything ()
962 while (all_widget_info
)
963 lw_destroy_all_widgets (all_widget_info
->id
);
967 lw_destroy_all_pop_ups ()
971 widget_instance
* instance
;
973 for (info
= all_widget_info
; info
; info
= next
)
976 instance
= info
->instances
;
977 if (instance
&& instance
->pop_up_p
)
978 lw_destroy_all_widgets (info
->id
);
983 extern Widget
first_child (Widget
); /* garbage */
987 lw_raise_all_pop_up_widgets ()
990 widget_instance
* instance
;
991 Widget result
= NULL
;
993 for (info
= all_widget_info
; info
; info
= info
->next
)
994 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
995 if (instance
->pop_up_p
)
997 Widget widget
= instance
->widget
;
1000 if (XtIsManaged (widget
)
1002 /* What a complete load of crap!!!!
1003 When a dialogShell is on the screen, it is not managed!
1005 || (lw_motif_widget_p (instance
->widget
) &&
1006 XtIsManaged (first_child (widget
)))
1012 XMapRaised (XtDisplay (widget
), XtWindow (widget
));
1020 lw_pop_all_widgets (id
, up
)
1024 widget_info
* info
= get_widget_info (id
, False
);
1025 widget_instance
* instance
;
1028 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1029 if (instance
->pop_up_p
&& instance
->widget
)
1031 #if defined (USE_LUCID)
1032 if (lw_lucid_widget_p (instance
->widget
))
1034 XtRealizeWidget (instance
->widget
);
1035 xlw_pop_instance (instance
, up
);
1038 #if defined (USE_MOTIF)
1039 if (lw_motif_widget_p (instance
->widget
))
1041 XtRealizeWidget (instance
->widget
);
1042 xm_pop_instance (instance
, up
);
1045 #if defined (USE_OLIT)
1046 if (lw_olit_widget_p (instance
->widget
))
1048 XtRealizeWidget (instance
->widget
);
1049 xol_pop_instance (instance
, up
);
1052 #if defined (USE_XAW)
1053 if (lw_xaw_widget_p (instance
->widget
))
1055 XtRealizeWidget (XtParent (instance
->widget
));
1056 XtRealizeWidget (instance
->widget
);
1057 xaw_pop_instance (instance
, up
);
1064 lw_pop_up_all_widgets (id
)
1067 lw_pop_all_widgets (id
, True
);
1071 lw_pop_down_all_widgets (id
)
1074 lw_pop_all_widgets (id
, False
);
1078 lw_popup_menu (widget
)
1081 #if defined (USE_LUCID)
1082 if (lw_lucid_widget_p (widget
))
1083 xlw_popup_menu (widget
);
1085 #if defined (USE_MOTIF)
1086 if (lw_motif_widget_p (widget
))
1087 xm_popup_menu (widget
);
1089 #if defined (USE_OLIT)
1090 if (lw_olit_widget_p (widget
))
1091 xol_popup_menu (widget
);
1093 #if defined (USE_XAW)
1094 if (lw_xaw_widget_p (widget
))
1095 xaw_popup_menu (widget
);
1099 \f/* get the values back */
1101 get_one_value (instance
, val
)
1102 widget_instance
* instance
;
1105 Widget widget
= name_to_widget (instance
, val
->name
);
1109 #if defined (USE_LUCID)
1110 if (lw_lucid_widget_p (instance
->widget
))
1111 xlw_update_one_value (instance
, widget
, val
);
1113 #if defined (USE_MOTIF)
1114 if (lw_motif_widget_p (instance
->widget
))
1115 xm_update_one_value (instance
, widget
, val
);
1117 #if defined (USE_OLIT)
1118 if (lw_olit_widget_p (instance
->widget
))
1119 xol_update_one_value (instance
, widget
, val
);
1121 #if defined (USE_XAW)
1122 if (lw_xaw_widget_p (instance
->widget
))
1123 xaw_update_one_value (instance
, widget
, val
);
1132 lw_get_some_values (id
, val_out
)
1134 widget_value
* val_out
;
1136 widget_info
* info
= get_widget_info (id
, False
);
1137 widget_instance
* instance
;
1139 Boolean result
= False
;
1144 instance
= info
->instances
;
1148 for (val
= val_out
; val
; val
= val
->next
)
1149 if (get_one_value (instance
, val
))
1156 lw_get_all_values (id
)
1159 widget_info
* info
= get_widget_info (id
, False
);
1160 widget_value
* val
= info
->val
;
1161 if (lw_get_some_values (id
, val
))
1167 /* internal function used by the library dependent implementation to get the
1168 widget_value for a given widget in an instance */
1170 lw_get_widget_value_for_widget (instance
, w
)
1171 widget_instance
* instance
;
1174 char* name
= XtName (w
);
1176 for (cur
= instance
->info
->val
; cur
; cur
= cur
->next
)
1177 if (!strcmp (cur
->name
, name
))
1182 \f/* update other instances value when one thing changed */
1183 /* This function can be used as a an XtCallback for the widgets that get
1184 modified to update other instances of the widgets. Closure should be the
1187 lw_internal_update_other_instances (widget
, closure
, call_data
)
1190 XtPointer call_data
;
1192 /* To forbid recursive calls */
1193 static Boolean updating
;
1195 widget_instance
* instance
= (widget_instance
*)closure
;
1196 char* name
= XtName (widget
);
1198 widget_instance
* cur
;
1201 /* never recurse as this could cause infinite recursions. */
1205 /* protect against the widget being destroyed */
1206 if (XtWidgetBeingDestroyedP (widget
))
1209 /* Return immediately if there are no other instances */
1210 info
= instance
->info
;
1211 if (!info
->instances
->next
)
1216 for (val
= info
->val
; val
&& strcmp (val
->name
, name
); val
= val
->next
);
1218 if (val
&& get_one_value (instance
, val
))
1219 for (cur
= info
->instances
; cur
; cur
= cur
->next
)
1220 if (cur
!= instance
)
1221 set_one_value (cur
, val
, True
);
1230 lw_get_widget_id (w
)
1233 widget_instance
* instance
= get_widget_instance (w
, False
);
1235 return instance
? instance
->info
->id
: 0;
1238 \f/* set the keyboard focus */
1240 lw_set_keyboard_focus (parent
, w
)
1244 #if defined (USE_MOTIF)
1245 xm_set_keyboard_focus (parent
, w
);
1247 XtSetKeyboardFocus (parent
, w
);
1253 show_one_widget_busy (w
, flag
)
1257 Pixel foreground
= 0;
1258 Pixel background
= 1;
1259 Widget widget_to_invert
= XtNameToWidget (w
, "*sheet");
1260 if (!widget_to_invert
)
1261 widget_to_invert
= w
;
1263 XtVaGetValues (widget_to_invert
,
1264 XtNforeground
, &foreground
,
1265 XtNbackground
, &background
,
1267 XtVaSetValues (widget_to_invert
,
1268 XtNforeground
, background
,
1269 XtNbackground
, foreground
,
1274 lw_show_busy (w
, busy
)
1278 widget_instance
* instance
= get_widget_instance (w
, False
);
1280 widget_instance
* next
;
1284 info
= instance
->info
;
1285 if (info
->busy
!= busy
)
1287 for (next
= info
->instances
; next
; next
= next
->next
)
1289 show_one_widget_busy (next
->widget
, busy
);