X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=driver%2Fdemo-Gtk-conf.c;h=bac6ecc7539b4e1a984e5cbb86817c7d61181fc2;hb=d5186197bc394e10a4402f7f6d23fbb14103bc50;hp=d41b58577c2c524ca8429e8261660c3b70bdc063;hpb=488f2fa8fbdbc77e91a70da2962d73af49e6cace;p=xscreensaver diff --git a/driver/demo-Gtk-conf.c b/driver/demo-Gtk-conf.c index d41b5857..bac6ecc7 100644 --- a/driver/demo-Gtk-conf.c +++ b/driver/demo-Gtk-conf.c @@ -1,5 +1,5 @@ /* demo-Gtk-conf.c --- implements the dynamic configuration dialogs. - * xscreensaver, Copyright (c) 2001, 2003, 2004, 2006 Jamie Zawinski + * xscreensaver, Copyright (c) 2001-2014 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -63,7 +63,22 @@ #include "demo-Gtk-conf.h" - +/* Deal with deprecation of direct access to struct fields on the way to GTK3 + See http://live.gnome.org/GnomeGoals/UseGseal + */ +#if GTK_CHECK_VERSION(2,14,0) +# define GET_PARENT(w) gtk_widget_get_parent (w) +# define GET_ADJ_VALUE(a) gtk_adjustment_get_value (a) +# define GET_ADJ_UPPER(a) gtk_adjustment_get_upper (a) +# define GET_ADJ_LOWER(a) gtk_adjustment_get_lower (a) +#else +# define GET_PARENT(w) ((w)->parent) +# define GET_ADJ_VALUE(a) ((a)->value) +# define GET_ADJ_UPPER(a) ((a)->upper) +# define GET_ADJ_LOWER(a) ((a)->lower) +#endif + + extern const char *blurb (void); @@ -72,6 +87,11 @@ const char *hack_configuration_path = HACK_CONFIGURATION_PATH; static gboolean debug_p = FALSE; +#define MIN_SLIDER_WIDTH 150 +#define MIN_SPINBUTTON_WIDTH 48 +#define MIN_LABEL_WIDTH 70 + + typedef enum { COMMAND, FAKE, @@ -127,8 +147,8 @@ typedef struct { static parameter *make_select_option (const char *file, xmlNodePtr); -static void make_parameter_widget (const char *filename, - parameter *, GtkWidget *, int *); +static void make_parameter_widget (const char *filename, + parameter *, GtkWidget *); static void browse_button_cb (GtkButton *button, gpointer user_data); @@ -278,8 +298,10 @@ make_parameter (const char *filename, xmlNodePtr node) else if (!strcmp (name, "number")) p->type = SPINBUTTON; else if (!strcmp (name, "select")) p->type = SELECT; - else if (!strcmp (name, "xscreensaver-text") || /* these are ignored in X11 */ - !strcmp (name, "xscreensaver-image")) /* (they are used in Cocoa) */ + else if (!strcmp (name, "xscreensaver-text") || /* ignored in X11; */ + !strcmp (name, "xscreensaver-image") || /* used in Cocoa. */ + !strcmp (name, "xscreensaver-updater") || + !strcmp (name, "video")) { free (p); return 0; @@ -668,8 +690,7 @@ sanity_check_parameters (const char *filename, GList *parms) /* Helper for make_parameters() */ static GList * -make_parameters_1 (const char *filename, xmlNodePtr node, - GtkWidget *parent, int *row) +make_parameters_1 (const char *filename, xmlNodePtr node, GtkWidget *parent) { GList *list = 0; @@ -684,17 +705,9 @@ make_parameters_1 (const char *filename, xmlNodePtr node, : gtk_vbox_new (FALSE, 0)); GList *list2; gtk_widget_show (box); + gtk_box_pack_start (GTK_BOX (parent), box, FALSE, FALSE, 0); - if (row) - gtk_table_attach (GTK_TABLE (parent), box, 0, 3, *row, *row + 1, - 0, 0, 0, 0); - else - gtk_box_pack_start (GTK_BOX (parent), box, FALSE, FALSE, 0); - - if (row) - (*row)++; - - list2 = make_parameters_1 (filename, node->xmlChildrenNode, box, 0); + list2 = make_parameters_1 (filename, node->xmlChildrenNode, box); if (list2) list = g_list_concat (list, list2); } @@ -704,7 +717,7 @@ make_parameters_1 (const char *filename, xmlNodePtr node, if (p) { list = g_list_append (list, p); - make_parameter_widget (filename, p, parent, row); + make_parameter_widget (filename, p, parent); } } } @@ -719,13 +732,11 @@ make_parameters_1 (const char *filename, xmlNodePtr node, static GList * make_parameters (const char *filename, xmlNodePtr node, GtkWidget *parent) { - int row = 0; for (; node; node = node->next) { if (node->type == XML_ELEMENT_NODE && !strcmp ((char *) node->name, "screensaver")) - return make_parameters_1 (filename, node->xmlChildrenNode, - parent, &row); + return make_parameters_1 (filename, node->xmlChildrenNode, parent); } return 0; } @@ -793,14 +804,52 @@ make_adjustment (const char *filename, parameter *p) +static void +set_widget_min_width (GtkWidget *w, int width) +{ + GtkRequisition req; + gtk_widget_size_request (GTK_WIDGET (w), &req); + if (req.width < width) + gtk_widget_set_size_request (GTK_WIDGET (w), width, -1); +} + + +/* If we're inside a vbox, we need to put an hbox in it, or labels appear + on top instead of to the left, and things stretch to the full width of + the window. + */ +static GtkWidget * +insert_fake_hbox (GtkWidget *parent) +{ + if (GTK_IS_VBOX (parent)) + { + GtkWidget *hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (parent), hbox, FALSE, FALSE, 4); + gtk_widget_show (hbox); + return hbox; + } + return parent; +} + + +static void +link_atk_label_to_widget(GtkWidget *label, GtkWidget *widget) +{ + AtkObject *atk_label = gtk_widget_get_accessible (label); + AtkObject *atk_widget = gtk_widget_get_accessible (widget); + + atk_object_add_relationship (atk_label, ATK_RELATION_LABEL_FOR, + atk_widget); + atk_object_add_relationship (atk_widget, ATK_RELATION_LABELLED_BY, + atk_label); +} + /* Given a `parameter' struct, allocates an appropriate GtkWidget for it, and stores it in `p->widget'. - `row' is used for keeping track of our position during table layout. - `parent' must be a GtkTable or a GtkBox. + `parent' must be a GtkBox. */ static void -make_parameter_widget (const char *filename, - parameter *p, GtkWidget *parent, int *row) +make_parameter_widget (const char *filename, parameter *p, GtkWidget *parent) { const char *label = (char *) p->label; if (p->widget) return; @@ -809,28 +858,23 @@ make_parameter_widget (const char *filename, { case STRING: { + GtkWidget *entry = gtk_entry_new (); + parent = insert_fake_hbox (parent); if (label) { GtkWidget *w = gtk_label_new (_(label)); + link_atk_label_to_widget (w, entry); gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_RIGHT); gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5); + set_widget_min_width (GTK_WIDGET (w), MIN_LABEL_WIDTH); gtk_widget_show (w); - if (row) - gtk_table_attach (GTK_TABLE (parent), w, 0, 1, *row, *row + 1, - GTK_FILL, 0, 0, 0); - else - gtk_box_pack_start (GTK_BOX (parent), w, FALSE, FALSE, 4); + gtk_box_pack_start (GTK_BOX (parent), w, FALSE, FALSE, 4); } - p->widget = gtk_entry_new (); + p->widget = entry; if (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_FILL, 0, 0, 0); - else - gtk_box_pack_start (GTK_BOX (parent), p->widget, FALSE, FALSE, 4); + gtk_box_pack_start (GTK_BOX (parent), p->widget, FALSE, FALSE, 4); break; } case FILENAME: @@ -838,6 +882,7 @@ make_parameter_widget (const char *filename, GtkWidget *L = gtk_label_new (label ? _(label) : ""); GtkWidget *entry = gtk_entry_new (); GtkWidget *button = gtk_button_new_with_label (_("Browse...")); + link_atk_label_to_widget (L, entry); gtk_widget_show (entry); gtk_widget_show (button); p->widget = entry; @@ -848,29 +893,16 @@ make_parameter_widget (const char *filename, gtk_label_set_justify (GTK_LABEL (L), GTK_JUSTIFY_RIGHT); gtk_misc_set_alignment (GTK_MISC (L), 1.0, 0.5); + set_widget_min_width (GTK_WIDGET (L), MIN_LABEL_WIDTH); gtk_widget_show (L); if (p->string) gtk_entry_set_text (GTK_ENTRY (entry), (char *) p->string); - if (row) - { - gtk_table_attach (GTK_TABLE (parent), L, 0, 1, - *row, *row + 1, - GTK_FILL, 0, 0, 0); - gtk_table_attach (GTK_TABLE (parent), entry, 1, 2, - *row, *row + 1, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - gtk_table_attach (GTK_TABLE (parent), button, 2, 3, - *row, *row + 1, - 0, 0, 0, 0); - } - else - { - gtk_box_pack_start (GTK_BOX (parent), L, FALSE, FALSE, 4); - gtk_box_pack_start (GTK_BOX (parent), entry, TRUE, TRUE, 4); - gtk_box_pack_start (GTK_BOX (parent), button, FALSE, FALSE, 4); - } + parent = insert_fake_hbox (parent); + gtk_box_pack_start (GTK_BOX (parent), L, FALSE, FALSE, 4); + gtk_box_pack_start (GTK_BOX (parent), entry, TRUE, TRUE, 4); + gtk_box_pack_start (GTK_BOX (parent), button, FALSE, FALSE, 4); break; } case SLIDER: @@ -882,95 +914,46 @@ make_parameter_widget (const char *filename, if (label) { labelw = gtk_label_new (_(label)); + link_atk_label_to_widget (labelw, scale); gtk_label_set_justify (GTK_LABEL (labelw), GTK_JUSTIFY_LEFT); gtk_misc_set_alignment (GTK_MISC (labelw), 0.0, 0.5); + set_widget_min_width (GTK_WIDGET (labelw), MIN_LABEL_WIDTH); gtk_widget_show (labelw); + gtk_box_pack_start (GTK_BOX (parent), labelw, FALSE, FALSE, 2); } - if (GTK_IS_VBOX (parent)) - { - /* If we're inside a vbox, we need to put an hbox in it, to get - the low/high labels to be to the left/right of the slider. - */ - GtkWidget *hbox = gtk_hbox_new (FALSE, 0); - - /* But if we have a label, put that above the slider's hbox. */ - if (labelw) - { - gtk_box_pack_start (GTK_BOX (parent), labelw, FALSE, TRUE, 2); - labelw = 0; - } - - gtk_box_pack_start (GTK_BOX (parent), hbox, TRUE, TRUE, 6); - gtk_widget_show (hbox); - parent = hbox; - } - - if (labelw) - { - if (row) - { - gtk_table_attach (GTK_TABLE (parent), labelw, - 0, 3, *row, *row + 1, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - (*row)++; - } - else - { - if (GTK_IS_HBOX (parent)) - { - GtkWidget *box = gtk_vbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (parent), box, FALSE, TRUE, 0); - gtk_widget_show (box); - gtk_box_pack_start (GTK_BOX (box), labelw, FALSE, TRUE, 4); - parent = box; - box = gtk_hbox_new (FALSE, 0); - gtk_widget_show (box); - gtk_box_pack_start (GTK_BOX (parent), box, TRUE, TRUE, 0); - parent = box; - } - else - gtk_box_pack_start (GTK_BOX (parent), labelw, - FALSE, TRUE, 0); - } - } + /* Do this after 'labelw' so that it appears above, not to left. */ + parent = insert_fake_hbox (parent); if (p->low_label) { GtkWidget *w = gtk_label_new (_((char *) p->low_label)); + link_atk_label_to_widget (w, scale); gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_RIGHT); gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5); + set_widget_min_width (GTK_WIDGET (w), MIN_LABEL_WIDTH); gtk_widget_show (w); - if (row) - gtk_table_attach (GTK_TABLE (parent), w, 0, 1, *row, *row + 1, - GTK_FILL, 0, 0, 0); - else - gtk_box_pack_start (GTK_BOX (parent), w, FALSE, FALSE, 4); + gtk_box_pack_start (GTK_BOX (parent), w, FALSE, FALSE, 4); } gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_BOTTOM); gtk_scale_set_draw_value (GTK_SCALE (scale), debug_p); gtk_scale_set_digits (GTK_SCALE (scale), (p->integer_p ? 0 : 2)); - if (row) - gtk_table_attach (GTK_TABLE (parent), scale, 1, 2, - *row, *row + 1, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - else - gtk_box_pack_start (GTK_BOX (parent), scale, TRUE, TRUE, 4); + set_widget_min_width (GTK_WIDGET (scale), MIN_SLIDER_WIDTH); + + gtk_box_pack_start (GTK_BOX (parent), scale, FALSE, FALSE, 4); gtk_widget_show (scale); if (p->high_label) { GtkWidget *w = gtk_label_new (_((char *) p->high_label)); + link_atk_label_to_widget (w, scale); gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_LEFT); gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5); + set_widget_min_width (GTK_WIDGET (w), MIN_LABEL_WIDTH); gtk_widget_show (w); - if (row) - gtk_table_attach (GTK_TABLE (parent), w, 2, 3, *row, *row + 1, - GTK_FILL, 0, 0, 0); - else - gtk_box_pack_start (GTK_BOX (parent), w, FALSE, FALSE, 4); + gtk_box_pack_start (GTK_BOX (parent), w, FALSE, FALSE, 4); } p->widget = scale; @@ -982,33 +965,23 @@ make_parameter_widget (const char *filename, GtkWidget *spin = gtk_spin_button_new (adj, 15, 0); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spin), TRUE); gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (spin), TRUE); - gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), adj->value); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), GET_ADJ_VALUE(adj)); + set_widget_min_width (GTK_WIDGET (spin), MIN_SPINBUTTON_WIDTH); if (label) { GtkWidget *w = gtk_label_new (_(label)); + link_atk_label_to_widget (w, spin); gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_RIGHT); gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5); + set_widget_min_width (GTK_WIDGET (w), MIN_LABEL_WIDTH); gtk_widget_show (w); - if (row) - gtk_table_attach (GTK_TABLE (parent), w, 0, 1, *row, *row + 1, - GTK_FILL, 0, 0, 0); - else - gtk_box_pack_start (GTK_BOX (parent), w, TRUE, TRUE, 4); + parent = insert_fake_hbox (parent); + gtk_box_pack_start (GTK_BOX (parent), w, FALSE, FALSE, 4); } gtk_widget_show (spin); - if (row) - { - GtkWidget *hbox = gtk_hbox_new (FALSE, 0); - gtk_widget_show (hbox); - gtk_table_attach (GTK_TABLE (parent), hbox, 1, 3, - *row, *row + 1, - GTK_EXPAND | GTK_FILL, 0, 8, 0); - gtk_box_pack_start (GTK_BOX (hbox), spin, FALSE, FALSE, 0); - } - else - gtk_box_pack_start (GTK_BOX (parent), spin, FALSE, FALSE, 4); + gtk_box_pack_start (GTK_BOX (parent), spin, FALSE, FALSE, 4); p->widget = spin; break; @@ -1016,12 +989,10 @@ make_parameter_widget (const char *filename, case BOOLEAN: { p->widget = gtk_check_button_new_with_label (_(label)); - if (row) - gtk_table_attach (GTK_TABLE (parent), p->widget, 0, 3, - *row, *row + 1, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - else - gtk_box_pack_start (GTK_BOX (parent), p->widget, FALSE, FALSE, 4); + /* Let these stretch -- doesn't hurt. + parent = insert_fake_hbox (parent); + */ + gtk_box_pack_start (GTK_BOX (parent), p->widget, FALSE, FALSE, 4); break; } case SELECT: @@ -1030,17 +1001,6 @@ make_parameter_widget (const char *filename, GtkWidget *menu = gtk_menu_new (); GList *opts; - if (label && row) - { - GtkWidget *w = gtk_label_new (_(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); - gtk_table_attach (GTK_TABLE (parent), w, 0, 3, *row, *row + 1, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - (*row)++; - } - for (opts = p->options; opts; opts = opts->next) { parameter *s = (parameter *) opts->data; @@ -1051,12 +1011,8 @@ make_parameter_widget (const char *filename, gtk_option_menu_set_menu (GTK_OPTION_MENU (opt), menu); p->widget = opt; - if (row) - gtk_table_attach (GTK_TABLE (parent), p->widget, 0, 3, - *row, *row + 1, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - else - gtk_box_pack_start (GTK_BOX (parent), p->widget, TRUE, TRUE, 4); + parent = insert_fake_hbox (parent); + gtk_box_pack_start (GTK_BOX (parent), p->widget, FALSE, FALSE, 4); break; } @@ -1073,8 +1029,6 @@ make_parameter_widget (const char *filename, { gtk_widget_set_name (p->widget, (char *) p->id); gtk_widget_show (p->widget); - if (row) - (*row)++; } } @@ -1090,8 +1044,8 @@ static void file_sel_cancel (GtkWidget *button, gpointer user_data) { GtkWidget *dialog = button; - while (dialog->parent) - dialog = dialog->parent; + while (GET_PARENT (dialog)) + dialog = GET_PARENT (dialog); gtk_widget_destroy (dialog); } @@ -1102,8 +1056,9 @@ file_sel_ok (GtkWidget *button, gpointer user_data) GtkWidget *entry = GTK_WIDGET (user_data); GtkWidget *dialog = button; const char *path; - while (dialog->parent) - dialog = dialog->parent; + + while (GET_PARENT (dialog)) + dialog = GET_PARENT (dialog); gtk_widget_hide (dialog); path = gtk_file_selection_get_filename (GTK_FILE_SELECTION (dialog)); @@ -1215,7 +1170,7 @@ de_stringify (char *s) char q = s[0]; if (q != '\'' && q != '\"' && q != '`') abort(); - memmove (s, s+1, strlen (s)+1); + memmove (s, s+1, strlen (s)); while (*s && *s != q) { if (*s == '\\') @@ -1295,8 +1250,9 @@ parameter_to_switch (parameter *p) char buf[255]; char *s1; float value = (p->invert_p - ? invert_range (adj->lower, adj->upper, adj->value) - 1 - : adj->value); + ? invert_range (GET_ADJ_LOWER(adj), GET_ADJ_UPPER(adj), + GET_ADJ_VALUE(adj)) - 1 + : GET_ADJ_VALUE(adj)); if (value == p->value) /* same as default */ return 0; @@ -1360,25 +1316,29 @@ parameter_to_switch (parameter *p) All arguments will be properly quoted. */ static char * -parameters_to_cmd_line (GList *parms) +parameters_to_cmd_line (GList *parms, gboolean default_p) { int L = g_list_length (parms); int LL = 0; char **strs = (char **) calloc (sizeof (*parms), L); char *result; char *out; - int i; + int i, j; - for (i = 0; parms; parms = parms->next, i++) + for (i = 0, j = 0; parms; parms = parms->next, i++) { - char *s = parameter_to_switch ((parameter *) parms->data); - strs[i] = s; - LL += (s ? strlen(s) : 0) + 1; + parameter *p = (parameter *) parms->data; + if (!default_p || p->type == COMMAND) + { + char *s = parameter_to_switch (p); + strs[j++] = s; + LL += (s ? strlen(s) : 0) + 1; + } } result = (char *) malloc (LL + 10); out = result; - for (i = 0; i < L; i++) + for (i = 0; i < j; i++) if (strs[i]) { strcpy (out, strs[i]); @@ -1653,7 +1613,7 @@ parameter_set_switch (parameter *p, gpointer value) if (1 == sscanf ((char *) value, "%f %c", &f, &c)) { if (p->invert_p) - f = invert_range (adj->lower, adj->upper, f) - 1; + f = invert_range (GET_ADJ_LOWER(adj), GET_ADJ_UPPER(adj), f) - 1; gtk_adjustment_set_value (adj, f); } break; @@ -1777,6 +1737,8 @@ get_description (GList *parms, gboolean verbose_p) s++; else if (s[1] == ' ' || s[1] == '\t') s++; /* next line is indented: leave newline */ + else if (!strncmp(s+1, "http:", 5)) + s++; /* next line begins a URL: leave newline */ else s[0] = ' '; /* delete newline to un-fold this line */ } @@ -1865,7 +1827,7 @@ load_configurator_1 (const char *program, const char *arguments, char chars[1024]; xmlParserCtxtPtr ctxt; xmlDocPtr doc = 0; - GtkWidget *table; + GtkWidget *vbox0; GList *parms; if (verbose_p) @@ -1889,13 +1851,10 @@ load_configurator_1 (const char *program, const char *arguments, /* Parsed the XML file. Now make some widgets. */ - table = gtk_table_new (1, 3, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 4); - gtk_table_set_col_spacings (GTK_TABLE (table), 4); - gtk_container_set_border_width (GTK_CONTAINER (table), 8); - gtk_widget_show (table); + vbox0 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox0); - parms = make_parameters (file, doc->xmlRootNode, table); + parms = make_parameters (file, doc->xmlRootNode, vbox0); sanity_check_parameters (file, parms); xmlFreeDoc (doc); @@ -1904,7 +1863,7 @@ load_configurator_1 (const char *program, const char *arguments, if (arguments && *arguments) parse_command_line_into_parameters (program, arguments, parms); - data->widget = table; + data->widget = vbox0; data->parameters = parms; data->description = get_description (parms, verbose_p); } @@ -1982,9 +1941,9 @@ load_configurator (const char *full_command_line, gboolean verbose_p) char * -get_configurator_command_line (conf_data *data) +get_configurator_command_line (conf_data *data, gboolean default_p) { - char *args = parameters_to_cmd_line (data->parameters); + char *args = parameters_to_cmd_line (data->parameters, default_p); char *result = (char *) malloc (strlen (data->progname) + strlen (args) + 2); strcpy (result, data->progname);