Mercurial > hg > xemacs-beta
comparison lwlib/lwlib.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 | de805c49cfc1 |
children | 41dbb7a9d5f2 |
comparison
equal
deleted
inserted
replaced
411:12e008d41344 | 412:697ef44129c6 |
---|---|
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 | |
46 #endif | 43 #endif |
47 #ifdef NEED_ATHENA | 44 #ifdef NEED_ATHENA |
48 #include "lwlib-Xaw.h" | 45 #include "lwlib-Xaw.h" |
49 #endif | 46 #endif |
50 | 47 |
68 /* whether the last menu operation was a keyboard accelerator */ | 65 /* whether the last menu operation was a keyboard accelerator */ |
69 int lw_menu_accelerate = False; | 66 int lw_menu_accelerate = False; |
70 | 67 |
71 | 68 |
72 /* Forward declarations */ | 69 /* Forward declarations */ |
73 static void instantiate_widget_instance (widget_instance *instance); | 70 static void |
74 static void free_widget_value_args (widget_value* wv); | 71 instantiate_widget_instance (widget_instance *instance); |
75 | 72 |
76 | 73 |
77 /* utility functions for widget_instance and widget_info */ | 74 /* utility functions for widget_instance and widget_info */ |
78 static char * | 75 static char * |
79 safe_strdup (const char *s) | 76 safe_strdup (CONST char *s) |
80 { | 77 { |
81 char *result; | 78 char *result; |
82 if (! s) return 0; | 79 if (! s) return 0; |
83 result = (char *) malloc (strlen (s) + 1); | 80 result = (char *) malloc (strlen (s) + 1); |
84 if (! result) | 81 if (! result) |
109 { | 106 { |
110 wv = (widget_value *) malloc (sizeof (widget_value)); | 107 wv = (widget_value *) malloc (sizeof (widget_value)); |
111 } | 108 } |
112 if (wv) | 109 if (wv) |
113 { | 110 { |
114 memset (wv, '\0', sizeof (widget_value)); | 111 memset (wv, 0, sizeof (widget_value)); |
115 } | 112 } |
116 return wv; | 113 return wv; |
117 } | 114 } |
118 | 115 |
119 /* this is analogous to free(). It frees only what was allocated | 116 /* this is analogous to free(). It frees only what was allocated |
126 abort (); | 123 abort (); |
127 wv->free_list = widget_value_free_list; | 124 wv->free_list = widget_value_free_list; |
128 widget_value_free_list = wv; | 125 widget_value_free_list = wv; |
129 } | 126 } |
130 | 127 |
128 static void free_widget_value_tree (widget_value *wv); | |
129 | |
131 static void | 130 static void |
132 free_widget_value_contents (widget_value *wv) | 131 free_widget_value_contents (widget_value *wv) |
133 { | 132 { |
134 if (wv->name) free (wv->name); | 133 if (wv->name) free (wv->name); |
135 if (wv->value) free (wv->value); | 134 if (wv->value) free (wv->value); |
154 if (wv->contents && (wv->contents != (widget_value*)1)) | 153 if (wv->contents && (wv->contents != (widget_value*)1)) |
155 { | 154 { |
156 free_widget_value_tree (wv->contents); | 155 free_widget_value_tree (wv->contents); |
157 wv->contents = (widget_value *) 0xDEADBEEF; | 156 wv->contents = (widget_value *) 0xDEADBEEF; |
158 } | 157 } |
159 | |
160 free_widget_value_args (wv); | |
161 | |
162 if (wv->next) | 158 if (wv->next) |
163 { | 159 { |
164 free_widget_value_tree (wv->next); | 160 free_widget_value_tree (wv->next); |
165 wv->next = (widget_value *) 0xDEADBEEF; | 161 wv->next = (widget_value *) 0xDEADBEEF; |
166 } | 162 } |
167 } | 163 } |
168 | 164 |
169 void | 165 static void |
170 free_widget_value_tree (widget_value *wv) | 166 free_widget_value_tree (widget_value *wv) |
171 { | 167 { |
172 if (!wv) | 168 if (!wv) |
173 return; | 169 return; |
174 | 170 |
186 (scrollbar_values *) malloc (sizeof (scrollbar_values)); | 182 (scrollbar_values *) malloc (sizeof (scrollbar_values)); |
187 | 183 |
188 if (val->scrollbar_data) | 184 if (val->scrollbar_data) |
189 *copy->scrollbar_data = *val->scrollbar_data; | 185 *copy->scrollbar_data = *val->scrollbar_data; |
190 else | 186 else |
191 memset (copy->scrollbar_data, '\0', sizeof (scrollbar_values)); | 187 memset (copy->scrollbar_data, 0, sizeof (scrollbar_values)); |
192 } | 188 } |
193 | 189 |
194 /* | 190 /* |
195 * Return true if old->scrollbar_data were not equivalent | 191 * Return true if old->scrollbar_data were not equivalent |
196 * to new->scrollbar_data. | 192 * to new->scrollbar_data. |
232 | 228 |
233 return changed; | 229 return changed; |
234 } | 230 } |
235 | 231 |
236 #endif /* NEED_SCROLLBARS */ | 232 #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 && new->args != old->args) | |
261 { | |
262 /* #### Do something more sensible here than just copying the | |
263 new values (like actually merging the values). */ | |
264 lw_copy_widget_value_args (new, old); | |
265 changed = True; | |
266 } | |
267 | |
268 return changed; | |
269 } | |
270 #endif /* HAVE_WIDGETS */ | |
271 | 233 |
272 /* Make a complete copy of a widget_value tree. Store CHANGE into | 234 /* Make a complete copy of a widget_value tree. Store CHANGE into |
273 the widget_value tree's `change' field. */ | 235 the widget_value tree's `change' field. */ |
274 | 236 |
275 static widget_value * | 237 static widget_value * |
299 copy->contents = copy_widget_value_tree (val->contents, change); | 261 copy->contents = copy_widget_value_tree (val->contents, change); |
300 copy->call_data = val->call_data; | 262 copy->call_data = val->call_data; |
301 copy->next = copy_widget_value_tree (val->next, change); | 263 copy->next = copy_widget_value_tree (val->next, change); |
302 copy->toolkit_data = NULL; | 264 copy->toolkit_data = NULL; |
303 copy->free_toolkit_data = False; | 265 copy->free_toolkit_data = False; |
304 | |
305 lw_copy_widget_value_args (val, copy); | |
306 #ifdef NEED_SCROLLBARS | 266 #ifdef NEED_SCROLLBARS |
307 copy_scrollbar_values (val, copy); | 267 copy_scrollbar_values (val, copy); |
308 #endif | 268 #endif |
309 } | 269 } |
310 return copy; | 270 return copy; |
327 free_widget_value (copy); /* free the node, but not its contents. */ | 287 free_widget_value (copy); /* free the node, but not its contents. */ |
328 return node; | 288 return node; |
329 } | 289 } |
330 | 290 |
331 static widget_info * | 291 static widget_info * |
332 allocate_widget_info (const char *type, const char *name, | 292 allocate_widget_info (CONST char *type, CONST char *name, |
333 LWLIB_ID id, widget_value *val, | 293 LWLIB_ID id, widget_value *val, |
334 lw_callback pre_activate_cb, lw_callback selection_cb, | 294 lw_callback pre_activate_cb, lw_callback selection_cb, |
335 lw_callback post_activate_cb) | 295 lw_callback post_activate_cb) |
336 { | 296 { |
337 widget_info *info = (widget_info *) malloc (sizeof (widget_info)); | 297 widget_info *info = (widget_info *) malloc (sizeof (widget_info)); |
355 free_widget_info (widget_info *info) | 315 free_widget_info (widget_info *info) |
356 { | 316 { |
357 safe_free_str (info->type); | 317 safe_free_str (info->type); |
358 safe_free_str (info->name); | 318 safe_free_str (info->name); |
359 free_widget_value_tree (info->val); | 319 free_widget_value_tree (info->val); |
360 memset (info, '\0', sizeof (widget_info)); | 320 memset ((void*)info, 0xDEADBEEF, sizeof (widget_info)); |
361 free (info); | 321 free (info); |
362 } | 322 } |
363 | 323 |
364 static void | 324 static void |
365 mark_widget_destroyed (Widget widget, XtPointer closure, XtPointer call_data) | 325 mark_widget_destroyed (Widget widget, XtPointer closure, XtPointer call_data) |
390 } | 350 } |
391 | 351 |
392 static void | 352 static void |
393 free_widget_instance (widget_instance *instance) | 353 free_widget_instance (widget_instance *instance) |
394 { | 354 { |
395 memset (instance, '\0', sizeof (widget_instance)); | 355 memset ((void *) instance, 0xDEADBEEF, sizeof (widget_instance)); |
396 free (instance); | 356 free (instance); |
397 } | 357 } |
398 | 358 |
399 static widget_info * | 359 static widget_info * |
400 get_widget_info (LWLIB_ID id, Boolean remove_p) | 360 get_widget_info (LWLIB_ID id, Boolean remove_p) |
500 } | 460 } |
501 | 461 |
502 | 462 |
503 /* utility function for widget_value */ | 463 /* utility function for widget_value */ |
504 static Boolean | 464 static Boolean |
505 safe_strcmp (const char *s1, const char *s2) | 465 safe_strcmp (CONST char *s1, CONST char *s2) |
506 { | 466 { |
507 if (!!s1 ^ !!s2) return True; | 467 if (!!s1 ^ !!s2) return True; |
508 return (s1 && s2) ? strcmp (s1, s2) : s1 ? False : !!s2; | 468 return (s1 && s2) ? strcmp (s1, s2) : s1 ? False : !!s2; |
509 } | 469 } |
510 | 470 |
511 #ifndef WIN32_NATIVE | 471 #ifndef WINDOWSNT |
512 static change_type | 472 static change_type |
513 max (change_type i1, change_type i2) | 473 max (change_type i1, change_type i2) |
514 { | 474 { |
515 return (int)i1 > (int)i2 ? i1 : i2; | 475 return (int)i1 > (int)i2 ? i1 : i2; |
516 } | 476 } |
615 EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "call-data change", | 575 EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "call-data change", |
616 val1->call_data, val2->call_data); | 576 val1->call_data, val2->call_data); |
617 change = max (change, INVISIBLE_CHANGE); | 577 change = max (change, INVISIBLE_CHANGE); |
618 val1->call_data = val2->call_data; | 578 val1->call_data = val2->call_data; |
619 } | 579 } |
620 #ifdef HAVE_WIDGETS | |
621 if (merge_widget_value_args (val1, val2)) | |
622 { | |
623 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "widget change", 0, 0); | |
624 change = max (change, VISIBLE_CHANGE); | |
625 } | |
626 #endif | |
627 | |
628 #ifdef NEED_SCROLLBARS | 580 #ifdef NEED_SCROLLBARS |
629 if (merge_scrollbar_values (val1, val2)) | 581 if (merge_scrollbar_values (val1, val2)) |
630 { | 582 { |
631 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "scrollbar change", 0, 0); | 583 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "scrollbar change", 0, 0); |
632 change = max (change, VISIBLE_CHANGE); | 584 change = max (change, VISIBLE_CHANGE); |
687 } | 639 } |
688 | 640 |
689 | 641 |
690 /* modifying the widgets */ | 642 /* modifying the widgets */ |
691 static Widget | 643 static Widget |
692 name_to_widget (widget_instance *instance, const char *name) | 644 name_to_widget (widget_instance *instance, CONST char *name) |
693 { | 645 { |
694 Widget widget = NULL; | 646 Widget widget = NULL; |
695 | 647 |
696 if (!instance->widget) | 648 if (!instance->widget) |
697 return NULL; | 649 return NULL; |
824 val->change = NO_CHANGE; | 776 val->change = NO_CHANGE; |
825 } | 777 } |
826 | 778 |
827 | 779 |
828 static widget_creation_function | 780 static widget_creation_function |
829 find_in_table (const char *type, widget_creation_entry *table) | 781 find_in_table (CONST char *type, widget_creation_entry *table) |
830 { | 782 { |
831 widget_creation_entry *cur; | 783 widget_creation_entry *cur; |
832 for (cur = table; cur->type; cur++) | 784 for (cur = table; cur->type; cur++) |
833 if (!strcasecmp (type, cur->type)) | 785 if (!strcasecmp (type, cur->type)) |
834 return cur->function; | 786 return cur->function; |
835 return NULL; | 787 return NULL; |
836 } | 788 } |
837 | 789 |
838 static Boolean | 790 static Boolean |
839 dialog_spec_p (const char *name) | 791 dialog_spec_p (CONST char *name) |
840 { | 792 { |
841 /* return True if name matches [EILPQeilpq][1-9][Bb] or | 793 /* return True if name matches [EILPQeilpq][1-9][Bb] or |
842 [EILPQeilpq][1-9][Bb][Rr][1-9] */ | 794 [EILPQeilpq][1-9][Bb][Rr][1-9] */ |
843 if (!name) | 795 if (!name) |
844 return False; | 796 return False; |
918 | 870 |
919 /* XtRealizeWidget (instance->widget);*/ | 871 /* XtRealizeWidget (instance->widget);*/ |
920 } | 872 } |
921 | 873 |
922 void | 874 void |
923 lw_register_widget (const char *type, const char *name, | 875 lw_register_widget (CONST char *type, CONST char *name, |
924 LWLIB_ID id, widget_value *val, | 876 LWLIB_ID id, widget_value *val, |
925 lw_callback pre_activate_cb, lw_callback selection_cb, | 877 lw_callback pre_activate_cb, lw_callback selection_cb, |
926 lw_callback post_activate_cb) | 878 lw_callback post_activate_cb) |
927 { | 879 { |
928 if (!get_widget_info (id, False)) | 880 if (!get_widget_info (id, False)) |
954 abort (); | 906 abort (); |
955 return instance->widget; | 907 return instance->widget; |
956 } | 908 } |
957 | 909 |
958 Widget | 910 Widget |
959 lw_create_widget (const char *type, const char *name, | 911 lw_create_widget (CONST char *type, CONST char *name, |
960 LWLIB_ID id, widget_value *val, | 912 LWLIB_ID id, widget_value *val, |
961 Widget parent, Boolean pop_up_p, lw_callback pre_activate_cb, | 913 Widget parent, Boolean pop_up_p, lw_callback pre_activate_cb, |
962 lw_callback selection_cb, lw_callback post_activate_cb) | 914 lw_callback selection_cb, lw_callback post_activate_cb) |
963 { | 915 { |
964 lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb, | 916 lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb, |
1046 free_widget_info (info); | 998 free_widget_info (info); |
1047 } | 999 } |
1048 } | 1000 } |
1049 | 1001 |
1050 void | 1002 void |
1051 lw_destroy_everything (void) | 1003 lw_destroy_everything () |
1052 { | 1004 { |
1053 while (all_widget_info) | 1005 while (all_widget_info) |
1054 lw_destroy_all_widgets (all_widget_info->id); | 1006 lw_destroy_all_widgets (all_widget_info->id); |
1055 } | 1007 } |
1056 | 1008 |
1057 void | 1009 void |
1058 lw_destroy_all_pop_ups (void) | 1010 lw_destroy_all_pop_ups () |
1059 { | 1011 { |
1060 widget_info *info; | 1012 widget_info *info; |
1061 widget_info *next; | 1013 widget_info *next; |
1062 widget_instance *instance; | 1014 widget_instance *instance; |
1063 | 1015 |
1346 show_one_widget_busy (next->widget, busy); | 1298 show_one_widget_busy (next->widget, busy); |
1347 info->busy = busy; | 1299 info->busy = busy; |
1348 } | 1300 } |
1349 } | 1301 } |
1350 } | 1302 } |
1351 | |
1352 void lw_add_value_args_to_args (widget_value* wv, ArgList addto, int* offset) | |
1353 { | |
1354 int i; | |
1355 if (wv->args && wv->args->nargs) | |
1356 { | |
1357 for (i = 0; i<wv->args->nargs; i++) | |
1358 { | |
1359 addto[i + *offset] = wv->args->args[i]; | |
1360 } | |
1361 *offset += wv->args->nargs; | |
1362 } | |
1363 } | |
1364 | |
1365 void lw_add_widget_value_arg (widget_value* wv, String name, XtArgVal value) | |
1366 { | |
1367 int i = 0; | |
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 /* If the arg is already there then we must replace it. */ | |
1382 for (i = 0; i < wv->args->nargs; i++) | |
1383 { | |
1384 if (!strcmp (wv->args->args[i].name, name)) | |
1385 { | |
1386 XtSetArg (wv->args->args [i], name, value); | |
1387 break; | |
1388 } | |
1389 } | |
1390 if (i >= wv->args->nargs) | |
1391 { | |
1392 XtSetArg (wv->args->args [wv->args->nargs], name, value); wv->args->nargs++; | |
1393 } | |
1394 } | |
1395 | |
1396 static void free_widget_value_args (widget_value* wv) | |
1397 { | |
1398 if (wv->args) | |
1399 { | |
1400 if (--wv->args->ref_count <= 0) | |
1401 { | |
1402 #ifdef LWLIB_WIDGETS_MOTIF | |
1403 int i; | |
1404 for (i = 0; i < wv->args->nargs; i++) | |
1405 { | |
1406 if (!strcmp (wv->args->args[i].name, XmNfontList)) | |
1407 XmFontListFree ((XmFontList)wv->args->args[i].value); | |
1408 } | |
1409 #endif | |
1410 free (wv->args->args); | |
1411 free (wv->args); | |
1412 wv->args = 0; | |
1413 } | |
1414 } | |
1415 } | |
1416 | |
1417 void lw_copy_widget_value_args (widget_value* val, widget_value* copy) | |
1418 { | |
1419 if (val == copy || val->args == copy->args) | |
1420 return; | |
1421 | |
1422 if (copy->args) | |
1423 { | |
1424 free_widget_value_args (copy); | |
1425 } | |
1426 | |
1427 if (val->args) | |
1428 { | |
1429 copy->args = val->args; | |
1430 copy->args->ref_count++; | |
1431 } | |
1432 } | |
1433 |