Mercurial > hg > xemacs-beta
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 { |