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
->contents
= copy_widget_value_tree (val
->contents
, change
);
242 copy
->call_data
= val
->call_data
;
243 copy
->next
= copy_widget_value_tree (val
->next
, change
);
244 copy
->toolkit_data
= NULL
;
245 copy
->free_toolkit_data
= False
;
250 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
255 lw_callback pre_activate_cb
;
256 lw_callback selection_cb
;
257 lw_callback post_activate_cb
;
259 widget_info
* info
= (widget_info
*)malloc (sizeof (widget_info
));
260 info
->type
= safe_strdup (type
);
261 info
->name
= safe_strdup (name
);
263 info
->val
= copy_widget_value_tree (val
, STRUCTURAL_CHANGE
);
265 info
->pre_activate_cb
= pre_activate_cb
;
266 info
->selection_cb
= selection_cb
;
267 info
->post_activate_cb
= post_activate_cb
;
268 info
->instances
= NULL
;
270 info
->next
= all_widget_info
;
271 all_widget_info
= info
;
277 free_widget_info (info
)
280 safe_free_str (info
->type
);
281 safe_free_str (info
->name
);
282 free_widget_value_tree (info
->val
);
283 lwlib_memset ((void*)info
, 0xDEADBEEF, sizeof (widget_info
));
288 mark_widget_destroyed (widget
, closure
, call_data
)
293 widget_instance
* instance
= (widget_instance
*)closure
;
295 /* be very conservative */
296 if (instance
->widget
== widget
)
297 instance
->widget
= NULL
;
300 static widget_instance
*
301 allocate_widget_instance (info
, parent
, pop_up_p
)
306 widget_instance
* instance
=
307 (widget_instance
*)malloc (sizeof (widget_instance
));
308 instance
->parent
= parent
;
309 instance
->pop_up_p
= pop_up_p
;
310 instance
->info
= info
;
311 instance
->next
= info
->instances
;
312 info
->instances
= instance
;
314 instantiate_widget_instance (instance
);
316 XtAddCallback (instance
->widget
, XtNdestroyCallback
,
317 mark_widget_destroyed
, (XtPointer
)instance
);
322 free_widget_instance (instance
)
323 widget_instance
* instance
;
325 lwlib_memset ((void*)instance
, 0xDEADBEEF, sizeof (widget_instance
));
330 get_widget_info (id
, remove_p
)
336 for (prev
= NULL
, info
= all_widget_info
;
338 prev
= info
, info
= info
->next
)
344 prev
->next
= info
->next
;
346 all_widget_info
= info
->next
;
353 /* Internal function used by the library dependent implementation to get the
354 widget_value for a given widget in an instance */
356 lw_get_widget_info (id
)
359 return get_widget_info (id
, 0);
362 static widget_instance
*
363 get_widget_instance (widget
, remove_p
)
368 widget_instance
* instance
;
369 widget_instance
* prev
;
370 for (info
= all_widget_info
; info
; info
= info
->next
)
371 for (prev
= NULL
, instance
= info
->instances
;
373 prev
= instance
, instance
= instance
->next
)
374 if (instance
->widget
== widget
)
379 prev
->next
= instance
->next
;
381 info
->instances
= instance
->next
;
385 return (widget_instance
*) 0;
388 static widget_instance
*
389 find_instance (id
, parent
, pop_up_p
)
394 widget_info
* info
= get_widget_info (id
, False
);
395 widget_instance
* instance
;
398 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
399 if (instance
->parent
== parent
&& instance
->pop_up_p
== pop_up_p
)
406 /* utility function for widget_value */
412 if (!!s1
^ !!s2
) return True
;
413 return (s1
&& s2
) ? strcmp (s1
, s2
) : s1
? False
: !!s2
;
418 # define EXPLAIN(name, oc, nc, desc, a1, a2) \
419 printf ("Change: \"%s\"\tmax(%s=%d,%s=%d)\t%s %d %d\n", \
421 (oc == NO_CHANGE ? "none" : \
422 (oc == INVISIBLE_CHANGE ? "invisible" : \
423 (oc == VISIBLE_CHANGE ? "visible" : \
424 (oc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
426 (nc == NO_CHANGE ? "none" : \
427 (nc == INVISIBLE_CHANGE ? "invisible" : \
428 (nc == VISIBLE_CHANGE ? "visible" : \
429 (nc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
432 # define EXPLAIN(name, oc, nc, desc, a1, a2)
436 static widget_value
*
437 merge_widget_value (val1
, val2
, level
)
443 widget_value
* merged_next
;
444 widget_value
* merged_contents
;
449 return copy_widget_value_tree (val2
, STRUCTURAL_CHANGE
);
455 free_widget_value_tree (val1
);
461 if (safe_strcmp (val1
->name
, val2
->name
))
463 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "name change",
464 val1
->name
, val2
->name
);
465 change
= max (change
, STRUCTURAL_CHANGE
);
466 safe_free_str (val1
->name
);
467 val1
->name
= safe_strdup (val2
->name
);
469 if (safe_strcmp (val1
->value
, val2
->value
))
471 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "value change",
472 val1
->value
, val2
->value
);
473 change
= max (change
, VISIBLE_CHANGE
);
474 safe_free_str (val1
->value
);
475 val1
->value
= safe_strdup (val2
->value
);
477 if (safe_strcmp (val1
->key
, val2
->key
))
479 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "key change",
480 val1
->key
, val2
->key
);
481 change
= max (change
, VISIBLE_CHANGE
);
482 safe_free_str (val1
->key
);
483 val1
->key
= safe_strdup (val2
->key
);
485 if (val1
->enabled
!= val2
->enabled
)
487 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "enablement change",
488 val1
->enabled
, val2
->enabled
);
489 change
= max (change
, VISIBLE_CHANGE
);
490 val1
->enabled
= val2
->enabled
;
492 if (val1
->selected
!= val2
->selected
)
494 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "selection change",
495 val1
->selected
, val2
->selected
);
496 change
= max (change
, VISIBLE_CHANGE
);
497 val1
->selected
= val2
->selected
;
499 if (val1
->call_data
!= val2
->call_data
)
501 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "call-data change",
502 val1
->call_data
, val2
->call_data
);
503 change
= max (change
, INVISIBLE_CHANGE
);
504 val1
->call_data
= val2
->call_data
;
510 merge_widget_value (val1
->contents
, val2
->contents
, level
- 1);
512 if (val1
->contents
&& !merged_contents
)
514 /* This used to say INVISIBLE_CHANGE,
515 but it is visible and vitally important when
516 the contents of the menu bar itself are entirely deleted.
518 But maybe it doesn't matter. This fails to fix the bug. */
519 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "(contents gone)",
521 change
= max (change
, STRUCTURAL_CHANGE
);
523 else if (merged_contents
&& merged_contents
->change
!= NO_CHANGE
)
525 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "(contents change)",
527 change
= max (change
, INVISIBLE_CHANGE
);
530 val1
->contents
= merged_contents
;
533 merged_next
= merge_widget_value (val1
->next
, val2
->next
, level
);
535 if (val1
->next
&& !merged_next
)
537 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "(following gone)",
539 change
= max (change
, STRUCTURAL_CHANGE
);
541 else if (merged_next
)
543 if (merged_next
->change
)
544 EXPLAIN (val1
->name
, change
, merged_next
->change
, "(following change)",
546 change
= max (change
, merged_next
->change
);
549 val1
->next
= merged_next
;
551 val1
->change
= change
;
553 if (change
> NO_CHANGE
&& val1
->toolkit_data
)
555 if (val1
->free_toolkit_data
)
556 XtFree (val1
->toolkit_data
);
557 val1
->toolkit_data
= NULL
;
564 /* modifying the widgets */
566 name_to_widget (instance
, name
)
567 widget_instance
* instance
;
570 Widget widget
= NULL
;
572 if (!instance
->widget
)
575 if (!strcmp (XtName (instance
->widget
), name
))
576 widget
= instance
->widget
;
579 int length
= strlen (name
) + 2;
580 char* real_name
= (char *) xmalloc (length
);
582 strcpy (real_name
+ 1, name
);
584 widget
= XtNameToWidget (instance
->widget
, real_name
);
592 set_one_value (instance
, val
, deep_p
)
593 widget_instance
* instance
;
597 Widget widget
= name_to_widget (instance
, val
->name
);
601 #if defined (USE_LUCID)
602 if (lw_lucid_widget_p (instance
->widget
))
603 xlw_update_one_widget (instance
, widget
, val
, deep_p
);
605 #if defined (USE_MOTIF)
606 if (lw_motif_widget_p (instance
->widget
))
607 xm_update_one_widget (instance
, widget
, val
, deep_p
);
609 #if defined (USE_OLIT)
610 if (lw_olit_widget_p (instance
->widget
))
611 xol_update_one_widget (instance
, widget
, val
, deep_p
);
613 #if defined (USE_XAW)
614 if (lw_xaw_widget_p (instance
->widget
))
615 xaw_update_one_widget (instance
, widget
, val
, deep_p
);
621 update_one_widget_instance (instance
, deep_p
)
622 widget_instance
* instance
;
627 if (!instance
->widget
)
628 /* the widget was destroyed */
631 for (val
= instance
->info
->val
; val
; val
= val
->next
)
632 if (val
->change
!= NO_CHANGE
)
633 set_one_value (instance
, val
, deep_p
);
637 update_all_widget_values (info
, deep_p
)
641 widget_instance
* instance
;
644 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
645 update_one_widget_instance (instance
, deep_p
);
647 for (val
= info
->val
; val
; val
= val
->next
)
648 val
->change
= NO_CHANGE
;
652 lw_modify_all_widgets (id
, val
, deep_p
)
657 widget_info
* info
= get_widget_info (id
, False
);
658 widget_value
* new_val
;
659 widget_value
* next_new_val
;
668 for (new_val
= val
; new_val
; new_val
= new_val
->next
)
670 next_new_val
= new_val
->next
;
671 new_val
->next
= NULL
;
673 for (prev
= NULL
, cur
= info
->val
; cur
; prev
= cur
, cur
= cur
->next
)
674 if (!strcmp (cur
->name
, new_val
->name
))
679 cur
= merge_widget_value (cur
, new_val
, deep_p
? 1000 : 1);
681 prev
->next
= cur
? cur
: next
;
683 info
->val
= cur
? cur
: next
;
690 /* Could not find it, add it */
692 prev
->next
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
694 info
->val
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
696 new_val
->next
= next_new_val
;
699 update_all_widget_values (info
, deep_p
);
703 /* creating the widgets */
706 initialize_widget_instance (instance
)
707 widget_instance
* instance
;
711 for (val
= instance
->info
->val
; val
; val
= val
->next
)
712 val
->change
= STRUCTURAL_CHANGE
;
714 update_one_widget_instance (instance
, True
);
716 for (val
= instance
->info
->val
; val
; val
= val
->next
)
717 val
->change
= NO_CHANGE
;
721 static widget_creation_function
722 find_in_table (type
, table
)
724 widget_creation_entry
* table
;
726 widget_creation_entry
* cur
;
727 for (cur
= table
; cur
->type
; cur
++)
728 if (!my_strcasecmp (type
, cur
->type
))
729 return cur
->function
;
737 /* return True if name matches [EILPQeilpq][1-9][Bb] or
738 [EILPQeilpq][1-9][Bb][Rr][1-9] */
744 case 'E': case 'I': case 'L': case 'P': case 'Q':
745 case 'e': case 'i': case 'l': case 'p': case 'q':
746 if (name
[1] >= '0' && name
[1] <= '9')
748 if (name
[2] != 'B' && name
[2] != 'b')
752 if ((name
[3] == 'T' || name
[3] == 't') && !name
[4])
754 if ((name
[3] == 'R' || name
[3] == 'r')
755 && name
[4] >= '0' && name
[4] <= '9' && !name
[5])
768 instantiate_widget_instance (instance
)
769 widget_instance
* instance
;
771 widget_creation_function function
= NULL
;
773 #if defined (USE_LUCID)
775 function
= find_in_table (instance
->info
->type
, xlw_creation_table
);
777 #if defined(USE_MOTIF)
779 function
= find_in_table (instance
->info
->type
, xm_creation_table
);
781 #if defined (USE_OLIT)
783 function
= find_in_table (instance
->info
->type
, xol_creation_table
);
785 #if defined (USE_XAW)
787 function
= find_in_table (instance
->info
->type
, xaw_creation_table
);
792 if (dialog_spec_p (instance
->info
->type
))
794 #if defined (USE_LUCID)
797 #if defined(USE_MOTIF)
799 function
= xm_create_dialog
;
801 #if defined (USE_XAW)
803 function
= xaw_create_dialog
;
805 #if defined (USE_OLIT)
813 printf ("No creation function for widget type %s\n",
814 instance
->info
->type
);
818 instance
->widget
= (*function
) (instance
);
820 if (!instance
->widget
)
823 /* XtRealizeWidget (instance->widget);*/
827 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
832 lw_callback pre_activate_cb
;
833 lw_callback selection_cb
;
834 lw_callback post_activate_cb
;
836 if (!get_widget_info (id
, False
))
837 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
842 lw_get_widget (id
, parent
, pop_up_p
)
847 widget_instance
* instance
;
849 instance
= find_instance (id
, parent
, pop_up_p
);
850 return instance
? instance
->widget
: NULL
;
854 lw_make_widget (id
, parent
, pop_up_p
)
859 widget_instance
* instance
;
862 instance
= find_instance (id
, parent
, pop_up_p
);
865 info
= get_widget_info (id
, False
);
868 instance
= allocate_widget_instance (info
, parent
, pop_up_p
);
869 initialize_widget_instance (instance
);
871 if (!instance
->widget
)
873 return instance
->widget
;
877 lw_create_widget (type
, name
, id
, val
, parent
, pop_up_p
, pre_activate_cb
, selection_cb
, post_activate_cb
)
884 lw_callback pre_activate_cb
;
885 lw_callback selection_cb
;
886 lw_callback post_activate_cb
;
888 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
890 return lw_make_widget (id
, parent
, pop_up_p
);
894 /* destroying the widgets */
896 destroy_one_instance (instance
)
897 widget_instance
* instance
;
899 /* Remove the destroy callback on the widget; that callback will try to
900 dereference the instance object (to set its widget slot to 0, since the
901 widget is dead.) Since the instance is now dead, we don't have to worry
902 about the fact that its widget is dead too.
904 This happens in the Phase2Destroy of the widget, so this callback would
905 not have been run until arbitrarily long after the instance was freed.
907 if (instance
->widget
)
908 XtRemoveCallback (instance
->widget
, XtNdestroyCallback
,
909 mark_widget_destroyed
, (XtPointer
)instance
);
911 if (instance
->widget
)
913 /* The else are pretty tricky here, including the empty statement
914 at the end because it would be very bad to destroy a widget
916 #if defined (USE_LUCID)
917 if (lw_lucid_widget_p (instance
->widget
))
918 xlw_destroy_instance (instance
);
921 #if defined (USE_MOTIF)
922 if (lw_motif_widget_p (instance
->widget
))
923 xm_destroy_instance (instance
);
926 #if defined (USE_OLIT)
927 if (lw_olit_widget_p (instance
->widget
))
928 xol_destroy_instance (instance
);
931 #if defined (USE_XAW)
932 if (lw_xaw_widget_p (instance
->widget
))
933 xaw_destroy_instance (instance
);
936 /* do not remove the empty statement */
940 free_widget_instance (instance
);
944 lw_destroy_widget (w
)
947 widget_instance
* instance
= get_widget_instance (w
, True
);
951 widget_info
*info
= instance
->info
;
952 /* instance has already been removed from the list; free it */
953 destroy_one_instance (instance
);
954 /* if there are no instances left, free the info too */
955 if (!info
->instances
)
956 lw_destroy_all_widgets (info
->id
);
961 lw_destroy_all_widgets (id
)
964 widget_info
* info
= get_widget_info (id
, True
);
965 widget_instance
* instance
;
966 widget_instance
* next
;
970 for (instance
= info
->instances
; instance
; )
972 next
= instance
->next
;
973 destroy_one_instance (instance
);
976 free_widget_info (info
);
981 lw_destroy_everything ()
983 while (all_widget_info
)
984 lw_destroy_all_widgets (all_widget_info
->id
);
988 lw_destroy_all_pop_ups ()
992 widget_instance
* instance
;
994 for (info
= all_widget_info
; info
; info
= next
)
997 instance
= info
->instances
;
998 if (instance
&& instance
->pop_up_p
)
999 lw_destroy_all_widgets (info
->id
);
1004 extern Widget
first_child (/* Widget */); /* garbage */
1008 lw_raise_all_pop_up_widgets ()
1011 widget_instance
* instance
;
1012 Widget result
= NULL
;
1014 for (info
= all_widget_info
; info
; info
= info
->next
)
1015 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1016 if (instance
->pop_up_p
)
1018 Widget widget
= instance
->widget
;
1021 if (XtIsManaged (widget
)
1023 /* What a complete load of crap!!!!
1024 When a dialogShell is on the screen, it is not managed!
1026 || (lw_motif_widget_p (instance
->widget
) &&
1027 XtIsManaged (first_child (widget
)))
1033 XMapRaised (XtDisplay (widget
), XtWindow (widget
));
1041 lw_pop_all_widgets (id
, up
)
1045 widget_info
* info
= get_widget_info (id
, False
);
1046 widget_instance
* instance
;
1049 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1050 if (instance
->pop_up_p
&& instance
->widget
)
1052 #if defined (USE_LUCID)
1053 if (lw_lucid_widget_p (instance
->widget
))
1055 XtRealizeWidget (instance
->widget
);
1056 xlw_pop_instance (instance
, up
);
1059 #if defined (USE_MOTIF)
1060 if (lw_motif_widget_p (instance
->widget
))
1062 XtRealizeWidget (instance
->widget
);
1063 xm_pop_instance (instance
, up
);
1066 #if defined (USE_OLIT)
1067 if (lw_olit_widget_p (instance
->widget
))
1069 XtRealizeWidget (instance
->widget
);
1070 xol_pop_instance (instance
, up
);
1073 #if defined (USE_XAW)
1074 if (lw_xaw_widget_p (instance
->widget
))
1076 XtRealizeWidget (XtParent (instance
->widget
));
1077 XtRealizeWidget (instance
->widget
);
1078 xaw_pop_instance (instance
, up
);
1085 lw_pop_up_all_widgets (id
)
1088 lw_pop_all_widgets (id
, True
);
1092 lw_pop_down_all_widgets (id
)
1095 lw_pop_all_widgets (id
, False
);
1099 lw_popup_menu (widget
, event
)
1103 #if defined (USE_LUCID)
1104 if (lw_lucid_widget_p (widget
))
1105 xlw_popup_menu (widget
, event
);
1107 #if defined (USE_MOTIF)
1108 if (lw_motif_widget_p (widget
))
1109 xm_popup_menu (widget
, event
);
1111 #if defined (USE_OLIT)
1112 if (lw_olit_widget_p (widget
))
1113 xol_popup_menu (widget
, event
);
1115 #if defined (USE_XAW)
1116 if (lw_xaw_widget_p (widget
))
1117 xaw_popup_menu (widget
, event
);
1121 \f/* get the values back */
1123 get_one_value (instance
, val
)
1124 widget_instance
* instance
;
1127 Widget widget
= name_to_widget (instance
, val
->name
);
1131 #if defined (USE_LUCID)
1132 if (lw_lucid_widget_p (instance
->widget
))
1133 xlw_update_one_value (instance
, widget
, val
);
1135 #if defined (USE_MOTIF)
1136 if (lw_motif_widget_p (instance
->widget
))
1137 xm_update_one_value (instance
, widget
, val
);
1139 #if defined (USE_OLIT)
1140 if (lw_olit_widget_p (instance
->widget
))
1141 xol_update_one_value (instance
, widget
, val
);
1143 #if defined (USE_XAW)
1144 if (lw_xaw_widget_p (instance
->widget
))
1145 xaw_update_one_value (instance
, widget
, val
);
1154 lw_get_some_values (id
, val_out
)
1156 widget_value
* val_out
;
1158 widget_info
* info
= get_widget_info (id
, False
);
1159 widget_instance
* instance
;
1161 Boolean result
= False
;
1166 instance
= info
->instances
;
1170 for (val
= val_out
; val
; val
= val
->next
)
1171 if (get_one_value (instance
, val
))
1178 lw_get_all_values (id
)
1181 widget_info
* info
= get_widget_info (id
, False
);
1182 widget_value
* val
= info
->val
;
1183 if (lw_get_some_values (id
, val
))
1189 /* internal function used by the library dependent implementation to get the
1190 widget_value for a given widget in an instance */
1192 lw_get_widget_value_for_widget (instance
, w
)
1193 widget_instance
* instance
;
1196 char* name
= XtName (w
);
1198 for (cur
= instance
->info
->val
; cur
; cur
= cur
->next
)
1199 if (!strcmp (cur
->name
, name
))
1204 \f/* update other instances value when one thing changed */
1206 /* To forbid recursive calls */
1207 static Boolean lwlib_updating
;
1209 /* This function can be used as a an XtCallback for the widgets that get
1210 modified to update other instances of the widgets. Closure should be the
1213 lw_internal_update_other_instances (widget
, closure
, call_data
)
1216 XtPointer call_data
;
1218 widget_instance
* instance
= (widget_instance
*)closure
;
1219 char* name
= XtName (widget
);
1221 widget_instance
* cur
;
1224 /* Avoid possibly infinite recursion. */
1228 /* protect against the widget being destroyed */
1229 if (XtWidgetBeingDestroyedP (widget
))
1232 /* Return immediately if there are no other instances */
1233 info
= instance
->info
;
1234 if (!info
->instances
->next
)
1237 lwlib_updating
= True
;
1239 for (val
= info
->val
; val
&& strcmp (val
->name
, name
); val
= val
->next
);
1241 if (val
&& get_one_value (instance
, val
))
1242 for (cur
= info
->instances
; cur
; cur
= cur
->next
)
1243 if (cur
!= instance
)
1244 set_one_value (cur
, val
, True
);
1246 lwlib_updating
= False
;
1253 lw_get_widget_id (w
)
1256 widget_instance
* instance
= get_widget_instance (w
, False
);
1258 return instance
? instance
->info
->id
: 0;
1261 \f/* set the keyboard focus */
1263 lw_set_keyboard_focus (parent
, w
)
1267 #if defined (USE_MOTIF)
1268 xm_set_keyboard_focus (parent
, w
);
1270 XtSetKeyboardFocus (parent
, w
);
1276 show_one_widget_busy (w
, flag
)
1280 Pixel foreground
= 0;
1281 Pixel background
= 1;
1282 Widget widget_to_invert
= XtNameToWidget (w
, "*sheet");
1283 if (!widget_to_invert
)
1284 widget_to_invert
= w
;
1286 XtVaGetValues (widget_to_invert
,
1287 XtNforeground
, &foreground
,
1288 XtNbackground
, &background
,
1290 XtVaSetValues (widget_to_invert
,
1291 XtNforeground
, background
,
1292 XtNbackground
, foreground
,
1297 lw_show_busy (w
, busy
)
1301 widget_instance
* instance
= get_widget_instance (w
, False
);
1303 widget_instance
* next
;
1307 info
= instance
->info
;
1308 if (info
->busy
!= busy
)
1310 for (next
= info
->instances
; next
; next
= next
->next
)
1312 show_one_widget_busy (next
->widget
, busy
);
1318 /* This hack exists because Lucid/Athena need to execute the strange
1319 function below to support geometry management. */
1321 lw_refigure_widget (w
, doit
)
1325 #if defined (USE_XAW)
1326 XawPanedSetRefigureMode (w
, doit
);
1328 #if defined (USE_MOTIF)
1332 XtUnmanageChild (w
);
1336 /* Toolkit independent way of determining if an event window is in the
1339 lw_window_is_in_menubar (win
, menubar_widget
)
1341 Widget menubar_widget
;
1343 return menubar_widget
1344 #if defined (USE_LUCID)
1345 && XtWindow (menubar_widget
) == win
;
1347 #if defined (USE_MOTIF)
1348 && ((XtWindow (menubar_widget
) == win
)
1349 || (XtWindowToWidget (XtDisplay (menubar_widget
), win
)
1350 && (XtParent (XtWindowToWidget (XtDisplay (menubar_widget
), win
))
1351 == menubar_widget
)));
1355 /* Motif hack to set the main window areas. */
1357 lw_set_main_areas (parent
, menubar
, work_area
)
1362 #if defined (USE_MOTIF)
1363 xm_set_main_areas (parent
, menubar
, work_area
);
1367 /* Manage resizing for Motif. This disables resizing when the menubar
1368 is about to be modified. */
1370 lw_allow_resizing (w
, flag
)
1374 #if defined (USE_MOTIF)
1375 xm_manage_resizing (w
, flag
);