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> Bulletproof X bits (cf. kubuntu_33_kdm_bulletproof_x.diff) ripped out by Kevin Kofler <Kevin@tigcc.ticalc.org> diff -up kdebase-workspace-4.4.2/kdm/backend/dm.c.kdm_plymouth kdebase-workspace-4.4.2/kdm/backend/dm.c --- kdebase-workspace-4.4.2/kdm/backend/dm.c.kdm_plymouth 2009-10-26 04:14:47.000000000 -0500 +++ kdebase-workspace-4.4.2/kdm/backend/dm.c 2010-04-12 14:38:14.125285141 -0500 @@ -1330,6 +1330,81 @@ getBusyVTs( void ) return activeVTs; } +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 +1414,44 @@ allocateVT( struct display *d ) 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 { diff -up kdebase-workspace-4.4.2/kdm/backend/dm.h.kdm_plymouth kdebase-workspace-4.4.2/kdm/backend/dm.h --- kdebase-workspace-4.4.2/kdm/backend/dm.h.kdm_plymouth 2010-03-26 12:26:49.000000000 -0500 +++ kdebase-workspace-4.4.2/kdm/backend/dm.h 2010-04-12 14:22:25.910296372 -0500 @@ -288,6 +288,8 @@ struct display { 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 @@ -400,6 +402,8 @@ int anyDisplaysLeft( void ); 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 diff -up kdebase-workspace-4.4.2/kdm/backend/server.c.kdm_plymouth kdebase-workspace-4.4.2/kdm/backend/server.c --- kdebase-workspace-4.4.2/kdm/backend/server.c.kdm_plymouth 2009-10-26 04:14:47.000000000 -0500 +++ kdebase-workspace-4.4.2/kdm/backend/server.c 2010-04-12 14:22:25.910296372 -0500 @@ -134,6 +134,11 @@ startServerSuccess() 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 ); }