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