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