diff --git a/gdm.spec b/gdm.spec index 9b8756e..1183f50 100644 --- a/gdm.spec +++ b/gdm.spec @@ -16,7 +16,7 @@ Summary: The GNOME Display Manager Name: gdm Version: 2.29.1 -Release: 2%{?dist} +Release: 3%{?dist} Epoch: 1 License: GPLv2+ Group: User Interface/X @@ -93,8 +93,7 @@ BuildRequires: libXdmcp-devel Provides: service(graphical-login) Requires: audit-libs >= %{libauditver} -Patch2: gdm-2.29.1-force-active-vt.patch -Patch3: gdm-2.23.92-save-root-window.patch +Patch2: plymouth.patch # uses /etc/sysconfig/keyboard and is thus not directly upstreamable # should probably be changed to get the system layout from the X server @@ -142,8 +141,7 @@ The GDM fingerprint plugin provides functionality necessary to use a fingerprint %prep %setup -q -%patch2 -p1 -b .force-active-vt -%patch3 -p1 -b .save-root-window +%patch2 -p1 -b .plymouth %patch13 -p1 -b .system-keyboard %patch96 -p1 -b .multistack %patch97 -p1 -b .bubble-location @@ -370,7 +368,6 @@ fi %dir %{_datadir}/gdm/autostart/LoginWindow %config %{_datadir}/gdm/autostart/LoginWindow/* %dir %{_localstatedir}/log/gdm -%dir %{_localstatedir}/spool/gdm %dir %{_localstatedir}/run/gdm/greeter %attr(1770, gdm, gdm) %dir %{_localstatedir}/lib/gdm %attr(1750, gdm, gdm) %dir %{_localstatedir}/lib/gdm/.gconf.mandatory @@ -401,6 +398,9 @@ fi %{_libdir}/gdm/simple-greeter/plugins/fingerprint.so %changelog +* Wed Dec 09 2009 Ray Strode 2.29.1-3 +- Update to work better with latest plymouth + * Thu Dec 03 2009 Ray Strode 2.29.1-2 - Drop upstreamed patches - rebase multi-stack patch diff --git a/plymouth.patch b/plymouth.patch new file mode 100644 index 0000000..9660a2e --- /dev/null +++ b/plymouth.patch @@ -0,0 +1,394 @@ +From 9768d9e2783de7e836421d9645070bb1917800dd Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 27 Nov 2009 18:27:53 -0500 +Subject: [PATCH 1/2] Save root window to pixmap at _XROOTPMAP_ID + +This combined with starting the X server with -nr +will give us a nice fade transition when g-s-d starts +--- + daemon/gdm-simple-slave.c | 9 +++++ + daemon/gdm-slave.c | 72 +++++++++++++++++++++++++++++++++++++++++++++ + daemon/gdm-slave.h | 1 + + 3 files changed, 82 insertions(+), 0 deletions(-) + +diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c +index 2cbb568..66d1c77 100644 +--- a/daemon/gdm-simple-slave.c ++++ b/daemon/gdm-simple-slave.c +@@ -863,6 +863,15 @@ setup_server (GdmSimpleSlave *slave) + { + /* Set the busy cursor */ + gdm_slave_set_busy_cursor (GDM_SLAVE (slave)); ++ ++ /* The root window has a background that may be useful ++ * to cross fade or transition from when setting the ++ * login screen background. We read it here, and stuff ++ * it into the standard _XROOTPMAP_ID root window property, ++ * so gnome-settings-daemon can get at it. ++ */ ++ gdm_slave_save_root_windows (GDM_SLAVE (slave)); ++ + } + + static void +diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c +index e11e16c..da86f77 100644 +--- a/daemon/gdm-slave.c ++++ b/daemon/gdm-slave.c +@@ -42,6 +42,7 @@ + #include + + #include /* for Display */ ++#include /* for XA_PIXMAP */ + #include /* for watch cursor */ + + #include "gdm-common.h" +@@ -351,6 +352,77 @@ gdm_slave_run_script (GdmSlave *slave, + return ret; + } + ++static void ++gdm_slave_save_root_window_of_screen (GdmSlave *slave, ++ Atom id_atom, ++ int screen_number) ++{ ++ Window root_window; ++ GC gc; ++ XGCValues values; ++ Pixmap pixmap; ++ int width, height, depth; ++ ++ root_window = RootWindow (slave->priv->server_display, ++ screen_number); ++ ++ width = DisplayWidth (slave->priv->server_display, screen_number); ++ height = DisplayHeight (slave->priv->server_display, screen_number); ++ depth = DefaultDepth (slave->priv->server_display, screen_number); ++ pixmap = XCreatePixmap (slave->priv->server_display, ++ root_window, ++ width, height, depth); ++ ++ values.function = GXcopy; ++ values.plane_mask = AllPlanes; ++ values.fill_style = FillSolid; ++ values.subwindow_mode = IncludeInferiors; ++ ++ gc = XCreateGC (slave->priv->server_display, ++ root_window, ++ GCFunction | GCPlaneMask | GCFillStyle | GCSubwindowMode, ++ &values); ++ ++ if (XCopyArea (slave->priv->server_display, ++ root_window, pixmap, gc, 0, 0, ++ width, height, 0, 0)) { ++ ++ long pixmap_as_long; ++ ++ pixmap_as_long = (long) pixmap; ++ ++ XChangeProperty (slave->priv->server_display, ++ root_window, id_atom, XA_PIXMAP, ++ 32, PropModeReplace, (guchar *) &pixmap_as_long, ++ 1); ++ ++ } ++ ++ XFreeGC (slave->priv->server_display, gc); ++} ++ ++void ++gdm_slave_save_root_windows (GdmSlave *slave) ++{ ++ int i, number_of_screens; ++ Atom atom; ++ ++ number_of_screens = ScreenCount (slave->priv->server_display); ++ ++ atom = XInternAtom (slave->priv->server_display, ++ "_XROOTPMAP_ID", False); ++ ++ if (atom == 0) { ++ return; ++ } ++ ++ for (i = 0; i < number_of_screens; i++) { ++ gdm_slave_save_root_window_of_screen (slave, atom, i); ++ } ++ ++ XSync (slave->priv->server_display, False); ++} ++ + void + gdm_slave_set_busy_cursor (GdmSlave *slave) + { +diff --git a/daemon/gdm-slave.h b/daemon/gdm-slave.h +index af28b00..1652457 100644 +--- a/daemon/gdm-slave.h ++++ b/daemon/gdm-slave.h +@@ -74,6 +74,7 @@ gboolean gdm_slave_switch_to_user_session (GdmSlave *slave, + + gboolean gdm_slave_connect_to_x11_display (GdmSlave *slave); + void gdm_slave_set_busy_cursor (GdmSlave *slave); ++void gdm_slave_save_root_windows (GdmSlave *slave); + gboolean gdm_slave_run_script (GdmSlave *slave, + const char *dir, + const char *username); +-- +1.6.5.2 + + +From 2343620d464b93cfa46abddf8af14c7268f17df2 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 27 Nov 2009 18:52:54 -0500 +Subject: [PATCH 2/2] Enable smooth transition between plymouth and X + +This commit checks if plymouth is running, and if so, +turns on the smooth transition between plymouth and X. +--- + daemon/gdm-server.c | 56 +++++++++++++++++++++++++++ + daemon/gdm-server.h | 1 + + daemon/gdm-simple-slave.c | 91 ++++++++++++++++++++++++++++++++++++++++++++- + 3 files changed, 147 insertions(+), 1 deletions(-) + +diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c +index ba10386..3ec21e9 100644 +--- a/daemon/gdm-server.c ++++ b/daemon/gdm-server.c +@@ -32,8 +32,11 @@ + #include + #include + #include ++#include + #include + ++#include ++ + #include + #include + #include +@@ -663,6 +666,44 @@ gdm_server_spawn (GdmServer *server, + return ret; + } + ++static int ++get_active_vt (void) ++{ ++ int console_fd; ++ struct vt_stat console_state = { 0 }; ++ ++ console_fd = open ("/dev/tty0", O_RDONLY | O_NOCTTY); ++ ++ if (console_fd < 0) { ++ goto out; ++ } ++ ++ if (ioctl (console_fd, VT_GETSTATE, &console_state) < 0) { ++ goto out; ++ } ++ ++out: ++ if (console_fd >= 0) { ++ close (console_fd); ++ } ++ ++ return console_state.v_active; ++} ++ ++static char * ++get_active_vt_as_string (void) ++{ ++ int vt; ++ ++ vt = get_active_vt (); ++ ++ if (vt <= 0) { ++ return NULL; ++ } ++ ++ return g_strdup_printf ("vt%d", vt); ++} ++ + /** + * gdm_server_start: + * @disp: Pointer to a GdmDisplay structure +@@ -681,6 +722,21 @@ gdm_server_start (GdmServer *server) + return res; + } + ++gboolean ++gdm_server_start_on_active_vt (GdmServer *server) ++{ ++ gboolean res; ++ char *vt; ++ ++ g_free (server->priv->command); ++ server->priv->command = g_strdup (X_SERVER " -nr -verbose"); ++ vt = get_active_vt_as_string (); ++ res = gdm_server_spawn (server, vt); ++ g_free (vt); ++ ++ return res; ++} ++ + static void + server_died (GdmServer *server) + { +diff --git a/daemon/gdm-server.h b/daemon/gdm-server.h +index 535a69a..bd6c60a 100644 +--- a/daemon/gdm-server.h ++++ b/daemon/gdm-server.h +@@ -56,6 +56,7 @@ GType gdm_server_get_type (void); + GdmServer * gdm_server_new (const char *display_id, + const char *auth_file); + gboolean gdm_server_start (GdmServer *server); ++gboolean gdm_server_start_on_active_vt (GdmServer *server); + gboolean gdm_server_stop (GdmServer *server); + char * gdm_server_get_display_device (GdmServer *server); + +diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c +index 66d1c77..4703537 100644 +--- a/daemon/gdm-simple-slave.c ++++ b/daemon/gdm-simple-slave.c +@@ -84,6 +84,7 @@ struct GdmSimpleSlavePrivate + + guint start_session_when_ready : 1; + guint waiting_to_start_session : 1; ++ guint plymouth_is_running : 1; + }; + + enum { +@@ -858,6 +859,72 @@ on_start_session_later (GdmGreeterServer *session, + slave->priv->start_session_when_ready = FALSE; + } + ++static gboolean ++plymouth_is_running (void) ++{ ++ int status; ++ gboolean res; ++ GError *error; ++ ++ error = NULL; ++ res = g_spawn_command_line_sync ("/bin/plymouth --ping", ++ NULL, NULL, &status, &error); ++ if (! res) { ++ g_debug ("Could not ping plymouth: %s", error->message); ++ g_error_free (error); ++ return FALSE; ++ } ++ ++ return WIFEXITED (status) && WEXITSTATUS (status) == 0; ++} ++ ++static void ++plymouth_prepare_for_transition (GdmSimpleSlave *slave) ++{ ++ gboolean res; ++ GError *error; ++ ++ error = NULL; ++ res = g_spawn_command_line_sync ("/bin/plymouth deactivate", ++ NULL, NULL, NULL, &error); ++ if (! res) { ++ g_warning ("Could not deactivate plymouth: %s", error->message); ++ g_error_free (error); ++ } ++} ++ ++static void ++plymouth_quit_with_transition (GdmSimpleSlave *slave) ++{ ++ gboolean res; ++ GError *error; ++ ++ error = NULL; ++ res = g_spawn_command_line_sync ("/bin/plymouth quit --retain-splash", ++ NULL, NULL, NULL, &error); ++ if (! res) { ++ g_warning ("Could not quit plymouth: %s", error->message); ++ g_error_free (error); ++ } ++ slave->priv->plymouth_is_running = FALSE; ++} ++ ++static void ++plymouth_quit_without_transition (GdmSimpleSlave *slave) ++{ ++ gboolean res; ++ GError *error; ++ ++ error = NULL; ++ res = g_spawn_command_line_sync ("/bin/plymouth quit", ++ NULL, NULL, NULL, &error); ++ if (! res) { ++ g_warning ("Could not quit plymouth: %s", error->message); ++ g_error_free (error); ++ } ++ slave->priv->plymouth_is_running = FALSE; ++} ++ + static void + setup_server (GdmSimpleSlave *slave) + { +@@ -872,6 +939,10 @@ setup_server (GdmSimpleSlave *slave) + */ + gdm_slave_save_root_windows (GDM_SLAVE (slave)); + ++ /* Plymouth is waiting for the go-ahead to exit */ ++ if (slave->priv->plymouth_is_running) { ++ plymouth_quit_with_transition (slave); ++ } + } + + static void +@@ -1063,6 +1134,10 @@ on_server_exited (GdmServer *server, + g_debug ("GdmSimpleSlave: server exited with code %d\n", exit_code); + + gdm_slave_stopped (GDM_SLAVE (slave)); ++ ++ if (slave->priv->plymouth_is_running) { ++ plymouth_quit_without_transition (slave); ++ } + } + + static void +@@ -1075,6 +1150,10 @@ on_server_died (GdmServer *server, + g_strsignal (signal_number)); + + gdm_slave_stopped (GDM_SLAVE (slave)); ++ ++ if (slave->priv->plymouth_is_running) { ++ plymouth_quit_without_transition (slave); ++ } + } + + static gboolean +@@ -1119,7 +1198,14 @@ gdm_simple_slave_run (GdmSimpleSlave *slave) + G_CALLBACK (on_server_ready), + slave); + +- res = gdm_server_start (slave->priv->server); ++ slave->priv->plymouth_is_running = plymouth_is_running (); ++ ++ if (slave->priv->plymouth_is_running) { ++ plymouth_prepare_for_transition (slave); ++ res = gdm_server_start_on_active_vt (slave->priv->server); ++ } else { ++ res = gdm_server_start (slave->priv->server); ++ } + if (! res) { + g_warning (_("Could not start the X " + "server (your graphical environment) " +@@ -1129,6 +1215,9 @@ gdm_simple_slave_run (GdmSimpleSlave *slave) + "In the meantime this display will be " + "disabled. Please restart GDM when " + "the problem is corrected.")); ++ if (slave->priv->plymouth_is_running) { ++ plymouth_quit_without_transition (slave); ++ } + exit (1); + } + +-- +1.6.5.2 +