summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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>