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, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 #undef __STRICT_BSD__ /* ick */
25 #include <sys/types.h>
28 #include "lwlib-int.h"
29 #include "lwlib-utils.h"
30 #include <X11/StringDefs.h>
35 extern long *xmalloc();
38 #if defined (USE_LUCID)
39 #include "lwlib-Xlw.h"
41 #if defined (USE_MOTIF)
43 #else /* not USE_MOTIF */
44 #if defined (USE_LUCID)
46 #endif /* not USE_MOTIF && USE_LUCID */
48 #if defined (USE_OLIT)
49 #include "lwlib-Xol.h"
52 #include "lwlib-Xaw.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
.
64 #define max(x, y) ((x) > (y) ? (x) : (y))
67 /* List of all widgets managed by the library. */
69 all_widget_info
= NULL
;
72 char *lwlib_toolkit_type
= "motif";
74 char *lwlib_toolkit_type
= "lucid";
76 \f/* Forward declarations */
78 instantiate_widget_instance (/* widget_instance* instance */);
80 lwlib_memset (address
, value
, length
)
87 for (i
= 0; i
< length
; i
++)
91 lwlib_bcopy (from
, to
, length
)
98 for (i
= 0; i
< length
; i
++)
101 \f/* utility functions for widget_instance and widget_info */
108 result
= (char *) malloc (strlen (s
) + 1);
115 /* Like strcmp but ignore differences in case. */
118 my_strcasecmp (s1
, s2
)
130 return (c1
> c2
? 1 : -1);
143 static widget_value
*widget_value_free_list
= 0;
144 static int malloc_cpt
= 0;
147 malloc_widget_value ()
150 if (widget_value_free_list
)
152 wv
= widget_value_free_list
;
153 widget_value_free_list
= wv
->free_list
;
158 wv
= (widget_value
*) malloc (sizeof (widget_value
));
161 lwlib_memset (wv
, 0, sizeof (widget_value
));
165 /* this is analogous to free(). It frees only what was allocated
166 by malloc_widget_value(), and no substructures.
169 free_widget_value (wv
)
177 /* When the number of already allocated cells is too big,
184 wv
->free_list
= widget_value_free_list
;
185 widget_value_free_list
= wv
;
190 free_widget_value_tree (wv
)
196 if (wv
->name
) free (wv
->name
);
197 if (wv
->value
) free (wv
->value
);
198 if (wv
->key
) free (wv
->key
);
200 wv
->name
= wv
->value
= wv
->key
= (char *) 0xDEADBEEF;
202 if (wv
->toolkit_data
&& wv
->free_toolkit_data
)
204 XtFree (wv
->toolkit_data
);
205 wv
->toolkit_data
= (void *) 0xDEADBEEF;
208 if (wv
->contents
&& (wv
->contents
!= (widget_value
*)1))
210 free_widget_value_tree (wv
->contents
);
211 wv
->contents
= (widget_value
*) 0xDEADBEEF;
215 free_widget_value_tree (wv
->next
);
216 wv
->next
= (widget_value
*) 0xDEADBEEF;
218 free_widget_value (wv
);
221 static widget_value
*
222 copy_widget_value_tree (val
, change
)
230 if (val
== (widget_value
*) 1)
233 copy
= malloc_widget_value ();
234 copy
->name
= safe_strdup (val
->name
);
235 copy
->value
= safe_strdup (val
->value
);
236 copy
->key
= safe_strdup (val
->key
);
237 copy
->enabled
= val
->enabled
;
238 copy
->selected
= val
->selected
;
239 copy
->edited
= False
;
240 copy
->change
= change
;
241 copy
->this_one_change
= change
;
242 copy
->contents
= copy_widget_value_tree (val
->contents
, change
);
243 copy
->call_data
= val
->call_data
;
244 copy
->next
= copy_widget_value_tree (val
->next
, change
);
245 copy
->toolkit_data
= NULL
;
246 copy
->free_toolkit_data
= False
;
251 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
256 lw_callback pre_activate_cb
;
257 lw_callback selection_cb
;
258 lw_callback post_activate_cb
;
260 widget_info
* info
= (widget_info
*)malloc (sizeof (widget_info
));
261 info
->type
= safe_strdup (type
);
262 info
->name
= safe_strdup (name
);
264 info
->val
= copy_widget_value_tree (val
, STRUCTURAL_CHANGE
);
266 info
->pre_activate_cb
= pre_activate_cb
;
267 info
->selection_cb
= selection_cb
;
268 info
->post_activate_cb
= post_activate_cb
;
269 info
->instances
= NULL
;
271 info
->next
= all_widget_info
;
272 all_widget_info
= info
;
278 free_widget_info (info
)
281 safe_free_str (info
->type
);
282 safe_free_str (info
->name
);
283 free_widget_value_tree (info
->val
);
284 lwlib_memset ((void*)info
, 0xDEADBEEF, sizeof (widget_info
));
289 mark_widget_destroyed (widget
, closure
, call_data
)
294 widget_instance
* instance
= (widget_instance
*)closure
;
296 /* be very conservative */
297 if (instance
->widget
== widget
)
298 instance
->widget
= NULL
;
301 static widget_instance
*
302 allocate_widget_instance (info
, parent
, pop_up_p
)
307 widget_instance
* instance
=
308 (widget_instance
*)malloc (sizeof (widget_instance
));
309 instance
->parent
= parent
;
310 instance
->pop_up_p
= pop_up_p
;
311 instance
->info
= info
;
312 instance
->next
= info
->instances
;
313 info
->instances
= instance
;
315 instantiate_widget_instance (instance
);
317 XtAddCallback (instance
->widget
, XtNdestroyCallback
,
318 mark_widget_destroyed
, (XtPointer
)instance
);
323 free_widget_instance (instance
)
324 widget_instance
* instance
;
326 lwlib_memset ((void*)instance
, 0xDEADBEEF, sizeof (widget_instance
));
331 get_widget_info (id
, remove_p
)
337 for (prev
= NULL
, info
= all_widget_info
;
339 prev
= info
, info
= info
->next
)
345 prev
->next
= info
->next
;
347 all_widget_info
= info
->next
;
354 /* Internal function used by the library dependent implementation to get the
355 widget_value for a given widget in an instance */
357 lw_get_widget_info (id
)
360 return get_widget_info (id
, 0);
363 static widget_instance
*
364 get_widget_instance (widget
, remove_p
)
369 widget_instance
* instance
;
370 widget_instance
* prev
;
371 for (info
= all_widget_info
; info
; info
= info
->next
)
372 for (prev
= NULL
, instance
= info
->instances
;
374 prev
= instance
, instance
= instance
->next
)
375 if (instance
->widget
== widget
)
380 prev
->next
= instance
->next
;
382 info
->instances
= instance
->next
;
386 return (widget_instance
*) 0;
389 static widget_instance
*
390 find_instance (id
, parent
, pop_up_p
)
395 widget_info
* info
= get_widget_info (id
, False
);
396 widget_instance
* instance
;
399 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
400 if (instance
->parent
== parent
&& instance
->pop_up_p
== pop_up_p
)
407 /* utility function for widget_value */
413 if (!!s1
^ !!s2
) return True
;
414 return (s1
&& s2
) ? strcmp (s1
, s2
) : s1
? False
: !!s2
;
419 # define EXPLAIN(name, oc, nc, desc, a1, a2) \
420 printf ("Change: \"%s\"\tmax(%s=%d,%s=%d)\t%s %d %d\n", \
422 (oc == NO_CHANGE ? "none" : \
423 (oc == INVISIBLE_CHANGE ? "invisible" : \
424 (oc == VISIBLE_CHANGE ? "visible" : \
425 (oc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
427 (nc == NO_CHANGE ? "none" : \
428 (nc == INVISIBLE_CHANGE ? "invisible" : \
429 (nc == VISIBLE_CHANGE ? "visible" : \
430 (nc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
433 # define EXPLAIN(name, oc, nc, desc, a1, a2)
437 static widget_value
*
438 merge_widget_value (val1
, val2
, level
)
443 change_type change
, this_one_change
;
444 widget_value
* merged_next
;
445 widget_value
* merged_contents
;
450 return copy_widget_value_tree (val2
, STRUCTURAL_CHANGE
);
456 free_widget_value_tree (val1
);
462 if (safe_strcmp (val1
->name
, val2
->name
))
464 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "name change",
465 val1
->name
, val2
->name
);
466 change
= max (change
, STRUCTURAL_CHANGE
);
467 safe_free_str (val1
->name
);
468 val1
->name
= safe_strdup (val2
->name
);
470 if (safe_strcmp (val1
->value
, val2
->value
))
472 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "value change",
473 val1
->value
, val2
->value
);
474 change
= max (change
, VISIBLE_CHANGE
);
475 safe_free_str (val1
->value
);
476 val1
->value
= safe_strdup (val2
->value
);
478 if (safe_strcmp (val1
->key
, val2
->key
))
480 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "key change",
481 val1
->key
, val2
->key
);
482 change
= max (change
, VISIBLE_CHANGE
);
483 safe_free_str (val1
->key
);
484 val1
->key
= safe_strdup (val2
->key
);
486 if (val1
->enabled
!= val2
->enabled
)
488 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "enablement change",
489 val1
->enabled
, val2
->enabled
);
490 change
= max (change
, VISIBLE_CHANGE
);
491 val1
->enabled
= val2
->enabled
;
493 if (val1
->selected
!= val2
->selected
)
495 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "selection change",
496 val1
->selected
, val2
->selected
);
497 change
= max (change
, VISIBLE_CHANGE
);
498 val1
->selected
= val2
->selected
;
500 if (val1
->call_data
!= val2
->call_data
)
502 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "call-data change",
503 val1
->call_data
, val2
->call_data
);
504 change
= max (change
, INVISIBLE_CHANGE
);
505 val1
->call_data
= val2
->call_data
;
511 merge_widget_value (val1
->contents
, val2
->contents
, level
- 1);
513 if (val1
->contents
&& !merged_contents
)
515 /* This used to say INVISIBLE_CHANGE,
516 but it is visible and vitally important when
517 the contents of the menu bar itself are entirely deleted.
519 But maybe it doesn't matter. This fails to fix the bug. */
520 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "(contents gone)",
522 change
= max (change
, STRUCTURAL_CHANGE
);
524 else if (merged_contents
&& merged_contents
->change
!= NO_CHANGE
)
526 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "(contents change)",
528 change
= max (change
, INVISIBLE_CHANGE
);
531 val1
->contents
= merged_contents
;
534 this_one_change
= change
;
536 merged_next
= merge_widget_value (val1
->next
, val2
->next
, level
);
538 if (val1
->next
&& !merged_next
)
540 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "(following gone)",
542 change
= max (change
, STRUCTURAL_CHANGE
);
544 else if (merged_next
)
546 if (merged_next
->change
)
547 EXPLAIN (val1
->name
, change
, merged_next
->change
, "(following change)",
549 change
= max (change
, merged_next
->change
);
552 val1
->next
= merged_next
;
554 val1
->this_one_change
= this_one_change
;
555 val1
->change
= change
;
557 if (change
> NO_CHANGE
&& val1
->toolkit_data
)
559 if (val1
->free_toolkit_data
)
560 XtFree (val1
->toolkit_data
);
561 val1
->toolkit_data
= NULL
;
568 /* modifying the widgets */
570 name_to_widget (instance
, name
)
571 widget_instance
* instance
;
574 Widget widget
= NULL
;
576 if (!instance
->widget
)
579 if (!strcmp (XtName (instance
->widget
), name
))
580 widget
= instance
->widget
;
583 int length
= strlen (name
) + 2;
584 char* real_name
= (char *) xmalloc (length
);
586 strcpy (real_name
+ 1, name
);
588 widget
= XtNameToWidget (instance
->widget
, real_name
);
596 set_one_value (instance
, val
, deep_p
)
597 widget_instance
* instance
;
601 Widget widget
= name_to_widget (instance
, val
->name
);
605 #if defined (USE_LUCID)
606 if (lw_lucid_widget_p (instance
->widget
))
607 xlw_update_one_widget (instance
, widget
, val
, deep_p
);
609 #if defined (USE_MOTIF)
610 if (lw_motif_widget_p (instance
->widget
))
611 xm_update_one_widget (instance
, widget
, val
, deep_p
);
613 #if defined (USE_OLIT)
614 if (lw_olit_widget_p (instance
->widget
))
615 xol_update_one_widget (instance
, widget
, val
, deep_p
);
617 #if defined (USE_XAW)
618 if (lw_xaw_widget_p (instance
->widget
))
619 xaw_update_one_widget (instance
, widget
, val
, deep_p
);
625 update_one_widget_instance (instance
, deep_p
)
626 widget_instance
* instance
;
631 if (!instance
->widget
)
632 /* the widget was destroyed */
635 for (val
= instance
->info
->val
; val
; val
= val
->next
)
636 if (val
->change
!= NO_CHANGE
)
637 set_one_value (instance
, val
, deep_p
);
641 update_all_widget_values (info
, deep_p
)
645 widget_instance
* instance
;
648 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
649 update_one_widget_instance (instance
, deep_p
);
651 for (val
= info
->val
; val
; val
= val
->next
)
652 val
->change
= NO_CHANGE
;
656 lw_modify_all_widgets (id
, val
, deep_p
)
661 widget_info
* info
= get_widget_info (id
, False
);
662 widget_value
* new_val
;
663 widget_value
* next_new_val
;
672 for (new_val
= val
; new_val
; new_val
= new_val
->next
)
674 next_new_val
= new_val
->next
;
675 new_val
->next
= NULL
;
677 for (prev
= NULL
, cur
= info
->val
; cur
; prev
= cur
, cur
= cur
->next
)
678 if (!strcmp (cur
->name
, new_val
->name
))
683 cur
= merge_widget_value (cur
, new_val
, deep_p
? 1000 : 1);
685 prev
->next
= cur
? cur
: next
;
687 info
->val
= cur
? cur
: next
;
694 /* Could not find it, add it */
696 prev
->next
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
698 info
->val
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
700 new_val
->next
= next_new_val
;
703 update_all_widget_values (info
, deep_p
);
707 /* creating the widgets */
710 initialize_widget_instance (instance
)
711 widget_instance
* instance
;
715 for (val
= instance
->info
->val
; val
; val
= val
->next
)
716 val
->change
= STRUCTURAL_CHANGE
;
718 update_one_widget_instance (instance
, True
);
720 for (val
= instance
->info
->val
; val
; val
= val
->next
)
721 val
->change
= NO_CHANGE
;
725 static widget_creation_function
726 find_in_table (type
, table
)
728 widget_creation_entry
* table
;
730 widget_creation_entry
* cur
;
731 for (cur
= table
; cur
->type
; cur
++)
732 if (!my_strcasecmp (type
, cur
->type
))
733 return cur
->function
;
741 /* return True if name matches [EILPQeilpq][1-9][Bb] or
742 [EILPQeilpq][1-9][Bb][Rr][1-9] */
748 case 'E': case 'I': case 'L': case 'P': case 'Q':
749 case 'e': case 'i': case 'l': case 'p': case 'q':
750 if (name
[1] >= '0' && name
[1] <= '9')
752 if (name
[2] != 'B' && name
[2] != 'b')
756 if ((name
[3] == 'T' || name
[3] == 't') && !name
[4])
758 if ((name
[3] == 'R' || name
[3] == 'r')
759 && name
[4] >= '0' && name
[4] <= '9' && !name
[5])
772 instantiate_widget_instance (instance
)
773 widget_instance
* instance
;
775 widget_creation_function function
= NULL
;
777 #if defined (USE_LUCID)
779 function
= find_in_table (instance
->info
->type
, xlw_creation_table
);
781 #if defined(USE_MOTIF)
783 function
= find_in_table (instance
->info
->type
, xm_creation_table
);
785 #if defined (USE_OLIT)
787 function
= find_in_table (instance
->info
->type
, xol_creation_table
);
789 #if defined (USE_XAW)
791 function
= find_in_table (instance
->info
->type
, xaw_creation_table
);
796 if (dialog_spec_p (instance
->info
->type
))
798 #if defined (USE_LUCID)
801 #if defined(USE_MOTIF)
803 function
= xm_create_dialog
;
805 #if defined (USE_XAW)
807 function
= xaw_create_dialog
;
809 #if defined (USE_OLIT)
817 printf ("No creation function for widget type %s\n",
818 instance
->info
->type
);
822 instance
->widget
= (*function
) (instance
);
824 if (!instance
->widget
)
827 /* XtRealizeWidget (instance->widget);*/
831 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
836 lw_callback pre_activate_cb
;
837 lw_callback selection_cb
;
838 lw_callback post_activate_cb
;
840 if (!get_widget_info (id
, False
))
841 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
846 lw_get_widget (id
, parent
, pop_up_p
)
851 widget_instance
* instance
;
853 instance
= find_instance (id
, parent
, pop_up_p
);
854 return instance
? instance
->widget
: NULL
;
858 lw_make_widget (id
, parent
, pop_up_p
)
863 widget_instance
* instance
;
866 instance
= find_instance (id
, parent
, pop_up_p
);
869 info
= get_widget_info (id
, False
);
872 instance
= allocate_widget_instance (info
, parent
, pop_up_p
);
873 initialize_widget_instance (instance
);
875 if (!instance
->widget
)
877 return instance
->widget
;
881 lw_create_widget (type
, name
, id
, val
, parent
, pop_up_p
, pre_activate_cb
, selection_cb
, post_activate_cb
)
888 lw_callback pre_activate_cb
;
889 lw_callback selection_cb
;
890 lw_callback post_activate_cb
;
892 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
894 return lw_make_widget (id
, parent
, pop_up_p
);
898 /* destroying the widgets */
900 destroy_one_instance (instance
)
901 widget_instance
* instance
;
903 /* Remove the destroy callback on the widget; that callback will try to
904 dereference the instance object (to set its widget slot to 0, since the
905 widget is dead.) Since the instance is now dead, we don't have to worry
906 about the fact that its widget is dead too.
908 This happens in the Phase2Destroy of the widget, so this callback would
909 not have been run until arbitrarily long after the instance was freed.
911 if (instance
->widget
)
912 XtRemoveCallback (instance
->widget
, XtNdestroyCallback
,
913 mark_widget_destroyed
, (XtPointer
)instance
);
915 if (instance
->widget
)
917 /* The else are pretty tricky here, including the empty statement
918 at the end because it would be very bad to destroy a widget
920 #if defined (USE_LUCID)
921 if (lw_lucid_widget_p (instance
->widget
))
922 xlw_destroy_instance (instance
);
925 #if defined (USE_MOTIF)
926 if (lw_motif_widget_p (instance
->widget
))
927 xm_destroy_instance (instance
);
930 #if defined (USE_OLIT)
931 if (lw_olit_widget_p (instance
->widget
))
932 xol_destroy_instance (instance
);
935 #if defined (USE_XAW)
936 if (lw_xaw_widget_p (instance
->widget
))
937 xaw_destroy_instance (instance
);
940 /* do not remove the empty statement */
944 free_widget_instance (instance
);
948 lw_destroy_widget (w
)
951 widget_instance
* instance
= get_widget_instance (w
, True
);
955 widget_info
*info
= instance
->info
;
956 /* instance has already been removed from the list; free it */
957 destroy_one_instance (instance
);
958 /* if there are no instances left, free the info too */
959 if (!info
->instances
)
960 lw_destroy_all_widgets (info
->id
);
965 lw_destroy_all_widgets (id
)
968 widget_info
* info
= get_widget_info (id
, True
);
969 widget_instance
* instance
;
970 widget_instance
* next
;
974 for (instance
= info
->instances
; instance
; )
976 next
= instance
->next
;
977 destroy_one_instance (instance
);
980 free_widget_info (info
);
985 lw_destroy_everything ()
987 while (all_widget_info
)
988 lw_destroy_all_widgets (all_widget_info
->id
);
992 lw_destroy_all_pop_ups ()
996 widget_instance
* instance
;
998 for (info
= all_widget_info
; info
; info
= next
)
1001 instance
= info
->instances
;
1002 if (instance
&& instance
->pop_up_p
)
1003 lw_destroy_all_widgets (info
->id
);
1008 extern Widget
first_child (/* Widget */); /* garbage */
1012 lw_raise_all_pop_up_widgets ()
1015 widget_instance
* instance
;
1016 Widget result
= NULL
;
1018 for (info
= all_widget_info
; info
; info
= info
->next
)
1019 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1020 if (instance
->pop_up_p
)
1022 Widget widget
= instance
->widget
;
1025 if (XtIsManaged (widget
)
1027 /* What a complete load of crap!!!!
1028 When a dialogShell is on the screen, it is not managed!
1030 || (lw_motif_widget_p (instance
->widget
) &&
1031 XtIsManaged (first_child (widget
)))
1037 XMapRaised (XtDisplay (widget
), XtWindow (widget
));
1045 lw_pop_all_widgets (id
, up
)
1049 widget_info
* info
= get_widget_info (id
, False
);
1050 widget_instance
* instance
;
1053 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1054 if (instance
->pop_up_p
&& instance
->widget
)
1056 #if defined (USE_LUCID)
1057 if (lw_lucid_widget_p (instance
->widget
))
1059 XtRealizeWidget (instance
->widget
);
1060 xlw_pop_instance (instance
, up
);
1063 #if defined (USE_MOTIF)
1064 if (lw_motif_widget_p (instance
->widget
))
1066 XtRealizeWidget (instance
->widget
);
1067 xm_pop_instance (instance
, up
);
1070 #if defined (USE_OLIT)
1071 if (lw_olit_widget_p (instance
->widget
))
1073 XtRealizeWidget (instance
->widget
);
1074 xol_pop_instance (instance
, up
);
1077 #if defined (USE_XAW)
1078 if (lw_xaw_widget_p (instance
->widget
))
1080 XtRealizeWidget (XtParent (instance
->widget
));
1081 XtRealizeWidget (instance
->widget
);
1082 xaw_pop_instance (instance
, up
);
1089 lw_pop_up_all_widgets (id
)
1092 lw_pop_all_widgets (id
, True
);
1096 lw_pop_down_all_widgets (id
)
1099 lw_pop_all_widgets (id
, False
);
1103 lw_popup_menu (widget
, event
)
1107 #if defined (USE_LUCID)
1108 if (lw_lucid_widget_p (widget
))
1109 xlw_popup_menu (widget
, event
);
1111 #if defined (USE_MOTIF)
1112 if (lw_motif_widget_p (widget
))
1113 xm_popup_menu (widget
, event
);
1115 #if defined (USE_OLIT)
1116 if (lw_olit_widget_p (widget
))
1117 xol_popup_menu (widget
, event
);
1119 #if defined (USE_XAW)
1120 if (lw_xaw_widget_p (widget
))
1121 xaw_popup_menu (widget
, event
);
1125 \f/* get the values back */
1127 get_one_value (instance
, val
)
1128 widget_instance
* instance
;
1131 Widget widget
= name_to_widget (instance
, val
->name
);
1135 #if defined (USE_LUCID)
1136 if (lw_lucid_widget_p (instance
->widget
))
1137 xlw_update_one_value (instance
, widget
, val
);
1139 #if defined (USE_MOTIF)
1140 if (lw_motif_widget_p (instance
->widget
))
1141 xm_update_one_value (instance
, widget
, val
);
1143 #if defined (USE_OLIT)
1144 if (lw_olit_widget_p (instance
->widget
))
1145 xol_update_one_value (instance
, widget
, val
);
1147 #if defined (USE_XAW)
1148 if (lw_xaw_widget_p (instance
->widget
))
1149 xaw_update_one_value (instance
, widget
, val
);
1158 lw_get_some_values (id
, val_out
)
1160 widget_value
* val_out
;
1162 widget_info
* info
= get_widget_info (id
, False
);
1163 widget_instance
* instance
;
1165 Boolean result
= False
;
1170 instance
= info
->instances
;
1174 for (val
= val_out
; val
; val
= val
->next
)
1175 if (get_one_value (instance
, val
))
1182 lw_get_all_values (id
)
1185 widget_info
* info
= get_widget_info (id
, False
);
1186 widget_value
* val
= info
->val
;
1187 if (lw_get_some_values (id
, val
))
1193 /* internal function used by the library dependent implementation to get the
1194 widget_value for a given widget in an instance */
1196 lw_get_widget_value_for_widget (instance
, w
)
1197 widget_instance
* instance
;
1200 char* name
= XtName (w
);
1202 for (cur
= instance
->info
->val
; cur
; cur
= cur
->next
)
1203 if (!strcmp (cur
->name
, name
))
1208 \f/* update other instances value when one thing changed */
1210 /* To forbid recursive calls */
1211 static Boolean lwlib_updating
;
1213 /* This function can be used as a an XtCallback for the widgets that get
1214 modified to update other instances of the widgets. Closure should be the
1217 lw_internal_update_other_instances (widget
, closure
, call_data
)
1220 XtPointer call_data
;
1222 widget_instance
* instance
= (widget_instance
*)closure
;
1223 char* name
= XtName (widget
);
1225 widget_instance
* cur
;
1228 /* Avoid possibly infinite recursion. */
1232 /* protect against the widget being destroyed */
1233 if (XtWidgetBeingDestroyedP (widget
))
1236 /* Return immediately if there are no other instances */
1237 info
= instance
->info
;
1238 if (!info
->instances
->next
)
1241 lwlib_updating
= True
;
1243 for (val
= info
->val
; val
&& strcmp (val
->name
, name
); val
= val
->next
);
1245 if (val
&& get_one_value (instance
, val
))
1246 for (cur
= info
->instances
; cur
; cur
= cur
->next
)
1247 if (cur
!= instance
)
1248 set_one_value (cur
, val
, True
);
1250 lwlib_updating
= False
;
1257 lw_get_widget_id (w
)
1260 widget_instance
* instance
= get_widget_instance (w
, False
);
1262 return instance
? instance
->info
->id
: 0;
1265 \f/* set the keyboard focus */
1267 lw_set_keyboard_focus (parent
, w
)
1271 #if defined (USE_MOTIF)
1272 xm_set_keyboard_focus (parent
, w
);
1274 XtSetKeyboardFocus (parent
, w
);
1280 show_one_widget_busy (w
, flag
)
1284 Pixel foreground
= 0;
1285 Pixel background
= 1;
1286 Widget widget_to_invert
= XtNameToWidget (w
, "*sheet");
1287 if (!widget_to_invert
)
1288 widget_to_invert
= w
;
1290 XtVaGetValues (widget_to_invert
,
1291 XtNforeground
, &foreground
,
1292 XtNbackground
, &background
,
1294 XtVaSetValues (widget_to_invert
,
1295 XtNforeground
, background
,
1296 XtNbackground
, foreground
,
1301 lw_show_busy (w
, busy
)
1305 widget_instance
* instance
= get_widget_instance (w
, False
);
1307 widget_instance
* next
;
1311 info
= instance
->info
;
1312 if (info
->busy
!= busy
)
1314 for (next
= info
->instances
; next
; next
= next
->next
)
1316 show_one_widget_busy (next
->widget
, busy
);
1322 /* This hack exists because Lucid/Athena need to execute the strange
1323 function below to support geometry management. */
1325 lw_refigure_widget (w
, doit
)
1329 #if defined (USE_XAW)
1330 XawPanedSetRefigureMode (w
, doit
);
1332 #if defined (USE_MOTIF)
1336 XtUnmanageChild (w
);
1340 /* Toolkit independent way of determining if an event window is in the
1343 lw_window_is_in_menubar (win
, menubar_widget
)
1345 Widget menubar_widget
;
1347 return menubar_widget
1348 #if defined (USE_LUCID)
1349 && XtWindow (menubar_widget
) == win
;
1351 #if defined (USE_MOTIF)
1352 && ((XtWindow (menubar_widget
) == win
)
1353 || (XtWindowToWidget (XtDisplay (menubar_widget
), win
)
1354 && (XtParent (XtWindowToWidget (XtDisplay (menubar_widget
), win
))
1355 == menubar_widget
)));
1359 /* Motif hack to set the main window areas. */
1361 lw_set_main_areas (parent
, menubar
, work_area
)
1366 #if defined (USE_MOTIF)
1367 xm_set_main_areas (parent
, menubar
, work_area
);
1371 /* Manage resizing for Motif. This disables resizing when the menubar
1372 is about to be modified. */
1374 lw_allow_resizing (w
, flag
)
1378 #if defined (USE_MOTIF)
1379 xm_manage_resizing (w
, flag
);