comparison lwlib/lwlib-Xm.c @ 398:74fd4e045ea6 r21-2-29

Import from CVS: tag r21-2-29
author cvs
date Mon, 13 Aug 2007 11:13:30 +0200
parents f220cc83d72e
children a86b2b5e0111
comparison
equal deleted inserted replaced
397:f4aeb21a5bad 398:74fd4e045ea6
2 Copyright (C) 1992, 1993, 1994 Lucid, Inc. 2 Copyright (C) 1992, 1993, 1994 Lucid, Inc.
3 Copyright (C) 1995 Tinker Systems and INS Engineering Corp. 3 Copyright (C) 1995 Tinker Systems and INS Engineering Corp.
4 4
5 This file is part of the Lucid Widget Library. 5 This file is part of the Lucid Widget Library.
6 6
7 The Lucid Widget Library is free software; you can redistribute it and/or 7 The Lucid Widget Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as published by 8 modify it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option) 9 the Free Software Foundation; either version 2, or (at your option)
10 any later version. 10 any later version.
11 11
12 The Lucid Widget Library is distributed in the hope that it will be useful, 12 The Lucid Widget Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to 18 along with XEmacs; see the file COPYING. If not, write to
58 #include <Xm/RowColumn.h> 58 #include <Xm/RowColumn.h>
59 #include <Xm/ScrolledW.h> 59 #include <Xm/ScrolledW.h>
60 #include <Xm/Separator.h> 60 #include <Xm/Separator.h>
61 #include <Xm/DialogS.h> 61 #include <Xm/DialogS.h>
62 #include <Xm/Form.h> 62 #include <Xm/Form.h>
63 #ifdef LWLIB_WIDGETS_MOTIF
64 #include <Xm/Scale.h>
65 #if XmVERSION > 1
66 #include <Xm/ComboBoxP.h>
67 #endif
68 #endif
63 69
64 #ifdef LWLIB_MENUBARS_MOTIF 70 #ifdef LWLIB_MENUBARS_MOTIF
65 static void xm_pull_down_callback (Widget, XtPointer, XtPointer); 71 static void xm_pull_down_callback (Widget, XtPointer, XtPointer);
66 #if 0
67 static void xm_pop_down_callback (Widget, XtPointer, XtPointer);
68 #endif /* 0 */
69 #endif 72 #endif
70 static void xm_internal_update_other_instances (Widget, XtPointer, 73 static void xm_internal_update_other_instances (Widget, XtPointer,
71 XtPointer); 74 XtPointer);
75 static void xm_pop_down_callback (Widget, XtPointer, XtPointer);
72 static void xm_generic_callback (Widget, XtPointer, XtPointer); 76 static void xm_generic_callback (Widget, XtPointer, XtPointer);
73 #ifdef LWLIB_DIALOGS_MOTIF 77 static void mark_dead_instance_destroyed (Widget widget, XtPointer closure,
78 XtPointer call_data);
79 #if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_WIDGETS_MOTIF)
74 static void xm_nosel_callback (Widget, XtPointer, XtPointer); 80 static void xm_nosel_callback (Widget, XtPointer, XtPointer);
75 #endif 81 #endif
76 #ifdef LWLIB_SCROLLBARS_MOTIF 82 #ifdef LWLIB_SCROLLBARS_MOTIF
77 static void xm_scrollbar_callback (Widget, XtPointer, XtPointer); 83 static void xm_scrollbar_callback (Widget, XtPointer, XtPointer);
78 #endif 84 #endif
82 xm_update_menu (widget_instance* instance, Widget widget, widget_value* val, 88 xm_update_menu (widget_instance* instance, Widget widget, widget_value* val,
83 Boolean deep_p); 89 Boolean deep_p);
84 #endif 90 #endif
85 91
86 /* Structures to keep destroyed instances */ 92 /* Structures to keep destroyed instances */
87 typedef struct _destroyed_instance 93 typedef struct _destroyed_instance
88 { 94 {
89 char* name; 95 char* name;
90 char* type; 96 char* type;
91 Widget widget; 97 Widget widget;
92 Widget parent; 98 Widget parent;
122 instance->parent = parent; 128 instance->parent = parent;
123 instance->pop_up_p = pop_up_p; 129 instance->pop_up_p = pop_up_p;
124 instance->next = NULL; 130 instance->next = NULL;
125 return instance; 131 return instance;
126 } 132 }
127 133
128 static void 134 static void
129 free_destroyed_instance (destroyed_instance* instance) 135 free_destroyed_instance (destroyed_instance* instance)
130 { 136 {
131 free (instance->name); 137 free (instance->name);
132 free (instance->type); 138 free (instance->type);
141 } 147 }
142 148
143 Boolean 149 Boolean
144 lw_motif_widget_p (Widget widget) 150 lw_motif_widget_p (Widget widget)
145 { 151 {
146 return 152 return
147 #ifdef LWLIB_DIALOGS_MOTIF 153 #ifdef LWLIB_DIALOGS_MOTIF
148 XtClass (widget) == xmDialogShellWidgetClass || 154 XtClass (widget) == xmDialogShellWidgetClass ||
149 #endif 155 #endif
150 XmIsPrimitive (widget) || XmIsManager (widget) || XmIsGadget (widget); 156 XmIsPrimitive (widget) || XmIsManager (widget) || XmIsGadget (widget);
151 } 157 }
153 static char * 159 static char *
154 resource_string (Widget widget, char *name) 160 resource_string (Widget widget, char *name)
155 { 161 {
156 XtResource resource; 162 XtResource resource;
157 char *result = NULL; 163 char *result = NULL;
158 164
159 resource.resource_name = "labelString"; 165 resource.resource_name = "labelString";
160 resource.resource_class = "LabelString"; /* #### should be Xmsomething... */ 166 resource.resource_class = "LabelString"; /* #### should be Xmsomething... */
161 resource.resource_type = XtRString; 167 resource.resource_type = XtRString;
162 resource.resource_size = sizeof (String); 168 resource.resource_size = sizeof (String);
163 resource.resource_offset = 0; 169 resource.resource_offset = 0;
167 XtGetSubresources (widget, (XtPointer)&result, name, 173 XtGetSubresources (widget, (XtPointer)&result, name,
168 name, &resource, 1, NULL, 0); 174 name, &resource, 1, NULL, 0);
169 return result; 175 return result;
170 } 176 }
171 177
172 #ifdef LWLIB_MENUBARS_MOTIF
173
174 static void
175 destroy_all_children (Widget widget)
176 {
177 Widget* children;
178 unsigned int number;
179 int i;
180
181 children = XtCompositeChildren (widget, &number);
182 if (children)
183 {
184 /* Unmanage all children and destroy them. They will only be
185 * really destroyed when we get out of DispatchEvent. */
186 for (i = 0; i < number; i++)
187 {
188 Widget child = children [i];
189 if (!child->core.being_destroyed)
190 {
191 XtUnmanageChild (child);
192 XtDestroyWidget (child);
193 }
194 }
195 XtFree ((char *) children);
196 }
197 }
198
199 #endif /* LWLIB_MENUBARS_MOTIF */
200
201 178
202 179
203 #ifdef LWLIB_DIALOGS_MOTIF 180 #ifdef LWLIB_DIALOGS_MOTIF
204 181
205 static Boolean 182 static Boolean
217 return False; 194 return False;
218 } 195 }
219 196
220 #endif /* LWLIB_DIALOGS_MOTIF */ 197 #endif /* LWLIB_DIALOGS_MOTIF */
221 198
222 #if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_MENUBARS_MOTIF) 199 #if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_MENUBARS_MOTIF) || defined (LWLIB_WIDGETS_MOTIF)
223 200
224 /* update the label of anything subclass of a label */ 201 /* update the label of anything subclass of a label */
225 static void 202 static void
226 xm_update_label (widget_instance* instance, Widget widget, widget_value* val) 203 xm_update_label (widget_instance* instance, Widget widget, widget_value* val)
227 { 204 {
229 XmString key_string = NULL; 206 XmString key_string = NULL;
230 XmString val_string = NULL; 207 XmString val_string = NULL;
231 XmString name_string = NULL; 208 XmString name_string = NULL;
232 Arg al [20]; 209 Arg al [20];
233 int ac = 0; 210 int ac = 0;
211 int type;
212
213 /* Don't clobber pixmap types. */
214 XtSetArg (al [0], XmNlabelType, &type);
215 XtGetValues (widget, al, 1);
216
217 if (type == XmPIXMAP)
218 return;
234 219
235 if (val->value) 220 if (val->value)
236 { 221 {
237 #ifdef LWLIB_DIALOGS_MOTIF 222 #ifdef LWLIB_DIALOGS_MOTIF
238 /* 223 /*
258 { 243 {
259 char *value_name = NULL; 244 char *value_name = NULL;
260 char *res_name = NULL; 245 char *res_name = NULL;
261 246
262 res_name = resource_string (widget, val->name); 247 res_name = resource_string (widget, val->name);
248 /* Concatenating the value with itself seems just plain daft. */
263 if (!res_name) 249 if (!res_name)
264 res_name = val->name; 250 {
265 251 built_string =
266 name_string = 252 XmStringCreateLtoR (val->value, XmSTRING_DEFAULT_CHARSET);
267 XmStringCreateLtoR (res_name, XmSTRING_DEFAULT_CHARSET); 253 }
268 254 else
269 value_name = XtMalloc (strlen (val->value) + 2); 255 {
270 *value_name = 0; 256 name_string =
271 strcat (value_name, " "); 257 XmStringCreateLtoR (res_name, XmSTRING_DEFAULT_CHARSET);
272 strcat (value_name, val->value); 258
273 259 value_name = XtMalloc (strlen (val->value) + 2);
274 val_string = 260 *value_name = 0;
275 XmStringCreateLtoR (value_name, XmSTRING_DEFAULT_CHARSET); 261 strcat (value_name, " ");
276 262 strcat (value_name, val->value);
277 built_string = 263
278 XmStringConcat (name_string, val_string); 264 val_string =
279 265 XmStringCreateLtoR (value_name, XmSTRING_DEFAULT_CHARSET);
280 XtFree (value_name); 266
267 built_string =
268 XmStringConcat (name_string, val_string);
269
270 XtFree (value_name);
271 }
281 } 272 }
282 273
283 XtSetArg (al [ac], XmNlabelString, built_string); ac++; 274 XtSetArg (al [ac], XmNlabelString, built_string); ac++;
284 XtSetArg (al [ac], XmNlabelType, XmSTRING); ac++; 275 XtSetArg (al [ac], XmNlabelType, XmSTRING); ac++;
285 } 276 }
286 277
287 if (val->key) 278 if (val->key)
288 { 279 {
289 key_string = XmStringCreateLtoR (val->key, XmSTRING_DEFAULT_CHARSET); 280 key_string = XmStringCreateLtoR (val->key, XmSTRING_DEFAULT_CHARSET);
290 XtSetArg (al [ac], XmNacceleratorText, key_string); ac++; 281 XtSetArg (al [ac], XmNacceleratorText, key_string); ac++;
291 } 282 }
299 if (key_string) 290 if (key_string)
300 XmStringFree (key_string); 291 XmStringFree (key_string);
301 292
302 if (name_string) 293 if (name_string)
303 XmStringFree (name_string); 294 XmStringFree (name_string);
295
296 if (val_string)
297 XmStringFree (val_string);
304 } 298 }
305 299
306 #endif /* defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_MENUBARS_MOTIF) */ 300 #endif /* defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_MENUBARS_MOTIF) */
307 301
308 /* update of list */ 302 /* update of list */
361 355
362 } else { 356 } else {
363 XtRemoveAllCallbacks (widget, XmNcascadingCallback); 357 XtRemoveAllCallbacks (widget, XmNcascadingCallback);
364 XtAddCallback (widget, XmNcascadingCallback, xm_pull_down_callback, 358 XtAddCallback (widget, XmNcascadingCallback, xm_pull_down_callback,
365 instance); 359 instance);
366 } 360 }
367 } 361 }
368 362
369 #endif /* LWLIB_MENUBARS_MOTIF */ 363 #endif /* LWLIB_MENUBARS_MOTIF */
370 364
371 /* update toggle and radiobox */ 365 /* update toggle and radiobox */
376 XtRemoveAllCallbacks (widget, XmNvalueChangedCallback); 370 XtRemoveAllCallbacks (widget, XmNvalueChangedCallback);
377 XtAddCallback (widget, XmNvalueChangedCallback, xm_generic_callback, 371 XtAddCallback (widget, XmNvalueChangedCallback, xm_generic_callback,
378 instance); 372 instance);
379 XtSetArg (al [0], XmNset, val->selected); 373 XtSetArg (al [0], XmNset, val->selected);
380 XtSetArg (al [1], XmNalignment, XmALIGNMENT_BEGINNING); 374 XtSetArg (al [1], XmNalignment, XmALIGNMENT_BEGINNING);
381 XtSetValues (widget, al, 2); 375 XtSetValues (widget, al, 1);
382 } 376 }
383 377
384 static void 378 static void
385 xm_update_radiobox (widget_instance* instance, Widget widget, 379 xm_update_radiobox (widget_instance* instance, Widget widget,
386 widget_value* val) 380 widget_value* val)
420 XtSetArg (al [0], XmNset, True); 414 XtSetArg (al [0], XmNset, True);
421 XtSetValues (toggle, al, 1); 415 XtSetValues (toggle, al, 1);
422 } 416 }
423 } 417 }
424 } 418 }
419
420 #if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
421 /* update of combo box */
422 static void
423 xm_update_combo_box (widget_instance* instance, Widget widget, widget_value* val)
424 {
425 widget_value* cur;
426 int i;
427 XtRemoveAllCallbacks (widget, XmNselectionCallback);
428 XtAddCallback (widget, XmNselectionCallback, xm_generic_callback,
429 instance);
430 for (cur = val->contents, i = 0; cur; cur = cur->next)
431 if (cur->value)
432 {
433 XmString xmstr = XmStringCreate (cur->value, XmSTRING_DEFAULT_CHARSET);
434 i += 1;
435 XmListAddItem (CB_List (widget), xmstr, 0);
436 if (cur->selected)
437 XmListSelectPos (CB_List (widget), i, False);
438 XmStringFree (xmstr);
439 }
440 }
441 #endif
425 442
426 #ifdef LWLIB_MENUBARS_MOTIF 443 #ifdef LWLIB_MENUBARS_MOTIF
427 444
428 /* update a popup menu, pulldown menu or a menubar */ 445 /* update a popup menu, pulldown menu or a menubar */
429 static void 446 static void
457 xm_pop_down_callback, (XtPointer)instance); 474 xm_pop_down_callback, (XtPointer)instance);
458 */ 475 */
459 476
460 num_children = 0; 477 num_children = 0;
461 for (child_index = 0, cur = val; cur; child_index++, cur = cur->next) 478 for (child_index = 0, cur = val; cur; child_index++, cur = cur->next)
462 { 479 {
463 ac = 0; 480 ac = 0;
464 button = 0; 481 button = 0;
465 XtSetArg (al [ac], XmNsensitive, cur->enabled); ac++; 482 XtSetArg (al [ac], XmNsensitive, cur->enabled); ac++;
466 XtSetArg (al [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; 483 XtSetArg (al [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
467 XtSetArg (al [ac], XmNuserData, cur->call_data); ac++; 484 XtSetArg (al [ac], XmNuserData, cur->call_data); ac++;
575 592
576 /* update the pulldown/pullaside as needed */ 593 /* update the pulldown/pullaside as needed */
577 menu = NULL; 594 menu = NULL;
578 XtSetArg (al [0], XmNsubMenuId, &menu); 595 XtSetArg (al [0], XmNsubMenuId, &menu);
579 XtGetValues (widget, al, 1); 596 XtGetValues (widget, al, 1);
580 597
581 contents = val->contents; 598 contents = val->contents;
582 599
583 if (!menu) 600 if (!menu)
584 { 601 {
585 if (contents) 602 if (contents)
656 } 673 }
657 674
658 #endif /* LWLIB_MENUBARS_MOTIF */ 675 #endif /* LWLIB_MENUBARS_MOTIF */
659 676
660 677
661 #ifdef LWLIB_DIALOGS_MOTIF
662
663 /* update text widgets */ 678 /* update text widgets */
664 679
665 static void 680 static void
666 xm_update_text (widget_instance* instance, Widget widget, widget_value* val) 681 xm_update_text (widget_instance* instance, Widget widget, widget_value* val)
667 { 682 {
668 XmTextSetString (widget, val->value ? val->value : ""); 683 XmTextSetString (widget, val->value ? val->value : (char *) "");
669 XtRemoveAllCallbacks (widget, XmNactivateCallback); 684 XtRemoveAllCallbacks (widget, XmNactivateCallback);
670 XtAddCallback (widget, XmNactivateCallback, xm_generic_callback, instance); 685 XtAddCallback (widget, XmNactivateCallback, xm_generic_callback, instance);
671 XtRemoveAllCallbacks (widget, XmNvalueChangedCallback); 686 XtRemoveAllCallbacks (widget, XmNvalueChangedCallback);
672 XtAddCallback (widget, XmNvalueChangedCallback, 687 XtAddCallback (widget, XmNvalueChangedCallback,
673 xm_internal_update_other_instances, instance); 688 xm_internal_update_other_instances, instance);
675 690
676 static void 691 static void
677 xm_update_text_field (widget_instance* instance, Widget widget, 692 xm_update_text_field (widget_instance* instance, Widget widget,
678 widget_value* val) 693 widget_value* val)
679 { 694 {
680 XmTextFieldSetString (widget, val->value ? val->value : ""); 695 XmTextFieldSetString (widget, val->value ? val->value : (char *) "");
681 XtRemoveAllCallbacks (widget, XmNactivateCallback); 696 XtRemoveAllCallbacks (widget, XmNactivateCallback);
682 XtAddCallback (widget, XmNactivateCallback, xm_generic_callback, instance); 697 XtAddCallback (widget, XmNactivateCallback, xm_generic_callback, instance);
683 XtRemoveAllCallbacks (widget, XmNvalueChangedCallback); 698 XtRemoveAllCallbacks (widget, XmNvalueChangedCallback);
684 XtAddCallback (widget, XmNvalueChangedCallback, 699 XtAddCallback (widget, XmNvalueChangedCallback,
685 xm_internal_update_other_instances, instance); 700 xm_internal_update_other_instances, instance);
686 } 701 }
687 702
688 #endif /* LWLIB_DIALOGS_MOTIF */
689 703
690 #ifdef LWLIB_SCROLLBARS_MOTIF 704 #ifdef LWLIB_SCROLLBARS_MOTIF
691 705
692 /* 706 /*
693 * If this function looks like it does a lot more work than it needs to, 707 * If this function looks like it does a lot more work than it needs to,
766 void 780 void
767 xm_update_one_widget (widget_instance* instance, Widget widget, 781 xm_update_one_widget (widget_instance* instance, Widget widget,
768 widget_value* val, Boolean deep_p) 782 widget_value* val, Boolean deep_p)
769 { 783 {
770 WidgetClass class; 784 WidgetClass class;
771 Arg al [2]; 785 Arg al [20];
772 786 int ac = 0;
787
773 /* Mark as not edited */ 788 /* Mark as not edited */
774 val->edited = False; 789 val->edited = False;
775 790
776 /* Common to all widget types */ 791 /* Common to all widget types */
777 XtSetArg (al [0], XmNsensitive, val->enabled); 792 XtSetArg (al [ac], XmNsensitive, val->enabled); ac++;
778 XtSetArg (al [1], XmNuserData, val->call_data); 793 XtSetArg (al [ac], XmNuserData, val->call_data); ac++;
779 XtSetValues (widget, al, 2); 794 lw_add_value_args_to_args (val, al, &ac);
780 795
781 #if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_MENUBARS_MOTIF) 796 XtSetValues (widget, al, ac);
797
798 #if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_MENUBARS_MOTIF) || defined (LWLIB_WIDGETS_MOTIF)
782 /* Common to all label like widgets */ 799 /* Common to all label like widgets */
783 if (XtIsSubclass (widget, xmLabelWidgetClass)) 800 if (XtIsSubclass (widget, xmLabelWidgetClass))
784 xm_update_label (instance, widget, val); 801 xm_update_label (instance, widget, val);
785 #endif 802 #endif
786
787 class = XtClass (widget); 803 class = XtClass (widget);
788 /* Class specific things */ 804 /* Class specific things */
789 if (class == xmPushButtonWidgetClass || 805 if (class == xmPushButtonWidgetClass ||
790 class == xmArrowButtonWidgetClass) 806 class == xmArrowButtonWidgetClass)
791 { 807 {
806 { 822 {
807 Boolean radiobox = 0; 823 Boolean radiobox = 0;
808 824
809 XtSetArg (al [0], XmNradioBehavior, &radiobox); 825 XtSetArg (al [0], XmNradioBehavior, &radiobox);
810 XtGetValues (widget, al, 1); 826 XtGetValues (widget, al, 1);
811 827
812 if (radiobox) 828 if (radiobox)
813 xm_update_radiobox (instance, widget, val); 829 xm_update_radiobox (instance, widget, val);
814 #ifdef LWLIB_MENUBARS_MOTIF 830 #ifdef LWLIB_MENUBARS_MOTIF
815 else 831 else
816 xm_update_menu (instance, widget, val, deep_p); 832 xm_update_menu (instance, widget, val, deep_p);
817 #endif 833 #endif
818 } 834 }
819 #ifdef LWLIB_DIALOGS_MOTIF
820 else if (class == xmTextWidgetClass) 835 else if (class == xmTextWidgetClass)
821 { 836 {
822 xm_update_text (instance, widget, val); 837 xm_update_text (instance, widget, val);
823 } 838 }
824 else if (class == xmTextFieldWidgetClass) 839 else if (class == xmTextFieldWidgetClass)
825 { 840 {
826 xm_update_text_field (instance, widget, val); 841 xm_update_text_field (instance, widget, val);
827 } 842 }
828 #endif
829 else if (class == xmListWidgetClass) 843 else if (class == xmListWidgetClass)
830 { 844 {
831 xm_update_list (instance, widget, val); 845 xm_update_list (instance, widget, val);
832 } 846 }
847 #if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
848 else if (class == xmComboBoxWidgetClass)
849 {
850 xm_update_combo_box (instance, widget, val);
851 }
852 #endif
833 #ifdef LWLIB_SCROLLBARS_MOTIF 853 #ifdef LWLIB_SCROLLBARS_MOTIF
834 else if (class == xmScrollBarWidgetClass) 854 else if (class == xmScrollBarWidgetClass)
835 { 855 {
836 xm_update_scrollbar (instance, widget, val); 856 xm_update_scrollbar (instance, widget, val);
837 } 857 }
851 if (!strcmp (val->name, old_wv->name)) 871 if (!strcmp (val->name, old_wv->name))
852 { 872 {
853 val->call_data = old_wv->call_data; 873 val->call_data = old_wv->call_data;
854 break; 874 break;
855 } 875 }
856 876
857 if (class == xmToggleButtonWidgetClass || class == xmToggleButtonGadgetClass) 877 if (class == xmToggleButtonWidgetClass || class == xmToggleButtonGadgetClass)
858 { 878 {
859 Arg al [1]; 879 Arg al [1];
860 XtSetArg (al [0], XmNset, &val->selected); 880 XtSetArg (al [0], XmNset, &val->selected);
861 XtGetValues (widget, al, 1); 881 XtGetValues (widget, al, 1);
862 val->edited = True; 882 val->edited = True;
863 } 883 }
864 #ifdef LWLIB_DIALOGS_MOTIF
865 else if (class == xmTextWidgetClass) 884 else if (class == xmTextWidgetClass)
866 { 885 {
867 if (val->value) 886 if (val->value)
868 free (val->value); 887 free (val->value);
869 val->value = XmTextGetString (widget); 888 val->value = XmTextGetString (widget);
874 if (val->value) 893 if (val->value)
875 free (val->value); 894 free (val->value);
876 val->value = XmTextFieldGetString (widget); 895 val->value = XmTextFieldGetString (widget);
877 val->edited = True; 896 val->edited = True;
878 } 897 }
879 #endif
880 else if (class == xmRowColumnWidgetClass) 898 else if (class == xmRowColumnWidgetClass)
881 { 899 {
882 Boolean radiobox = 0; 900 Boolean radiobox = 0;
883 { 901 {
884 Arg al [1]; 902 Arg al [1];
906 } 924 }
907 } 925 }
908 val->edited = True; 926 val->edited = True;
909 } 927 }
910 } 928 }
911 else if (class == xmListWidgetClass) 929 else if (class == xmListWidgetClass
930 #if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
931 || class == xmComboBoxWidgetClass
932 #endif
933 )
912 { 934 {
913 int pos_cnt; 935 int pos_cnt;
914 int* pos_list; 936 int* pos_list;
915 if (XmListGetSelectedPos (widget, &pos_list, &pos_cnt)) 937 Widget list = widget;
938 #if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
939 if (class == xmComboBoxWidgetClass)
940 list = CB_List (widget);
941 #endif
942 if (XmListGetSelectedPos (list, &pos_list, &pos_cnt))
916 { 943 {
917 int i; 944 int i;
918 widget_value* cur; 945 widget_value* cur;
919 for (cur = val->contents, i = 0; cur; cur = cur->next) 946 for (cur = val->contents, i = 0; cur; cur = cur->next)
920 if (cur->value) 947 if (cur->value)
944 971
945 972
946 /* This function is for activating a button from a program. It's wrong because 973 /* This function is for activating a button from a program. It's wrong because
947 we pass a NULL argument in the call_data which is not Motif compatible. 974 we pass a NULL argument in the call_data which is not Motif compatible.
948 This is used from the XmNdefaultAction callback of the List widgets to 975 This is used from the XmNdefaultAction callback of the List widgets to
949 have a dble-click put down a dialog box like the button woudl do. 976 have a double-click put down a dialog box like the button would do.
950 I could not find a way to do that with accelerators. 977 I could not find a way to do that with accelerators.
951 */ 978 */
952 static void 979 static void
953 activate_button (Widget widget, XtPointer closure, XtPointer call_data) 980 activate_button (Widget widget, XtPointer closure, XtPointer call_data)
954 { 981 {
994 1021
995 #ifdef DND_KLUDGE 1022 #ifdef DND_KLUDGE
996 /* This is a kludge to disable drag-and-drop in dialog boxes. The symptom 1023 /* This is a kludge to disable drag-and-drop in dialog boxes. The symptom
997 was a segv down in libXm somewhere if you used the middle button on a 1024 was a segv down in libXm somewhere if you used the middle button on a
998 dialog box to begin a drag; when you released the button to make a drop 1025 dialog box to begin a drag; when you released the button to make a drop
999 things would lose if you were not over the button where you started the 1026 things would lose if you were not over the button where you started the
1000 drag (canceling the operation). This was probably due to the fact that 1027 drag (canceling the operation). This was probably due to the fact that
1001 the dialog boxes were not set up to handle a drag but were trying to do 1028 the dialog boxes were not set up to handle a drag but were trying to do
1002 so anyway for some reason. 1029 so anyway for some reason.
1003 1030
1004 So we disable drag-and-drop in dialog boxes by turning off the binding for 1031 So we disable drag-and-drop in dialog boxes by turning off the binding for
1009 #endif /* DND_KLUDGE */ 1036 #endif /* DND_KLUDGE */
1010 1037
1011 1038
1012 static Widget 1039 static Widget
1013 make_dialog (char* name, Widget parent, Boolean pop_up_p, 1040 make_dialog (char* name, Widget parent, Boolean pop_up_p,
1014 CONST char* shell_title, CONST char* icon_name, 1041 const char* shell_title, const char* icon_name,
1015 Boolean text_input_slot, Boolean radio_box, Boolean list, 1042 Boolean text_input_slot, Boolean radio_box, Boolean list,
1016 int left_buttons, int right_buttons) 1043 int left_buttons, int right_buttons)
1017 { 1044 {
1018 Widget result; 1045 Widget result;
1019 Widget form; 1046 Widget form;
1027 Widget children [16]; /* for the final XtManageChildren */ 1054 Widget children [16]; /* for the final XtManageChildren */
1028 int n_children; 1055 int n_children;
1029 Arg al[64]; /* Arg List */ 1056 Arg al[64]; /* Arg List */
1030 int ac; /* Arg Count */ 1057 int ac; /* Arg Count */
1031 int i; 1058 int i;
1032 1059
1033 #ifdef DND_KLUDGE 1060 #ifdef DND_KLUDGE
1034 XtTranslations dnd_override = XtParseTranslationTable (disable_dnd_trans); 1061 XtTranslations dnd_override = XtParseTranslationTable (disable_dnd_trans);
1035 # define DO_DND_KLUDGE(widget) XtOverrideTranslations ((widget), dnd_override) 1062 # define DO_DND_KLUDGE(widget) XtOverrideTranslations ((widget), dnd_override)
1036 #else /* ! DND_KLUDGE */ 1063 #else /* ! DND_KLUDGE */
1037 # define DO_DND_KLUDGE(widget) 1064 # define DO_DND_KLUDGE(widget)
1075 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; 1102 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1076 XtSetArg(al[ac], XmNleftOffset, 13); ac++; 1103 XtSetArg(al[ac], XmNleftOffset, 13); ac++;
1077 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; 1104 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1078 XtSetArg(al[ac], XmNrightOffset, 13); ac++; 1105 XtSetArg(al[ac], XmNrightOffset, 13); ac++;
1079 row = XmCreateRowColumn (form, "row", al, ac); 1106 row = XmCreateRowColumn (form, "row", al, ac);
1080 1107
1081 n_children = 0; 1108 n_children = 0;
1082 for (i = 0; i < left_buttons; i++) 1109 for (i = 0; i < left_buttons; i++)
1083 { 1110 {
1084 char button_name [16]; 1111 char button_name [16];
1085 sprintf (button_name, "button%d", i + 1); 1112 sprintf (button_name, "button%d", i + 1);
1117 XtSetArg (al[ac], XmNmappedWhenManaged, FALSE); ac++; 1144 XtSetArg (al[ac], XmNmappedWhenManaged, FALSE); ac++;
1118 children [n_children] = XmCreateLabel (row, "separator_button", 1145 children [n_children] = XmCreateLabel (row, "separator_button",
1119 al, ac); 1146 al, ac);
1120 DO_DND_KLUDGE (children [n_children]); 1147 DO_DND_KLUDGE (children [n_children]);
1121 n_children++; 1148 n_children++;
1122 1149
1123 for (i = 0; i < right_buttons; i++) 1150 for (i = 0; i < right_buttons; i++)
1124 { 1151 {
1125 char button_name [16]; 1152 char button_name [16];
1126 sprintf (button_name, "button%d", left_buttons + i + 1); 1153 sprintf (button_name, "button%d", left_buttons + i + 1);
1127 ac = 0; 1154 ac = 0;
1129 children [n_children] = XmCreatePushButton (row, button_name, al, ac); 1156 children [n_children] = XmCreatePushButton (row, button_name, al, ac);
1130 DO_DND_KLUDGE (children [n_children]); 1157 DO_DND_KLUDGE (children [n_children]);
1131 if (! button) button = children [n_children]; 1158 if (! button) button = children [n_children];
1132 n_children++; 1159 n_children++;
1133 } 1160 }
1134 1161
1135 XtManageChildren (children, n_children); 1162 XtManageChildren (children, n_children);
1136 1163
1137 ac = 0; 1164 ac = 0;
1138 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE); ac++; 1165 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
1139 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++; 1166 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
1140 XtSetArg(al[ac], XmNbottomOffset, 13); ac++; 1167 XtSetArg(al[ac], XmNbottomOffset, 13); ac++;
1141 XtSetArg(al[ac], XmNbottomWidget, row); ac++; 1168 XtSetArg(al[ac], XmNbottomWidget, row); ac++;
1230 1257
1231 /* this is the easiest way I found to have the dble click in the 1258 /* this is the easiest way I found to have the dble click in the
1232 list activate the default button */ 1259 list activate the default button */
1233 XtAddCallback (value, XmNdefaultActionCallback, activate_button, button); 1260 XtAddCallback (value, XmNdefaultActionCallback, activate_button, button);
1234 } 1261 }
1235 1262
1236 ac = 0; 1263 ac = 0;
1237 XtSetArg(al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++; 1264 XtSetArg(al[ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
1238 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++; 1265 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1239 XtSetArg(al[ac], XmNtopOffset, 13); ac++; 1266 XtSetArg(al[ac], XmNtopOffset, 13); ac++;
1240 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++; 1267 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++;
1246 XtSetArg(al[ac], XmNleftWidget, icon); ac++; 1273 XtSetArg(al[ac], XmNleftWidget, icon); ac++;
1247 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; 1274 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1248 XtSetArg(al[ac], XmNrightOffset, 13); ac++; 1275 XtSetArg(al[ac], XmNrightOffset, 13); ac++;
1249 message = XmCreateLabel (form, "message", al, ac); 1276 message = XmCreateLabel (form, "message", al, ac);
1250 DO_DND_KLUDGE (message); 1277 DO_DND_KLUDGE (message);
1251 1278
1252 if (list) 1279 if (list)
1253 XtManageChild (value); 1280 XtManageChild (value);
1254 1281
1255 i = 0; 1282 i = 0;
1256 children [i] = row; i++; 1283 children [i] = row; i++;
1261 } 1288 }
1262 children [i] = message; i++; 1289 children [i] = message; i++;
1263 children [i] = icon; i++; 1290 children [i] = icon; i++;
1264 children [i] = icon_separator; i++; 1291 children [i] = icon_separator; i++;
1265 XtManageChildren (children, i); 1292 XtManageChildren (children, i);
1266 1293
1267 if (text_input_slot || list) 1294 if (text_input_slot || list)
1268 { 1295 {
1269 XtInstallAccelerators (value, button); 1296 XtInstallAccelerators (value, button);
1270 XmProcessTraversal(value, XmTRAVERSE_CURRENT); 1297 XmProcessTraversal(value, XmTRAVERSE_CURRENT);
1271 } 1298 }
1272 else 1299 else
1273 { 1300 {
1274 XtInstallAccelerators (form, button); 1301 XtInstallAccelerators (form, button);
1275 XmProcessTraversal(value, XmTRAVERSE_CURRENT); 1302 XmProcessTraversal(value, XmTRAVERSE_CURRENT);
1276 } 1303 }
1277 1304
1278 #ifdef DND_KLUDGE 1305 #ifdef DND_KLUDGE
1279 XtFree ((char *) dnd_override); 1306 XtFree ((char *) dnd_override);
1280 #endif 1307 #endif
1281 #undef DO_DND_KLUDGE 1308 #undef DO_DND_KLUDGE
1282 1309
1319 } 1346 }
1320 return NULL; 1347 return NULL;
1321 } 1348 }
1322 1349
1323 static void 1350 static void
1324 mark_dead_instance_destroyed (Widget widget, XtPointer closure,
1325 XtPointer call_data)
1326 {
1327 destroyed_instance* instance = (destroyed_instance*)closure;
1328 instance->widget = NULL;
1329 }
1330
1331 static void
1332 recenter_widget (Widget widget) 1351 recenter_widget (Widget widget)
1333 { 1352 {
1334 Widget parent = XtParent (widget); 1353 Widget parent = XtParent (widget);
1335 Screen* screen = XtScreen (widget); 1354 Screen* screen = XtScreen (widget);
1336 Dimension screen_width = WidthOfScreen (screen); 1355 Dimension screen_width = WidthOfScreen (screen);
1351 XtSetArg (al [1], XtNheight, &parent_height); 1370 XtSetArg (al [1], XtNheight, &parent_height);
1352 XtGetValues (parent, al, 2); 1371 XtGetValues (parent, al, 2);
1353 1372
1354 x = (Position) ((parent_width - child_width) / 2); 1373 x = (Position) ((parent_width - child_width) / 2);
1355 y = (Position) ((parent_height - child_height) / 2); 1374 y = (Position) ((parent_height - child_height) / 2);
1356 1375
1357 XtTranslateCoords (parent, x, y, &x, &y); 1376 XtTranslateCoords (parent, x, y, &x, &y);
1358 1377
1359 if ((Dimension) (x + child_width) > screen_width) 1378 if ((Dimension) (x + child_width) > screen_width)
1360 x = screen_width - child_width; 1379 x = screen_width - child_width;
1361 if (x < 0) 1380 if (x < 0)
1417 { 1436 {
1418 char* name = instance->info->type; 1437 char* name = instance->info->type;
1419 Widget parent = instance->parent; 1438 Widget parent = instance->parent;
1420 Widget widget; 1439 Widget widget;
1421 Boolean pop_up_p = instance->pop_up_p; 1440 Boolean pop_up_p = instance->pop_up_p;
1422 CONST char* shell_name = 0; 1441 const char* shell_name = 0;
1423 CONST char* icon_name = 0; 1442 const char* icon_name = 0;
1424 Boolean text_input_slot = False; 1443 Boolean text_input_slot = False;
1425 Boolean radio_box = False; 1444 Boolean radio_box = False;
1426 Boolean list = False; 1445 Boolean list = False;
1427 int total_buttons; 1446 int total_buttons;
1428 int left_buttons = 0; 1447 int left_buttons = 0;
1464 case 'Q': case 'q': 1483 case 'Q': case 'q':
1465 icon_name = "dbox-question"; 1484 icon_name = "dbox-question";
1466 shell_name = "Question"; 1485 shell_name = "Question";
1467 break; 1486 break;
1468 } 1487 }
1469 1488
1470 total_buttons = name [1] - '0'; 1489 total_buttons = name [1] - '0';
1471 1490
1472 if (name [3] == 'T' || name [3] == 't') 1491 if (name [3] == 'T' || name [3] == 't')
1473 { 1492 {
1474 text_input_slot = False; 1493 text_input_slot = False;
1475 radio_box = True; 1494 radio_box = True;
1476 } 1495 }
1477 else if (name [3]) 1496 else if (name [3])
1478 right_buttons = name [4] - '0'; 1497 right_buttons = name [4] - '0';
1479 1498
1480 left_buttons = total_buttons - right_buttons; 1499 left_buttons = total_buttons - right_buttons;
1481 1500
1482 widget = make_dialog (name, parent, pop_up_p, 1501 widget = make_dialog (name, parent, pop_up_p,
1483 shell_name, icon_name, text_input_slot, radio_box, 1502 shell_name, icon_name, text_input_slot, radio_box,
1484 list, left_buttons, right_buttons); 1503 list, left_buttons, right_buttons);
1485 1504
1486 XtAddCallback (widget, XmNpopdownCallback, xm_nosel_callback, 1505 XtAddCallback (widget, XmNpopdownCallback, xm_nosel_callback,
1535 int ac = 0; 1554 int ac = 0;
1536 static XtCallbackRec callbacks[2] = 1555 static XtCallbackRec callbacks[2] =
1537 { {xm_scrollbar_callback, NULL}, {NULL, NULL} }; 1556 { {xm_scrollbar_callback, NULL}, {NULL, NULL} };
1538 1557
1539 callbacks[0].closure = (XtPointer) instance; 1558 callbacks[0].closure = (XtPointer) instance;
1540 1559
1541 XtSetArg (al[ac], XmNminimum, 1); ac++; 1560 XtSetArg (al[ac], XmNminimum, 1); ac++;
1542 XtSetArg (al[ac], XmNmaximum, INT_MAX); ac++; 1561 XtSetArg (al[ac], XmNmaximum, INT_MAX); ac++;
1543 XtSetArg (al[ac], XmNincrement, 1); ac++; 1562 XtSetArg (al[ac], XmNincrement, 1); ac++;
1544 XtSetArg (al[ac], XmNpageIncrement, 1); ac++; 1563 XtSetArg (al[ac], XmNpageIncrement, 1); ac++;
1545 XtSetArg (al[ac], XmNborderWidth, 0); ac++; 1564 XtSetArg (al[ac], XmNborderWidth, 0); ac++;
1569 return make_scrollbar (instance, 0); 1588 return make_scrollbar (instance, 0);
1570 } 1589 }
1571 1590
1572 #endif /* LWLIB_SCROLLBARS_MOTIF */ 1591 #endif /* LWLIB_SCROLLBARS_MOTIF */
1573 1592
1574 /* Table of functions to create widgets */ 1593 #ifdef LWLIB_WIDGETS_MOTIF
1594 /* glyph widgets */
1595 static Widget
1596 xm_create_button (widget_instance *instance)
1597 {
1598 Arg al[20];
1599 int ac = 0;
1600 Widget button = 0;
1601 widget_value* val = instance->info->val;
1602
1603 XtSetArg (al [ac], XmNsensitive, val->enabled); ac++;
1604 XtSetArg (al [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
1605 XtSetArg (al [ac], XmNuserData, val->call_data); ac++;
1606 XtSetArg (al [ac], XmNmappedWhenManaged, FALSE); ac++;
1607 /* The highlight doesn't appear to be dynamically set which makes it
1608 look ugly. I think this may be a LessTif bug but for now we just
1609 get rid of it. */
1610 XtSetArg (al [ac], XmNhighlightThickness, (Dimension)0);ac++;
1611
1612 /* add any args the user supplied for creation time */
1613 lw_add_value_args_to_args (val, al, &ac);
1614
1615 if (!val->call_data)
1616 button = XmCreateLabel (instance->parent, val->name, al, ac);
1617
1618 else if (val->type == TOGGLE_TYPE || val->type == RADIO_TYPE)
1619 {
1620 XtSetArg (al [ac], XmNset, val->selected); ac++;
1621 XtSetArg (al [ac], XmNindicatorType,
1622 (val->type == TOGGLE_TYPE ?
1623 XmN_OF_MANY : XmONE_OF_MANY)); ac++;
1624 XtSetArg (al [ac], XmNvisibleWhenOff, True); ac++;
1625 button = XmCreateToggleButton (instance->parent, val->name, al, ac);
1626 XtRemoveAllCallbacks (button, XmNvalueChangedCallback);
1627 XtAddCallback (button, XmNvalueChangedCallback, xm_generic_callback,
1628 (XtPointer)instance);
1629 }
1630 else
1631 {
1632 button = XmCreatePushButton (instance->parent, val->name, al, ac);
1633 XtAddCallback (button, XmNactivateCallback, xm_generic_callback,
1634 (XtPointer)instance);
1635 }
1636
1637 XtManageChild (button);
1638
1639 return button;
1640 }
1641
1642 static Widget
1643 xm_create_progress (widget_instance *instance)
1644 {
1645 Arg al[20];
1646 int ac = 0;
1647 Widget scale = 0;
1648 widget_value* val = instance->info->val;
1649
1650 if (!val->call_data)
1651 {
1652 XtSetArg (al [ac], XmNsensitive, False); ac++;
1653 }
1654 else
1655 {
1656 XtSetArg (al [ac], XmNsensitive, val->enabled); ac++;
1657 }
1658 XtSetArg (al [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
1659 XtSetArg (al [ac], XmNuserData, val->call_data); ac++;
1660 XtSetArg (al [ac], XmNmappedWhenManaged, FALSE); ac++;
1661 XtSetArg (al [ac], XmNorientation, XmHORIZONTAL); ac++;
1662 /* The highlight doesn't appear to be dynamically set which makes it
1663 look ugly. I think this may be a LessTif bug but for now we just
1664 get rid of it. */
1665 XtSetArg (al [ac], XmNhighlightThickness, (Dimension)0);ac++;
1666 /* add any args the user supplied for creation time */
1667 lw_add_value_args_to_args (val, al, &ac);
1668
1669 scale = XmCreateScale (instance->parent, val->name, al, ac);
1670 if (val->call_data)
1671 XtAddCallback (scale, XmNvalueChangedCallback, xm_generic_callback,
1672 (XtPointer)instance);
1673
1674 XtManageChild (scale);
1675
1676 return scale;
1677 }
1678
1679 static Widget
1680 xm_create_text_field (widget_instance *instance)
1681 {
1682 Arg al[20];
1683 int ac = 0;
1684 Widget text = 0;
1685 widget_value* val = instance->info->val;
1686
1687 XtSetArg (al [ac], XmNsensitive, val->enabled && val->call_data); ac++;
1688 XtSetArg (al [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
1689 XtSetArg (al [ac], XmNuserData, val->call_data); ac++;
1690 XtSetArg (al [ac], XmNmappedWhenManaged, FALSE); ac++;
1691 /* The highlight doesn't appear to be dynamically set which makes it
1692 look ugly. I think this may be a LessTif bug but for now we just
1693 get rid of it. */
1694 XtSetArg (al [ac], XmNhighlightThickness, (Dimension)0);ac++;
1695
1696 /* add any args the user supplied for creation time */
1697 lw_add_value_args_to_args (val, al, &ac);
1698
1699 text = XmCreateTextField (instance->parent, val->name, al, ac);
1700 if (val->call_data)
1701 XtAddCallback (text, XmNvalueChangedCallback, xm_generic_callback,
1702 (XtPointer)instance);
1703
1704 XtManageChild (text);
1705
1706 return text;
1707 }
1708
1709 static Widget
1710 xm_create_label_field (widget_instance *instance)
1711 {
1712 return xm_create_label (instance->parent, instance->info->val);
1713 }
1714
1715 Widget
1716 xm_create_label (Widget parent, widget_value* val)
1717 {
1718 Arg al[20];
1719 int ac = 0;
1720 Widget label = 0;
1721
1722 XtSetArg (al [ac], XmNsensitive, val->enabled); ac++;
1723 XtSetArg (al [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
1724 XtSetArg (al [ac], XmNmappedWhenManaged, FALSE); ac++;
1725 /* The highlight doesn't appear to be dynamically set which makes it
1726 look ugly. I think this may be a LessTif bug but for now we just
1727 get rid of it. */
1728 XtSetArg (al [ac], XmNhighlightThickness, (Dimension)0);ac++;
1729
1730 /* add any args the user supplied for creation time */
1731 lw_add_value_args_to_args (val, al, &ac);
1732
1733 label = XmCreateLabel (parent, val->name, al, ac);
1734
1735 XtManageChild (label);
1736
1737 /* Do it again for arguments that have no effect until the widget is realized. */
1738 ac = 0;
1739 lw_add_value_args_to_args (val, al, &ac);
1740 XtSetValues (label, al, ac);
1741
1742 return label;
1743 }
1744
1745 #if XmVERSION > 1
1746 static Widget
1747 xm_create_combo_box (widget_instance *instance)
1748 {
1749 Arg al[20];
1750 int ac = 0;
1751 Widget combo = 0;
1752 widget_value* val = instance->info->val;
1753
1754 XtSetArg (al [ac], XmNsensitive, val->enabled); ac++;
1755 XtSetArg (al [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
1756 XtSetArg (al [ac], XmNuserData, val->call_data); ac++;
1757 XtSetArg (al [ac], XmNmappedWhenManaged, FALSE); ac++;
1758 /* The highlight doesn't appear to be dynamically set which makes it
1759 look ugly. I think this may be a LessTif bug but for now we just
1760 get rid of it. */
1761 XtSetArg (al [ac], XmNhighlightThickness, (Dimension)0);ac++;
1762
1763 /* add any args the user supplied for creation time */
1764 lw_add_value_args_to_args (val, al, &ac);
1765
1766 combo = XmCreateDropDownComboBox (instance->parent, val->name, al, ac);
1767 if (val->call_data)
1768 XtAddCallback (combo, XmNselectionCallback, xm_generic_callback,
1769 (XtPointer)instance);
1770
1771 XtManageChild (combo);
1772
1773 return combo;
1774 }
1775 #endif
1776 #endif /* LWLIB_WIDGETS_MOTIF */
1777
1778
1779 /* Table of functions to create widgets */
1575 1780
1576 widget_creation_entry 1781 widget_creation_entry
1577 xm_creation_table [] = 1782 xm_creation_table [] =
1578 { 1783 {
1579 #ifdef LWLIB_MENUBARS_MOTIF 1784 #ifdef LWLIB_MENUBARS_MOTIF
1580 {"menubar", make_menubar}, 1785 {"menubar", make_menubar},
1581 {"popup", make_popup_menu}, 1786 {"popup", make_popup_menu},
1582 #endif 1787 #endif
1583 #ifdef LWLIB_SCROLLBARS_MOTIF 1788 #ifdef LWLIB_SCROLLBARS_MOTIF
1584 {"vertical-scrollbar", make_vertical_scrollbar}, 1789 {"vertical-scrollbar", make_vertical_scrollbar},
1585 {"horizontal-scrollbar", make_horizontal_scrollbar}, 1790 {"horizontal-scrollbar", make_horizontal_scrollbar},
1586 #endif 1791 #endif
1792 #ifdef LWLIB_WIDGETS_MOTIF
1793 {"button", xm_create_button},
1794 {"progress", xm_create_progress},
1795 {"text-field", xm_create_text_field},
1796 {"label", xm_create_label_field},
1797 #if XmVERSION > 1
1798 {"combo-box", xm_create_combo_box},
1799 #endif
1800 #endif
1587 {NULL, NULL} 1801 {NULL, NULL}
1588 }; 1802 };
1589 1803
1590 /* Destruction of instances */ 1804 /* Destruction of instances */
1591 void 1805 void
1592 xm_destroy_instance (widget_instance* instance) 1806 xm_destroy_instance (widget_instance* instance)
1593 { 1807 {
1594 #ifdef LWLIB_DIALOGS_MOTIF 1808 #if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_WIDGETS_MOTIF)
1595 /* It appears that this is used only for dialog boxes. */ 1809 /* It appears that this is used only for dialog boxes. */
1596 Widget widget = instance->widget; 1810 Widget widget = instance->widget;
1597 /* recycle the dialog boxes */ 1811 /* recycle the dialog boxes */
1598 /* Disable the recycling until we can find a way to have the dialog box 1812 /* Disable the recycling until we can find a way to have the dialog box
1599 get reasonable layout after we modify its contents. */ 1813 get reasonable layout after we modify its contents. */
1620 XtRemoveCallback (instance->widget, XtNdestroyCallback, 1834 XtRemoveCallback (instance->widget, XtNdestroyCallback,
1621 xm_nosel_callback, (XtPointer)instance); 1835 xm_nosel_callback, (XtPointer)instance);
1622 1836
1623 XtDestroyWidget (instance->widget); 1837 XtDestroyWidget (instance->widget);
1624 } 1838 }
1625 #endif /* LWLIB_DIALOGS_MOTIF */ 1839 #endif /* LWLIB_DIALOGS_MOTIF || LWLIB_WIDGETS_MOTIF */
1626 } 1840 }
1627 1841
1628 /* popup utility */ 1842 /* popup utility */
1629 #ifdef LWLIB_MENUBARS_MOTIF 1843 #ifdef LWLIB_MENUBARS_MOTIF
1630 1844
1698 #endif 1912 #endif
1699 { 1913 {
1700 if (up) 1914 if (up)
1701 XtManageChild (widget); 1915 XtManageChild (widget);
1702 else 1916 else
1703 XtUnmanageChild (widget); 1917 XtUnmanageChild (widget);
1704 } 1918 }
1705 } 1919 }
1706 1920
1707 1921
1708 /* motif callback */ 1922 /* motif callback */
1709 1923
1710 enum do_call_type { pre_activate, selection, no_selection, post_activate }; 1924 enum do_call_type { pre_activate, selection, no_selection, post_activate };
1711 1925
1712 static void 1926 static void
1713 do_call (Widget widget, XtPointer closure, enum do_call_type type) 1927 do_call (Widget widget, XtPointer closure, enum do_call_type type)
1753 abort (); 1967 abort ();
1754 } 1968 }
1755 } 1969 }
1756 1970
1757 /* Like lw_internal_update_other_instances except that it does not do 1971 /* Like lw_internal_update_other_instances except that it does not do
1758 anything if its shell parent is not managed. This is to protect 1972 anything if its shell parent is not managed. This is to protect
1759 lw_internal_update_other_instances to dereference freed memory 1973 lw_internal_update_other_instances to dereference freed memory
1760 if the widget was ``destroyed'' by caching it in the all_destroyed_instances 1974 if the widget was ``destroyed'' by caching it in the all_destroyed_instances
1761 list */ 1975 list */
1762 static void 1976 static void
1763 xm_internal_update_other_instances (Widget widget, XtPointer closure, 1977 xm_internal_update_other_instances (Widget widget, XtPointer closure,
1773 } 1987 }
1774 1988
1775 static void 1989 static void
1776 xm_generic_callback (Widget widget, XtPointer closure, XtPointer call_data) 1990 xm_generic_callback (Widget widget, XtPointer closure, XtPointer call_data)
1777 { 1991 {
1778 #if (defined (LWLIB_MENUBARS_MOTIF) || defined (LWLIB_DIALOGS_MOTIF)) 1992 #if (defined (LWLIB_MENUBARS_MOTIF) || defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_WIDGETS_MOTIF))
1779 /* We want the selected status to change only when we decide it 1993 /* We want the selected status to change only when we decide it
1780 should change. Yuck but correct. */ 1994 should change. Yuck but correct. */
1781 if (XtClass (widget) == xmToggleButtonWidgetClass 1995 if (XtClass (widget) == xmToggleButtonWidgetClass
1782 || XtClass (widget) == xmToggleButtonGadgetClass) 1996 || XtClass (widget) == xmToggleButtonGadgetClass)
1783 { 1997 {
1788 XtGetValues (widget, al, 1); 2002 XtGetValues (widget, al, 1);
1789 2003
1790 XtSetArg (al [0], XmNset, !check); 2004 XtSetArg (al [0], XmNset, !check);
1791 XtSetValues (widget, al, 1); 2005 XtSetValues (widget, al, 1);
1792 } 2006 }
1793 #endif 2007 #endif
1794 lw_internal_update_other_instances (widget, closure, call_data); 2008 lw_internal_update_other_instances (widget, closure, call_data);
1795 do_call (widget, closure, selection); 2009 do_call (widget, closure, selection);
1796 } 2010 }
1797 2011
1798 #ifdef LWLIB_DIALOGS_MOTIF 2012 static void
1799 2013 xm_pop_down_callback (Widget widget, XtPointer closure, XtPointer call_data)
1800 static void 2014 {
1801 xm_nosel_callback (Widget widget, XtPointer closure, XtPointer call_data) 2015 do_call (widget, closure, post_activate);
1802 { 2016 }
1803 /* This callback is only called when a dialog box is dismissed with the wm's
1804 destroy button (WM_DELETE_WINDOW.) We want the dialog box to be destroyed
1805 in that case, not just unmapped, so that it releases its keyboard grabs.
1806 But there are problems with running our callbacks while the widget is in
1807 the process of being destroyed, so we set XmNdeleteResponse to XmUNMAP
1808 instead of XmDESTROY and then destroy it ourself after having run the
1809 callback.
1810 */
1811 do_call (widget, closure, no_selection);
1812 XtDestroyWidget (widget);
1813 }
1814
1815 #endif
1816 2017
1817 #ifdef LWLIB_MENUBARS_MOTIF 2018 #ifdef LWLIB_MENUBARS_MOTIF
1818 2019
1819 static void 2020 static void
1820 xm_pull_down_callback (Widget widget, XtPointer closure, XtPointer call_data) 2021 xm_pull_down_callback (Widget widget, XtPointer closure, XtPointer call_data)
1821 { 2022 {
1822 #if 0 2023 #if 0
1823 if (call_data) 2024 if (call_data)
1824 { 2025 {
1825 /* new behavior for incremental menu construction */ 2026 /* new behavior for incremental menu construction */
1826 2027
1827 } 2028 }
1828 else 2029 else
1829 #endif 2030 #endif
1830 do_call (widget, closure, pre_activate); 2031 do_call (widget, closure, pre_activate);
1831 } 2032 }
1832
1833 #if 0
1834 static void
1835 xm_pop_down_callback (Widget widget, XtPointer closure, XtPointer call_data)
1836 {
1837 do_call (widget, closure, post_activate);
1838 }
1839 #endif /* 0 */
1840 2033
1841 #endif /* LWLIB_MENUBARS_MOTIF */ 2034 #endif /* LWLIB_MENUBARS_MOTIF */
1842 2035
1843 #ifdef LWLIB_SCROLLBARS_MOTIF 2036 #ifdef LWLIB_SCROLLBARS_MOTIF
1844 static void 2037 static void
1928 if (instance->info->pre_activate_cb) 2121 if (instance->info->pre_activate_cb)
1929 instance->info->pre_activate_cb (widget, id, (XtPointer) &event_data); 2122 instance->info->pre_activate_cb (widget, id, (XtPointer) &event_data);
1930 } 2123 }
1931 #endif /* LWLIB_SCROLLBARS_MOTIF */ 2124 #endif /* LWLIB_SCROLLBARS_MOTIF */
1932 2125
2126 #if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_WIDGETS_MOTIF)
2127 static void
2128 mark_dead_instance_destroyed (Widget widget, XtPointer closure,
2129 XtPointer call_data)
2130 {
2131 destroyed_instance* instance = (destroyed_instance*)closure;
2132 instance->widget = NULL;
2133 }
2134
2135 static void
2136 xm_nosel_callback (Widget widget, XtPointer closure, XtPointer call_data)
2137 {
2138 /* This callback is only called when a dialog box is dismissed with the wm's
2139 destroy button (WM_DELETE_WINDOW.) We want the dialog box to be destroyed
2140 in that case, not just unmapped, so that it releases its keyboard grabs.
2141 But there are problems with running our callbacks while the widget is in
2142 the process of being destroyed, so we set XmNdeleteResponse to XmUNMAP
2143 instead of XmDESTROY and then destroy it ourself after having run the
2144 callback.
2145 */
2146 do_call (widget, closure, no_selection);
2147 XtDestroyWidget (widget);
2148 }
2149 #endif
2150
1933 2151
1934 /* set the keyboard focus */ 2152 /* set the keyboard focus */
1935 void 2153 void
1936 xm_set_keyboard_focus (Widget parent, Widget w) 2154 xm_set_keyboard_focus (Widget parent, Widget w)
1937 { 2155 {