params.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:12k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* $Header: /usr/src/mash/repository/vint/xgraph/params.c,v 1.2 1999/12/08 19:32:41 heideman Exp $ */
  2. /*
  3.  * Xgraph Parameters
  4.  *
  5.  * This file contains routines for setting and retrieving
  6.  * various X style display parameters for xgraph.
  7.  *
  8.  * $Log: params.c,v $
  9.  * Revision 1.2  1999/12/08 19:32:41  heideman
  10.  * strcasecmp portability fix
  11.  *
  12.  * Revision 1.1.1.1  1999/12/03 23:15:52  heideman
  13.  * xgraph-12.0
  14.  *
  15.  */
  16. #ifndef lint
  17. static char rcsid[] = "$Id: params.c,v 1.2 1999/12/08 19:32:41 heideman Exp $";
  18. #endif
  19. #include <ctype.h>
  20. #include <stdio.h>
  21. #include "st.h"
  22. #include "params.h"
  23. #include "hard_devices.h"
  24. #include "xgraph.h" /* for string.h */
  25. /* For use by convenience macros */
  26. params  param_temp,
  27.        *param_temp_ptr;
  28. XColor  param_null_color =
  29. {0, 0, 0, 0, 0, 0};
  30. param_style param_null_style =
  31. {STYLE, 0, (char *) 0};
  32. static st_table *param_table = (st_table *) 0;
  33. typedef struct param_full_defn {
  34.     param_types type;
  35.     char   *text_form;
  36.     params *real_form;
  37. }       param_full;
  38. #define ISO_FONT "*-*-%s-medium-r-normal-*-*-%d-*-*-*-*-iso8859-*"
  39. static Display *param_disp;
  40. static Colormap param_cmap;
  41. static int param_scrn;
  42. static void free_resource();
  43. static params *resolve_entry();
  44. static int strihash();
  45. static int do_color();
  46. static int do_font();
  47. static int do_style();
  48. static int do_bool();
  49. #define DEF_INT "0"
  50. #define DEF_STR ""
  51. #define DEF_FONT "fixed"
  52. #define DEF_PIXEL "black"
  53. #define DEF_STYLE "1"
  54. #define DEF_BOOL "false"
  55. #define DEF_DBL "0.0"
  56. #define DEF_MAX_FONT 1024
  57. #define DEF_MAX_NAMES 10
  58. #define DUP(str)
  59. strcpy((char *) Malloc((unsigned) (strlen(str)+1)), (str))
  60. void
  61. param_init(disp, cmap)
  62. Display *disp; /* X Connection        */
  63. Colormap cmap; /* Colormap for colors */
  64. /*
  65.  * Initializes parameter package.  The display and colormap arguments
  66.  * are used to resolve font and pixel values.
  67.  */
  68. {
  69.     param_table = st_init_table(stricmp, strihash);
  70.     if (disp != NULL) {
  71. param_disp = disp;
  72. param_cmap = cmap;
  73. /* This could also be a parameter for greater generality */
  74. param_scrn = DefaultScreen(disp);
  75.     }
  76. }
  77. void
  78. param_set(name, type, val)
  79. char   *name; /* Name of parameter   */
  80. param_types type; /* Type                */
  81. char   *val; /* Text form for value */
  82. /*
  83.  * Sets the parameter with the given name to have the type
  84.  * `type' and the text value `value'.  This will be evaluated
  85.  * to its full form the first time it is referenced using
  86.  * param_get().  If it is already filled, the old value
  87.  * will be reclaimed.
  88.  */
  89. {
  90.     param_full *entry;
  91.     if (!param_table) {
  92. (void) fprintf(stderr, "Parameter table not initializedn");
  93. return;
  94.     }
  95.     if (st_lookup(param_table, name, (char **) &entry)) {
  96. if (entry->real_form)
  97.     free_resource(entry->real_form);
  98. entry->real_form = (params *) 0;
  99.     }
  100.     else {
  101. entry = (param_full *) Malloc(sizeof(param_full));
  102. entry->text_form = (char *) 0;
  103. entry->real_form = (params *) 0;
  104. (void) st_insert(param_table, DUP(name), (char *) entry);
  105.     }
  106.     entry->type = type;
  107.     if (entry->text_form)
  108. (void) Free((char *) (entry->text_form));
  109.     entry->text_form = DUP(val);
  110. }
  111. void
  112. param_reset(name, val)
  113. char   *name; /* Name of parameter   */
  114. char   *val; /* Text form for value */
  115. /*
  116.  * This routine sets the value of an existing parameter to a new
  117.  * value.  The type of the parameter remains the same.  Changes
  118.  * in type should be done by using param_set() directly.
  119.  */
  120. {
  121.     param_full *entry;
  122.     if (!param_table) {
  123. (void) fprintf(stderr, "Parameter table not initializedn");
  124. return;
  125.     }
  126.     if (st_lookup(param_table, name, (char **) &entry))
  127. param_set(name, entry->type, val);
  128.     else
  129. (void) fprintf(stderr, "Cannot reset unknown parameter `%s'n", name);
  130. }
  131. params *
  132. param_get(name, val)
  133. char   *name; /* Name of parameter */
  134. params *val; /* Result value      */
  135. /*
  136.  * Retrieves a value from the parameter table.  The value
  137.  * is placed in `val'.  If successful, the routine will
  138.  * return `val'.  Otherwise, it will return zero.
  139.  */
  140. {
  141.     param_full *entry;
  142.     if (!param_table) {
  143. (void) fprintf(stderr, "Parameter table not initializedn");
  144. return (params *) 0;
  145.     }
  146.     if (st_lookup(param_table, name, (char **) &entry)) {
  147. if (!entry->real_form)
  148.     entry->real_form = resolve_entry(name, entry->type,
  149.      entry->text_form);
  150. *val = *(entry->real_form);
  151. return val;
  152.     }
  153.     else {
  154. return (params *) 0;
  155.     }
  156. }
  157. static void
  158. free_resource(val)
  159. params *val; /* Value to free */
  160. /*
  161.  * Reclaims a resource based on its type.
  162.  */
  163. {
  164.     switch (val->type) {
  165.     case INT:
  166.     case STR:
  167.     case BOOL:
  168.     case DBL:
  169. /* No reclaimation necessary */
  170. break;
  171.     case PIXEL:
  172. if ((val->pixv.value.pixel != WhitePixel(param_disp, param_scrn)) &&
  173.     (val->pixv.value.pixel != BlackPixel(param_disp, param_scrn)))
  174.     XFreeColors(param_disp, param_cmap, &(val->pixv.value.pixel), 1, 0);
  175. break;
  176.     case FONT:
  177. XFreeFont(param_disp, val->fontv.value);
  178. break;
  179.     case STYLE:
  180. (void) Free(val->stylev.dash_list);
  181. break;
  182.     }
  183.     (void) Free((char *) val);
  184. }
  185. static params *
  186. resolve_entry(name, type, form)
  187. char   *name; /* Name of item for errors */
  188. param_types type; /* What type of thing */
  189. char   *form; /* Textual form       */
  190. /*
  191.  * Allocates and returns an appropriate parameter structure
  192.  * by translating `form' into its native type as given by `type'.
  193.  * If it can't translate the given form, it will fall back onto
  194.  * the default.
  195.  */
  196. {
  197.     static char paramstr[] =
  198.     "Parameter %s: can't translate `%s' into a %s (defaulting to `%s')n";
  199.     params *result = (params *) Malloc(sizeof(params));
  200.     result->type = type;
  201.     switch (type) {
  202.     case INT:
  203. if (sscanf(form, "%d", &result->intv.value) != 1) {
  204.     (void) fprintf(stderr, paramstr, name, form, "integer", DEF_INT);
  205.     result->intv.value = atoi(DEF_INT);
  206. }
  207. break;
  208.     case STR:
  209. result->strv.value = form;
  210. break;
  211.     case PIXEL:
  212. if (!do_color(form, &result->pixv.value)) {
  213.     (void) fprintf(stderr, paramstr, name, form, "color", DEF_PIXEL);
  214.     (void) do_color(DEF_PIXEL, &result->pixv.value);
  215. }
  216. break;
  217.     case FONT:
  218. if (!do_font(form, &result->fontv.value)) {
  219.     (void) fprintf(stderr, paramstr, name, form, "font", DEF_FONT);
  220.     (void) do_font(DEF_FONT, &result->fontv.value);
  221. }
  222. break;
  223.     case STYLE:
  224. if (!do_style(form, &result->stylev)) {
  225.     (void) fprintf(stderr, paramstr, name, form, "line style",
  226.    DEF_STYLE);
  227.     (void) do_style(DEF_STYLE, &result->stylev);
  228. }
  229. break;
  230.     case BOOL:
  231. if (!do_bool(form, &result->boolv.value)) {
  232.     (void) fprintf(stderr, paramstr, name, form, "boolean flag",
  233.    DEF_BOOL);
  234.     (void) do_bool(DEF_BOOL, &result->boolv.value);
  235. }
  236. break;
  237.     case DBL:
  238. if (sscanf(form, "%lf", &result->dblv.value) != 1) {
  239.     (void) fprintf(stderr, paramstr, name, form, "double", DEF_DBL);
  240.     result->dblv.value = atof(DEF_DBL);
  241. }
  242. break;
  243.     }
  244.     return result;
  245. }
  246. static int
  247. do_color(name, color)
  248. char   *name; /* Name for color */
  249. XColor *color; /* Returned color */
  250. /*
  251.  * Translates `name' into a color and attempts to get the pixel
  252.  * for the color using XAllocColor().
  253.  */
  254. {
  255.     int     result = 1;
  256.     if (PM_INT("Output Device") == D_XWINDOWS) {
  257. if (XParseColor(param_disp, param_cmap, name, color)) {
  258.     if (stricmp(name, "black") == 0) {
  259. color->pixel = BlackPixel(param_disp, param_scrn);
  260. XQueryColor(param_disp, param_cmap, color);
  261.     }
  262.     else if (stricmp(name, "white") == 0) {
  263. color->pixel = WhitePixel(param_disp, param_scrn);
  264. XQueryColor(param_disp, param_cmap, color);
  265.     }
  266.     else
  267. result = XAllocColor(param_disp, param_cmap, color);
  268. }
  269. else
  270.     result = 0;
  271.     }
  272.     return result;
  273. }
  274. static int
  275. do_font(name, font_info)
  276. char   *name; /* Name of desired font      */
  277. XFontStruct **font_info; /* Returned font information */
  278. /*
  279.  * This routine translates a font name into a font structure.  The
  280.  * font name can be in two forms.  The first form is <family>-<size>.
  281.  * The family is a family name (like helvetica) and the size is
  282.  * in points (like 12).  If the font is not in this form, it
  283.  * is assumed to be a regular X font name specification and
  284.  * is looked up using the standard means.
  285.  */
  286. {
  287.     char    name_copy[DEF_MAX_FONT],
  288.             query_spec[DEF_MAX_FONT];
  289.     char   *font_family,
  290.            *font_size,
  291.           **font_list;
  292.     int     font_size_value,
  293.             font_count,
  294.             i;
  295.     /* First attempt to interpret as font family/size */
  296.     if (PM_INT("Output Device") == D_XWINDOWS) {
  297. (void) strcpy(name_copy, name);
  298. if (font_size = index(name_copy, '-')) {
  299.     *font_size = '';
  300.     font_family = name_copy;
  301.     font_size++;
  302.     font_size_value = atoi(font_size);
  303.     if (font_size_value > 0) {
  304. /*
  305.  * Still a little iffy -- what about weight and roman vs. other
  306.  */
  307. (void) sprintf(query_spec, ISO_FONT,
  308.        font_family, font_size_value * 10);
  309. font_list = XListFonts(param_disp, query_spec,
  310.        DEF_MAX_NAMES, &font_count);
  311. /* Load first one that you can */
  312. for (i = 0; i < font_count; i++)
  313.     if (*font_info = XLoadQueryFont(param_disp, font_list[i]))
  314. break;
  315. if (*font_info)
  316.     return 1;
  317.     }
  318. }
  319. /* Assume normal font name */
  320. return (int) (*font_info = XLoadQueryFont(param_disp, name));
  321.     }
  322. }
  323. static int
  324. do_style(list, val)
  325. char   *list; /* List of ones and zeros */
  326. param_style *val; /* Line style returned    */
  327. /*
  328.  * Translates a string representation of a dash specification into
  329.  * a form suitable for use in XSetDashes().  Assumes `list'
  330.  * is a null terminated string of ones and zeros.
  331.  */
  332. {
  333.     char   *i,
  334.            *spot,
  335.             last_char;
  336.     int     count;
  337.     for (i = list; *i; i++)
  338. if ((*i != '0') && (*i != '1'))
  339.     break;
  340.     if (!*i) {
  341. val->len = 0;
  342. last_char = '';
  343. for (i = list; *i; i++) {
  344.     if (*i != last_char) {
  345. val->len += 1;
  346. last_char = *i;
  347.     }
  348. }
  349. val->dash_list = (char *) Malloc((unsigned)
  350.  (sizeof(char) * val->len + 1));
  351. last_char = *list;
  352. spot = val->dash_list;
  353. count = 0;
  354. for (i = list; *i; i++) {
  355.     if (*i != last_char) {
  356. *spot++ = (char) count;
  357. last_char = *i;
  358. count = 1;
  359.     }
  360.     else
  361. count++;
  362. }
  363. *spot = (char) count;
  364. return 1;
  365.     }
  366.     else {
  367. return 0;
  368.     }
  369. }
  370. static char *positive[] =
  371. {"on", "yes", "true", "1", "affirmative", (char *) 0};
  372. static char *negative[] =
  373. {"off", "no", "false", "0", "negative", (char *) 0};
  374. static int
  375. do_bool(name, val)
  376. char   *name; /* String representation */
  377. int    *val; /* Returned value        */
  378. /*
  379.  * Translates a string representation into a suitable binary value.
  380.  * Can parse all kinds of interesting boolean type words.
  381.  */
  382. {
  383.     char  **term;
  384.     for (term = positive; *term; term++) {
  385. if (stricmp(name, *term) == 0)
  386.     break;
  387.     }
  388.     if (*term) {
  389. *val = 1;
  390. return 1;
  391.     }
  392.     for (term = negative; *term; term++)
  393. if (stricmp(name, *term) == 0)
  394.     break;
  395.     if (*term) {
  396. *val = 0;
  397. return 1;
  398.     }
  399.     return 0;
  400. }
  401. /*ARGSUSED*/
  402. static enum st_retval
  403. dump_it(key, value, arg)
  404. char   *key,
  405.        *value,
  406.        *arg;
  407. {
  408.     param_full *val = (param_full *) value;
  409.     (void) fprintf(stdout, "%s (", key);
  410.     switch (val->type) {
  411.     case INT:
  412. (void) fprintf(stdout, "INT");
  413. break;
  414.     case STR:
  415. (void) fprintf(stdout, "STR");
  416. break;
  417.     case PIXEL:
  418. (void) fprintf(stdout, "PIXEL");
  419. break;
  420.     case FONT:
  421. (void) fprintf(stdout, "FONT");
  422. break;
  423.     case STYLE:
  424. (void) fprintf(stdout, "STYLE");
  425. break;
  426.     case BOOL:
  427. (void) fprintf(stdout, "BOOL");
  428. break;
  429.     case DBL:
  430. (void) fprintf(stdout, "DBL");
  431. break;
  432.     }
  433.     (void) fprintf(stdout, ") = %sn", val->text_form);
  434.     return ST_CONTINUE;
  435. }
  436. void
  437. param_dump()
  438. /*
  439.  * Dumps all of the parameter values to standard output.
  440.  */
  441. {
  442.     st_foreach(param_table, dump_it, (char *) 0);
  443. }
  444. #ifdef HAVE_STRCASECMP
  445. int
  446. stricmp(a, b)
  447. char *a, *b;
  448. {
  449. return strcasecmp(a, b);
  450. }
  451. #else
  452. int
  453. stricmp(a, b)
  454. register char *a,
  455.        *b;
  456. /*
  457.  * This routine compares two strings disregarding case.
  458.  */
  459. {
  460.     register int value;
  461.     if ((a == (char *) 0) || (b == (char *) 0)) {
  462. return a - b;
  463.     }
  464.     for ( /* nothing */ ;
  465.  ((*a | *b) &&
  466.   !(value = ((isupper(*a) ? *a - 'A' + 'a' : *a) -
  467.      (isupper(*b) ? *b - 'A' + 'a' : *b))));
  468.  a++, b++)
  469.  /* Empty Body */ ;
  470.     return value;
  471. }
  472. #endif
  473. static int
  474. strihash(string, modulus)
  475. register char *string;
  476. int     modulus;
  477. /* Case insensitive computation */
  478. {
  479.     register int val = 0;
  480.     register int c;
  481.     while ((c = *string++) != '') {
  482. if (isupper(c))
  483.     c = tolower(c);
  484. val = val * 997 + c;
  485.     }
  486.     return ((val < 0) ? -val : val) % modulus;
  487. }