@ -45,6 +45,7 @@
# include "rpi-renderer.h"
# include "evdev.h"
# include "launcher-util.h"
# include "udev-seat.h"
#if 0
# define DBG(...) \
@ -87,6 +88,7 @@ struct rpi_compositor {
uint32_t prev_state ;
struct udev * udev ;
struct udev_input input ;
struct wl_listener session_listener ;
int single_buffer ;
@ -414,243 +416,12 @@ out_free:
return - 1 ;
}
static void
rpi_led_update ( struct weston_seat * seat_base , enum weston_led leds )
{
struct rpi_seat * seat = to_rpi_seat ( seat_base ) ;
struct evdev_device * device ;
wl_list_for_each ( device , & seat - > devices_list , link )
evdev_led_update ( device , leds ) ;
}
static const char default_seat [ ] = " seat0 " ;
static void
device_added ( struct udev_device * udev_device , struct rpi_seat * master )
{
struct evdev_device * device ;
const char * devnode ;
const char * device_seat ;
int fd ;
device_seat = udev_device_get_property_value ( udev_device , " ID_SEAT " ) ;
if ( ! device_seat )
device_seat = default_seat ;
if ( strcmp ( device_seat , master - > seat_id ) )
return ;
devnode = udev_device_get_devnode ( udev_device ) ;
/* Use non-blocking mode so that we can loop on read on
* evdev_device_data ( ) until all events on the fd are
* read . mtdev_get ( ) also expects this . */
fd = open ( devnode , O_RDWR | O_NONBLOCK | O_CLOEXEC ) ;
if ( fd < 0 ) {
weston_log ( " opening input device '%s' failed. \n " , devnode ) ;
return ;
}
device = evdev_device_create ( & master - > base , devnode , fd ) ;
if ( ! device ) {
close ( fd ) ;
weston_log ( " not using input device '%s'. \n " , devnode ) ;
return ;
}
wl_list_insert ( master - > devices_list . prev , & device - > link ) ;
}
static void
evdev_add_devices ( struct udev * udev , struct weston_seat * seat_base )
{
struct rpi_seat * seat = to_rpi_seat ( seat_base ) ;
struct udev_enumerate * e ;
struct udev_list_entry * entry ;
struct udev_device * device ;
const char * path , * sysname ;
e = udev_enumerate_new ( udev ) ;
udev_enumerate_add_match_subsystem ( e , " input " ) ;
udev_enumerate_scan_devices ( e ) ;
udev_list_entry_foreach ( entry , udev_enumerate_get_list_entry ( e ) ) {
path = udev_list_entry_get_name ( entry ) ;
device = udev_device_new_from_syspath ( udev , path ) ;
sysname = udev_device_get_sysname ( device ) ;
if ( strncmp ( " event " , sysname , 5 ) ! = 0 ) {
udev_device_unref ( device ) ;
continue ;
}
device_added ( device , seat ) ;
udev_device_unref ( device ) ;
}
udev_enumerate_unref ( e ) ;
evdev_notify_keyboard_focus ( & seat - > base , & seat - > devices_list ) ;
if ( wl_list_empty ( & seat - > devices_list ) ) {
weston_log (
" warning: no input devices on entering Weston. "
" Possible causes: \n "
" \t - no permissions to read /dev/input/event* \n "
" \t - seats misconfigured "
" (Weston backend option 'seat', "
" udev device property ID_SEAT) \n " ) ;
}
}
static int
evdev_udev_handler ( int fd , uint32_t mask , void * data )
{
struct rpi_seat * seat = data ;
struct udev_device * udev_device ;
struct evdev_device * device , * next ;
const char * action ;
const char * devnode ;
udev_device = udev_monitor_receive_device ( seat - > udev_monitor ) ;
if ( ! udev_device )
return 1 ;
action = udev_device_get_action ( udev_device ) ;
if ( ! action )
goto out ;
if ( strncmp ( " event " , udev_device_get_sysname ( udev_device ) , 5 ) ! = 0 )
goto out ;
if ( ! strcmp ( action , " add " ) ) {
device_added ( udev_device , seat ) ;
}
else if ( ! strcmp ( action , " remove " ) ) {
devnode = udev_device_get_devnode ( udev_device ) ;
wl_list_for_each_safe ( device , next , & seat - > devices_list , link )
if ( ! strcmp ( device - > devnode , devnode ) ) {
weston_log ( " input device %s, %s removed \n " ,
device - > devname , device - > devnode ) ;
evdev_device_destroy ( device ) ;
break ;
}
}
out :
udev_device_unref ( udev_device ) ;
return 0 ;
}
static int
evdev_enable_udev_monitor ( struct udev * udev , struct weston_seat * seat_base )
{
struct rpi_seat * master = to_rpi_seat ( seat_base ) ;
struct wl_event_loop * loop ;
struct weston_compositor * c = master - > base . compositor ;
int fd ;
master - > udev_monitor = udev_monitor_new_from_netlink ( udev , " udev " ) ;
if ( ! master - > udev_monitor ) {
weston_log ( " udev: failed to create the udev monitor \n " ) ;
return 0 ;
}
udev_monitor_filter_add_match_subsystem_devtype ( master - > udev_monitor ,
" input " , NULL ) ;
if ( udev_monitor_enable_receiving ( master - > udev_monitor ) ) {
weston_log ( " udev: failed to bind the udev monitor \n " ) ;
udev_monitor_unref ( master - > udev_monitor ) ;
return 0 ;
}
loop = wl_display_get_event_loop ( c - > wl_display ) ;
fd = udev_monitor_get_fd ( master - > udev_monitor ) ;
master - > udev_monitor_source =
wl_event_loop_add_fd ( loop , fd , WL_EVENT_READABLE ,
evdev_udev_handler , master ) ;
if ( ! master - > udev_monitor_source ) {
udev_monitor_unref ( master - > udev_monitor ) ;
return 0 ;
}
return 1 ;
}
static void
evdev_disable_udev_monitor ( struct weston_seat * seat_base )
{
struct rpi_seat * seat = to_rpi_seat ( seat_base ) ;
if ( ! seat - > udev_monitor )
return ;
udev_monitor_unref ( seat - > udev_monitor ) ;
seat - > udev_monitor = NULL ;
wl_event_source_remove ( seat - > udev_monitor_source ) ;
seat - > udev_monitor_source = NULL ;
}
static void
evdev_input_create ( struct weston_compositor * c , struct udev * udev ,
const char * seat_id )
{
struct rpi_seat * seat ;
seat = zalloc ( sizeof * seat ) ;
if ( seat = = NULL )
return ;
weston_seat_init ( & seat - > base , c , " default " ) ;
seat - > base . led_update = rpi_led_update ;
wl_list_init ( & seat - > devices_list ) ;
seat - > seat_id = strdup ( seat_id ) ;
if ( ! evdev_enable_udev_monitor ( udev , & seat - > base ) ) {
free ( seat - > seat_id ) ;
free ( seat ) ;
return ;
}
evdev_add_devices ( udev , & seat - > base ) ;
}
static void
evdev_remove_devices ( struct weston_seat * seat_base )
{
struct rpi_seat * seat = to_rpi_seat ( seat_base ) ;
struct evdev_device * device , * next ;
wl_list_for_each_safe ( device , next , & seat - > devices_list , link )
evdev_device_destroy ( device ) ;
if ( seat - > base . keyboard )
notify_keyboard_focus_out ( & seat - > base ) ;
}
static void
evdev_input_destroy ( struct weston_seat * seat_base )
{
struct rpi_seat * seat = to_rpi_seat ( seat_base ) ;
evdev_remove_devices ( seat_base ) ;
evdev_disable_udev_monitor ( & seat - > base ) ;
weston_seat_release ( seat_base ) ;
free ( seat - > seat_id ) ;
free ( seat ) ;
}
static void
rpi_compositor_destroy ( struct weston_compositor * base )
{
struct rpi_compositor * compositor = to_rpi_compositor ( base ) ;
struct weston_seat * seat , * next ;
wl_list_for_each_safe ( seat , next , & compositor - > base . seat_list , link )
evdev_input_destroy ( seat ) ;
udev_input_destroy ( & compositor - > input ) ;
compositor - > base . renderer - > destroy ( & compositor - > base ) ;
@ -667,23 +438,16 @@ static void
session_notify ( struct wl_listener * listener , void * data )
{
struct rpi_compositor * compositor = data ;
struct weston_seat * seat ;
struct weston_output * output ;
if ( compositor - > base . session_active ) {
weston_log ( " activating session \n " ) ;
compositor - > base . state = compositor - > prev_state ;
weston_compositor_damage_all ( & compositor - > base ) ;
wl_list_for_each ( seat , & compositor - > base . seat_list , link ) {
evdev_add_devices ( compositor - > udev , seat ) ;
evdev_enable_udev_monitor ( compositor - > udev , seat ) ;
}
udev_input_enable ( & compositor - > input , compositor - > udev ) ;
} else {
weston_log ( " deactivating session \n " ) ;
wl_list_for_each ( seat , & compositor - > base . seat_list , link ) {
evdev_disable_udev_monitor ( seat ) ;
evdev_remove_devices ( seat ) ;
}
udev_input_disable ( & compositor - > input ) ;
compositor - > prev_state = compositor - > base . state ;
weston_compositor_offscreen ( & compositor - > base ) ;
@ -729,7 +493,6 @@ rpi_compositor_create(struct wl_display *display, int *argc, char *argv[],
struct rpi_parameters * param )
{
struct rpi_compositor * compositor ;
const char * seat = default_seat ;
uint32_t key ;
weston_log ( " initializing Raspberry Pi backend \n " ) ;
@ -748,6 +511,13 @@ rpi_compositor_create(struct wl_display *display, int *argc, char *argv[],
goto out_compositor ;
}
if ( udev_input_init ( & compositor - > input ,
& compositor - > base ,
compositor - > udev , " ID_SEAT " ) ! = 0 ) {
weston_log ( " Failed to initialize udev input. \n " ) ;
goto out_udev ;
}
compositor - > session_listener . notify = session_notify ;
wl_signal_add ( & compositor - > base . session_signal ,
& compositor - > session_listener ) ;
@ -755,7 +525,7 @@ rpi_compositor_create(struct wl_display *display, int *argc, char *argv[],
weston_launcher_connect ( & compositor - > base , param - > tty , " seat0 " ) ;
if ( ! compositor - > base . launcher ) {
weston_log ( " Failed to initialize tty. \n " ) ;
goto out_udev ;
goto out_udev_input ;
}
compositor - > base . destroy = rpi_compositor_destroy ;
@ -787,8 +557,6 @@ rpi_compositor_create(struct wl_display *display, int *argc, char *argv[],
if ( rpi_output_create ( compositor , param - > output_transform ) < 0 )
goto out_renderer ;
evdev_input_create ( & compositor - > base , compositor - > udev , seat ) ;
return & compositor - > base ;
out_renderer :
@ -797,6 +565,9 @@ out_renderer:
out_launcher :
weston_launcher_destroy ( compositor - > base . launcher ) ;
out_udev_input :
udev_input_destroy ( & compositor - > input ) ;
out_udev :
udev_unref ( compositor - > udev ) ;