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>
36 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 <X11/Xaw/Paned.h>
53 #include "lwlib-Xaw.h"
56 #if !defined (USE_LUCID) && !defined (USE_MOTIF) && !defined (USE_OLIT)
57 ERROR
! At least one of USE_LUCID
, USE_MOTIF
or USE_OLIT must be defined
.
60 #if defined (USE_MOTIF) && defined (USE_OLIT)
61 ERROR
! no more than one of USE_MOTIF
and USE_OLIT may be defined
.
65 #define max(x, y) ((x) > (y) ? (x) : (y))
68 /* List of all widgets managed by the library. */
70 all_widget_info
= NULL
;
73 char *lwlib_toolkit_type
= "motif";
75 char *lwlib_toolkit_type
= "lucid";
77 \f/* Forward declarations */
79 instantiate_widget_instance (/* widget_instance* instance */);
82 lwlib_memset (address
, value
, length
)
89 for (i
= 0; i
< length
; i
++)
94 lwlib_bcopy (from
, to
, length
)
101 for (i
= 0; i
< length
; i
++)
104 \f/* utility functions for widget_instance and widget_info */
111 result
= (char *) malloc (strlen (s
) + 1);
118 /* Like strcmp but ignore differences in case. */
121 my_strcasecmp (s1
, s2
)
133 return (c1
> c2
? 1 : -1);
146 static widget_value
*widget_value_free_list
= 0;
147 static int malloc_cpt
= 0;
150 malloc_widget_value ()
153 if (widget_value_free_list
)
155 wv
= widget_value_free_list
;
156 widget_value_free_list
= wv
->free_list
;
161 wv
= (widget_value
*) malloc (sizeof (widget_value
));
164 lwlib_memset (wv
, 0, sizeof (widget_value
));
168 /* this is analogous to free(). It frees only what was allocated
169 by malloc_widget_value(), and no substructures.
172 free_widget_value (wv
)
180 /* When the number of already allocated cells is too big,
187 wv
->free_list
= widget_value_free_list
;
188 widget_value_free_list
= wv
;
193 free_widget_value_tree (wv
)
199 if (wv
->name
) free (wv
->name
);
200 if (wv
->value
) free (wv
->value
);
201 if (wv
->key
) free (wv
->key
);
203 wv
->name
= wv
->value
= wv
->key
= (char *) 0xDEADBEEF;
205 if (wv
->toolkit_data
&& wv
->free_toolkit_data
)
207 XtFree (wv
->toolkit_data
);
208 wv
->toolkit_data
= (void *) 0xDEADBEEF;
211 if (wv
->contents
&& (wv
->contents
!= (widget_value
*)1))
213 free_widget_value_tree (wv
->contents
);
214 wv
->contents
= (widget_value
*) 0xDEADBEEF;
218 free_widget_value_tree (wv
->next
);
219 wv
->next
= (widget_value
*) 0xDEADBEEF;
221 free_widget_value (wv
);
224 static widget_value
*
225 copy_widget_value_tree (val
, change
)
233 if (val
== (widget_value
*) 1)
236 copy
= malloc_widget_value ();
237 copy
->name
= safe_strdup (val
->name
);
238 copy
->value
= safe_strdup (val
->value
);
239 copy
->key
= safe_strdup (val
->key
);
240 copy
->enabled
= val
->enabled
;
241 copy
->selected
= val
->selected
;
242 copy
->edited
= False
;
243 copy
->change
= change
;
244 copy
->this_one_change
= change
;
245 copy
->contents
= copy_widget_value_tree (val
->contents
, change
);
246 copy
->call_data
= val
->call_data
;
247 copy
->next
= copy_widget_value_tree (val
->next
, change
);
248 copy
->toolkit_data
= NULL
;
249 copy
->free_toolkit_data
= False
;
254 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
259 lw_callback pre_activate_cb
;
260 lw_callback selection_cb
;
261 lw_callback post_activate_cb
;
263 widget_info
* info
= (widget_info
*)malloc (sizeof (widget_info
));
264 info
->type
= safe_strdup (type
);
265 info
->name
= safe_strdup (name
);
267 info
->val
= copy_widget_value_tree (val
, STRUCTURAL_CHANGE
);
269 info
->pre_activate_cb
= pre_activate_cb
;
270 info
->selection_cb
= selection_cb
;
271 info
->post_activate_cb
= post_activate_cb
;
272 info
->instances
= NULL
;
274 info
->next
= all_widget_info
;
275 all_widget_info
= info
;
281 free_widget_info (info
)
284 safe_free_str (info
->type
);
285 safe_free_str (info
->name
);
286 free_widget_value_tree (info
->val
);
287 lwlib_memset ((void*)info
, 0xDEADBEEF, sizeof (widget_info
));
292 mark_widget_destroyed (widget
, closure
, call_data
)
297 widget_instance
* instance
= (widget_instance
*)closure
;
299 /* be very conservative */
300 if (instance
->widget
== widget
)
301 instance
->widget
= NULL
;
304 static widget_instance
*
305 allocate_widget_instance (info
, parent
, pop_up_p
)
310 widget_instance
* instance
=
311 (widget_instance
*)malloc (sizeof (widget_instance
));
312 instance
->parent
= parent
;
313 instance
->pop_up_p
= pop_up_p
;
314 instance
->info
= info
;
315 instance
->next
= info
->instances
;
316 info
->instances
= instance
;
318 instantiate_widget_instance (instance
);
320 XtAddCallback (instance
->widget
, XtNdestroyCallback
,
321 mark_widget_destroyed
, (XtPointer
)instance
);
326 free_widget_instance (instance
)
327 widget_instance
* instance
;
329 lwlib_memset ((void*)instance
, 0xDEADBEEF, sizeof (widget_instance
));
334 get_widget_info (id
, remove_p
)
340 for (prev
= NULL
, info
= all_widget_info
;
342 prev
= info
, info
= info
->next
)
348 prev
->next
= info
->next
;
350 all_widget_info
= info
->next
;
357 /* Internal function used by the library dependent implementation to get the
358 widget_value for a given widget in an instance */
360 lw_get_widget_info (id
)
363 return get_widget_info (id
, 0);
366 static widget_instance
*
367 get_widget_instance (widget
, remove_p
)
372 widget_instance
* instance
;
373 widget_instance
* prev
;
374 for (info
= all_widget_info
; info
; info
= info
->next
)
375 for (prev
= NULL
, instance
= info
->instances
;
377 prev
= instance
, instance
= instance
->next
)
378 if (instance
->widget
== widget
)
383 prev
->next
= instance
->next
;
385 info
->instances
= instance
->next
;
389 return (widget_instance
*) 0;
392 static widget_instance
*
393 find_instance (id
, parent
, pop_up_p
)
398 widget_info
* info
= get_widget_info (id
, False
);
399 widget_instance
* instance
;
402 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
403 if (instance
->parent
== parent
&& instance
->pop_up_p
== pop_up_p
)
410 /* utility function for widget_value */
416 if (!!s1
^ !!s2
) return True
;
417 return (s1
&& s2
) ? strcmp (s1
, s2
) : s1
? False
: !!s2
;
422 # define EXPLAIN(name, oc, nc, desc, a1, a2) \
423 printf ("Change: \"%s\"\tmax(%s=%d,%s=%d)\t%s %d %d\n", \
425 (oc == NO_CHANGE ? "none" : \
426 (oc == INVISIBLE_CHANGE ? "invisible" : \
427 (oc == VISIBLE_CHANGE ? "visible" : \
428 (oc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
430 (nc == NO_CHANGE ? "none" : \
431 (nc == INVISIBLE_CHANGE ? "invisible" : \
432 (nc == VISIBLE_CHANGE ? "visible" : \
433 (nc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
436 # define EXPLAIN(name, oc, nc, desc, a1, a2)
440 static widget_value
*
441 merge_widget_value (val1
, val2
, level
)
446 change_type change
, this_one_change
;
447 widget_value
* merged_next
;
448 widget_value
* merged_contents
;
453 return copy_widget_value_tree (val2
, STRUCTURAL_CHANGE
);
459 free_widget_value_tree (val1
);
465 if (safe_strcmp (val1
->name
, val2
->name
))
467 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "name change",
468 val1
->name
, val2
->name
);
469 change
= max (change
, STRUCTURAL_CHANGE
);
470 safe_free_str (val1
->name
);
471 val1
->name
= safe_strdup (val2
->name
);
473 if (safe_strcmp (val1
->value
, val2
->value
))
475 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "value change",
476 val1
->value
, val2
->value
);
477 change
= max (change
, VISIBLE_CHANGE
);
478 safe_free_str (val1
->value
);
479 val1
->value
= safe_strdup (val2
->value
);
481 if (safe_strcmp (val1
->key
, val2
->key
))
483 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "key change",
484 val1
->key
, val2
->key
);
485 change
= max (change
, VISIBLE_CHANGE
);
486 safe_free_str (val1
->key
);
487 val1
->key
= safe_strdup (val2
->key
);
489 if (val1
->enabled
!= val2
->enabled
)
491 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "enablement change",
492 val1
->enabled
, val2
->enabled
);
493 change
= max (change
, VISIBLE_CHANGE
);
494 val1
->enabled
= val2
->enabled
;
496 if (val1
->selected
!= val2
->selected
)
498 EXPLAIN (val1
->name
, change
, VISIBLE_CHANGE
, "selection change",
499 val1
->selected
, val2
->selected
);
500 change
= max (change
, VISIBLE_CHANGE
);
501 val1
->selected
= val2
->selected
;
503 if (val1
->call_data
!= val2
->call_data
)
505 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "call-data change",
506 val1
->call_data
, val2
->call_data
);
507 change
= max (change
, INVISIBLE_CHANGE
);
508 val1
->call_data
= val2
->call_data
;
514 merge_widget_value (val1
->contents
, val2
->contents
, level
- 1);
516 if (val1
->contents
&& !merged_contents
)
518 /* This used to say INVISIBLE_CHANGE,
519 but it is visible and vitally important when
520 the contents of the menu bar itself are entirely deleted.
522 But maybe it doesn't matter. This fails to fix the bug. */
523 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "(contents gone)",
525 change
= max (change
, STRUCTURAL_CHANGE
);
527 else if (merged_contents
&& merged_contents
->change
!= NO_CHANGE
)
529 EXPLAIN (val1
->name
, change
, INVISIBLE_CHANGE
, "(contents change)",
531 change
= max (change
, INVISIBLE_CHANGE
);
532 #if 0 /* This was replaced by the August 9 1996 change in lwlib-Xm.c. */
534 change
= max (merged_contents
->change
, change
);
539 val1
->contents
= merged_contents
;
542 this_one_change
= change
;
544 merged_next
= merge_widget_value (val1
->next
, val2
->next
, level
);
546 if (val1
->next
&& !merged_next
)
548 EXPLAIN (val1
->name
, change
, STRUCTURAL_CHANGE
, "(following gone)",
550 change
= max (change
, STRUCTURAL_CHANGE
);
552 else if (merged_next
)
554 if (merged_next
->change
)
555 EXPLAIN (val1
->name
, change
, merged_next
->change
, "(following change)",
557 change
= max (change
, merged_next
->change
);
560 val1
->next
= merged_next
;
562 val1
->this_one_change
= this_one_change
;
563 val1
->change
= change
;
565 if (change
> NO_CHANGE
&& val1
->toolkit_data
)
567 if (val1
->free_toolkit_data
)
568 XtFree (val1
->toolkit_data
);
569 val1
->toolkit_data
= NULL
;
576 /* modifying the widgets */
578 name_to_widget (instance
, name
)
579 widget_instance
* instance
;
582 Widget widget
= NULL
;
584 if (!instance
->widget
)
587 if (!strcmp (XtName (instance
->widget
), name
))
588 widget
= instance
->widget
;
591 int length
= strlen (name
) + 2;
592 char* real_name
= (char *) xmalloc (length
);
594 strcpy (real_name
+ 1, name
);
596 widget
= XtNameToWidget (instance
->widget
, real_name
);
604 set_one_value (instance
, val
, deep_p
)
605 widget_instance
* instance
;
609 Widget widget
= name_to_widget (instance
, val
->name
);
613 #if defined (USE_LUCID)
614 if (lw_lucid_widget_p (instance
->widget
))
615 xlw_update_one_widget (instance
, widget
, val
, deep_p
);
617 #if defined (USE_MOTIF)
618 if (lw_motif_widget_p (instance
->widget
))
619 xm_update_one_widget (instance
, widget
, val
, deep_p
);
621 #if defined (USE_OLIT)
622 if (lw_olit_widget_p (instance
->widget
))
623 xol_update_one_widget (instance
, widget
, val
, deep_p
);
625 #if defined (USE_XAW)
626 if (lw_xaw_widget_p (instance
->widget
))
627 xaw_update_one_widget (instance
, widget
, val
, deep_p
);
633 update_one_widget_instance (instance
, deep_p
)
634 widget_instance
* instance
;
639 if (!instance
->widget
)
640 /* the widget was destroyed */
643 for (val
= instance
->info
->val
; val
; val
= val
->next
)
644 if (val
->change
!= NO_CHANGE
)
645 set_one_value (instance
, val
, deep_p
);
649 update_all_widget_values (info
, deep_p
)
653 widget_instance
* instance
;
656 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
657 update_one_widget_instance (instance
, deep_p
);
659 for (val
= info
->val
; val
; val
= val
->next
)
660 val
->change
= NO_CHANGE
;
664 lw_modify_all_widgets (id
, val
, deep_p
)
669 widget_info
* info
= get_widget_info (id
, False
);
670 widget_value
* new_val
;
671 widget_value
* next_new_val
;
680 for (new_val
= val
; new_val
; new_val
= new_val
->next
)
682 next_new_val
= new_val
->next
;
683 new_val
->next
= NULL
;
685 for (prev
= NULL
, cur
= info
->val
; cur
; prev
= cur
, cur
= cur
->next
)
686 if (!strcmp (cur
->name
, new_val
->name
))
691 cur
= merge_widget_value (cur
, new_val
, deep_p
? 1000 : 1);
693 prev
->next
= cur
? cur
: next
;
695 info
->val
= cur
? cur
: next
;
702 /* Could not find it, add it */
704 prev
->next
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
706 info
->val
= copy_widget_value_tree (new_val
, STRUCTURAL_CHANGE
);
708 new_val
->next
= next_new_val
;
711 update_all_widget_values (info
, deep_p
);
715 /* creating the widgets */
718 initialize_widget_instance (instance
)
719 widget_instance
* instance
;
723 for (val
= instance
->info
->val
; val
; val
= val
->next
)
724 val
->change
= STRUCTURAL_CHANGE
;
726 update_one_widget_instance (instance
, True
);
728 for (val
= instance
->info
->val
; val
; val
= val
->next
)
729 val
->change
= NO_CHANGE
;
733 static widget_creation_function
734 find_in_table (type
, table
)
736 widget_creation_entry
* table
;
738 widget_creation_entry
* cur
;
739 for (cur
= table
; cur
->type
; cur
++)
740 if (!my_strcasecmp (type
, cur
->type
))
741 return cur
->function
;
749 /* return True if name matches [EILPQeilpq][1-9][Bb] or
750 [EILPQeilpq][1-9][Bb][Rr][1-9] */
756 case 'E': case 'I': case 'L': case 'P': case 'Q':
757 case 'e': case 'i': case 'l': case 'p': case 'q':
758 if (name
[1] >= '0' && name
[1] <= '9')
760 if (name
[2] != 'B' && name
[2] != 'b')
764 if ((name
[3] == 'T' || name
[3] == 't') && !name
[4])
766 if ((name
[3] == 'R' || name
[3] == 'r')
767 && name
[4] >= '0' && name
[4] <= '9' && !name
[5])
780 instantiate_widget_instance (instance
)
781 widget_instance
* instance
;
783 widget_creation_function function
= NULL
;
785 #if defined (USE_LUCID)
787 function
= find_in_table (instance
->info
->type
, xlw_creation_table
);
789 #if defined(USE_MOTIF)
791 function
= find_in_table (instance
->info
->type
, xm_creation_table
);
793 #if defined (USE_OLIT)
795 function
= find_in_table (instance
->info
->type
, xol_creation_table
);
797 #if defined (USE_XAW)
799 function
= find_in_table (instance
->info
->type
, xaw_creation_table
);
804 if (dialog_spec_p (instance
->info
->type
))
806 #if defined (USE_LUCID)
809 #if defined(USE_MOTIF)
811 function
= xm_create_dialog
;
813 #if defined (USE_XAW)
815 function
= xaw_create_dialog
;
817 #if defined (USE_OLIT)
825 printf ("No creation function for widget type %s\n",
826 instance
->info
->type
);
830 instance
->widget
= (*function
) (instance
);
832 if (!instance
->widget
)
835 /* XtRealizeWidget (instance->widget);*/
839 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
, post_activate_cb
)
844 lw_callback pre_activate_cb
;
845 lw_callback selection_cb
;
846 lw_callback post_activate_cb
;
848 if (!get_widget_info (id
, False
))
849 allocate_widget_info (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
854 lw_get_widget (id
, parent
, pop_up_p
)
859 widget_instance
* instance
;
861 instance
= find_instance (id
, parent
, pop_up_p
);
862 return instance
? instance
->widget
: NULL
;
866 lw_make_widget (id
, parent
, pop_up_p
)
871 widget_instance
* instance
;
874 instance
= find_instance (id
, parent
, pop_up_p
);
877 info
= get_widget_info (id
, False
);
880 instance
= allocate_widget_instance (info
, parent
, pop_up_p
);
881 initialize_widget_instance (instance
);
883 if (!instance
->widget
)
885 return instance
->widget
;
889 lw_create_widget (type
, name
, id
, val
, parent
, pop_up_p
, pre_activate_cb
, selection_cb
, post_activate_cb
)
896 lw_callback pre_activate_cb
;
897 lw_callback selection_cb
;
898 lw_callback post_activate_cb
;
900 lw_register_widget (type
, name
, id
, val
, pre_activate_cb
, selection_cb
,
902 return lw_make_widget (id
, parent
, pop_up_p
);
906 /* destroying the widgets */
908 destroy_one_instance (instance
)
909 widget_instance
* instance
;
911 /* Remove the destroy callback on the widget; that callback will try to
912 dereference the instance object (to set its widget slot to 0, since the
913 widget is dead.) Since the instance is now dead, we don't have to worry
914 about the fact that its widget is dead too.
916 This happens in the Phase2Destroy of the widget, so this callback would
917 not have been run until arbitrarily long after the instance was freed.
919 if (instance
->widget
)
920 XtRemoveCallback (instance
->widget
, XtNdestroyCallback
,
921 mark_widget_destroyed
, (XtPointer
)instance
);
923 if (instance
->widget
)
925 /* The else are pretty tricky here, including the empty statement
926 at the end because it would be very bad to destroy a widget
928 #if defined (USE_LUCID)
929 if (lw_lucid_widget_p (instance
->widget
))
930 xlw_destroy_instance (instance
);
933 #if defined (USE_MOTIF)
934 if (lw_motif_widget_p (instance
->widget
))
935 xm_destroy_instance (instance
);
938 #if defined (USE_OLIT)
939 if (lw_olit_widget_p (instance
->widget
))
940 xol_destroy_instance (instance
);
943 #if defined (USE_XAW)
944 if (lw_xaw_widget_p (instance
->widget
))
945 xaw_destroy_instance (instance
);
948 /* do not remove the empty statement */
952 free_widget_instance (instance
);
956 lw_destroy_widget (w
)
959 widget_instance
* instance
= get_widget_instance (w
, True
);
963 widget_info
*info
= instance
->info
;
964 /* instance has already been removed from the list; free it */
965 destroy_one_instance (instance
);
966 /* if there are no instances left, free the info too */
967 if (!info
->instances
)
968 lw_destroy_all_widgets (info
->id
);
973 lw_destroy_all_widgets (id
)
976 widget_info
* info
= get_widget_info (id
, True
);
977 widget_instance
* instance
;
978 widget_instance
* next
;
982 for (instance
= info
->instances
; instance
; )
984 next
= instance
->next
;
985 destroy_one_instance (instance
);
988 free_widget_info (info
);
993 lw_destroy_everything ()
995 while (all_widget_info
)
996 lw_destroy_all_widgets (all_widget_info
->id
);
1000 lw_destroy_all_pop_ups ()
1004 widget_instance
* instance
;
1006 for (info
= all_widget_info
; info
; info
= next
)
1009 instance
= info
->instances
;
1010 if (instance
&& instance
->pop_up_p
)
1011 lw_destroy_all_widgets (info
->id
);
1016 extern Widget
first_child (/* Widget */); /* garbage */
1020 lw_raise_all_pop_up_widgets ()
1023 widget_instance
* instance
;
1024 Widget result
= NULL
;
1026 for (info
= all_widget_info
; info
; info
= info
->next
)
1027 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1028 if (instance
->pop_up_p
)
1030 Widget widget
= instance
->widget
;
1033 if (XtIsManaged (widget
)
1035 /* What a complete load of crap!!!!
1036 When a dialogShell is on the screen, it is not managed!
1038 || (lw_motif_widget_p (instance
->widget
) &&
1039 XtIsManaged (first_child (widget
)))
1045 XMapRaised (XtDisplay (widget
), XtWindow (widget
));
1053 lw_pop_all_widgets (id
, up
)
1057 widget_info
* info
= get_widget_info (id
, False
);
1058 widget_instance
* instance
;
1061 for (instance
= info
->instances
; instance
; instance
= instance
->next
)
1062 if (instance
->pop_up_p
&& instance
->widget
)
1064 #if defined (USE_LUCID)
1065 if (lw_lucid_widget_p (instance
->widget
))
1067 XtRealizeWidget (instance
->widget
);
1068 xlw_pop_instance (instance
, up
);
1071 #if defined (USE_MOTIF)
1072 if (lw_motif_widget_p (instance
->widget
))
1074 XtRealizeWidget (instance
->widget
);
1075 xm_pop_instance (instance
, up
);
1078 #if defined (USE_OLIT)
1079 if (lw_olit_widget_p (instance
->widget
))
1081 XtRealizeWidget (instance
->widget
);
1082 xol_pop_instance (instance
, up
);
1085 #if defined (USE_XAW)
1086 if (lw_xaw_widget_p (instance
->widget
))
1088 XtRealizeWidget (XtParent (instance
->widget
));
1089 XtRealizeWidget (instance
->widget
);
1090 xaw_pop_instance (instance
, up
);
1097 lw_pop_up_all_widgets (id
)
1100 lw_pop_all_widgets (id
, True
);
1104 lw_pop_down_all_widgets (id
)
1107 lw_pop_all_widgets (id
, False
);
1111 lw_popup_menu (widget
, event
)
1115 #if defined (USE_LUCID)
1116 if (lw_lucid_widget_p (widget
))
1117 xlw_popup_menu (widget
, event
);
1119 #if defined (USE_MOTIF)
1120 if (lw_motif_widget_p (widget
))
1121 xm_popup_menu (widget
, event
);
1123 #if defined (USE_OLIT)
1124 if (lw_olit_widget_p (widget
))
1125 xol_popup_menu (widget
, event
);
1127 #if defined (USE_XAW)
1128 if (lw_xaw_widget_p (widget
))
1129 xaw_popup_menu (widget
, event
);
1133 \f/* get the values back */
1135 get_one_value (instance
, val
)
1136 widget_instance
* instance
;
1139 Widget widget
= name_to_widget (instance
, val
->name
);
1143 #if defined (USE_LUCID)
1144 if (lw_lucid_widget_p (instance
->widget
))
1145 xlw_update_one_value (instance
, widget
, val
);
1147 #if defined (USE_MOTIF)
1148 if (lw_motif_widget_p (instance
->widget
))
1149 xm_update_one_value (instance
, widget
, val
);
1151 #if defined (USE_OLIT)
1152 if (lw_olit_widget_p (instance
->widget
))
1153 xol_update_one_value (instance
, widget
, val
);
1155 #if defined (USE_XAW)
1156 if (lw_xaw_widget_p (instance
->widget
))
1157 xaw_update_one_value (instance
, widget
, val
);
1166 lw_get_some_values (id
, val_out
)
1168 widget_value
* val_out
;
1170 widget_info
* info
= get_widget_info (id
, False
);
1171 widget_instance
* instance
;
1173 Boolean result
= False
;
1178 instance
= info
->instances
;
1182 for (val
= val_out
; val
; val
= val
->next
)
1183 if (get_one_value (instance
, val
))
1190 lw_get_all_values (id
)
1193 widget_info
* info
= get_widget_info (id
, False
);
1194 widget_value
* val
= info
->val
;
1195 if (lw_get_some_values (id
, val
))
1201 /* internal function used by the library dependent implementation to get the
1202 widget_value for a given widget in an instance */
1204 lw_get_widget_value_for_widget (instance
, w
)
1205 widget_instance
* instance
;
1208 char* name
= XtName (w
);
1210 for (cur
= instance
->info
->val
; cur
; cur
= cur
->next
)
1211 if (!strcmp (cur
->name
, name
))
1216 \f/* update other instances value when one thing changed */
1218 /* To forbid recursive calls */
1219 static Boolean lwlib_updating
;
1221 /* This function can be used as a an XtCallback for the widgets that get
1222 modified to update other instances of the widgets. Closure should be the
1225 lw_internal_update_other_instances (widget
, closure
, call_data
)
1228 XtPointer call_data
;
1230 widget_instance
* instance
= (widget_instance
*)closure
;
1231 char* name
= XtName (widget
);
1233 widget_instance
* cur
;
1236 /* Avoid possibly infinite recursion. */
1240 /* protect against the widget being destroyed */
1241 if (XtWidgetBeingDestroyedP (widget
))
1244 /* Return immediately if there are no other instances */
1245 info
= instance
->info
;
1246 if (!info
->instances
->next
)
1249 lwlib_updating
= True
;
1251 for (val
= info
->val
; val
&& strcmp (val
->name
, name
); val
= val
->next
);
1253 if (val
&& get_one_value (instance
, val
))
1254 for (cur
= info
->instances
; cur
; cur
= cur
->next
)
1255 if (cur
!= instance
)
1256 set_one_value (cur
, val
, True
);
1258 lwlib_updating
= False
;
1265 lw_get_widget_id (w
)
1268 widget_instance
* instance
= get_widget_instance (w
, False
);
1270 return instance
? instance
->info
->id
: 0;
1273 \f/* set the keyboard focus */
1275 lw_set_keyboard_focus (parent
, w
)
1279 #if defined (USE_MOTIF)
1280 xm_set_keyboard_focus (parent
, w
);
1282 XtSetKeyboardFocus (parent
, w
);
1288 show_one_widget_busy (w
, flag
)
1292 Pixel foreground
= 0;
1293 Pixel background
= 1;
1294 Widget widget_to_invert
= XtNameToWidget (w
, "*sheet");
1295 if (!widget_to_invert
)
1296 widget_to_invert
= w
;
1298 XtVaGetValues (widget_to_invert
,
1299 XtNforeground
, &foreground
,
1300 XtNbackground
, &background
,
1302 XtVaSetValues (widget_to_invert
,
1303 XtNforeground
, background
,
1304 XtNbackground
, foreground
,
1309 lw_show_busy (w
, busy
)
1313 widget_instance
* instance
= get_widget_instance (w
, False
);
1315 widget_instance
* next
;
1319 info
= instance
->info
;
1320 if (info
->busy
!= busy
)
1322 for (next
= info
->instances
; next
; next
= next
->next
)
1324 show_one_widget_busy (next
->widget
, busy
);
1330 /* This hack exists because Lucid/Athena need to execute the strange
1331 function below to support geometry management. */
1333 lw_refigure_widget (w
, doit
)
1337 #if defined (USE_XAW)
1338 XawPanedSetRefigureMode (w
, doit
);
1340 #if defined (USE_MOTIF)
1344 XtUnmanageChild (w
);
1348 /* Toolkit independent way of determining if an event window is in the
1351 lw_window_is_in_menubar (win
, menubar_widget
)
1353 Widget menubar_widget
;
1355 return menubar_widget
1356 #if defined (USE_LUCID)
1357 && XtWindow (menubar_widget
) == win
;
1359 #if defined (USE_MOTIF)
1360 && ((XtWindow (menubar_widget
) == win
)
1361 || (XtWindowToWidget (XtDisplay (menubar_widget
), win
)
1362 && (XtParent (XtWindowToWidget (XtDisplay (menubar_widget
), win
))
1363 == menubar_widget
)));
1367 /* Motif hack to set the main window areas. */
1369 lw_set_main_areas (parent
, menubar
, work_area
)
1374 #if defined (USE_MOTIF)
1375 xm_set_main_areas (parent
, menubar
, work_area
);
1379 /* Manage resizing for Motif. This disables resizing when the menubar
1380 is about to be modified. */
1382 lw_allow_resizing (w
, flag
)
1386 #if defined (USE_MOTIF)
1387 xm_manage_resizing (w
, flag
);