Mercurial > hg > xemacs-beta
comparison lwlib/lwlib.c @ 442:abe6d1db359e r21-2-36
Import from CVS: tag r21-2-36
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:35:02 +0200 |
parents | 84b14dcb0985 |
children | 98528da0b7fc |
comparison
equal
deleted
inserted
replaced
441:72a7cfa4a488 | 442:abe6d1db359e |
---|---|
74 static void free_widget_value_args (widget_value* wv); | 74 static void free_widget_value_args (widget_value* wv); |
75 | 75 |
76 | 76 |
77 /* utility functions for widget_instance and widget_info */ | 77 /* utility functions for widget_instance and widget_info */ |
78 static char * | 78 static char * |
79 safe_strdup (CONST char *s) | 79 safe_strdup (const char *s) |
80 { | 80 { |
81 char *result; | 81 char *result; |
82 if (! s) return 0; | 82 if (! s) return 0; |
83 result = (char *) malloc (strlen (s) + 1); | 83 result = (char *) malloc (strlen (s) + 1); |
84 if (! result) | 84 if (! result) |
255 else if (!new->args && old->args) | 255 else if (!new->args && old->args) |
256 { | 256 { |
257 lw_copy_widget_value_args (old, new); | 257 lw_copy_widget_value_args (old, new); |
258 changed = True; | 258 changed = True; |
259 } | 259 } |
260 else if (new->args && old->args) | 260 else if (new->args && old->args && new->args != old->args) |
261 { | 261 { |
262 /* #### Do something more sensible here than just copying the | 262 /* #### Do something more sensible here than just copying the |
263 new values (like actually merging the values). */ | 263 new values (like actually merging the values). */ |
264 free_widget_value_args (old); | |
265 lw_copy_widget_value_args (new, old); | 264 lw_copy_widget_value_args (new, old); |
266 changed = True; | 265 changed = True; |
267 } | 266 } |
268 | 267 |
269 return changed; | 268 return changed; |
271 #endif /* HAVE_WIDGETS */ | 270 #endif /* HAVE_WIDGETS */ |
272 | 271 |
273 /* Make a complete copy of a widget_value tree. Store CHANGE into | 272 /* Make a complete copy of a widget_value tree. Store CHANGE into |
274 the widget_value tree's `change' field. */ | 273 the widget_value tree's `change' field. */ |
275 | 274 |
276 static widget_value * | 275 widget_value * |
277 copy_widget_value_tree (widget_value *val, change_type change) | 276 copy_widget_value_tree (widget_value *val, change_type change) |
278 { | 277 { |
279 widget_value *copy; | 278 widget_value *copy; |
280 | 279 |
281 if (!val) | 280 if (!val) |
328 free_widget_value (copy); /* free the node, but not its contents. */ | 327 free_widget_value (copy); /* free the node, but not its contents. */ |
329 return node; | 328 return node; |
330 } | 329 } |
331 | 330 |
332 static widget_info * | 331 static widget_info * |
333 allocate_widget_info (CONST char *type, CONST char *name, | 332 allocate_widget_info (const char *type, const char *name, |
334 LWLIB_ID id, widget_value *val, | 333 LWLIB_ID id, widget_value *val, |
335 lw_callback pre_activate_cb, lw_callback selection_cb, | 334 lw_callback pre_activate_cb, lw_callback selection_cb, |
336 lw_callback post_activate_cb) | 335 lw_callback post_activate_cb) |
337 { | 336 { |
338 widget_info *info = (widget_info *) malloc (sizeof (widget_info)); | 337 widget_info *info = (widget_info *) malloc (sizeof (widget_info)); |
501 } | 500 } |
502 | 501 |
503 | 502 |
504 /* utility function for widget_value */ | 503 /* utility function for widget_value */ |
505 static Boolean | 504 static Boolean |
506 safe_strcmp (CONST char *s1, CONST char *s2) | 505 safe_strcmp (const char *s1, const char *s2) |
507 { | 506 { |
508 if (!!s1 ^ !!s2) return True; | 507 if (!!s1 ^ !!s2) return True; |
509 return (s1 && s2) ? strcmp (s1, s2) : s1 ? False : !!s2; | 508 return (s1 && s2) ? strcmp (s1, s2) : s1 ? False : !!s2; |
510 } | 509 } |
511 | 510 |
512 #ifndef WINDOWSNT | 511 #ifndef WIN32_NATIVE |
513 static change_type | 512 static change_type |
514 max (change_type i1, change_type i2) | 513 max (change_type i1, change_type i2) |
515 { | 514 { |
516 return (int)i1 > (int)i2 ? i1 : i2; | 515 return (int)i1 > (int)i2 ? i1 : i2; |
517 } | 516 } |
688 } | 687 } |
689 | 688 |
690 | 689 |
691 /* modifying the widgets */ | 690 /* modifying the widgets */ |
692 static Widget | 691 static Widget |
693 name_to_widget (widget_instance *instance, CONST char *name) | 692 name_to_widget (widget_instance *instance, const char *name) |
694 { | 693 { |
695 Widget widget = NULL; | 694 Widget widget = NULL; |
696 | 695 |
697 if (!instance->widget) | 696 if (!instance->widget) |
698 return NULL; | 697 return NULL; |
823 | 822 |
824 for (val = instance->info->val; val; val = val->next) | 823 for (val = instance->info->val; val; val = val->next) |
825 val->change = NO_CHANGE; | 824 val->change = NO_CHANGE; |
826 } | 825 } |
827 | 826 |
827 /* strcasecmp() is not sufficiently portable or standard, | |
828 and it's easier just to write our own. */ | |
829 static int | |
830 ascii_strcasecmp (const char *s1, const char *s2) | |
831 { | |
832 while (1) | |
833 { | |
834 char c1 = *s1++; | |
835 char c2 = *s2++; | |
836 if (c1 >= 'A' && c1 <= 'Z') c1 += 'a' - 'A'; | |
837 if (c2 >= 'A' && c2 <= 'Z') c2 += 'a' - 'A'; | |
838 if (c1 != c2) return c1 - c2; | |
839 if (c1 == '\0') return 0; | |
840 } | |
841 } | |
828 | 842 |
829 static widget_creation_function | 843 static widget_creation_function |
830 find_in_table (CONST char *type, widget_creation_entry *table) | 844 find_in_table (const char *type, widget_creation_entry *table) |
831 { | 845 { |
832 widget_creation_entry *cur; | 846 widget_creation_entry *cur; |
833 for (cur = table; cur->type; cur++) | 847 for (cur = table; cur->type; cur++) |
834 if (!strcasecmp (type, cur->type)) | 848 if (!ascii_strcasecmp (type, cur->type)) |
835 return cur->function; | 849 return cur->function; |
836 return NULL; | 850 return NULL; |
837 } | 851 } |
838 | 852 |
839 static Boolean | 853 static Boolean |
840 dialog_spec_p (CONST char *name) | 854 dialog_spec_p (const char *name) |
841 { | 855 { |
842 /* return True if name matches [EILPQeilpq][1-9][Bb] or | 856 /* return True if name matches [EILPQeilpq][1-9][Bb] or |
843 [EILPQeilpq][1-9][Bb][Rr][1-9] */ | 857 [EILPQeilpq][1-9][Bb][Rr][1-9] */ |
844 if (!name) | 858 if (!name) |
845 return False; | 859 return False; |
919 | 933 |
920 /* XtRealizeWidget (instance->widget);*/ | 934 /* XtRealizeWidget (instance->widget);*/ |
921 } | 935 } |
922 | 936 |
923 void | 937 void |
924 lw_register_widget (CONST char *type, CONST char *name, | 938 lw_register_widget (const char *type, const char *name, |
925 LWLIB_ID id, widget_value *val, | 939 LWLIB_ID id, widget_value *val, |
926 lw_callback pre_activate_cb, lw_callback selection_cb, | 940 lw_callback pre_activate_cb, lw_callback selection_cb, |
927 lw_callback post_activate_cb) | 941 lw_callback post_activate_cb) |
928 { | 942 { |
929 if (!get_widget_info (id, False)) | 943 if (!get_widget_info (id, False)) |
955 abort (); | 969 abort (); |
956 return instance->widget; | 970 return instance->widget; |
957 } | 971 } |
958 | 972 |
959 Widget | 973 Widget |
960 lw_create_widget (CONST char *type, CONST char *name, | 974 lw_create_widget (const char *type, const char *name, |
961 LWLIB_ID id, widget_value *val, | 975 LWLIB_ID id, widget_value *val, |
962 Widget parent, Boolean pop_up_p, lw_callback pre_activate_cb, | 976 Widget parent, Boolean pop_up_p, lw_callback pre_activate_cb, |
963 lw_callback selection_cb, lw_callback post_activate_cb) | 977 lw_callback selection_cb, lw_callback post_activate_cb) |
964 { | 978 { |
965 lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb, | 979 lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb, |
1047 free_widget_info (info); | 1061 free_widget_info (info); |
1048 } | 1062 } |
1049 } | 1063 } |
1050 | 1064 |
1051 void | 1065 void |
1052 lw_destroy_everything () | 1066 lw_destroy_everything (void) |
1053 { | 1067 { |
1054 while (all_widget_info) | 1068 while (all_widget_info) |
1055 lw_destroy_all_widgets (all_widget_info->id); | 1069 lw_destroy_all_widgets (all_widget_info->id); |
1056 } | 1070 } |
1057 | 1071 |
1058 void | 1072 void |
1059 lw_destroy_all_pop_ups () | 1073 lw_destroy_all_pop_ups (void) |
1060 { | 1074 { |
1061 widget_info *info; | 1075 widget_info *info; |
1062 widget_info *next; | 1076 widget_info *next; |
1063 widget_instance *instance; | 1077 widget_instance *instance; |
1064 | 1078 |
1363 } | 1377 } |
1364 } | 1378 } |
1365 | 1379 |
1366 void lw_add_widget_value_arg (widget_value* wv, String name, XtArgVal value) | 1380 void lw_add_widget_value_arg (widget_value* wv, String name, XtArgVal value) |
1367 { | 1381 { |
1382 int i = 0; | |
1368 if (!wv->args) | 1383 if (!wv->args) |
1369 { | 1384 { |
1370 wv->args = (widget_args *) malloc (sizeof (widget_args)); | 1385 wv->args = (widget_args *) malloc (sizeof (widget_args)); |
1371 memset (wv->args, '\0', sizeof (widget_args)); | 1386 memset (wv->args, '\0', sizeof (widget_args)); |
1372 wv->args->ref_count = 1; | 1387 wv->args->ref_count = 1; |
1376 } | 1391 } |
1377 | 1392 |
1378 if (wv->args->nargs > 10) | 1393 if (wv->args->nargs > 10) |
1379 return; | 1394 return; |
1380 | 1395 |
1381 XtSetArg (wv->args->args [wv->args->nargs], name, value); wv->args->nargs++; | 1396 /* If the arg is already there then we must replace it. */ |
1397 for (i = 0; i < wv->args->nargs; i++) | |
1398 { | |
1399 if (!strcmp (wv->args->args[i].name, name)) | |
1400 { | |
1401 XtSetArg (wv->args->args [i], name, value); | |
1402 break; | |
1403 } | |
1404 } | |
1405 if (i >= wv->args->nargs) | |
1406 { | |
1407 XtSetArg (wv->args->args [wv->args->nargs], name, value); wv->args->nargs++; | |
1408 } | |
1382 } | 1409 } |
1383 | 1410 |
1384 static void free_widget_value_args (widget_value* wv) | 1411 static void free_widget_value_args (widget_value* wv) |
1385 { | 1412 { |
1386 if (wv->args) | 1413 if (wv->args) |
1395 XmFontListFree ((XmFontList)wv->args->args[i].value); | 1422 XmFontListFree ((XmFontList)wv->args->args[i].value); |
1396 } | 1423 } |
1397 #endif | 1424 #endif |
1398 free (wv->args->args); | 1425 free (wv->args->args); |
1399 free (wv->args); | 1426 free (wv->args); |
1400 wv->args = (widget_args*)0xDEADBEEF; | 1427 wv->args = 0; |
1401 } | 1428 } |
1402 } | 1429 } |
1403 } | 1430 } |
1404 | 1431 |
1405 void lw_copy_widget_value_args (widget_value* val, widget_value* copy) | 1432 void lw_copy_widget_value_args (widget_value* val, widget_value* copy) |
1406 { | 1433 { |
1407 if (!val->args) | 1434 if (val == copy || val->args == copy->args) |
1408 { | 1435 return; |
1409 if (copy->args) | 1436 |
1410 free_widget_value_args (copy); | 1437 if (copy->args) |
1411 copy->args = 0; | 1438 { |
1412 } | 1439 free_widget_value_args (copy); |
1413 else | 1440 } |
1441 | |
1442 if (val->args) | |
1414 { | 1443 { |
1415 copy->args = val->args; | 1444 copy->args = val->args; |
1416 copy->args->ref_count++; | 1445 copy->args->ref_count++; |
1417 } | 1446 } |
1418 } | 1447 } |
1419 | 1448 |
1449 /* Remove %_ and convert %% to %. We can do this in-place because we | |
1450 are always shortening, never lengthening, the string. */ | |
1451 void | |
1452 lw_remove_accelerator_spec (char *val) | |
1453 { | |
1454 char *foo = val, *bar = val; | |
1455 | |
1456 while (*bar) | |
1457 { | |
1458 if (*bar == '%' && *(bar+1) == '_') | |
1459 bar += 2; | |
1460 else if (*bar == '%' && *(bar+1) == '%') | |
1461 { | |
1462 *foo++ = *bar++; | |
1463 bar++; | |
1464 } | |
1465 else | |
1466 *foo++ = *bar++; | |
1467 } | |
1468 *foo = '\0'; | |
1469 } |