params.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:12k
- /* $Header: /usr/src/mash/repository/vint/xgraph/params.c,v 1.2 1999/12/08 19:32:41 heideman Exp $ */
- /*
- * Xgraph Parameters
- *
- * This file contains routines for setting and retrieving
- * various X style display parameters for xgraph.
- *
- * $Log: params.c,v $
- * Revision 1.2 1999/12/08 19:32:41 heideman
- * strcasecmp portability fix
- *
- * Revision 1.1.1.1 1999/12/03 23:15:52 heideman
- * xgraph-12.0
- *
- */
- #ifndef lint
- static char rcsid[] = "$Id: params.c,v 1.2 1999/12/08 19:32:41 heideman Exp $";
- #endif
- #include <ctype.h>
- #include <stdio.h>
- #include "st.h"
- #include "params.h"
- #include "hard_devices.h"
- #include "xgraph.h" /* for string.h */
- /* For use by convenience macros */
- params param_temp,
- *param_temp_ptr;
- XColor param_null_color =
- {0, 0, 0, 0, 0, 0};
- param_style param_null_style =
- {STYLE, 0, (char *) 0};
- static st_table *param_table = (st_table *) 0;
- typedef struct param_full_defn {
- param_types type;
- char *text_form;
- params *real_form;
- } param_full;
- #define ISO_FONT "*-*-%s-medium-r-normal-*-*-%d-*-*-*-*-iso8859-*"
- static Display *param_disp;
- static Colormap param_cmap;
- static int param_scrn;
- static void free_resource();
- static params *resolve_entry();
- static int strihash();
- static int do_color();
- static int do_font();
- static int do_style();
- static int do_bool();
- #define DEF_INT "0"
- #define DEF_STR ""
- #define DEF_FONT "fixed"
- #define DEF_PIXEL "black"
- #define DEF_STYLE "1"
- #define DEF_BOOL "false"
- #define DEF_DBL "0.0"
- #define DEF_MAX_FONT 1024
- #define DEF_MAX_NAMES 10
- #define DUP(str)
- strcpy((char *) Malloc((unsigned) (strlen(str)+1)), (str))
- void
- param_init(disp, cmap)
- Display *disp; /* X Connection */
- Colormap cmap; /* Colormap for colors */
- /*
- * Initializes parameter package. The display and colormap arguments
- * are used to resolve font and pixel values.
- */
- {
- param_table = st_init_table(stricmp, strihash);
- if (disp != NULL) {
- param_disp = disp;
- param_cmap = cmap;
- /* This could also be a parameter for greater generality */
- param_scrn = DefaultScreen(disp);
- }
- }
- void
- param_set(name, type, val)
- char *name; /* Name of parameter */
- param_types type; /* Type */
- char *val; /* Text form for value */
- /*
- * Sets the parameter with the given name to have the type
- * `type' and the text value `value'. This will be evaluated
- * to its full form the first time it is referenced using
- * param_get(). If it is already filled, the old value
- * will be reclaimed.
- */
- {
- param_full *entry;
- if (!param_table) {
- (void) fprintf(stderr, "Parameter table not initializedn");
- return;
- }
- if (st_lookup(param_table, name, (char **) &entry)) {
- if (entry->real_form)
- free_resource(entry->real_form);
- entry->real_form = (params *) 0;
- }
- else {
- entry = (param_full *) Malloc(sizeof(param_full));
- entry->text_form = (char *) 0;
- entry->real_form = (params *) 0;
- (void) st_insert(param_table, DUP(name), (char *) entry);
- }
- entry->type = type;
- if (entry->text_form)
- (void) Free((char *) (entry->text_form));
- entry->text_form = DUP(val);
- }
- void
- param_reset(name, val)
- char *name; /* Name of parameter */
- char *val; /* Text form for value */
- /*
- * This routine sets the value of an existing parameter to a new
- * value. The type of the parameter remains the same. Changes
- * in type should be done by using param_set() directly.
- */
- {
- param_full *entry;
- if (!param_table) {
- (void) fprintf(stderr, "Parameter table not initializedn");
- return;
- }
- if (st_lookup(param_table, name, (char **) &entry))
- param_set(name, entry->type, val);
- else
- (void) fprintf(stderr, "Cannot reset unknown parameter `%s'n", name);
- }
- params *
- param_get(name, val)
- char *name; /* Name of parameter */
- params *val; /* Result value */
- /*
- * Retrieves a value from the parameter table. The value
- * is placed in `val'. If successful, the routine will
- * return `val'. Otherwise, it will return zero.
- */
- {
- param_full *entry;
- if (!param_table) {
- (void) fprintf(stderr, "Parameter table not initializedn");
- return (params *) 0;
- }
- if (st_lookup(param_table, name, (char **) &entry)) {
- if (!entry->real_form)
- entry->real_form = resolve_entry(name, entry->type,
- entry->text_form);
- *val = *(entry->real_form);
- return val;
- }
- else {
- return (params *) 0;
- }
- }
- static void
- free_resource(val)
- params *val; /* Value to free */
- /*
- * Reclaims a resource based on its type.
- */
- {
- switch (val->type) {
- case INT:
- case STR:
- case BOOL:
- case DBL:
- /* No reclaimation necessary */
- break;
- case PIXEL:
- if ((val->pixv.value.pixel != WhitePixel(param_disp, param_scrn)) &&
- (val->pixv.value.pixel != BlackPixel(param_disp, param_scrn)))
- XFreeColors(param_disp, param_cmap, &(val->pixv.value.pixel), 1, 0);
- break;
- case FONT:
- XFreeFont(param_disp, val->fontv.value);
- break;
- case STYLE:
- (void) Free(val->stylev.dash_list);
- break;
- }
- (void) Free((char *) val);
- }
- static params *
- resolve_entry(name, type, form)
- char *name; /* Name of item for errors */
- param_types type; /* What type of thing */
- char *form; /* Textual form */
- /*
- * Allocates and returns an appropriate parameter structure
- * by translating `form' into its native type as given by `type'.
- * If it can't translate the given form, it will fall back onto
- * the default.
- */
- {
- static char paramstr[] =
- "Parameter %s: can't translate `%s' into a %s (defaulting to `%s')n";
- params *result = (params *) Malloc(sizeof(params));
- result->type = type;
- switch (type) {
- case INT:
- if (sscanf(form, "%d", &result->intv.value) != 1) {
- (void) fprintf(stderr, paramstr, name, form, "integer", DEF_INT);
- result->intv.value = atoi(DEF_INT);
- }
- break;
- case STR:
- result->strv.value = form;
- break;
- case PIXEL:
- if (!do_color(form, &result->pixv.value)) {
- (void) fprintf(stderr, paramstr, name, form, "color", DEF_PIXEL);
- (void) do_color(DEF_PIXEL, &result->pixv.value);
- }
- break;
- case FONT:
- if (!do_font(form, &result->fontv.value)) {
- (void) fprintf(stderr, paramstr, name, form, "font", DEF_FONT);
- (void) do_font(DEF_FONT, &result->fontv.value);
- }
- break;
- case STYLE:
- if (!do_style(form, &result->stylev)) {
- (void) fprintf(stderr, paramstr, name, form, "line style",
- DEF_STYLE);
- (void) do_style(DEF_STYLE, &result->stylev);
- }
- break;
- case BOOL:
- if (!do_bool(form, &result->boolv.value)) {
- (void) fprintf(stderr, paramstr, name, form, "boolean flag",
- DEF_BOOL);
- (void) do_bool(DEF_BOOL, &result->boolv.value);
- }
- break;
- case DBL:
- if (sscanf(form, "%lf", &result->dblv.value) != 1) {
- (void) fprintf(stderr, paramstr, name, form, "double", DEF_DBL);
- result->dblv.value = atof(DEF_DBL);
- }
- break;
- }
- return result;
- }
- static int
- do_color(name, color)
- char *name; /* Name for color */
- XColor *color; /* Returned color */
- /*
- * Translates `name' into a color and attempts to get the pixel
- * for the color using XAllocColor().
- */
- {
- int result = 1;
- if (PM_INT("Output Device") == D_XWINDOWS) {
- if (XParseColor(param_disp, param_cmap, name, color)) {
- if (stricmp(name, "black") == 0) {
- color->pixel = BlackPixel(param_disp, param_scrn);
- XQueryColor(param_disp, param_cmap, color);
- }
- else if (stricmp(name, "white") == 0) {
- color->pixel = WhitePixel(param_disp, param_scrn);
- XQueryColor(param_disp, param_cmap, color);
- }
- else
- result = XAllocColor(param_disp, param_cmap, color);
- }
- else
- result = 0;
- }
- return result;
- }
- static int
- do_font(name, font_info)
- char *name; /* Name of desired font */
- XFontStruct **font_info; /* Returned font information */
- /*
- * This routine translates a font name into a font structure. The
- * font name can be in two forms. The first form is <family>-<size>.
- * The family is a family name (like helvetica) and the size is
- * in points (like 12). If the font is not in this form, it
- * is assumed to be a regular X font name specification and
- * is looked up using the standard means.
- */
- {
- char name_copy[DEF_MAX_FONT],
- query_spec[DEF_MAX_FONT];
- char *font_family,
- *font_size,
- **font_list;
- int font_size_value,
- font_count,
- i;
- /* First attempt to interpret as font family/size */
- if (PM_INT("Output Device") == D_XWINDOWS) {
- (void) strcpy(name_copy, name);
- if (font_size = index(name_copy, '-')) {
- *font_size = ' ';
- font_family = name_copy;
- font_size++;
- font_size_value = atoi(font_size);
- if (font_size_value > 0) {
- /*
- * Still a little iffy -- what about weight and roman vs. other
- */
- (void) sprintf(query_spec, ISO_FONT,
- font_family, font_size_value * 10);
- font_list = XListFonts(param_disp, query_spec,
- DEF_MAX_NAMES, &font_count);
- /* Load first one that you can */
- for (i = 0; i < font_count; i++)
- if (*font_info = XLoadQueryFont(param_disp, font_list[i]))
- break;
- if (*font_info)
- return 1;
- }
- }
- /* Assume normal font name */
- return (int) (*font_info = XLoadQueryFont(param_disp, name));
- }
- }
- static int
- do_style(list, val)
- char *list; /* List of ones and zeros */
- param_style *val; /* Line style returned */
- /*
- * Translates a string representation of a dash specification into
- * a form suitable for use in XSetDashes(). Assumes `list'
- * is a null terminated string of ones and zeros.
- */
- {
- char *i,
- *spot,
- last_char;
- int count;
- for (i = list; *i; i++)
- if ((*i != '0') && (*i != '1'))
- break;
- if (!*i) {
- val->len = 0;
- last_char = ' ';
- for (i = list; *i; i++) {
- if (*i != last_char) {
- val->len += 1;
- last_char = *i;
- }
- }
- val->dash_list = (char *) Malloc((unsigned)
- (sizeof(char) * val->len + 1));
- last_char = *list;
- spot = val->dash_list;
- count = 0;
- for (i = list; *i; i++) {
- if (*i != last_char) {
- *spot++ = (char) count;
- last_char = *i;
- count = 1;
- }
- else
- count++;
- }
- *spot = (char) count;
- return 1;
- }
- else {
- return 0;
- }
- }
- static char *positive[] =
- {"on", "yes", "true", "1", "affirmative", (char *) 0};
- static char *negative[] =
- {"off", "no", "false", "0", "negative", (char *) 0};
- static int
- do_bool(name, val)
- char *name; /* String representation */
- int *val; /* Returned value */
- /*
- * Translates a string representation into a suitable binary value.
- * Can parse all kinds of interesting boolean type words.
- */
- {
- char **term;
- for (term = positive; *term; term++) {
- if (stricmp(name, *term) == 0)
- break;
- }
- if (*term) {
- *val = 1;
- return 1;
- }
- for (term = negative; *term; term++)
- if (stricmp(name, *term) == 0)
- break;
- if (*term) {
- *val = 0;
- return 1;
- }
- return 0;
- }
- /*ARGSUSED*/
- static enum st_retval
- dump_it(key, value, arg)
- char *key,
- *value,
- *arg;
- {
- param_full *val = (param_full *) value;
- (void) fprintf(stdout, "%s (", key);
- switch (val->type) {
- case INT:
- (void) fprintf(stdout, "INT");
- break;
- case STR:
- (void) fprintf(stdout, "STR");
- break;
- case PIXEL:
- (void) fprintf(stdout, "PIXEL");
- break;
- case FONT:
- (void) fprintf(stdout, "FONT");
- break;
- case STYLE:
- (void) fprintf(stdout, "STYLE");
- break;
- case BOOL:
- (void) fprintf(stdout, "BOOL");
- break;
- case DBL:
- (void) fprintf(stdout, "DBL");
- break;
- }
- (void) fprintf(stdout, ") = %sn", val->text_form);
- return ST_CONTINUE;
- }
- void
- param_dump()
- /*
- * Dumps all of the parameter values to standard output.
- */
- {
- st_foreach(param_table, dump_it, (char *) 0);
- }
- #ifdef HAVE_STRCASECMP
- int
- stricmp(a, b)
- char *a, *b;
- {
- return strcasecmp(a, b);
- }
- #else
- int
- stricmp(a, b)
- register char *a,
- *b;
- /*
- * This routine compares two strings disregarding case.
- */
- {
- register int value;
- if ((a == (char *) 0) || (b == (char *) 0)) {
- return a - b;
- }
- for ( /* nothing */ ;
- ((*a | *b) &&
- !(value = ((isupper(*a) ? *a - 'A' + 'a' : *a) -
- (isupper(*b) ? *b - 'A' + 'a' : *b))));
- a++, b++)
- /* Empty Body */ ;
- return value;
- }
- #endif
- static int
- strihash(string, modulus)
- register char *string;
- int modulus;
- /* Case insensitive computation */
- {
- register int val = 0;
- register int c;
- while ((c = *string++) != ' ') {
- if (isupper(c))
- c = tolower(c);
- val = val * 997 + c;
- }
- return ((val < 0) ? -val : val) % modulus;
- }