# Description: Add support for smooth transition from Plymouth's bootsplash # If possible, KDM will try to deactivate plymouth, start X (with -nr) on # the active vt and leave the bootsplash on the screen until the graphical # login takes place. # Forwarded: no # Bug: https://bugs.launchpad.net/ubuntu/+source/kdebase-workspace/+bug/540177 # Author: Alberto Milone <alberto.milone@canonical.com> # Index: kdm/backend/dm.c =================================================================== --- kdm/backend/dm.c +++ kdm/backend/dm.c 2010-05-05 17:33:05.000000000 +0200 @@ -1330,6 +1330,82 @@ return activeVTs; } +/* Return the active VT as an integer */ +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 int +plymouth_is_running (void) +{ + int status; + status = system ("/bin/plymouth --ping"); + + return WIFEXITED (status) && WEXITSTATUS (status) == 0; +} + +static int +plymouth_has_active_vt (void) +{ + int status; + status = system ("/bin/plymouth --has-active-vt"); + + return WIFEXITED (status) && WEXITSTATUS (status) == 0; +} + +static int +plymouth_prepare_for_transition (void) +{ + int status; + status = system ("/bin/plymouth deactivate"); + + return WIFEXITED (status) && WEXITSTATUS (status) == 0; +} + +int +plymouth_quit_with_transition (void) +{ + int status; + status = system ("/bin/plymouth quit --retain-splash"); + + return WIFEXITED (status) && WEXITSTATUS (status) == 0; +} + +static int +plymouth_quit_without_transition (void) +{ + int status; + status = system ("/bin/plymouth quit"); + + return WIFEXITED (status) && WEXITSTATUS (status) == 0; +} + +static int +triggered_to_force_display_on_active_vt (void) +{ + int should_force_display_on_active_vt; + should_force_display_on_active_vt=open("/var/spool/gdm/force-display-on-active-vt", O_RDONLY); + if ( should_force_display_on_active_vt >= 0 ) + close(should_force_display_on_active_vt); + unlink("/var/spool/gdm/force-display-on-active-vt"); + return should_force_display_on_active_vt; +} + static void allocateVT( struct display *d ) { @@ -1339,6 +1415,43 @@ if ((d->displayType & d_location) == dLocal && d->status == notRunning && !d->serverVT && d->reqSrvVT >= 0) { + /* check for pymouth using old/deprecated method first */ + if ( triggered_to_force_display_on_active_vt() >= 0 ) { + int vt; + vt = get_active_vt(); + if (vt > 0) { + d->serverVT = vt; + return; + } + } + + /* check for plymouth using newer methods */ + d->plymouth_is_running = plymouth_is_running (); + if (d->plymouth_is_running) { + /* call plymouth deactivate */ + plymouth_prepare_for_transition (); + if (plymouth_has_active_vt ()) { + /* plymouth was displaying a splash screen and has + * terminated leaving it on screen + */ + int vt; + vt = get_active_vt (); + if (vt > 0) { + /* start the X server on the active vt */ + d->serverVT = vt; + return; + } + } + else { + /* plymouth might have been running but did not display + * a splash screen. + */ + + /* call plymouth quit and start the X server as usual */ + d->plymouth_is_running = !plymouth_quit_without_transition (); + } + } + if (d->reqSrvVT && d->reqSrvVT < 16) d->serverVT = d->reqSrvVT; else { Index: kdm/backend/dm.h =================================================================== --- kdm/backend/dm.h +++ kdm/backend/dm.h 2010-05-05 17:33:05.000000000 +0200 @@ -291,6 +291,7 @@ Xauth **authorizations; /* authorization data */ int authNum; /* number of authorizations */ char *authFile; /* file to store authorization in */ + int plymouth_is_running; /* Plymouth's status */ }; #define d_location 1 @@ -403,6 +404,8 @@ void forEachDisplay( void (*f)( struct display * ) ); #ifdef HAVE_VTS void forEachDisplayRev( void (*f)( struct display * ) ); +/* function for plymouth */ +int plymouth_quit_with_transition (void); #endif void removeDisplay( struct display *old ); struct display Index: kdm/backend/server.c =================================================================== --- kdm/backend/server.c +++ kdm/backend/server.c 2010-05-05 17:33:05.000000000 +0200 @@ -134,6 +134,11 @@ struct display *d = startingServer; d->serverStatus = ignore; serverTimeout = TO_INF; + if (d->plymouth_is_running) { + debug( "Quitting Plymouth with transition\n" ); + d->plymouth_is_running = !plymouth_quit_with_transition (); + debug ("Is Plymouth still running? %s\n", d->plymouth_is_running ? "yes" : "no"); + } debug( "X server ready, starting session\n" ); startDisplayP2( d ); }