Mercurial > hg > xemacs-beta
comparison lwlib/lwlib.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 | c5d627a313b1 |
children | a86b2b5e0111 |
comparison
equal
deleted
inserted
replaced
397:f4aeb21a5bad | 398:74fd4e045ea6 |
---|---|
38 #ifdef NEED_LUCID | 38 #ifdef NEED_LUCID |
39 #include "lwlib-Xlw.h" | 39 #include "lwlib-Xlw.h" |
40 #endif | 40 #endif |
41 #ifdef NEED_MOTIF | 41 #ifdef NEED_MOTIF |
42 #include "lwlib-Xm.h" | 42 #include "lwlib-Xm.h" |
43 #ifdef LWLIB_WIDGETS_MOTIF | |
44 #include <Xm/Xm.h> | |
45 #endif | |
43 #endif | 46 #endif |
44 #ifdef NEED_ATHENA | 47 #ifdef NEED_ATHENA |
45 #include "lwlib-Xaw.h" | 48 #include "lwlib-Xaw.h" |
46 #endif | 49 #endif |
47 | 50 |
65 /* whether the last menu operation was a keyboard accelerator */ | 68 /* whether the last menu operation was a keyboard accelerator */ |
66 int lw_menu_accelerate = False; | 69 int lw_menu_accelerate = False; |
67 | 70 |
68 | 71 |
69 /* Forward declarations */ | 72 /* Forward declarations */ |
70 static void | 73 static void instantiate_widget_instance (widget_instance *instance); |
71 instantiate_widget_instance (widget_instance *instance); | 74 static void free_widget_value_args (widget_value* wv); |
72 | 75 |
73 | 76 |
74 /* utility functions for widget_instance and widget_info */ | 77 /* utility functions for widget_instance and widget_info */ |
75 static char * | 78 static char * |
76 safe_strdup (CONST char *s) | 79 safe_strdup (const char *s) |
77 { | 80 { |
78 char *result; | 81 char *result; |
79 if (! s) return 0; | 82 if (! s) return 0; |
80 result = (char *) malloc (strlen (s) + 1); | 83 result = (char *) malloc (strlen (s) + 1); |
81 if (! result) | 84 if (! result) |
106 { | 109 { |
107 wv = (widget_value *) malloc (sizeof (widget_value)); | 110 wv = (widget_value *) malloc (sizeof (widget_value)); |
108 } | 111 } |
109 if (wv) | 112 if (wv) |
110 { | 113 { |
111 memset (wv, 0, sizeof (widget_value)); | 114 memset (wv, '\0', sizeof (widget_value)); |
112 } | 115 } |
113 return wv; | 116 return wv; |
114 } | 117 } |
115 | 118 |
116 /* this is analogous to free(). It frees only what was allocated | 119 /* this is analogous to free(). It frees only what was allocated |
123 abort (); | 126 abort (); |
124 wv->free_list = widget_value_free_list; | 127 wv->free_list = widget_value_free_list; |
125 widget_value_free_list = wv; | 128 widget_value_free_list = wv; |
126 } | 129 } |
127 | 130 |
128 static void free_widget_value_tree (widget_value *wv); | |
129 | |
130 static void | 131 static void |
131 free_widget_value_contents (widget_value *wv) | 132 free_widget_value_contents (widget_value *wv) |
132 { | 133 { |
133 if (wv->name) free (wv->name); | 134 if (wv->name) free (wv->name); |
134 if (wv->value) free (wv->value); | 135 if (wv->value) free (wv->value); |
153 if (wv->contents && (wv->contents != (widget_value*)1)) | 154 if (wv->contents && (wv->contents != (widget_value*)1)) |
154 { | 155 { |
155 free_widget_value_tree (wv->contents); | 156 free_widget_value_tree (wv->contents); |
156 wv->contents = (widget_value *) 0xDEADBEEF; | 157 wv->contents = (widget_value *) 0xDEADBEEF; |
157 } | 158 } |
159 | |
160 free_widget_value_args (wv); | |
161 | |
158 if (wv->next) | 162 if (wv->next) |
159 { | 163 { |
160 free_widget_value_tree (wv->next); | 164 free_widget_value_tree (wv->next); |
161 wv->next = (widget_value *) 0xDEADBEEF; | 165 wv->next = (widget_value *) 0xDEADBEEF; |
162 } | 166 } |
163 } | 167 } |
164 | 168 |
165 static void | 169 void |
166 free_widget_value_tree (widget_value *wv) | 170 free_widget_value_tree (widget_value *wv) |
167 { | 171 { |
168 if (!wv) | 172 if (!wv) |
169 return; | 173 return; |
170 | 174 |
182 (scrollbar_values *) malloc (sizeof (scrollbar_values)); | 186 (scrollbar_values *) malloc (sizeof (scrollbar_values)); |
183 | 187 |
184 if (val->scrollbar_data) | 188 if (val->scrollbar_data) |
185 *copy->scrollbar_data = *val->scrollbar_data; | 189 *copy->scrollbar_data = *val->scrollbar_data; |
186 else | 190 else |
187 memset (copy->scrollbar_data, 0, sizeof (scrollbar_values)); | 191 memset (copy->scrollbar_data, '\0', sizeof (scrollbar_values)); |
188 } | 192 } |
189 | 193 |
190 /* | 194 /* |
191 * Return true if old->scrollbar_data were not equivalent | 195 * Return true if old->scrollbar_data were not equivalent |
192 * to new->scrollbar_data. | 196 * to new->scrollbar_data. |
228 | 232 |
229 return changed; | 233 return changed; |
230 } | 234 } |
231 | 235 |
232 #endif /* NEED_SCROLLBARS */ | 236 #endif /* NEED_SCROLLBARS */ |
237 | |
238 #ifdef HAVE_WIDGETS | |
239 /* | |
240 * Return true if old->args was not equivalent | |
241 * to new->args. | |
242 */ | |
243 static Boolean | |
244 merge_widget_value_args (widget_value *old, widget_value *new) | |
245 { | |
246 Boolean changed = False; | |
247 | |
248 if (new->args && !old->args) | |
249 { | |
250 lw_copy_widget_value_args (new, old); | |
251 changed = True; | |
252 } | |
253 /* Generally we don't want to lose values that are already in the | |
254 widget. */ | |
255 else if (!new->args && old->args) | |
256 { | |
257 lw_copy_widget_value_args (old, new); | |
258 changed = True; | |
259 } | |
260 else if (new->args && old->args) | |
261 { | |
262 /* #### Do something more sensible here than just copying the | |
263 new values (like actually merging the values). */ | |
264 free_widget_value_args (old); | |
265 lw_copy_widget_value_args (new, old); | |
266 changed = True; | |
267 } | |
268 | |
269 return changed; | |
270 } | |
271 #endif /* HAVE_WIDGETS */ | |
233 | 272 |
234 /* Make a complete copy of a widget_value tree. Store CHANGE into | 273 /* Make a complete copy of a widget_value tree. Store CHANGE into |
235 the widget_value tree's `change' field. */ | 274 the widget_value tree's `change' field. */ |
236 | 275 |
237 static widget_value * | 276 static widget_value * |
261 copy->contents = copy_widget_value_tree (val->contents, change); | 300 copy->contents = copy_widget_value_tree (val->contents, change); |
262 copy->call_data = val->call_data; | 301 copy->call_data = val->call_data; |
263 copy->next = copy_widget_value_tree (val->next, change); | 302 copy->next = copy_widget_value_tree (val->next, change); |
264 copy->toolkit_data = NULL; | 303 copy->toolkit_data = NULL; |
265 copy->free_toolkit_data = False; | 304 copy->free_toolkit_data = False; |
305 | |
306 lw_copy_widget_value_args (val, copy); | |
266 #ifdef NEED_SCROLLBARS | 307 #ifdef NEED_SCROLLBARS |
267 copy_scrollbar_values (val, copy); | 308 copy_scrollbar_values (val, copy); |
268 #endif | 309 #endif |
269 } | 310 } |
270 return copy; | 311 return copy; |
287 free_widget_value (copy); /* free the node, but not its contents. */ | 328 free_widget_value (copy); /* free the node, but not its contents. */ |
288 return node; | 329 return node; |
289 } | 330 } |
290 | 331 |
291 static widget_info * | 332 static widget_info * |
292 allocate_widget_info (CONST char *type, CONST char *name, | 333 allocate_widget_info (const char *type, const char *name, |
293 LWLIB_ID id, widget_value *val, | 334 LWLIB_ID id, widget_value *val, |
294 lw_callback pre_activate_cb, lw_callback selection_cb, | 335 lw_callback pre_activate_cb, lw_callback selection_cb, |
295 lw_callback post_activate_cb) | 336 lw_callback post_activate_cb) |
296 { | 337 { |
297 widget_info *info = (widget_info *) malloc (sizeof (widget_info)); | 338 widget_info *info = (widget_info *) malloc (sizeof (widget_info)); |
315 free_widget_info (widget_info *info) | 356 free_widget_info (widget_info *info) |
316 { | 357 { |
317 safe_free_str (info->type); | 358 safe_free_str (info->type); |
318 safe_free_str (info->name); | 359 safe_free_str (info->name); |
319 free_widget_value_tree (info->val); | 360 free_widget_value_tree (info->val); |
320 memset ((void*)info, 0xDEADBEEF, sizeof (widget_info)); | 361 memset (info, '\0', sizeof (widget_info)); |
321 free (info); | 362 free (info); |
322 } | 363 } |
323 | 364 |
324 static void | 365 static void |
325 mark_widget_destroyed (Widget widget, XtPointer closure, XtPointer call_data) | 366 mark_widget_destroyed (Widget widget, XtPointer closure, XtPointer call_data) |
350 } | 391 } |
351 | 392 |
352 static void | 393 static void |
353 free_widget_instance (widget_instance *instance) | 394 free_widget_instance (widget_instance *instance) |
354 { | 395 { |
355 memset ((void *) instance, 0xDEADBEEF, sizeof (widget_instance)); | 396 memset (instance, '\0', sizeof (widget_instance)); |
356 free (instance); | 397 free (instance); |
357 } | 398 } |
358 | 399 |
359 static widget_info * | 400 static widget_info * |
360 get_widget_info (LWLIB_ID id, Boolean remove_p) | 401 get_widget_info (LWLIB_ID id, Boolean remove_p) |
460 } | 501 } |
461 | 502 |
462 | 503 |
463 /* utility function for widget_value */ | 504 /* utility function for widget_value */ |
464 static Boolean | 505 static Boolean |
465 safe_strcmp (CONST char *s1, CONST char *s2) | 506 safe_strcmp (const char *s1, const char *s2) |
466 { | 507 { |
467 if (!!s1 ^ !!s2) return True; | 508 if (!!s1 ^ !!s2) return True; |
468 return (s1 && s2) ? strcmp (s1, s2) : s1 ? False : !!s2; | 509 return (s1 && s2) ? strcmp (s1, s2) : s1 ? False : !!s2; |
469 } | 510 } |
470 | 511 |
575 EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "call-data change", | 616 EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "call-data change", |
576 val1->call_data, val2->call_data); | 617 val1->call_data, val2->call_data); |
577 change = max (change, INVISIBLE_CHANGE); | 618 change = max (change, INVISIBLE_CHANGE); |
578 val1->call_data = val2->call_data; | 619 val1->call_data = val2->call_data; |
579 } | 620 } |
621 #ifdef HAVE_WIDGETS | |
622 if (merge_widget_value_args (val1, val2)) | |
623 { | |
624 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "widget change", 0, 0); | |
625 change = max (change, VISIBLE_CHANGE); | |
626 } | |
627 #endif | |
628 | |
580 #ifdef NEED_SCROLLBARS | 629 #ifdef NEED_SCROLLBARS |
581 if (merge_scrollbar_values (val1, val2)) | 630 if (merge_scrollbar_values (val1, val2)) |
582 { | 631 { |
583 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "scrollbar change", 0, 0); | 632 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "scrollbar change", 0, 0); |
584 change = max (change, VISIBLE_CHANGE); | 633 change = max (change, VISIBLE_CHANGE); |
639 } | 688 } |
640 | 689 |
641 | 690 |
642 /* modifying the widgets */ | 691 /* modifying the widgets */ |
643 static Widget | 692 static Widget |
644 name_to_widget (widget_instance *instance, CONST char *name) | 693 name_to_widget (widget_instance *instance, const char *name) |
645 { | 694 { |
646 Widget widget = NULL; | 695 Widget widget = NULL; |
647 | 696 |
648 if (!instance->widget) | 697 if (!instance->widget) |
649 return NULL; | 698 return NULL; |
776 val->change = NO_CHANGE; | 825 val->change = NO_CHANGE; |
777 } | 826 } |
778 | 827 |
779 | 828 |
780 static widget_creation_function | 829 static widget_creation_function |
781 find_in_table (CONST char *type, widget_creation_entry *table) | 830 find_in_table (const char *type, widget_creation_entry *table) |
782 { | 831 { |
783 widget_creation_entry *cur; | 832 widget_creation_entry *cur; |
784 for (cur = table; cur->type; cur++) | 833 for (cur = table; cur->type; cur++) |
785 if (!strcasecmp (type, cur->type)) | 834 if (!strcasecmp (type, cur->type)) |
786 return cur->function; | 835 return cur->function; |
787 return NULL; | 836 return NULL; |
788 } | 837 } |
789 | 838 |
790 static Boolean | 839 static Boolean |
791 dialog_spec_p (CONST char *name) | 840 dialog_spec_p (const char *name) |
792 { | 841 { |
793 /* return True if name matches [EILPQeilpq][1-9][Bb] or | 842 /* return True if name matches [EILPQeilpq][1-9][Bb] or |
794 [EILPQeilpq][1-9][Bb][Rr][1-9] */ | 843 [EILPQeilpq][1-9][Bb][Rr][1-9] */ |
795 if (!name) | 844 if (!name) |
796 return False; | 845 return False; |
870 | 919 |
871 /* XtRealizeWidget (instance->widget);*/ | 920 /* XtRealizeWidget (instance->widget);*/ |
872 } | 921 } |
873 | 922 |
874 void | 923 void |
875 lw_register_widget (CONST char *type, CONST char *name, | 924 lw_register_widget (const char *type, const char *name, |
876 LWLIB_ID id, widget_value *val, | 925 LWLIB_ID id, widget_value *val, |
877 lw_callback pre_activate_cb, lw_callback selection_cb, | 926 lw_callback pre_activate_cb, lw_callback selection_cb, |
878 lw_callback post_activate_cb) | 927 lw_callback post_activate_cb) |
879 { | 928 { |
880 if (!get_widget_info (id, False)) | 929 if (!get_widget_info (id, False)) |
906 abort (); | 955 abort (); |
907 return instance->widget; | 956 return instance->widget; |
908 } | 957 } |
909 | 958 |
910 Widget | 959 Widget |
911 lw_create_widget (CONST char *type, CONST char *name, | 960 lw_create_widget (const char *type, const char *name, |
912 LWLIB_ID id, widget_value *val, | 961 LWLIB_ID id, widget_value *val, |
913 Widget parent, Boolean pop_up_p, lw_callback pre_activate_cb, | 962 Widget parent, Boolean pop_up_p, lw_callback pre_activate_cb, |
914 lw_callback selection_cb, lw_callback post_activate_cb) | 963 lw_callback selection_cb, lw_callback post_activate_cb) |
915 { | 964 { |
916 lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb, | 965 lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb, |
1298 show_one_widget_busy (next->widget, busy); | 1347 show_one_widget_busy (next->widget, busy); |
1299 info->busy = busy; | 1348 info->busy = busy; |
1300 } | 1349 } |
1301 } | 1350 } |
1302 } | 1351 } |
1352 | |
1353 void lw_add_value_args_to_args (widget_value* wv, ArgList addto, int* offset) | |
1354 { | |
1355 int i; | |
1356 if (wv->args && wv->args->nargs) | |
1357 { | |
1358 for (i = 0; i<wv->args->nargs; i++) | |
1359 { | |
1360 addto[i + *offset] = wv->args->args[i]; | |
1361 } | |
1362 *offset += wv->args->nargs; | |
1363 } | |
1364 } | |
1365 | |
1366 void lw_add_widget_value_arg (widget_value* wv, String name, XtArgVal value) | |
1367 { | |
1368 if (!wv->args) | |
1369 { | |
1370 wv->args = (widget_args *) malloc (sizeof (widget_args)); | |
1371 memset (wv->args, '\0', sizeof (widget_args)); | |
1372 wv->args->ref_count = 1; | |
1373 wv->args->nargs = 0; | |
1374 wv->args->args = (ArgList) malloc (sizeof (Arg) * 10); | |
1375 memset (wv->args->args, '\0', sizeof (Arg) * 10); | |
1376 } | |
1377 | |
1378 if (wv->args->nargs > 10) | |
1379 return; | |
1380 | |
1381 XtSetArg (wv->args->args [wv->args->nargs], name, value); wv->args->nargs++; | |
1382 } | |
1383 | |
1384 static void free_widget_value_args (widget_value* wv) | |
1385 { | |
1386 if (wv->args) | |
1387 { | |
1388 if (--wv->args->ref_count <= 0) | |
1389 { | |
1390 #ifdef LWLIB_WIDGETS_MOTIF | |
1391 int i; | |
1392 for (i = 0; i < wv->args->nargs; i++) | |
1393 { | |
1394 if (!strcmp (wv->args->args[i].name, XmNfontList)) | |
1395 XmFontListFree ((XmFontList)wv->args->args[i].value); | |
1396 } | |
1397 #endif | |
1398 free (wv->args->args); | |
1399 free (wv->args); | |
1400 wv->args = (widget_args*)0xDEADBEEF; | |
1401 } | |
1402 } | |
1403 } | |
1404 | |
1405 void lw_copy_widget_value_args (widget_value* val, widget_value* copy) | |
1406 { | |
1407 if (!val->args) | |
1408 { | |
1409 if (copy->args) | |
1410 free_widget_value_args (copy); | |
1411 copy->args = 0; | |
1412 } | |
1413 else | |
1414 { | |
1415 copy->args = val->args; | |
1416 copy->args->ref_count++; | |
1417 } | |
1418 } | |
1419 |