/* demo-Gtk-conf.c --- implements the dynamic configuration dialogs.
- * xscreensaver, Copyright (c) 2001, 2003 Jamie Zawinski <jwz@jwz.org>
+ * xscreensaver, Copyright (c) 2001, 2003, 2004 Jamie Zawinski <jwz@jwz.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
parameter_type type;
- char *id; /* widget name */
- char *label; /* heading label, or null */
+ xmlChar *id; /* widget name */
+ xmlChar *label; /* heading label, or null */
/* command, fake, description, fakepreview, string, file
*/
- char *string; /* file name, description, whatever. */
+ xmlChar *string; /* file name, description, whatever. */
/* slider, spinbutton
*/
- char *low_label; /* label for the left side */
- char *high_label; /* label for the right side */
+ xmlChar *low_label; /* label for the left side */
+ xmlChar *high_label; /* label for the right side */
float low; /* minimum value */
float high; /* maximum value */
float value; /* default value */
gboolean integer_p; /* whether the range is integral, or real */
- char *arg; /* command-line option to set (substitute "%") */
+ xmlChar *arg; /* command-line option to set (substitute "%") */
gboolean invert_p; /* whether to flip the value and pretend the
range goes from hi-low instead of low-hi. */
/* boolean, select-option
*/
- char *arg_set; /* command-line option to set for "yes", or null */
- char *arg_unset; /* command-line option to set for "no", or null */
- char *test; /* #### no idea - enablement? */
+ xmlChar *arg_set; /* command-line option to set for "yes", or null */
+ xmlChar *arg_unset; /* command-line option to set for "no", or null */
+ xmlChar *test; /* #### no idea - enablement? */
/* select
*/
`floatp' is set to TRUE. Otherwise, it is unchanged.
*/
static float
-xml_get_float (xmlNodePtr node, const char *name, gboolean *floatpP)
+xml_get_float (xmlNodePtr node, const xmlChar *name, gboolean *floatpP)
{
- const char *s = xmlGetProp (node, name);
+ const char *s = (char *) xmlGetProp (node, name);
float f;
char c;
if (!s || 1 != sscanf (s, "%f %c", &f, &c))
static void sanity_check_parameter (const char *filename,
- const char *node_name,
+ const xmlChar *node_name,
parameter *p);
+static void sanity_check_text_node (const char *filename,
+ const xmlNodePtr node);
/* Allocates and returns a new `parameter' object based on the
properties in the given XML node. Returns 0 if there's nothing
make_parameter (const char *filename, xmlNodePtr node)
{
parameter *p;
- const char *name = node->name;
+ const char *name = (char *) node->name;
const char *convert;
gboolean floatp = FALSE;
else if (!strcmp (name, "file")) p->type = FILENAME;
else if (!strcmp (name, "number")) p->type = SPINBUTTON;
else if (!strcmp (name, "select")) p->type = SELECT;
+ else if (node->type == XML_TEXT_NODE)
+ {
+ sanity_check_text_node (filename, node);
+ free (p);
+ return 0;
+ }
else
{
if (debug_p)
if (p->type == SPINBUTTON)
{
- const char *type = xmlGetProp (node, "type");
+ const char *type = (char *) xmlGetProp (node, (xmlChar *) "type");
if (!type || !strcmp (type, "spinbutton")) p->type = SPINBUTTON;
else if (!strcmp (type, "slider")) p->type = SLIDER;
else
if (node->xmlChildrenNode &&
node->xmlChildrenNode->type == XML_TEXT_NODE &&
!node->xmlChildrenNode->next)
- p->string = strdup (node->xmlChildrenNode->content);
+ p->string = (xmlChar *)
+ strdup ((char *) node->xmlChildrenNode->content);
}
- p->id = xmlGetProp (node, "id");
- p->label = xmlGetProp (node, "_label");
- p->low_label = xmlGetProp (node, "_low-label");
- p->high_label = xmlGetProp (node, "_high-label");
- p->low = xml_get_float (node, "low", &floatp);
- p->high = xml_get_float (node, "high", &floatp);
- p->value = xml_get_float (node, "default", &floatp);
+ p->id = xmlGetProp (node, (xmlChar *) "id");
+ p->label = xmlGetProp (node, (xmlChar *) "_label");
+ p->low_label = xmlGetProp (node, (xmlChar *) "_low-label");
+ p->high_label = xmlGetProp (node, (xmlChar *) "_high-label");
+ p->low = xml_get_float (node, (xmlChar *) "low", &floatp);
+ p->high = xml_get_float (node, (xmlChar *) "high", &floatp);
+ p->value = xml_get_float (node, (xmlChar *) "default", &floatp);
p->integer_p = !floatp;
- convert = xmlGetProp (node, "convert");
+ convert = (char *) xmlGetProp (node, (xmlChar *) "convert");
p->invert_p = (convert && !strcmp (convert, "invert"));
- p->arg = xmlGetProp (node, "arg");
- p->arg_set = xmlGetProp (node, "arg-set");
- p->arg_unset = xmlGetProp (node, "arg-unset");
- p->test = xmlGetProp (node, "test");
+ p->arg = xmlGetProp (node, (xmlChar *) "arg");
+ p->arg_set = xmlGetProp (node, (xmlChar *) "arg-set");
+ p->arg_unset = xmlGetProp (node, (xmlChar *) "arg-unset");
+ p->test = xmlGetProp (node, (xmlChar *) "test");
/* Check for missing decimal point */
if (debug_p &&
}
}
- sanity_check_parameter (filename, name, p);
+ sanity_check_parameter (filename, (const xmlChar *) name, p);
return p;
}
{
if (node->type == XML_COMMENT_NODE)
return 0;
+ else if (node->type == XML_TEXT_NODE)
+ {
+ sanity_check_text_node (filename, node);
+ return 0;
+ }
else if (node->type != XML_ELEMENT_NODE)
{
if (debug_p)
blurb(), filename, node->name, (int)node->type);
return 0;
}
- else if (strcmp (node->name, "option"))
+ else if (strcmp ((char *) node->name, "option"))
{
if (debug_p)
fprintf (stderr,
char *enable, *e;
s->type = SELECT_OPTION;
- s->id = xmlGetProp (node, "id");
- s->label = xmlGetProp (node, "_label");
- s->arg_set = xmlGetProp (node, "arg-set");
- s->arg_unset = xmlGetProp (node, "arg-unset");
- s->test = xmlGetProp (node, "test");
- enable = xmlGetProp (node, "enable");
+ s->id = xmlGetProp (node, (xmlChar *) "id");
+ s->label = xmlGetProp (node, (xmlChar *) "_label");
+ s->arg_set = xmlGetProp (node, (xmlChar *) "arg-set");
+ s->arg_unset = xmlGetProp (node, (xmlChar *) "arg-unset");
+ s->test = xmlGetProp (node, (xmlChar *) "test");
+ enable = (char*)xmlGetProp (node, (xmlChar *) "enable");
if (enable)
{
when they should have typed "arg=", etc.
*/
static void
-sanity_check_parameter (const char *filename, const char *node_name,
+sanity_check_parameter (const char *filename, const xmlChar *node_name,
parameter *p)
{
struct {
# define WARN(STR) \
fprintf (stderr, "%s: %s: " STR " in <%s%s id=\"%s\">\n", \
blurb(), filename, node_name, \
- (!strcmp(node_name, "number") \
+ (!strcmp((char *) node_name, "number") \
? (p->type == SPINBUTTON ? " type=spinbutton" : " type=slider")\
: ""), \
- (p->id ? p->id : ""))
+ (p->id ? (char *) p->id : ""))
# define CHECK(SLOT,NAME) \
if (p->SLOT && !allowed.SLOT) \
WARN ("\"" NAME "\" is not a valid option"); \
# undef WARN
}
+/* "text" nodes show up for all the non-tag text in the file, including
+ all the newlines between tags. Warn if there is text there that
+ is not whitespace.
+ */
+static void
+sanity_check_text_node (const char *filename, const xmlNodePtr node)
+{
+ const char *body = (const char *) node->content;
+ if (node->type != XML_TEXT_NODE) abort();
+ while (isspace (*body)) body++;
+ if (*body)
+ fprintf (stderr, "%s: WARNING: %s: random text present: \"%s\"\n",
+ blurb(), filename, body);
+}
+
+
+/* Returns a list of strings, every switch mentioned in the parameters.
+ The strings must be freed.
+ */
+static GList *
+get_all_switches (const char *filename, GList *parms)
+{
+ GList *switches = 0;
+ GList *p;
+ for (p = parms; p; p = p->next)
+ {
+ parameter *pp = (parameter *) p->data;
+
+ if (pp->type == SELECT)
+ {
+ GList *list2 = get_all_switches (filename, pp->options);
+ switches = g_list_concat (switches, list2);
+ }
+ if (pp->arg && *pp->arg)
+ switches = g_list_append (switches, strdup ((char *) pp->arg));
+ if (pp->arg_set && *pp->arg_set)
+ switches = g_list_append (switches, strdup ((char *) pp->arg_set));
+ if (pp->arg_unset && *pp->arg_unset)
+ switches = g_list_append (switches, strdup ((char *) pp->arg_unset));
+ }
+ return switches;
+}
+
+
+/* Ensures that no switch is mentioned more than once.
+ */
+static void
+sanity_check_parameters (const char *filename, GList *parms)
+{
+ GList *list = get_all_switches (filename, parms);
+ GList *p;
+ for (p = list; p; p = p->next)
+ {
+ char *sw = (char *) p->data;
+ GList *p2;
+
+ if (*sw != '-' && *sw != '+')
+ fprintf (stderr, "%s: %s: switch does not begin with hyphen \"%s\"\n",
+ blurb(), filename, sw);
+
+ for (p2 = p->next; p2; p2 = p2->next)
+ {
+ const char *sw2 = (const char *) p2->data;
+ if (!strcmp (sw, sw2))
+ fprintf (stderr, "%s: %s: duplicate switch \"%s\"\n",
+ blurb(), filename, sw);
+ }
+
+ free (sw);
+ }
+ g_list_free (list);
+}
/* Helper for make_parameters()
for (; node; node = node->next)
{
- const char *name = node->name;
+ const char *name = (char *) node->name;
if (!strcmp (name, "hgroup") ||
!strcmp (name, "vgroup"))
{
for (; node; node = node->next)
{
if (node->type == XML_ELEMENT_NODE &&
- !strcmp (node->name, "screensaver"))
- return make_parameters_1 (filename, node->xmlChildrenNode, parent, &row);
+ !strcmp ((char *) node->name, "screensaver"))
+ return make_parameters_1 (filename, node->xmlChildrenNode,
+ parent, &row);
}
return 0;
}
make_parameter_widget (const char *filename,
parameter *p, GtkWidget *parent, int *row)
{
- const char *label = p->label;
+ const char *label = (char *) p->label;
if (p->widget) return;
switch (p->type)
p->widget = gtk_entry_new ();
if (p->string)
- gtk_entry_set_text (GTK_ENTRY (p->widget), p->string);
+ gtk_entry_set_text (GTK_ENTRY (p->widget), (char *) p->string);
if (row)
gtk_table_attach (GTK_TABLE (parent), p->widget, 1, 3,
*row, *row + 1,
gtk_widget_show (L);
if (p->string)
- gtk_entry_set_text (GTK_ENTRY (entry), p->string);
+ gtk_entry_set_text (GTK_ENTRY (entry), (char *) p->string);
if (row)
{
if (p->low_label)
{
- GtkWidget *w = gtk_label_new (_(p->low_label));
+ GtkWidget *w = gtk_label_new (_((char *) p->low_label));
gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_RIGHT);
gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5);
gtk_widget_show (w);
if (p->high_label)
{
- GtkWidget *w = gtk_label_new (_(p->high_label));
+ GtkWidget *w = gtk_label_new (_((char *) p->high_label));
gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_LEFT);
gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
gtk_widget_show (w);
for (opts = p->options; opts; opts = opts->next)
{
parameter *s = (parameter *) opts->data;
- GtkWidget *i = gtk_menu_item_new_with_label (_(s->label));
+ GtkWidget *i = gtk_menu_item_new_with_label (_((char *) s->label));
gtk_widget_show (i);
gtk_menu_append (GTK_MENU (menu), i);
}
if (p->widget)
{
- gtk_widget_set_name (p->widget, p->id);
+ gtk_widget_set_name (p->widget, (char *) p->id);
gtk_widget_show (p->widget);
if (row)
(*row)++;
static char *
format_switch (parameter *p, const char *value)
{
- char *fmt = p->arg;
+ char *fmt = (char *) p->arg;
char *v2;
char *result, *s;
if (!fmt || !value) return 0;
{
case COMMAND:
if (p->arg)
- return strdup (p->arg);
+ return strdup ((char *) p->arg);
else
return 0;
break;
const char *s = gtk_entry_get_text (GTK_ENTRY (p->widget));
char *v;
if (!strcmp ((s ? s : ""),
- (p->string ? p->string : "")))
+ (p->string ? (char *) p->string : "")))
v = 0; /* same as default */
else
v = format_switch (p, s);
{
GtkToggleButton *b = GTK_TOGGLE_BUTTON (p->widget);
const char *s = (gtk_toggle_button_get_active (b)
- ? p->arg_set
- : p->arg_unset);
+ ? (char *) p->arg_set
+ : (char *) p->arg_unset);
if (s)
return strdup (s);
else
const char *s;
if (!o) abort();
if (o->type != SELECT_OPTION) abort();
- s = o->arg_set;
+ s = (char *) o->arg_set;
if (s)
return strdup (s);
else
char *option = rest->data;
rest->data = 0;
- if (option[0] != '-')
+ if (option[0] != '-' && option[0] != '+')
{
if (debug_p)
fprintf (stderr, "%s: WARNING: %s: not a switch: \"%s\"\n",
{
GList *p;
parameter *match = 0;
- int which = -1;
- int index = 0;
+ gint which = -1;
+ gint index = 0;
for (p = parms; p; p = p->next)
{
}
else if (pp->arg)
{
- if (compare_opts (option, value, pp->arg))
+ if (compare_opts (option, value, (char *) pp->arg))
{
which = -1;
match = pp;
}
else if (pp->arg_set)
{
- if (compare_opts (option, value, pp->arg_set))
+ if (compare_opts (option, value, (char *) pp->arg_set))
{
which = 1;
match = pp;
}
else if (pp->arg_unset)
{
- if (compare_opts (option, value, pp->arg_unset))
+ if (compare_opts (option, value, (char *) pp->arg_unset))
{
which = 0;
match = pp;
break;
case BOOLEAN:
if (which != 0 && which != 1) abort();
- parameter_set_switch (match, (gpointer) which);
+ parameter_set_switch (match, GINT_TO_POINTER(which));
break;
case SELECT_OPTION:
if (which != 1) abort();
- parameter_set_switch (parent, (gpointer) index);
+ parameter_set_switch (parent, GINT_TO_POINTER(index));
break;
default:
break;
case BOOLEAN:
{
GtkToggleButton *b = GTK_TOGGLE_BUTTON (p->widget);
- gtk_toggle_button_set_active (b, (int) value);
+ gtk_toggle_button_set_active (b, GPOINTER_TO_INT(value));
break;
}
case SELECT:
{
gtk_option_menu_set_history (GTK_OPTION_MENU (p->widget),
- (int) value);
+ GPOINTER_TO_INT(value));
break;
}
default:
case FILENAME:
{
gtk_entry_set_text (GTK_ENTRY (p->widget),
- (p->string ? p->string : ""));
+ (p->string ? (char *) p->string : ""));
break;
}
case SLIDER:
*/
static char *
-get_description (GList *parms)
+get_description (GList *parms, gboolean verbose_p)
{
parameter *doc = 0;
for (; parms; parms = parms->next)
return 0;
else
{
- char *d = strdup (doc->string);
+ char *d = strdup ((char *) doc->string);
char *s;
+ char *p;
for (s = d; *s; s++)
if (s[0] == '\n')
{
d[--L] = 0;
}
- return _(d);
+ /* strip off duplicated whitespaces */
+ for (s = d; *s; s++)
+ if (s[0] == ' ')
+ {
+ p = s+1;
+ while (*s == ' ')
+ s++;
+ if (*p && (s != p))
+ memmove (p, s, strlen(s)+1);
+ }
+
+#if 0
+ if (verbose_p)
+ {
+ fprintf (stderr, "%s: text read is \"%s\"\n", blurb(),doc->string);
+ fprintf (stderr, "%s: description is \"%s\"\n", blurb(), d);
+ fprintf (stderr, "%s: translation is \"%s\"\n", blurb(), _(d));
+ }
+#endif /* 0 */
+
+ return (d);
}
}
gtk_widget_show (table);
parms = make_parameters (file, doc->xmlRootNode, table);
+ sanity_check_parameters (file, parms);
xmlFreeDoc (doc);
data->widget = table;
data->parameters = parms;
- data->description = get_description (parms);
+ data->description = get_description (parms, verbose_p);
}
else
{
p = calloc (1, sizeof(*p));
p->type = COMMAND;
- p->arg = strdup (arguments);
+ p->arg = (xmlChar *) strdup (arguments);
data->parameters = g_list_append (0, (gpointer) p);
}