@ -25,6 +25,9 @@
# include <string.h>
# include <string.h>
# include <unistd.h>
# include <unistd.h>
# include <linux/input.h>
# include <linux/input.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <fcntl.h>
# include "wayland-server.h"
# include "wayland-server.h"
# include "compositor.h"
# include "compositor.h"
@ -37,6 +40,11 @@ struct wl_shell {
struct wl_listener panel_listener ;
struct wl_listener panel_listener ;
struct wlsc_surface * background ;
struct wlsc_surface * background ;
struct wl_listener background_listener ;
struct wl_listener background_listener ;
struct {
struct wlsc_process process ;
struct wl_client * client ;
} child ;
} ;
} ;
struct wlsc_move_grab {
struct wlsc_move_grab {
@ -925,6 +933,61 @@ attach(struct wlsc_shell *base, struct wlsc_surface *es)
}
}
}
}
static void
desktop_shell_sigchld ( struct wlsc_process * process , int status )
{
struct wl_shell * shell =
container_of ( process , struct wl_shell , child . process ) ;
shell - > child . process . pid = 0 ;
shell - > child . client = NULL ; /* already destroyed by wayland */
}
static int
launch_desktop_shell_process ( struct wl_shell * shell )
{
const char * shell_exe = " ./clients/desktop-shell " ;
struct wlsc_compositor * compositor = shell - > compositor ;
char s [ 32 ] ;
int sv [ 2 ] , flags ;
if ( socketpair ( AF_UNIX , SOCK_STREAM | SOCK_CLOEXEC , 0 , sv ) < 0 ) {
fprintf ( stderr , " socketpair failed \n " ) ;
return - 1 ;
}
shell - > child . process . pid = fork ( ) ;
shell - > child . process . cleanup = desktop_shell_sigchld ;
switch ( shell - > child . process . pid ) {
case 0 :
/* SOCK_CLOEXEC closes both ends, so we need to unset
* the flag on the client fd . */
flags = fcntl ( sv [ 1 ] , F_GETFD ) ;
if ( flags ! = - 1 )
fcntl ( sv [ 1 ] , F_SETFD , flags & ~ FD_CLOEXEC ) ;
snprintf ( s , sizeof s , " %d " , sv [ 1 ] ) ;
setenv ( " WAYLAND_SOCKET " , s , 1 ) ;
if ( execl ( shell_exe , shell_exe , NULL ) < 0 )
fprintf ( stderr , " %s: running '%s' failed: %m \n " ,
__func__ , shell_exe ) ;
exit ( - 1 ) ;
default :
close ( sv [ 1 ] ) ;
shell - > child . client =
wl_client_create ( compositor - > wl_display , sv [ 0 ] ) ;
wlsc_watch_process ( & shell - > child . process ) ;
break ;
case - 1 :
fprintf ( stderr , " %s: fork failed: %m \n " , __func__ ) ;
return - 1 ;
}
return 0 ;
}
static void
static void
bind_shell ( struct wl_client * client , void * data , uint32_t version , uint32_t id )
bind_shell ( struct wl_client * client , void * data , uint32_t version , uint32_t id )
{
{
@ -972,6 +1035,9 @@ shell_init(struct wlsc_compositor *ec)
shell , bind_desktop_shell ) = = NULL )
shell , bind_desktop_shell ) = = NULL )
return - 1 ;
return - 1 ;
if ( launch_desktop_shell_process ( shell ) ! = 0 )
return - 1 ;
wlsc_compositor_add_binding ( ec , 0 , BTN_LEFT , MODIFIER_SUPER ,
wlsc_compositor_add_binding ( ec , 0 , BTN_LEFT , MODIFIER_SUPER ,
move_binding , shell ) ;
move_binding , shell ) ;
wlsc_compositor_add_binding ( ec , 0 , BTN_MIDDLE , MODIFIER_SUPER ,
wlsc_compositor_add_binding ( ec , 0 , BTN_MIDDLE , MODIFIER_SUPER ,