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
);
529 #if 0 /* This was replaced by the August 9 1996 change in lwlib-Xm.c. */
531 change
= max (merged_contents
->change
, change
);
536 val1
->contents
= merged_contents
;
539 this_one_change
= change
;
541 merged_next
= merge_widget_value (val1
->next
, val2
->next
, level
);
543 if (val1
->next
&& !merged_next
)
545 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "(following gone)",
547 change
= max (change
, STRUCTURAL_CHANGE
);
549 else if (merged_next
)
551 if (merged_next
->change
)
552 EXPLAIN (val1
->name
, change
, merged_next
->change
, "(following change)",
554 change
= max (change
, merged_next
->change
);
557 val1
->next
= merged_next
;
559 val1
->this_one_change
= this_one_change
;
560 val1
->change
= change
;
562 if (change
> NO_CHANGE
&& val1
->toolkit_data
)
564 if (val1
->free_toolkit_data
)
565 XtFree (val1
->toolkit_data
);
566 val1
->toolkit_data
= NULL
;
573 /* modifying the widgets */
575 name_to_widget (instance
, name
)
576 widget_instance
* instance
;
579 Widget widget
= NULL
;
581 if (!instance
->widget
)
584 if (!strcmp (XtName (instance
->widget
), name
))
585 widget
= instance
->widget
;
588 int length
= strlen (name
) + 2;
589 char* real_name
= (char *) xmalloc (length
);
591 strcpy (real_name
+ 1, name
);
593 widget
= XtNameToWidget (instance
->widget
, real_name
);
601 set_one_value (instance
, val
, deep_p
)
602 widget_instance
* instance
;
606 Widget widget
= name_to_widget (instance
, val
->name
);
610 #if defined (USE_LUCID)
611 if (lw_lucid_widget_p (instance
->widget
))
612 xlw_update_one_widget (instance
, widget
, val
, deep_p
);
614 #if defined (USE_MOTIF)
615 if (lw_motif_widget_p (instance
->widget
))
616 xm_update_one_widget (instance
, widget
, val
, deep_p
);
618 #if defined (USE_OLIT)
619 if (lw_olit_widget_p (instance
->widget
))
620 xol_update_one_widget (instance
, widget
, val
, deep_p
);
622 #if defined (USE_XAW)
623 if (lw_xaw_widget_p (instance
->widget
))
624 xaw_update_one_widget (instance
, widget
, val
, deep_p
);
630 update_one_widget_instance (instance
, deep_p
)
631 widget_instance
* instance
;
636 if (!instance
->widget
)
637 /* the widget was destroyed */
640 for (val
= instance
->info
->val
; val
; val
= val
->next
)
641 if (val
->change
!= NO_CHANGE
)
642 set_one_value (instance
, val
, deep_p
);
646 update_all_widget_values (info
, deep_p
)
650 widget_instance
* instance
;
653 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
654 update_one_widget_instance (instance
, deep_p
);
656 for (val
= info
->val
; val
; val
= val
->next
)
657 val
->change
= NO_CHANGE
;
661 lw_modify_all_widgets (id
, val
, deep_p
)
666 widget_info
* info
= get_widget_info (id
, False
);
667 widget_value
* new_val
;
668 widget_value
* next_new_val
;
677 for (new_val
= val
; new_val
; new_val
= new_val
->next
)
679 next_new_val
= new_val
->next
;
680 new_val
->next
= NULL
;
682 for (prev
= NULL
, cur
= info
->val
; cur
; prev
= cur
, cur
= cur
->next
)
683 if (!strcmp (cur
->name
, new_val
->name
))
688 cur
= merge_widget_value (cur
, new_val
, deep_p
? 1000 : 1);
690 prev
->next
= cur
? cur
: next
;
692 info
->val
= cur
? cur
: next
;
699 /* Could not find it, add it */
701 prev
->next
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
703 info
->val
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
705 new_val
->next
= next_new_val
;
708 update_all_widget_values (info
, deep_p
);
712 /* creating the widgets */
715 initialize_widget_instance (instance
)
716 widget_instance
* instance
;
720 for (val
= instance
->info
->val
; val
; val
= val
->next
)
721 val
->change
= STRUCTURAL_CHANGE
;
723 update_one_widget_instance (instance
, True
);
725 for (val
= instance
->info
->val
; val
; val
= val
->next
)
726 val
->change
= NO_CHANGE
;
730 static widget_creation_function
731 find_in_table (type
, table
)
733 widget_creation_entry
* table
;
735 widget_creation_entry
* cur
;
736 for (cur
= table
; cur
->type
; cur
++)
737 if (!my_strcasecmp (type
, cur
->type
))
738 return cur
->function
;
746 /* return True if name matches [EILPQeilpq][1-9][Bb] or
747 [EILPQeilpq][1-9][Bb][Rr][1-9] */
753 case 'E': case 'I': case 'L': case 'P': case 'Q':
754 case 'e': case 'i': case 'l': case 'p': case 'q':
755 if (name
[1] >= '0' && name
[1] <= '9')
757 if (name
[2] != 'B' && name
[2] != 'b')
761 if ((name
[3] == 'T' || name
[3] == 't') && !name
[4])
763 if ((name
[3] == 'R' || name
[3] == 'r')
764 && name
[4] >= '0' && name
[4] <= '9' && !name
[5])
777 instantiate_widget_instance (instance
)
778 widget_instance
* instance
;
780 widget_creation_function function
= NULL
;
782 #if defined (USE_LUCID)
784 function
= find_in_table (instance
->info
->type
, xlw_creation_table
);
786 #if defined(USE_MOTIF)
788 function
= find_in_table (instance
->info
->type
, xm_creation_table
);
790 #if defined (USE_OLIT)
792 function
= find_in_table (instance
->info
->type
, xol_creation_table
);
794 #if defined (USE_XAW)
796 function
= find_in_table (instance
->info
->type
, xaw_creation_table
);
801 if (dialog_spec_p (instance
->info
->type
))
803 #if defined (USE_LUCID)
806 #if defined(USE_MOTIF)
808 function
= xm_create_dialog
;
810 #if defined (USE_XAW)
812 function
= xaw_create_dialog
;
814 #if defined (USE_OLIT)
822 printf ("No creation function for widget type %s\n",
823 instance
->info
->type
);
827 instance
->widget
= (*function
) (instance
);
829 if (!instance
->widget
)
832 /* XtRealizeWidget (instance->widget);*/
836 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
841 lw_callback pre_activate_cb
;
842 lw_callback selection_cb
;
843 lw_callback post_activate_cb
;
845 if (!get_widget_info (id
, False
))
846 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
851 lw_get_widget (id
, parent
, pop_up_p
)
856 widget_instance
* instance
;
858 instance
= find_instance (id
, parent
, pop_up_p
);
859 return instance
? instance
->widget
: NULL
;
863 lw_make_widget (id
, parent
, pop_up_p
)
868 widget_instance
* instance
;
871 instance
= find_instance (id
, parent
, pop_up_p
);
874 info
= get_widget_info (id
, False
);
877 instance
= allocate_widget_instance (info
, parent
, pop_up_p
);
878 initialize_widget_instance (instance
);
880 if (!instance
->widget
)
882 return instance
->widget
;
886 lw_create_widget (type
, name
, id
, val
, parent
, pop_up_p
, pre_activate_cb
, selection_cb
, post_activate_cb
)
893 lw_callback pre_activate_cb
;
894 lw_callback selection_cb
;
895 lw_callback post_activate_cb
;
897 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
899 return lw_make_widget (id
, parent
, pop_up_p
);
903 /* destroying the widgets */
905 destroy_one_instance (instance
)
906 widget_instance
* instance
;
908 /* Remove the destroy callback on the widget; that callback will try to
909 dereference the instance object (to set its widget slot to 0, since the
910 widget is dead.) Since the instance is now dead, we don't have to worry
911 about the fact that its widget is dead too.
913 This happens in the Phase2Destroy of the widget, so this callback would
914 not have been run until arbitrarily long after the instance was freed.
916 if (instance
->widget
)
917 XtRemoveCallback (instance
->widget
, XtNdestroyCallback
,
918 mark_widget_destroyed
, (XtPointer
)instance
);
920 if (instance
->widget
)
922 /* The else are pretty tricky here, including the empty statement
923 at the end because it would be very bad to destroy a widget
925 #if defined (USE_LUCID)
926 if (lw_lucid_widget_p (instance
->widget
))
927 xlw_destroy_instance (instance
);
930 #if defined (USE_MOTIF)
931 if (lw_motif_widget_p (instance
->widget
))
932 xm_destroy_instance (instance
);
935 #if defined (USE_OLIT)
936 if (lw_olit_widget_p (instance
->widget
))
937 xol_destroy_instance (instance
);
940 #if defined (USE_XAW)
941 if (lw_xaw_widget_p (instance
->widget
))
942 xaw_destroy_instance (instance
);
945 /* do not remove the empty statement */
949 free_widget_instance (instance
);
953 lw_destroy_widget (w
)
956 widget_instance
* instance
= get_widget_instance (w
, True
);
960 widget_info
*info
= instance
->info
;
961 /* instance has already been removed from the list; free it */
962 destroy_one_instance (instance
);
963 /* if there are no instances left, free the info too */
964 if (!info
->instances
)
965 lw_destroy_all_widgets (info
->id
);
970 lw_destroy_all_widgets (id
)
973 widget_info
* info
= get_widget_info (id
, True
);
974 widget_instance
* instance
;
975 widget_instance
* next
;
979 for (instance
= info
->instances
; instance
; )
981 next
= instance
->next
;
982 destroy_one_instance (instance
);
985 free_widget_info (info
);
990 lw_destroy_everything ()
992 while (all_widget_info
)
993 lw_destroy_all_widgets (all_widget_info
->id
);
997 lw_destroy_all_pop_ups ()
1001 widget_instance
* instance
;
1003 for (info
= all_widget_info
; info
; info
= next
)
1006 instance
= info
->instances
;
1007 if (instance
&& instance
->pop_up_p
)
1008 lw_destroy_all_widgets (info
->id
);
1013 extern Widget
first_child (/* Widget */); /* garbage */
1017 lw_raise_all_pop_up_widgets ()
1020 widget_instance
* instance
;
1021 Widget result
= NULL
;
1023 for (info
= all_widget_info
; info
; info
= info
->next
)
1024 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1025 if (instance
->pop_up_p
)
1027 Widget widget
= instance
->widget
;
1030 if (XtIsManaged (widget
)
1032 /* What a complete load of crap!!!!
1033 When a dialogShell is on the screen, it is not managed!
1035 || (lw_motif_widget_p (instance
->widget
) &&
1036 XtIsManaged (first_child (widget
)))
1042 XMapRaised (XtDisplay (widget
), XtWindow (widget
));
1050 lw_pop_all_widgets (id
, up
)
1054 widget_info
* info
= get_widget_info (id
, False
);
1055 widget_instance
* instance
;
1058 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1059 if (instance
->pop_up_p
&& instance
->widget
)
1061 #if defined (USE_LUCID)
1062 if (lw_lucid_widget_p (instance
->widget
))
1064 XtRealizeWidget (instance
->widget
);
1065 xlw_pop_instance (instance
, up
);
1068 #if defined (USE_MOTIF)
1069 if (lw_motif_widget_p (instance
->widget
))
1071 XtRealizeWidget (instance
->widget
);
1072 xm_pop_instance (instance
, up
);
1075 #if defined (USE_OLIT)
1076 if (lw_olit_widget_p (instance
->widget
))
1078 XtRealizeWidget (instance
->widget
);
1079 xol_pop_instance (instance
, up
);
1082 #if defined (USE_XAW)
1083 if (lw_xaw_widget_p (instance
->widget
))
1085 XtRealizeWidget (XtParent (instance
->widget
));
1086 XtRealizeWidget (instance
->widget
);
1087 xaw_pop_instance (instance
, up
);
1094 lw_pop_up_all_widgets (id
)
1097 lw_pop_all_widgets (id
, True
);
1101 lw_pop_down_all_widgets (id
)
1104 lw_pop_all_widgets (id
, False
);
1108 lw_popup_menu (widget
, event
)
1112 #if defined (USE_LUCID)
1113 if (lw_lucid_widget_p (widget
))
1114 xlw_popup_menu (widget
, event
);
1116 #if defined (USE_MOTIF)
1117 if (lw_motif_widget_p (widget
))
1118 xm_popup_menu (widget
, event
);
1120 #if defined (USE_OLIT)
1121 if (lw_olit_widget_p (widget
))
1122 xol_popup_menu (widget
, event
);
1124 #if defined (USE_XAW)
1125 if (lw_xaw_widget_p (widget
))
1126 xaw_popup_menu (widget
, event
);
1130 \f/* get the values back */
1132 get_one_value (instance
, val
)
1133 widget_instance
* instance
;
1136 Widget widget
= name_to_widget (instance
, val
->name
);
1140 #if defined (USE_LUCID)
1141 if (lw_lucid_widget_p (instance
->widget
))
1142 xlw_update_one_value (instance
, widget
, val
);
1144 #if defined (USE_MOTIF)
1145 if (lw_motif_widget_p (instance
->widget
))
1146 xm_update_one_value (instance
, widget
, val
);
1148 #if defined (USE_OLIT)
1149 if (lw_olit_widget_p (instance
->widget
))
1150 xol_update_one_value (instance
, widget
, val
);
1152 #if defined (USE_XAW)
1153 if (lw_xaw_widget_p (instance
->widget
))
1154 xaw_update_one_value (instance
, widget
, val
);
1163 lw_get_some_values (id
, val_out
)
1165 widget_value
* val_out
;
1167 widget_info
* info
= get_widget_info (id
, False
);
1168 widget_instance
* instance
;
1170 Boolean result
= False
;
1175 instance
= info
->instances
;
1179 for (val
= val_out
; val
; val
= val
->next
)
1180 if (get_one_value (instance
, val
))
1187 lw_get_all_values (id
)
1190 widget_info
* info
= get_widget_info (id
, False
);
1191 widget_value
* val
= info
->val
;
1192 if (lw_get_some_values (id
, val
))
1198 /* internal function used by the library dependent implementation to get the
1199 widget_value for a given widget in an instance */
1201 lw_get_widget_value_for_widget (instance
, w
)
1202 widget_instance
* instance
;
1205 char* name
= XtName (w
);
1207 for (cur
= instance
->info
->val
; cur
; cur
= cur
->next
)
1208 if (!strcmp (cur
->name
, name
))
1213 \f/* update other instances value when one thing changed */
1215 /* To forbid recursive calls */
1216 static Boolean lwlib_updating
;
1218 /* This function can be used as a an XtCallback for the widgets that get
1219 modified to update other instances of the widgets. Closure should be the
1222 lw_internal_update_other_instances (widget
, closure
, call_data
)
1225 XtPointer call_data
;
1227 widget_instance
* instance
= (widget_instance
*)closure
;
1228 char* name
= XtName (widget
);
1230 widget_instance
* cur
;
1233 /* Avoid possibly infinite recursion. */
1237 /* protect against the widget being destroyed */
1238 if (XtWidgetBeingDestroyedP (widget
))
1241 /* Return immediately if there are no other instances */
1242 info
= instance
->info
;
1243 if (!info
->instances
->next
)
1246 lwlib_updating
= True
;
1248 for (val
= info
->val
; val
&& strcmp (val
->name
, name
); val
= val
->next
);
1250 if (val
&& get_one_value (instance
, val
))
1251 for (cur
= info
->instances
; cur
; cur
= cur
->next
)
1252 if (cur
!= instance
)
1253 set_one_value (cur
, val
, True
);
1255 lwlib_updating
= False
;
1262 lw_get_widget_id (w
)
1265 widget_instance
* instance
= get_widget_instance (w
, False
);
1267 return instance
? instance
->info
->id
: 0;
1270 \f/* set the keyboard focus */
1272 lw_set_keyboard_focus (parent
, w
)
1276 #if defined (USE_MOTIF)
1277 xm_set_keyboard_focus (parent
, w
);
1279 XtSetKeyboardFocus (parent
, w
);
1285 show_one_widget_busy (w
, flag
)
1289 Pixel foreground
= 0;
1290 Pixel background
= 1;
1291 Widget widget_to_invert
= XtNameToWidget (w
, "*sheet");
1292 if (!widget_to_invert
)
1293 widget_to_invert
= w
;
1295 XtVaGetValues (widget_to_invert
,
1296 XtNforeground
, &foreground
,
1297 XtNbackground
, &background
,
1299 XtVaSetValues (widget_to_invert
,
1300 XtNforeground
, background
,
1301 XtNbackground
, foreground
,
1306 lw_show_busy (w
, busy
)
1310 widget_instance
* instance
= get_widget_instance (w
, False
);
1312 widget_instance
* next
;
1316 info
= instance
->info
;
1317 if (info
->busy
!= busy
)
1319 for (next
= info
->instances
; next
; next
= next
->next
)
1321 show_one_widget_busy (next
->widget
, busy
);
1327 /* This hack exists because Lucid/Athena need to execute the strange
1328 function below to support geometry management. */
1330 lw_refigure_widget (w
, doit
)
1334 #if defined (USE_XAW)
1335 XawPanedSetRefigureMode (w
, doit
);
1337 #if defined (USE_MOTIF)
1341 XtUnmanageChild (w
);
1345 /* Toolkit independent way of determining if an event window is in the
1348 lw_window_is_in_menubar (win
, menubar_widget
)
1350 Widget menubar_widget
;
1352 return menubar_widget
1353 #if defined (USE_LUCID)
1354 && XtWindow (menubar_widget
) == win
;
1356 #if defined (USE_MOTIF)
1357 && ((XtWindow (menubar_widget
) == win
)
1358 || (XtWindowToWidget (XtDisplay (menubar_widget
), win
)
1359 && (XtParent (XtWindowToWidget (XtDisplay (menubar_widget
), win
))
1360 == menubar_widget
)));
1364 /* Motif hack to set the main window areas. */
1366 lw_set_main_areas (parent
, menubar
, work_area
)
1371 #if defined (USE_MOTIF)
1372 xm_set_main_areas (parent
, menubar
, work_area
);
1376 /* Manage resizing for Motif. This disables resizing when the menubar
1377 is about to be modified. */
1379 lw_allow_resizing (w
, flag
)
1383 #if defined (USE_MOTIF)
1384 xm_manage_resizing (w
, flag
);