diff options
-rw-r--r-- | ChangeLog | 32 | ||||
-rw-r--r-- | daemon/slave.c | 79 | ||||
-rw-r--r-- | docs/C/gdm.xml | 43 | ||||
-rw-r--r-- | gui/greeter/greeter.c | 8 | ||||
-rw-r--r-- | gui/greeter/greeter_canvas_item.c | 135 | ||||
-rw-r--r-- | gui/greeter/greeter_canvas_item.h | 2 | ||||
-rw-r--r-- | gui/greeter/greeter_events.c | 16 | ||||
-rw-r--r-- | gui/greeter/greeter_geometry.c | 127 | ||||
-rw-r--r-- | gui/greeter/greeter_item.c | 61 | ||||
-rw-r--r-- | gui/greeter/greeter_item.h | 133 | ||||
-rw-r--r-- | gui/greeter/greeter_item_customlist.c | 2 | ||||
-rw-r--r-- | gui/greeter/greeter_item_pam.c | 121 | ||||
-rw-r--r-- | gui/greeter/greeter_parser.c | 216 | ||||
-rw-r--r-- | gui/greeter/themes/circles/circles.xml.in | 8 | ||||
-rw-r--r-- | gui/greeter/themes/happygnome-list/happygnome.xml.in | 2 | ||||
-rw-r--r-- | gui/greeter/themes/happygnome/happygnome.xml.in | 6 |
16 files changed, 602 insertions, 389 deletions
@@ -1,3 +1,35 @@ +Wed Sep 24 13:21:43 2003 George Lebl <jirka@5z.com> + + * daemon/slave.c: don't exec chooser/greeter in shell that's kind of + evil and resets too many env vars. Instead reset to the original + env first and then setup our env vars and exec the greeter or + chooser. + + * gui/greeter/greeter.c, gui/greeter/greeter_canvas_item.[ch], + gui/greeter/greeter_events.c, gui/greeter/greeter_geometry.c, + gui/greeter/greeter_item.[ch], + gui/greeter/greeter_item_customlist.c, + gui/greeter/greeter_item_pam.c, gui/greeter/greeter_parser.c: + Fix bug #123017 with use of evil hacks (as if the original + text code was not evil). Check max-width and + max-screen-percent-width attributes for label pos elements. + Wrap text if it goes over it's width or the max-width + (Mental note: the greeter layout stuff is on complete crack + and should be rewritten with great prejudice). Also while + at it save an extra 112 bytes off every element by using + more appropriate types and some unions, adds up to about + 5k for Bluecurve so it's not much actually. Also fix + the enriched string parsing to understand \n just like + gdmlogin does + + * gui/greeter/themes/circles/circles.xml.in, + gui/greeter/themes/happygnome/happygnome.xml.in, + gui/greeter/themes/happygnome-list/happygnome.xml.in: + For some reason the canvas now gives me larger fonts, so + use smaller fonts and tweak the layout a bit. + + * docs/C/gdm.xml: update the docs a bit + Tue Sep 23 10:16:08 2003 George Lebl <jirka@5z.com> * gui/greeter/gdmthemetester: fix shell parse error diff --git a/daemon/slave.c b/daemon/slave.c index 28a5e6ec..1b78ff0b 100644 --- a/daemon/slave.c +++ b/daemon/slave.c @@ -2190,28 +2190,32 @@ copy_auth_file (uid_t fromuid, uid_t touid, const char *file) } static void -exec_in_shell (const char *command) +exec_command (const char *command, const char *extra_arg) { - char *shell_cmd; - char *argv[10]; - char *first_word = ve_first_word (command); + char **argv = ve_split (command); - if (access (first_word, X_OK) != 0) + if (argv == NULL || + ve_string_empty (argv[0])) return; - if (access ("/bin/bash", X_OK) == 0) { - shell_cmd = "/bin/bash"; - argv[0] = "-/bin/bash"; - } else { - shell_cmd = "/bin/sh"; - argv[0] = "-/bin/sh"; - } + if (access (argv[0], X_OK) != 0) + return; - argv[1] = "-c"; - argv[2] = g_strdup_printf ("exec %s", command); - argv[3] = NULL; + if (extra_arg != NULL) { + char **new_argv; + int i; + for (i = 0; argv[i] != NULL; i++) + ; + new_argv = g_new0 (char *, i+2); + for (i = 0; argv[i] != NULL; i++) + new_argv[i] = argv[i]; + new_argv[i++] = (char *)extra_arg; + new_argv[i++] = NULL; + + argv = new_argv; + } - IGNORE_EINTR (execv (shell_cmd, argv)); + IGNORE_EINTR (execv (argv[0], argv)); } static void @@ -2289,11 +2293,9 @@ gdm_slave_greeter (void) gdm_child_exit (DISPLAY_ABORT, _("%s: Couldn't set userid to %d"), "gdm_slave_greeter", GdmUserId); - - /* FIXME: clearing environment is likely fairly stupid, - * is there any reason we should do it anyway? */ - /* gdm_clearenv_no_lang (); */ + gdm_restoreenv (); + ve_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE); ve_setenv ("DISPLAY", d->name, TRUE); @@ -2321,7 +2323,11 @@ gdm_slave_greeter (void) ve_setenv ("HOME", ve_sure_string (GdmServAuthDir), TRUE); /* Hack */ ve_setenv ("SHELL", "/bin/sh", TRUE); } - ve_setenv ("PATH", GdmDefaultPath, TRUE); + if (ve_string_empty (g_getenv ("PATH"))) { + ve_setenv ("PATH", GdmDefaultPath, TRUE); + } else if ( ! ve_string_empty (GdmDefaultPath)) { + ve_setenv ("PATH", g_strconcat (g_getenv ("PATH"), ":", GdmDefaultPath, NULL), TRUE); + } ve_setenv ("RUNNING_UNDER_GDM", "true", TRUE); /* Note that this is just informative, the slave will not listen to @@ -2416,15 +2422,15 @@ gdm_slave_greeter (void) /* don't add modules if we're trying to prevent crashes, perhaps it's the modules causing the problem in the first place */ ! d->try_different_greeter) { - gchar *modules = g_strdup_printf("%s --gtk-module=%s", command, GdmGtkModulesList); - exec_in_shell (modules); + gchar *modules = g_strdup_printf ("--gtk-module=%s", GdmGtkModulesList); + exec_command (command, modules); /* Something went wrong */ gdm_error (_("%s: Cannot start greeter with gtk modules: %s. Trying without modules"), "gdm_slave_greeter", GdmGtkModulesList); - g_free(modules); + g_free (modules); } - exec_in_shell (command); + exec_command (command, NULL); gdm_error (_("%s: Cannot start greeter trying default: %s"), "gdm_slave_greeter", @@ -2432,7 +2438,7 @@ gdm_slave_greeter (void) ve_setenv ("GDM_WHACKED_GREETER_CONFIG", "true", TRUE); - exec_in_shell (EXPANDED_BINDIR "/gdmlogin"); + exec_command (EXPANDED_BINDIR "/gdmlogin", NULL); IGNORE_EINTR (execl (EXPANDED_BINDIR "/gdmlogin", EXPANDED_BINDIR "/gdmlogin", NULL)); @@ -2677,7 +2683,6 @@ send_chosen_host (GdmDisplay *disp, const char *hostname) static void gdm_slave_chooser (void) { - char *cmd; gint p[2]; struct passwd *pwent; char buf[1024]; @@ -2743,9 +2748,7 @@ gdm_slave_chooser (void) _("%s: Couldn't set userid to %d"), "gdm_slave_chooser", GdmUserId); - /* FIXME: clearing environment is likely fairly stupid, - * is there any reason we should do it anyway? */ - /* gdm_clearenv_no_lang (); */ + gdm_restoreenv (); ve_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE); ve_setenv ("DISPLAY", d->name, TRUE); @@ -2770,20 +2773,20 @@ gdm_slave_chooser (void) ve_setenv ("HOME", ve_sure_string (GdmServAuthDir), TRUE); /* Hack */ ve_setenv ("SHELL", "/bin/sh", TRUE); } - ve_setenv ("PATH", GdmDefaultPath, TRUE); + if (ve_string_empty (g_getenv ("PATH"))) { + ve_setenv ("PATH", GdmDefaultPath, TRUE); + } else if ( ! ve_string_empty (GdmDefaultPath)) { + ve_setenv ("PATH", g_strconcat (g_getenv ("PATH"), ":", GdmDefaultPath, NULL), TRUE); + } ve_setenv ("RUNNING_UNDER_GDM", "true", TRUE); - cmd = GdmChooser; - if (GdmAddGtkModules && ! ve_string_empty (GdmGtkModulesList)) { - cmd = g_strdup_printf("%s --gtk-module=%s", GdmChooser, GdmGtkModulesList); + char *modules = g_strdup_printf ("--gtk-module=%s", GdmGtkModulesList); + exec_command (GdmChooser, modules); } - exec_in_shell (cmd); - - /* anality */ - exec_in_shell (GdmChooser); + exec_command (GdmChooser, NULL); gdm_error_box (d, GTK_MESSAGE_ERROR, diff --git a/docs/C/gdm.xml b/docs/C/gdm.xml index a07c002d..2f51f911 100644 --- a/docs/C/gdm.xml +++ b/docs/C/gdm.xml @@ -2,8 +2,8 @@ <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ <!ENTITY legal SYSTEM "legal.xml"> - <!ENTITY version "2.4.4.2"> - <!ENTITY date "9/22/2003"> + <!ENTITY version "2.4.4.3"> + <!ENTITY date "9/23/2003"> ]> <article id="index" lang="en"> @@ -3119,6 +3119,30 @@ If the box is homogeneous then the children are allocated equal amount of space. </para> + + <para> + The "min-width" must be specified in pixels. Obviously there is + also a corresponding "min-height" property as well. + </para> + </sect3> + + <sect3 id="fixednodes"> + <title>Fixed Nodes</title> + + <para> + Fixed is a container that just has it's children scattered about + layed out with precise coordinates. The size of this container + is the biggest rectangle that contains all the children. Fixed + has no extra properties and so you just use: + <screen> + <fixed> +</screen> + Then you put other items with proper position nodes inside this. + </para> + + <para> + The "toplevel" node is really just like a fixed node. + </para> </sect3> <sect3 id="itemnodes"> @@ -3458,6 +3482,21 @@ or false. If true then the child will be expanded in the box as much as possible (that is it will be given more space if available). </para> + + <para> + There are two extra properties you can specify (as of 2.4.4.3) for + labels (and labels only). The first + is "max-width" which will specify the maximum width of the label in + pixels. And the second is "max-screen-percent-width" which specifies + the maximum percentage of the screen width that the label can occupy. + By default no label will occupy more then 90% of the screen by width. + An example may be: + <screen> + <item type="label"> + <pos x="10%" max-screen-percent-width="50%"/> +</screen> + </para> + </sect3> <sect3 id="shownodes"> diff --git a/gui/greeter/greeter.c b/gui/greeter/greeter.c index 3ba784cc..f73e0a28 100644 --- a/gui/greeter/greeter.c +++ b/gui/greeter/greeter.c @@ -964,8 +964,8 @@ greeter_reread_config (int sig, gpointer data) g_free (GdmWelcome); GdmWelcome = str; if (welcome_string_info != NULL) { - g_free (welcome_string_info->orig_text); - welcome_string_info->orig_text = g_strdup (str); + g_free (welcome_string_info->data.text.orig_text); + welcome_string_info->data.text.orig_text = g_strdup (str); greeter_item_update_text (welcome_string_info); } } else { @@ -1136,10 +1136,10 @@ main (int argc, char *argv[]) bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); - greeter_parse_config (); - setlocale (LC_ALL, ""); + greeter_parse_config (); + gtk_init (&argc, &argv); /* Should be a watch already, but anyway */ diff --git a/gui/greeter/greeter_canvas_item.c b/gui/greeter/greeter_canvas_item.c index 89cf913d..368c9e32 100644 --- a/gui/greeter/greeter_canvas_item.c +++ b/gui/greeter/greeter_canvas_item.c @@ -174,6 +174,73 @@ get_gdk_color_from_rgb (GdkColor *c, guint32 rgb) } void +greeter_item_recreate_label (GreeterItemInfo *item, const char *text, gboolean markup) +{ + GtkJustification just; + GnomeCanvasGroup *group; + double x1, y1, x2, y2; + GtkAllocation rect; + int width, height; + + if ( ! greeter_item_is_visible (item)) + return; + + rect = item->allocation; + + x1 = (gdouble) rect.x; + y1 = (gdouble) rect.y; + x2 = (gdouble) rect.x + rect.width; + y2 = (gdouble) rect.y + rect.height; + + group = item->group_item; + if (group == NULL) + group = item->parent->group_item; + + if (item->item != NULL) + gtk_object_destroy (GTK_OBJECT (item->item)); + + /* Justification is taken from the anchor */ + if (item->anchor == GTK_ANCHOR_NORTH_WEST || + item->anchor == GTK_ANCHOR_SOUTH_WEST || + item->anchor == GTK_ANCHOR_WEST) { + just = GTK_JUSTIFY_LEFT; + } else if (item->anchor == GTK_ANCHOR_NORTH_EAST || + item->anchor == GTK_ANCHOR_SOUTH_EAST || + item->anchor == GTK_ANCHOR_EAST) { + just = GTK_JUSTIFY_RIGHT; + } else { + just = GTK_JUSTIFY_CENTER; + } + + item->item = gnome_canvas_item_new (group, + GNOME_TYPE_CANVAS_TEXT, + markup ? "markup" : "text", text, + "x", x1, + "y", y1, + "anchor", item->anchor, + "font_desc", item->data.text.fonts[GREETER_ITEM_STATE_NORMAL], + "fill_color_rgba", item->data.text.colors[GREETER_ITEM_STATE_NORMAL], + "justification", just, + NULL); + + + pango_layout_get_pixel_size (GNOME_CANVAS_TEXT (item->item)->layout, &width, &height); + + if (item->data.text.real_max_width > 0 && + width > item->data.text.real_max_width) { + pango_layout_set_wrap (GNOME_CANVAS_TEXT (item->item)->layout, PANGO_WRAP_WORD_CHAR); + pango_layout_set_width (GNOME_CANVAS_TEXT (item->item)->layout, + (item->data.text.real_max_width * PANGO_SCALE) - PANGO_SCALE/2); + } + + /* Hack, we may have done something to the layout this will force + a redraw using the new layout thingie */ + gnome_canvas_item_set (item->item, + "justification", just, + NULL); +} + +void greeter_item_create_canvas_item (GreeterItemInfo *item) { GnomeCanvasGroup *group; @@ -183,7 +250,6 @@ greeter_item_create_canvas_item (GreeterItemInfo *item) double x1, y1, x2, y2; int i; GtkAllocation rect; - GtkJustification just; char *text; GtkTooltips *tooltips; char *num_locale; @@ -227,7 +293,7 @@ greeter_item_create_canvas_item (GreeterItemInfo *item) "y1", y1, "x2", x2, "y2", y2, - "fill_color_rgba", item->colors[GREETER_ITEM_STATE_NORMAL], + "fill_color_rgba", item->data.rect.colors[GREETER_ITEM_STATE_NORMAL], NULL); break; case GREETER_ITEM_TYPE_SVG: @@ -235,21 +301,21 @@ greeter_item_create_canvas_item (GreeterItemInfo *item) setlocale (LC_NUMERIC, "C"); for (i = 0; i < GREETER_ITEM_STATE_MAX; i++) { - if (item->files[i] != NULL) + if (item->data.pixmap.files[i] != NULL) { if (i > 0 && - item->files[0] != NULL && - item->pixbufs[0] != NULL && - strcmp (item->files[0], item->files[i]) == 0) - item->pixbufs[i] = g_object_ref (item->pixbufs[0]); + item->data.pixmap.files[0] != NULL && + item->data.pixmap.pixbufs[0] != NULL && + strcmp (item->data.pixmap.files[0], item->data.pixmap.files[i]) == 0) + item->data.pixmap.pixbufs[i] = g_object_ref (item->data.pixmap.pixbufs[0]); else - item->pixbufs[i] = - rsvg_pixbuf_from_file_at_size (item->files[i], + item->data.pixmap.pixbufs[i] = + rsvg_pixbuf_from_file_at_size (item->data.pixmap.files[i], rect.width, rect.height, NULL); } else - item->pixbufs[i] = NULL; + item->data.pixmap.pixbufs[i] = NULL; } setlocale (LC_NUMERIC, num_locale); g_free (num_locale); @@ -259,56 +325,35 @@ greeter_item_create_canvas_item (GreeterItemInfo *item) case GREETER_ITEM_TYPE_PIXMAP: for (i = 0; i < GREETER_ITEM_STATE_MAX; i++) { - GdkPixbuf *pb = item->pixbufs[i]; + GdkPixbuf *pb = item->data.pixmap.pixbufs[i]; if (pb != NULL) { - item->pixbufs[i] = + item->data.pixmap.pixbufs[i] = transform_pixbuf (pb, - (item->have_tint & (1<<i)), item->tints[i], - item->alphas[i], rect.width, rect.height); + (item->data.pixmap.have_tint & (1<<i)), item->data.pixmap.tints[i], + (double)item->data.pixmap.alphas[i] / 256.0, rect.width, rect.height); g_object_unref (pb); } } - if (item->pixbufs[GREETER_ITEM_STATE_NORMAL] != NULL) + if (item->data.pixmap.pixbufs[GREETER_ITEM_STATE_NORMAL] != NULL) item->item = gnome_canvas_item_new (group, GNOME_TYPE_CANVAS_PIXBUF, "x", (gdouble) x1, "y", (gdouble) y1, - "pixbuf", item->pixbufs[GREETER_ITEM_STATE_NORMAL], + "pixbuf", item->data.pixmap.pixbufs[GREETER_ITEM_STATE_NORMAL], NULL); break; case GREETER_ITEM_TYPE_LABEL: - text = greeter_item_expand_text (item->orig_text); - - /* Justification is taken from the anchor */ - if (item->anchor == GTK_ANCHOR_NORTH_WEST || - item->anchor == GTK_ANCHOR_SOUTH_WEST || - item->anchor == GTK_ANCHOR_WEST) - just = GTK_JUSTIFY_LEFT; - else if (item->anchor == GTK_ANCHOR_NORTH_EAST || - item->anchor == GTK_ANCHOR_SOUTH_EAST || - item->anchor == GTK_ANCHOR_EAST) - just = GTK_JUSTIFY_RIGHT; - else - just = GTK_JUSTIFY_CENTER; - - item->item = gnome_canvas_item_new (group, - GNOME_TYPE_CANVAS_TEXT, - "markup", text, - "x", x1, - "y", y1, - "anchor", item->anchor, - "font_desc", item->fonts[GREETER_ITEM_STATE_NORMAL], - "fill_color_rgba", item->colors[GREETER_ITEM_STATE_NORMAL], - "justification", just, - NULL); + text = greeter_item_expand_text (item->data.text.orig_text); + greeter_item_recreate_label (item, text, TRUE /* markup */); + g_free (text); /* if there is an accelerator we do an INCREDIBLE hack */ - if (strchr (item->orig_text, '_') != NULL) + if (strchr (item->data.text.orig_text, '_') != NULL) { GreeterItemInfo *button; - GtkWidget *fake_button = gtk_button_new_with_mnemonic (item->orig_text); + GtkWidget *fake_button = gtk_button_new_with_mnemonic (item->data.text.orig_text); gtk_widget_show (fake_button); GTK_WIDGET_UNSET_FLAGS (fake_button, GTK_CAN_FOCUS); gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (canvas)), @@ -328,8 +373,6 @@ greeter_item_create_canvas_item (GreeterItemInfo *item) (GClosureNotify)g_free, 0 /* connect_flags */); } - - g_free (text); break; @@ -338,9 +381,9 @@ greeter_item_create_canvas_item (GreeterItemInfo *item) gtk_entry_set_has_frame (GTK_ENTRY (entry), FALSE); if (GdmUseCirclesInEntry) gtk_entry_set_invisible_char (GTK_ENTRY (entry), 0x25cf); - gtk_widget_modify_font (entry, item->fonts[GREETER_ITEM_STATE_NORMAL]); + gtk_widget_modify_font (entry, item->data.text.fonts[GREETER_ITEM_STATE_NORMAL]); - get_gdk_color_from_rgb (&c, item->colors[GREETER_ITEM_STATE_NORMAL]); + get_gdk_color_from_rgb (&c, item->data.text.colors[GREETER_ITEM_STATE_NORMAL]); gtk_widget_modify_text (entry, GTK_STATE_NORMAL, &c); if (item->id != NULL && strcmp (item->id, "user-pw-entry") == 0) { diff --git a/gui/greeter/greeter_canvas_item.h b/gui/greeter/greeter_canvas_item.h index 36d31aae..99be6de3 100644 --- a/gui/greeter/greeter_canvas_item.h +++ b/gui/greeter/greeter_canvas_item.h @@ -3,4 +3,6 @@ void greeter_item_create_canvas_item (GreeterItemInfo *item); +void greeter_item_recreate_label (GreeterItemInfo *item, const char *text, gboolean markup); + #endif /* GREETER_CANVAS_ITEM_H */ diff --git a/gui/greeter/greeter_events.c b/gui/greeter/greeter_events.c index 8833b1fc..cf7fdb2e 100644 --- a/gui/greeter/greeter_events.c +++ b/gui/greeter/greeter_events.c @@ -24,17 +24,21 @@ state_run (GreeterItemInfo *info, info->have_state != (1<<GREETER_ITEM_STATE_NORMAL) && info->item != NULL) { - if (info->pixbufs[info->state]) + if (GREETER_ITEM_TYPE_IS_PIXMAP (info) && + info->data.pixmap.pixbufs[info->state] != NULL) gnome_canvas_item_set (info->item, - "pixbuf", info->pixbufs[info->state], + "pixbuf", info->data.pixmap.pixbufs[info->state], NULL); - if (info->have_color & (1<<(info->state))) + if ((GREETER_ITEM_TYPE_IS_TEXT (info) || + GREETER_ITEM_TYPE_IS_RECT (info)) && + info->data.rect.have_color & (1<<(info->state))) gnome_canvas_item_set (info->item, - "fill_color_rgba", info->colors[info->state], + "fill_color_rgba", info->data.rect.colors[info->state], NULL); - if (info->fonts[info->state]) + if (GREETER_ITEM_TYPE_IS_TEXT (info) && + info->data.text.fonts[info->state] != NULL) gnome_canvas_item_set (info->item, - "font_desc", info->fonts[info->state], + "font_desc", info->data.text.fonts[info->state], NULL); } } diff --git a/gui/greeter/greeter_geometry.c b/gui/greeter/greeter_geometry.c index 2c40fcda..145ee772 100644 --- a/gui/greeter/greeter_geometry.c +++ b/gui/greeter/greeter_geometry.c @@ -1,6 +1,7 @@ #include "config.h" #include <gtk/gtk.h> +#include "gdmwm.h" #include "greeter_geometry.h" #include "greeter_canvas_item.h" @@ -18,6 +19,17 @@ static void greeter_size_allocate_box (GreeterItemInfo *box, GtkAllocation *allocation); static void fixup_from_anchor (GtkAllocation *rect, GtkAnchorType anchor); +static void update_real_max_width (GreeterItemInfo *info, + int max_width); + +static void +update_real_max_width (GreeterItemInfo *info, int max_width) +{ + if (info->data.text.real_max_width == 0 || + info->data.text.real_max_width > max_width) + info->data.text.real_max_width = max_width; +} + /* Position the item */ static void @@ -283,7 +295,12 @@ greeter_size_allocate_box (GreeterItemInfo *box, child_allocation.width = child_requisition.width; child_allocation.height = child_requisition.height; - + + if (box->box_orientation == GTK_ORIENTATION_VERTICAL && + child->item_type == GREETER_ITEM_TYPE_LABEL) { + update_real_max_width (child, allocation->width); + } + if (box->box_orientation == GTK_ORIENTATION_HORIZONTAL) { child_allocation.x = major; @@ -403,7 +420,6 @@ greeter_size_request_box (GreeterItemInfo *box, requisition->height = MAX (requisition->height, box->box_min_height); } - /* Calculate the requested minimum size of the item */ static void greeter_item_size_request (GreeterItemInfo *item, @@ -414,6 +430,8 @@ greeter_item_size_request (GreeterItemInfo *item, { GtkRequisition *req; GtkRequisition box_requisition; + int set_width = 0; + int set_height = 0; if (item->has_requisition) { @@ -426,41 +444,6 @@ greeter_item_size_request (GreeterItemInfo *item, req->width = 0; req->height = 0; - if (item->item_type == GREETER_ITEM_TYPE_LABEL) - { - GnomeCanvasItem *canvas_item; - double x1, y1, x2, y2; - char *text; - - /* This is not the ugly hack you're looking for. - * You can go about your business. - * Move Along - */ - text = greeter_item_expand_text (item->orig_text); - - canvas_item = gnome_canvas_item_new (gnome_canvas_root (canvas), - GNOME_TYPE_CANVAS_TEXT, - "markup", text, - "x", 0.0, - "y", 0.0, - "font_desc", item->fonts[GREETER_ITEM_STATE_NORMAL], - NULL); - - gnome_canvas_item_get_bounds (canvas_item, - &x1, &y1, &x2, &y2); - req->width = x2 - x1; - req->height = y2 - y1; - - gtk_object_destroy (GTK_OBJECT (canvas_item)); - g_free (text); - } - - if (item->item_type == GREETER_ITEM_TYPE_PIXMAP) - { - req->width = gdk_pixbuf_get_width (item->pixbufs[0]); - req->height = gdk_pixbuf_get_height (item->pixbufs[0]); - } - if (item->width_type == GREETER_ITEM_SIZE_BOX || item->height_type == GREETER_ITEM_SIZE_BOX) { @@ -472,13 +455,13 @@ greeter_item_size_request (GreeterItemInfo *item, switch (item->width_type) { case GREETER_ITEM_SIZE_ABSOLUTE: - req->width = (item->width > 0) ? item->width : parent_width + item->width; + set_width = (item->width > 0) ? item->width : parent_width + item->width; break; case GREETER_ITEM_SIZE_RELATIVE: - req->width = item->width*parent_width / 100.0; + set_width = item->width*parent_width / 100.0; break; case GREETER_ITEM_SIZE_BOX: - req->width = box_requisition.width; + set_width = box_requisition.width; break; case GREETER_ITEM_SIZE_UNSET: break; @@ -487,18 +470,76 @@ greeter_item_size_request (GreeterItemInfo *item, switch (item->height_type) { case GREETER_ITEM_SIZE_ABSOLUTE: - req->height = (item->height > 0) ? item->height : parent_height + item->height; + set_height = (item->height > 0) ? item->height : parent_height + item->height; break; case GREETER_ITEM_SIZE_RELATIVE: - req->height = item->height*parent_height / 100.0; + set_height = item->height*parent_height / 100.0; break; case GREETER_ITEM_SIZE_BOX: - req->height = box_requisition.height; + set_height = box_requisition.height; break; case GREETER_ITEM_SIZE_UNSET: break; } + if (item->item_type == GREETER_ITEM_TYPE_LABEL) + { + GnomeCanvasItem *canvas_item; + int width, height; + char *text; + int max_width = G_MAXINT; + + /* This is not the ugly hack you're looking for. + * You can go about your business. + * Move Along + */ + text = greeter_item_expand_text (item->data.text.orig_text); + + canvas_item = gnome_canvas_item_new (gnome_canvas_root (canvas), + GNOME_TYPE_CANVAS_TEXT, + "markup", text, + "x", 0.0, + "y", 0.0, + "font_desc", item->data.text.fonts[GREETER_ITEM_STATE_NORMAL], + NULL); + + if (set_width > 0) + max_width = set_width; + + if (item->data.text.max_width < max_width) + max_width = item->data.text.max_width; + + if (item->data.text.max_screen_percent_width/100.0 * gdm_wm_screen.width < max_width) + max_width = item->data.text.max_screen_percent_width/100.0 * gdm_wm_screen.width; + + if (max_width < G_MAXINT) { + pango_layout_set_wrap (GNOME_CANVAS_TEXT (canvas_item)->layout, PANGO_WRAP_WORD_CHAR); + pango_layout_set_width (GNOME_CANVAS_TEXT (canvas_item)->layout, (max_width * PANGO_SCALE) - PANGO_SCALE/2); + /* HACK: this forces the thing to relayout */ + gnome_canvas_item_set (GNOME_CANVAS_ITEM (canvas_item), "justification", GTK_JUSTIFY_CENTER, NULL); + update_real_max_width (item, max_width); + } + + pango_layout_get_pixel_size (GNOME_CANVAS_TEXT (canvas_item)->layout, &width, &height); + + req->width = width; + req->height = height; + + gtk_object_destroy (GTK_OBJECT (canvas_item)); + g_free (text); + } + + if (item->item_type == GREETER_ITEM_TYPE_PIXMAP) + { + req->width = gdk_pixbuf_get_width (item->data.pixmap.pixbufs[0]); + req->height = gdk_pixbuf_get_height (item->data.pixmap.pixbufs[0]); + } + + if (set_width > 0) + req->width = set_width; + if (set_height > 0) + req->height = set_height; + *requisition_out = item->requisition; item->has_requisition = TRUE; } diff --git a/gui/greeter/greeter_item.c b/gui/greeter/greeter_item.c index d61e69c6..cd5d1fb6 100644 --- a/gui/greeter/greeter_item.c +++ b/gui/greeter/greeter_item.c @@ -32,9 +32,14 @@ greeter_item_info_new (GreeterItemInfo *parent, info->width_type = GREETER_ITEM_SIZE_UNSET; info->height_type = GREETER_ITEM_SIZE_UNSET; - for (i=0; i< GREETER_ITEM_STATE_MAX; i++) + if (type != GREETER_ITEM_TYPE_LIST) { - info->alphas[i] = 1.0; + for (i=0; i< GREETER_ITEM_STATE_MAX; i++) + { + /* these happen to coincide for all + items but list */ + info->data.rect.alphas[i] = 0xff; + } } info->box_orientation = GTK_ORIENTATION_VERTICAL; @@ -46,6 +51,13 @@ greeter_item_info_new (GreeterItemInfo *parent, info->button = FALSE; + if (GREETER_ITEM_TYPE_IS_TEXT (info)) + { + info->data.text.max_width = 0xffff; + info->data.text.max_screen_percent_width = 90; + info->data.text.real_max_width = 0; + } + return info; } @@ -57,12 +69,18 @@ greeter_item_info_free (GreeterItemInfo *info) for (i = 0; i < GREETER_ITEM_STATE_MAX; i++) { - if (info->pixbufs[i]) - g_object_unref (G_OBJECT (info->pixbufs[i])); - if (info->files[i]) - g_free (info->files[i]); - if (info->fonts[i]) - pango_font_description_free (info->fonts[i]); + if (GREETER_ITEM_TYPE_IS_PIXMAP (info)) + { + if (info->data.pixmap.pixbufs[i] != NULL) + g_object_unref (G_OBJECT (info->data.pixmap.pixbufs[i])); + if (info->data.pixmap.files[i] != NULL) + g_free (info->data.pixmap.files[i]); + } + else if (GREETER_ITEM_TYPE_IS_TEXT (info)) + { + if (info->data.text.fonts[i] != NULL) + pango_font_description_free (info->data.text.fonts[i]); + } } list = info->fixed_children; @@ -75,8 +93,12 @@ greeter_item_info_free (GreeterItemInfo *info) g_list_foreach (list, (GFunc) greeter_item_info_free, NULL); g_list_free (list); + if (GREETER_ITEM_TYPE_IS_TEXT (info)) + g_free (info->data.text.orig_text); + + /* FIXME: what about custom list items! */ + g_free (info->id); - g_free (info->orig_text); g_free (info->show_type); memset (info, 0, sizeof (GreeterItemInfo)); @@ -88,9 +110,10 @@ greeter_item_update_text (GreeterItemInfo *info) { char *text; if (info && info->item && - GNOME_IS_CANVAS_TEXT (info->item)) + GNOME_IS_CANVAS_TEXT (info->item) && + GREETER_ITEM_TYPE_IS_TEXT (info)) { - text = greeter_item_expand_text (info->orig_text); + text = greeter_item_expand_text (info->data.text.orig_text); g_object_set (G_OBJECT (info->item), "markup", text, @@ -139,7 +162,21 @@ greeter_item_expand_text (const char *text) while (*p) { - if (*p == '%') + /* Backslash commands */ + if (*p == '\\') + { + p++; + if (*p == '\n') + g_string_append_c (str, '\n'); + else if (*p != '\0') + g_string_append_c (str, *p); + else + { + g_warning ("Unescaped \\ at end of text\n"); + goto bail; + } + } + else if (*p == '%') { p++; switch (*p) diff --git a/gui/greeter/greeter_item.h b/gui/greeter/greeter_item.h index 016f55f6..f85e78ef 100644 --- a/gui/greeter/greeter_item.h +++ b/gui/greeter/greeter_item.h @@ -17,7 +17,7 @@ enum _GreeterItemState { GREETER_ITEM_STATE_NORMAL, GREETER_ITEM_STATE_PRELIGHT, GREETER_ITEM_STATE_ACTIVE, - GREETER_ITEM_STATE_MAX, + GREETER_ITEM_STATE_MAX }; /* Make sure to adjust the bitfield in the structure if @@ -28,7 +28,7 @@ enum _GreeterItemType { GREETER_ITEM_TYPE_PIXMAP, GREETER_ITEM_TYPE_LABEL, GREETER_ITEM_TYPE_ENTRY, - GREETER_ITEM_TYPE_LIST, + GREETER_ITEM_TYPE_LIST }; /* Make sure to adjust the bitfield in the structure if @@ -37,7 +37,7 @@ enum _GreeterItemSizeType { GREETER_ITEM_SIZE_UNSET, GREETER_ITEM_SIZE_ABSOLUTE, GREETER_ITEM_SIZE_RELATIVE, - GREETER_ITEM_SIZE_BOX, + GREETER_ITEM_SIZE_BOX }; /* Make sure to adjust the bitfield in the structure if @@ -45,7 +45,7 @@ enum _GreeterItemSizeType { enum _GreeterItemPosType { GREETER_ITEM_POS_UNSET, GREETER_ITEM_POS_ABSOLUTE, - GREETER_ITEM_POS_RELATIVE, + GREETER_ITEM_POS_RELATIVE }; /* Make sure to adjust the bitfield in the structure if @@ -65,10 +65,14 @@ struct _GreeterItemInfo { GreeterItemInfo *parent; GtkAnchorType anchor; - double x; - double y; + float x; + float y; + float width; + float height; GreeterItemPosType x_type:2; GreeterItemPosType y_type:2; + GreeterItemSizeType width_type:2; + GreeterItemSizeType height_type:2; gboolean x_negative:1; /* needed for -0 */ gboolean y_negative:1; /* needed for -0 */ @@ -79,66 +83,95 @@ struct _GreeterItemInfo { GreeterItemType item_type:4; GreeterItemShowModes show_modes:4; - char *show_type; /* timed, system, config, chooser, halt, suspend, reboot */ - - GreeterItemSizeType width_type:2; - GreeterItemSizeType height_type:2; - double width; - double height; - char *id; + /* Runtime state: */ + GreeterItemState state:2; + GreeterItemState base_state:2; + gboolean mouse_down:1; + gboolean mouse_over:1; + + /* box flags */ + gboolean box_homogeneous:1; + + /* is a button (see my_button comment) */ + gboolean button:1; + + /* geometry handling: */ + gboolean has_requisition:1; + GtkRequisition requisition; + GtkAllocation allocation; /* Button can propagate states and collect states from underlying items, * it should be a parent of this item */ - gboolean button; GreeterItemInfo *my_button; - char *files[GREETER_ITEM_STATE_MAX]; - gdouble alphas[GREETER_ITEM_STATE_MAX]; - GdkPixbuf *pixbufs[GREETER_ITEM_STATE_MAX]; - guint32 tints[GREETER_ITEM_STATE_MAX]; - guint32 colors[GREETER_ITEM_STATE_MAX]; - - guint8 have_color; /* this is a bitfield since these are - true/false values */ - guint8 have_tint; /* this is a bitfield since these are - true/false values */ - guint8 have_state; /* this is a bitfield since these are - true/false values */ + char *show_type; /* timed, system, config, chooser, halt, suspend, reboot */ - PangoFontDescription *fonts[GREETER_ITEM_STATE_MAX]; - char *orig_text; + char *id; - /* If this is a custom list, then these are the items - to pick from */ - GList *list_items; + GList *box_children; + GtkOrientation box_orientation; + guint16 box_x_padding; + guint16 box_y_padding; + guint16 box_min_width; + guint16 box_min_height; + guint16 box_spacing; /* Container data */ GList *fixed_children; - GtkOrientation box_orientation; - gboolean box_homogeneous:1; - double box_x_padding; - double box_y_padding; - double box_min_width; - double box_min_height; - double box_spacing; - GList *box_children; - - /* Runtime state: */ - GreeterItemState state:2; - GreeterItemState base_state:2; - gboolean mouse_down:1; - gboolean mouse_over:1; + union { + /* Note: we want to have alphas, colors and have_color coincide for all types + that have it */ +#define GREETER_ITEM_TYPE_IS_TEXT(info) ((info)->item_type == GREETER_ITEM_TYPE_LABEL || (info)->item_type == GREETER_ITEM_TYPE_ENTRY) + struct { + guint8 alphas[GREETER_ITEM_STATE_MAX]; + guint32 colors[GREETER_ITEM_STATE_MAX]; + + guint8 have_color; /* this is a bitfield since these are + true/false values */ + + PangoFontDescription *fonts[GREETER_ITEM_STATE_MAX]; + char *orig_text; + guint16 max_width; + guint8 max_screen_percent_width; + guint16 real_max_width; + } text; /* text and entry (entry only uses fonts) */ + +#define GREETER_ITEM_TYPE_IS_PIXMAP(info) ((info)->item_type == GREETER_ITEM_TYPE_PIXMAP || (info)->item_type == GREETER_ITEM_TYPE_SVG) + struct { + guint8 alphas[GREETER_ITEM_STATE_MAX]; + guint32 tints[GREETER_ITEM_STATE_MAX]; + guint8 have_tint; /* this is a bitfield since these are + true/false values */ + + char *files[GREETER_ITEM_STATE_MAX]; + GdkPixbuf *pixbufs[GREETER_ITEM_STATE_MAX]; + } pixmap; + +#define GREETER_ITEM_TYPE_IS_LIST(info) ((info)->item_type == GREETER_ITEM_TYPE_LIST) + struct { + /* If this is a custom list, then these are the items + to pick from */ + GList *items; + } list; + +#define GREETER_ITEM_TYPE_IS_RECT(info) ((info)->item_type == GREETER_ITEM_TYPE_RECT) + struct { + guint8 alphas[GREETER_ITEM_STATE_MAX]; + guint32 colors[GREETER_ITEM_STATE_MAX]; + + guint8 have_color; /* this is a bitfield since these are + true/false values */ + } rect; + } data; + + guint8 have_state; /* this is a bitfield since these are + true/false values */ /* Canvas data: */ GnomeCanvasItem *item; GnomeCanvasGroup *group_item; - - /* geometry handling: */ - gboolean has_requisition:1; - GtkRequisition requisition; - GtkAllocation allocation; }; struct _GreeterItemListItem { diff --git a/gui/greeter/greeter_item_customlist.c b/gui/greeter/greeter_item_customlist.c index c52ee324..dafab71a 100644 --- a/gui/greeter/greeter_item_customlist.c +++ b/gui/greeter/greeter_item_customlist.c @@ -93,7 +93,7 @@ setup_customlist (GtkWidget *tv, GreeterItemInfo *item) NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column); - populate_list (tm, selection, item->list_items); + populate_list (tm, selection, item->data.list.items); } gboolean diff --git a/gui/greeter/greeter_item_pam.c b/gui/greeter/greeter_item_pam.c index f6064c6b..71dc2e0f 100644 --- a/gui/greeter/greeter_item_pam.c +++ b/gui/greeter/greeter_item_pam.c @@ -9,6 +9,7 @@ #include "greeter_item_timed.h" #include "greeter_parser.h" #include "greeter_configuration.h" +#include "greeter_canvas_item.h" #include "gdm.h" #include "gdmwm.h" #include "vicious.h" @@ -25,57 +26,6 @@ gboolean require_quarter = FALSE; extern gboolean greeter_probably_login_prompt; -static char * -break_at (const char *orig, int columns) -{ - PangoLogAttr *attrs; - int n_chars; - GString *str; - int i; - int in_current_row; - const char *p; - - str = g_string_new (NULL); - n_chars = g_utf8_strlen (orig, -1); - - attrs = g_new0 (PangoLogAttr, n_chars + 1); - pango_get_log_attrs (orig, -1, - 0, gtk_get_default_language (), - attrs, n_chars + 1); - - in_current_row = 0; - i = 0; - p = orig; - while (i < n_chars) - { - gunichar ch; - - ch = g_utf8_get_char (p); - - /* Broken algorithm for simplicity; we just break - * at the first place we can within 10 of the end - */ - - if (in_current_row > (columns - 10) && - attrs[i].is_line_break) - { - in_current_row = 0; - g_string_append_unichar (str, '\n'); - } - - ++in_current_row; - g_string_append_unichar (str, ch); - - p = g_utf8_next_char (p); - ++i; - } - - g_free (attrs); - - return g_string_free (str, FALSE); -} - - void greeter_item_pam_set_user (const char *user) { @@ -108,6 +58,19 @@ evil (GtkEntry *entry, const char *user) } static void +set_text (GreeterItemInfo *info, const char *text) +{ + greeter_item_recreate_label (info, text, FALSE /* markup */); + /* + g_object_set (G_OBJECT (info->item), + "text", text, + "font_desc", info->data.text.fonts[info->state], + "justification", GTK_JUSTIFY_CENTER, + NULL); + */ +} + +static void user_pw_activate (GtkEntry *entry, GreeterItemInfo *info) { const char *str; @@ -145,9 +108,7 @@ user_pw_activate (GtkEntry *entry, GreeterItemInfo *info) } error_info = greeter_lookup_id ("pam-error"); if (error_info) - g_object_set (G_OBJECT (error_info->item), - "text", "", - NULL); + set_text (error_info, ""); tmp = ve_locale_from_utf8 (str); printf ("%c%s\n", STX, tmp); @@ -220,19 +181,7 @@ greeter_item_pam_prompt (const char *message, if (conversation_info) { - char *text; - - /* This is a bad hack that I added because - * the canvas text item doesn't support - * text wrapping... - */ - text = break_at (message, 50); - - g_object_set (G_OBJECT (conversation_info->item), - "text", text, - NULL); - - g_free (text); + set_text (conversation_info, message); } if (entry_info && entry_info->item && @@ -265,14 +214,6 @@ greeter_item_pam_message (const char *message) if (message_info) { - char *text; - - /* This is a bad hack that I added because - * the canvas text item doesn't support - * text wrapping... - */ - text = break_at (message, 50); - /* HAAAAAAACK. Sometimes pam sends many many messages, SO * we try to collect them until the next prompt or reset or * whatnot */ @@ -284,22 +225,14 @@ greeter_item_pam_message (const char *message) if (strlen (oldtext) > 0) { newtext = g_strdup_printf ("%s\n%s", oldtext, message); - g_object_set (G_OBJECT (message_info->item), - "text", newtext, - NULL); + set_text (message_info, newtext); g_free (newtext); } else - g_object_set (G_OBJECT (message_info->item), - "text", text, - NULL); + set_text (message_info, message); } else - g_object_set (G_OBJECT (message_info->item), - "text", text, - NULL); - - g_free (text); + set_text (message_info, message); } replace_msg = FALSE; } @@ -310,9 +243,7 @@ error_clear (gpointer data) { GreeterItemInfo *error_info = data; - g_object_set (G_OBJECT (error_info->item), - "text", "", - NULL); + set_text (error_info, ""); err_box_clear_handler = 0; return FALSE; @@ -322,7 +253,6 @@ void greeter_item_pam_error (const char *message) { GreeterItemInfo *error_info; - char *text; /* The message I got from pam had a silly newline * in the beginning. That may make sense for a @@ -335,16 +265,7 @@ greeter_item_pam_error (const char *message) error_info = greeter_lookup_id ("pam-error"); if (error_info) { - /* This is a bad hack that I added because - * the canvas text item doesn't support - * text wrapping... - */ - text = break_at (message, 50); - - g_object_set (G_OBJECT (error_info->item), - "text", text, - NULL); - g_free (text); + set_text (error_info, message); if (err_box_clear_handler > 0) g_source_remove (err_box_clear_handler); diff --git a/gui/greeter/greeter_parser.c b/gui/greeter/greeter_parser.c index 4b14355b..cff837f7 100644 --- a/gui/greeter/greeter_parser.c +++ b/gui/greeter/greeter_parser.c @@ -119,7 +119,7 @@ parse_button (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "bad button spec %s\n", prop); + "bad button spec %s", prop); xmlFree (prop); return FALSE; } @@ -168,7 +168,7 @@ parse_pos (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Unknown anchor type %s\n", prop); + "Unknown anchor type %s", prop); xmlFree (prop); return FALSE; } @@ -186,7 +186,7 @@ parse_pos (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad position specifier %s\n", prop); + "Bad position specifier %s", prop); xmlFree (prop); return FALSE; } @@ -213,7 +213,7 @@ parse_pos (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad position specifier %s\n", prop); + "Bad position specifier %s", prop); xmlFree (prop); return FALSE; } @@ -239,14 +239,12 @@ parse_pos (xmlNodePtr node, { info->width = g_ascii_strtod (prop, &p); - printf ("width == '%s' == '%g'\n", prop, info->width); - if ((char *)prop == p) { g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad size specifier %s\n", prop); + "Bad size specifier %s", prop); xmlFree (prop); return FALSE; } @@ -273,7 +271,7 @@ parse_pos (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad size specifier %s\n", prop); + "Bad size specifier %s", prop); xmlFree (prop); return FALSE; } @@ -302,7 +300,7 @@ parse_pos (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad expand spec %s\n", prop); + "Bad expand spec %s", prop); xmlFree (prop); return FALSE; } @@ -441,7 +439,7 @@ parse_box (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad orientation %s\n", prop); + "Bad orientation %s", prop); xmlFree (prop); return FALSE; } @@ -465,7 +463,7 @@ parse_box (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad homogenous spec %s\n", prop); + "Bad homogenous spec %s", prop); xmlFree (prop); return FALSE; } @@ -484,7 +482,7 @@ parse_box (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad padding specification %s\n", prop); + "Bad padding specification %s", prop); xmlFree (prop); return FALSE; } @@ -501,7 +499,7 @@ parse_box (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad padding specification %s\n", prop); + "Bad padding specification %s", prop); xmlFree (prop); return FALSE; } @@ -518,7 +516,7 @@ parse_box (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad min-width specification %s\n", prop); + "Bad min-width specification %s", prop); xmlFree (prop); return FALSE; } @@ -535,7 +533,7 @@ parse_box (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad min-height specification %s\n", prop); + "Bad min-height specification %s", prop); xmlFree (prop); return FALSE; } @@ -552,7 +550,7 @@ parse_box (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad spacing specification %s\n", prop); + "Bad spacing specification %s", prop); xmlFree (prop); return FALSE; } @@ -579,7 +577,7 @@ parse_color (const char *str, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "colors must start with #, %s is an invalid color\n", str); + "colors must start with #, %s is an invalid color", str); return FALSE; } if G_UNLIKELY (strlen (str) != 7) @@ -587,7 +585,7 @@ parse_color (const char *str, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Colors must be on the format #xxxxxx, %s is an invalid color\n", str); + "Colors must be on the format #xxxxxx, %s is an invalid color", str); return FALSE; } @@ -602,10 +600,10 @@ parse_color (const char *str, } static gboolean -parse_state_file (xmlNodePtr node, - GreeterItemInfo *info, - GreeterItemState state, - GError **error) +parse_state_file_pixmap (xmlNodePtr node, + GreeterItemInfo *info, + GreeterItemState state, + GError **error) { xmlChar *prop; char *p; @@ -616,9 +614,9 @@ parse_state_file (xmlNodePtr node, if (prop) { if (g_path_is_absolute (prop)) - info->files[state] = g_strdup (prop); + info->data.pixmap.files[state] = g_strdup (prop); else - info->files[state] = g_build_filename (file_search_path, + info->data.pixmap.files[state] = g_build_filename (file_search_path, prop, NULL); @@ -628,37 +626,44 @@ parse_state_file (xmlNodePtr node, prop = xmlGetProp (node, "tint"); if (prop) { - if (!parse_color (prop, &info->tints[state], error)) + if (!parse_color (prop, &info->data.pixmap.tints[state], error)) return FALSE; - info->have_tint |= (1<<state); + info->data.pixmap.have_tint |= (1<<state); xmlFree (prop); } prop = xmlGetProp (node, "alpha"); if (prop) { - info->alphas[state] = g_ascii_strtod (prop, &p); + double alpha = g_ascii_strtod (prop, &p); if G_UNLIKELY ((char *)prop == p) { g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad alpha specifier format %s\n", prop); + "Bad alpha specifier format %s", prop); xmlFree (prop); return FALSE; } xmlFree (prop); + + if (alpha >= 1.0) + info->data.pixmap.alphas[state] = 0xff; + else if (alpha < 0) + info->data.pixmap.alphas[state] = 0; + else + info->data.pixmap.alphas[state] = floor (alpha * 0xff); } return TRUE; } static gboolean -parse_state_color (xmlNodePtr node, - GreeterItemInfo *info, - GreeterItemState state, - GError **error) +parse_state_color_rect (xmlNodePtr node, + GreeterItemInfo *info, + GreeterItemState state, + GError **error) { xmlChar *prop; char *p; @@ -668,27 +673,34 @@ parse_state_color (xmlNodePtr node, prop = xmlGetProp (node, "color"); if (prop) { - if G_UNLIKELY (!parse_color (prop, &info->colors[state], error)) + if G_UNLIKELY (!parse_color (prop, &info->data.rect.colors[state], error)) return FALSE; - info->have_color |= (1<<state); + info->data.rect.have_color |= (1<<state); xmlFree (prop); } prop = xmlGetProp (node, "alpha"); if (prop) { - info->alphas[state] = g_ascii_strtod (prop, &p); + double alpha = g_ascii_strtod (prop, &p); if G_UNLIKELY ((char *)prop == p) { g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad alpha specifier format %s\n", prop); + "Bad alpha specifier format %s", prop); xmlFree (prop); return FALSE; } xmlFree (prop); + + if (alpha >= 1.0) + info->data.rect.alphas[state] = 0xff; + else if (alpha < 0) + info->data.rect.alphas[state] = 0; + else + info->data.rect.alphas[state] = floor (alpha * 0xff); } return TRUE; @@ -709,17 +721,17 @@ parse_pixmap (xmlNodePtr node, { if (strcmp (child->name, "normal") == 0) { - if G_UNLIKELY (!parse_state_file (child, info, GREETER_ITEM_STATE_NORMAL, error)) + if G_UNLIKELY (!parse_state_file_pixmap (child, info, GREETER_ITEM_STATE_NORMAL, error)) return FALSE; } else if (strcmp (child->name, "prelight") == 0) { - if G_UNLIKELY (!parse_state_file (child, info, GREETER_ITEM_STATE_PRELIGHT, error)) + if G_UNLIKELY (!parse_state_file_pixmap (child, info, GREETER_ITEM_STATE_PRELIGHT, error)) return FALSE; } else if (strcmp (child->name, "active") == 0) { - if G_UNLIKELY (!parse_state_file (child, info, GREETER_ITEM_STATE_ACTIVE, error)) + if G_UNLIKELY (!parse_state_file_pixmap (child, info, GREETER_ITEM_STATE_ACTIVE, error)) return FALSE; } else if (strcmp (child->name, "pos") == 0) @@ -746,7 +758,7 @@ parse_pixmap (xmlNodePtr node, child = child->next; } - if G_UNLIKELY (!info->files[GREETER_ITEM_STATE_NORMAL]) + if G_UNLIKELY (!info->data.pixmap.files[GREETER_ITEM_STATE_NORMAL]) { g_set_error (error, GREETER_PARSER_ERROR, @@ -759,15 +771,15 @@ parse_pixmap (xmlNodePtr node, { for (i = 0; i < GREETER_ITEM_STATE_MAX; i++) { - if (info->files[i] != NULL) + if (info->data.pixmap.files[i] != NULL) { - info->pixbufs[i] = load_pixbuf (info->files[i], error); + info->data.pixmap.pixbufs[i] = load_pixbuf (info->data.pixmap.files[i], error); - if G_UNLIKELY (info->pixbufs[i] == NULL) + if G_UNLIKELY (info->data.pixmap.pixbufs[i] == NULL) return FALSE; } else - info->pixbufs[i] = NULL; + info->data.pixmap.pixbufs[i] = NULL; } } @@ -788,17 +800,17 @@ parse_rect (xmlNodePtr node, { if (strcmp (child->name, "normal") == 0) { - if G_UNLIKELY (!parse_state_color (child, info, GREETER_ITEM_STATE_NORMAL, error)) + if G_UNLIKELY (!parse_state_color_rect (child, info, GREETER_ITEM_STATE_NORMAL, error)) return FALSE; } else if (strcmp (child->name, "prelight") == 0) { - if G_UNLIKELY (!parse_state_color (child, info, GREETER_ITEM_STATE_PRELIGHT, error)) + if G_UNLIKELY (!parse_state_color_rect (child, info, GREETER_ITEM_STATE_PRELIGHT, error)) return FALSE; } else if (strcmp (child->name, "active") == 0) { - if G_UNLIKELY (!parse_state_color (child, info, GREETER_ITEM_STATE_ACTIVE, error)) + if G_UNLIKELY (!parse_state_color_rect (child, info, GREETER_ITEM_STATE_ACTIVE, error)) return FALSE; } else if (strcmp (child->name, "pos") == 0) @@ -827,15 +839,10 @@ parse_rect (xmlNodePtr node, for (i = 0; i < GREETER_ITEM_STATE_MAX; i++) { - if ( ! (info->have_color & (1<<i))) + if ( ! (info->data.rect.have_color & (1<<i))) continue; - if (info->alphas[i] >= 1.0) - info->colors[i] = (info->colors[i] << 8) | 0xff; - else if (info->alphas[i] > 0) - info->colors[i] = (info->colors[i] << 8) | (guint) floor (0xff*info->alphas[i]); - else - info->colors[i] = 0; + info->data.rect.colors[i] = (info->data.rect.colors[i] << 8) | (guint) info->data.rect.alphas[i]; } return TRUE; @@ -856,13 +863,13 @@ parse_state_text (xmlNodePtr node, prop = xmlGetProp (node, "font"); if (prop) { - info->fonts[state] = pango_font_description_from_string (prop); - if G_UNLIKELY (info->fonts[state] == NULL) + info->data.text.fonts[state] = pango_font_description_from_string (prop); + if G_UNLIKELY (info->data.text.fonts[state] == NULL) { g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad font specification %s\n", prop); + "Bad font specification %s", prop); xmlFree (prop); return FALSE; } @@ -872,27 +879,34 @@ parse_state_text (xmlNodePtr node, prop = xmlGetProp (node, "color"); if (prop) { - if G_UNLIKELY (!parse_color (prop, &info->colors[state], error)) + if G_UNLIKELY (!parse_color (prop, &info->data.text.colors[state], error)) return FALSE; - info->have_color |= (1<<state); + info->data.text.have_color |= (1<<state); xmlFree (prop); } prop = xmlGetProp (node, "alpha"); if (prop) { - info->alphas[state] = g_ascii_strtod (prop, &p); + double alpha = g_ascii_strtod (prop, &p); if G_UNLIKELY ((char *)prop == p) { g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad alpha specifier format %s\n", prop); + "Bad alpha specifier format %s", prop); xmlFree (prop); return FALSE; } xmlFree (prop); + + if (alpha >= 1.0) + info->data.rect.alphas[state] = 0xff; + else if (alpha < 0) + info->data.rect.alphas[state] = 0; + else + info->data.rect.alphas[state] = floor (alpha * 0xff); } return TRUE; @@ -1051,7 +1065,7 @@ parse_stock (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Bad stock label type\n"); + "Bad stock label type"); xmlFree (prop); return FALSE; } @@ -1068,7 +1082,7 @@ parse_stock (xmlNodePtr node, g_set_error (error, GREETER_PARSER_ERROR, GREETER_PARSER_ERROR_BAD_SPEC, - "Stock type not specified\n"); + "Stock type not specified"); return FALSE; } } @@ -1089,15 +1103,62 @@ do_font_size_reduction (GreeterItemInfo *info) { for (i = 0; i < GREETER_ITEM_STATE_MAX; i++) { - if (info->fonts[i] != NULL) + if (info->data.text.fonts[i] != NULL) { - int old_size = pango_font_description_get_size (info->fonts[i]); - pango_font_description_set_size (info->fonts[i], old_size * size_reduction); + int old_size = pango_font_description_get_size (info->data.text.fonts[i]); + pango_font_description_set_size (info->data.text.fonts[i], old_size * size_reduction); } } } } + +static gboolean +parse_label_pos_extras (xmlNodePtr node, + GreeterItemInfo *info, + GError **error) +{ + xmlChar *prop; + char *p; + + prop = xmlGetProp (node, "max-width"); + if (prop) + { + info->data.text.max_width = g_ascii_strtod (prop, &p); + + if G_UNLIKELY ((char *)prop == p) + { + g_set_error (error, + GREETER_PARSER_ERROR, + GREETER_PARSER_ERROR_BAD_SPEC, + "Bad max-width specification %s", prop); + xmlFree (prop); + return FALSE; + } + xmlFree (prop); + } + + prop = xmlGetProp (node, "max-screen-percent-width"); + if (prop) + { + info->data.text.max_screen_percent_width = g_ascii_strtod (prop, &p); + + if G_UNLIKELY ((char *)prop == p) + { + g_set_error (error, + GREETER_PARSER_ERROR, + GREETER_PARSER_ERROR_BAD_SPEC, + "Bad max-screen-percent-width specification %s", prop); + xmlFree (prop); + return FALSE; + } + xmlFree (prop); + } + + return TRUE; +} + + static gboolean parse_label (xmlNodePtr node, GreeterItemInfo *info, @@ -1109,7 +1170,7 @@ parse_label (xmlNodePtr node, gint translation_score = 1000; translated_text = NULL; - + child = node->children; while (child) { @@ -1132,6 +1193,8 @@ parse_label (xmlNodePtr node, { if G_UNLIKELY (!parse_pos (child, info, error)) return FALSE; + if G_UNLIKELY (!parse_label_pos_extras (child, info, error)) + return FALSE; } else if (child->type == XML_ELEMENT_NODE && strcmp (child->name, "text") == 0) @@ -1182,23 +1245,18 @@ parse_label (xmlNodePtr node, for (i = 0; i < GREETER_ITEM_STATE_MAX; i++) { - if ( ! (info->have_color & (1<<i))) + if ( ! (info->data.text.have_color & (1<<i))) continue; - if (info->alphas[i] >= 1.0) - info->colors[i] = (info->colors[i] << 8) | 0xff; - else if (info->alphas[i] > 0) - info->colors[i] = (info->colors[i] << 8) | (guint) floor (0xff*info->alphas[i]); - else - info->colors[i] = 0; + info->data.text.colors[i] = (info->data.text.colors[i] << 8) | (guint) info->data.text.alphas[i]; } - if (info->fonts[GREETER_ITEM_STATE_NORMAL] == NULL) - info->fonts[GREETER_ITEM_STATE_NORMAL] = pango_font_description_from_string ("Sans"); + if (info->data.text.fonts[GREETER_ITEM_STATE_NORMAL] == NULL) + info->data.text.fonts[GREETER_ITEM_STATE_NORMAL] = pango_font_description_from_string ("Sans"); do_font_size_reduction (info); - info->orig_text = translated_text; + info->data.text.orig_text = translated_text; return TRUE; } @@ -1260,7 +1318,7 @@ parse_listitem (xmlNodePtr node, } li->text = translated_text; - info->list_items = g_list_append (info->list_items, li); + info->data.list.items = g_list_append (info->data.list.items, li); return TRUE; } @@ -1303,7 +1361,7 @@ parse_list (xmlNodePtr node, child = child->next; } - if (info->list_items != NULL) { + if (info->data.list.items != NULL) { if G_UNLIKELY (strcmp (info->id, "userlist") == 0) { g_set_error (error, GREETER_PARSER_ERROR, diff --git a/gui/greeter/themes/circles/circles.xml.in b/gui/greeter/themes/circles/circles.xml.in index 4bad8629..21f69e9c 100644 --- a/gui/greeter/themes/circles/circles.xml.in +++ b/gui/greeter/themes/circles/circles.xml.in @@ -149,7 +149,7 @@ <item type="rect"> <normal color="#FFFFFF" alpha="0.5"/> <pos anchor="c" x="50%" y="50%" width="box" height="box"/> - <box orientation="vertical" min-width="300" xpadding="30" ypadding="30" spacing="10"> + <box orientation="vertical" min-width="340" xpadding="30" ypadding="30" spacing="10"> <item type="label"> <pos anchor="n" x="50%"/> <normal color="#000000" font="Sans 18"/> @@ -158,7 +158,7 @@ </item> <item type="label" id="pam-prompt"> <pos anchor="nw" x="10%"/> - <normal color="#000000" font="Sans 16"/> + <normal color="#000000" font="Sans 14"/> <!-- Stock label for: Username: --> <stock type="username-label"/> </item> @@ -173,14 +173,14 @@ </item> <item type="label" id="pam-message"> <pos anchor="n" x="50%"/> - <normal color="#000000" font="Sans 16"/> + <normal color="#000000" font="Sans 14"/> <text></text> </item> </box> <fixed> <item type="label" id="pam-error"> <pos anchor="n" x="50%" y="110%"/> - <normal color="#000000" font="Sans 16"/> + <normal color="#000000" font="Sans 14"/> <text></text> </item> </fixed> diff --git a/gui/greeter/themes/happygnome-list/happygnome.xml.in b/gui/greeter/themes/happygnome-list/happygnome.xml.in index 643bf6a9..015048b5 100644 --- a/gui/greeter/themes/happygnome-list/happygnome.xml.in +++ b/gui/greeter/themes/happygnome-list/happygnome.xml.in @@ -165,7 +165,7 @@ <item type="rect"> <normal color="#FFFFFF" alpha="0.5"/> <pos anchor="c" x="75%" y="50%" width="box" height="box"/> - <box orientation="vertical" min-width="300" xpadding="30" ypadding="30" spacing="10"> + <box orientation="vertical" min-width="340" xpadding="30" ypadding="30" spacing="10"> <item type="label"> <pos anchor="n" x="50%"/> <normal color="#000000" font="Sans 18"/> diff --git a/gui/greeter/themes/happygnome/happygnome.xml.in b/gui/greeter/themes/happygnome/happygnome.xml.in index 8452a428..87927368 100644 --- a/gui/greeter/themes/happygnome/happygnome.xml.in +++ b/gui/greeter/themes/happygnome/happygnome.xml.in @@ -149,7 +149,7 @@ <item type="rect"> <normal color="#FFFFFF" alpha="0.5"/> <pos anchor="c" x="50%" y="50%" width="box" height="box"/> - <box orientation="vertical" min-width="300" xpadding="30" ypadding="30" spacing="10"> + <box orientation="vertical" min-width="340" xpadding="30" ypadding="30" spacing="10"> <item type="label"> <pos anchor="n" x="50%"/> <normal color="#000000" font="Sans 18"/> @@ -158,7 +158,7 @@ </item> <item type="label" id="pam-prompt"> <pos anchor="nw" x="10%"/> - <normal color="#000000" font="Sans 16"/> + <normal color="#000000" font="Sans 14"/> <!-- Stock label for: Username: --> <stock type="username-label"/> </item> @@ -173,7 +173,7 @@ </item> <item type="label" id="pam-message"> <pos anchor="n" x="50%"/> - <normal color="#000000" font="Sans 16"/> + <normal color="#000000" font="Sans 14"/> <text></text> </item> </box> |