comparison lwlib/lwlib-Xm.c @ 412:697ef44129c6 r21-2-14

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