summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Lebl <jirka@5z.com>2003-09-24 20:23:42 +0000
committerGeorge Lebl <jirka@src.gnome.org>2003-09-24 20:23:42 +0000
commit3be4bed1ac236af772aedc81daf8c2c9e97032ae (patch)
treeeed134bd9d7b143c7a52a8750b96d28eac1d9538
parent3cbc20f21614ce1b16595079d0cbb209d478e352 (diff)
downloadgdm-3be4bed1ac236af772aedc81daf8c2c9e97032ae.tar.gz
don't exec chooser/greeter in shell that's kind of evil and resets too
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
-rw-r--r--ChangeLog32
-rw-r--r--daemon/slave.c79
-rw-r--r--docs/C/gdm.xml43
-rw-r--r--gui/greeter/greeter.c8
-rw-r--r--gui/greeter/greeter_canvas_item.c135
-rw-r--r--gui/greeter/greeter_canvas_item.h2
-rw-r--r--gui/greeter/greeter_events.c16
-rw-r--r--gui/greeter/greeter_geometry.c127
-rw-r--r--gui/greeter/greeter_item.c61
-rw-r--r--gui/greeter/greeter_item.h133
-rw-r--r--gui/greeter/greeter_item_customlist.c2
-rw-r--r--gui/greeter/greeter_item_pam.c121
-rw-r--r--gui/greeter/greeter_parser.c216
-rw-r--r--gui/greeter/themes/circles/circles.xml.in8
-rw-r--r--gui/greeter/themes/happygnome-list/happygnome.xml.in2
-rw-r--r--gui/greeter/themes/happygnome/happygnome.xml.in6
16 files changed, 602 insertions, 389 deletions
diff --git a/ChangeLog b/ChangeLog
index ff1352a3..961de5ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
+ &lt;fixed&gt;
+</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>
+ &lt;item type="label"&gt;
+ &lt;pos x="10%" max-screen-percent-width="50%"/&gt;
+</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>