@ -204,7 +204,6 @@ struct input {
struct data_offer * selection_offer ;
struct {
struct xkb_rule_names names ;
struct xkb_keymap * keymap ;
struct xkb_state * state ;
xkb_mod_mask_t control_mask ;
@ -1833,7 +1832,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
input - > display - > serial = serial ;
code = key + 8 ;
if ( ! window | | window - > keyboard_device ! = input )
if ( ! window | | window - > keyboard_device ! = input | | ! input - > xkb . state )
return ;
if ( state )
@ -1876,13 +1875,8 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
{
struct input * input = data ;
xkb_state_update_mask ( input - > xkb . state ,
mods_depressed ,
mods_latched ,
mods_locked ,
0 ,
0 ,
group ) ;
xkb_state_update_mask ( input - > xkb . state , mods_depressed , mods_latched ,
mods_locked , 0 , 0 , group ) ;
}
static void
@ -1989,6 +1983,57 @@ keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
input_remove_keyboard_focus ( input ) ;
}
static void
keyboard_handle_keymap ( void * data , struct wl_keyboard * keyboard ,
uint32_t format , int fd , uint32_t size )
{
struct input * input = data ;
char * map_str ;
if ( ! data ) {
close ( fd ) ;
return ;
}
if ( format ! = WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 ) {
close ( fd ) ;
return ;
}
map_str = mmap ( NULL , size , PROT_READ , MAP_SHARED , fd , 0 ) ;
if ( map_str = = MAP_FAILED ) {
close ( fd ) ;
return ;
}
input - > xkb . keymap = xkb_map_new_from_string ( input - > display - > xkb_context ,
map_str ,
XKB_KEYMAP_FORMAT_TEXT_V1 ,
0 ) ;
munmap ( map_str , size ) ;
close ( fd ) ;
if ( ! input - > xkb . keymap ) {
fprintf ( stderr , " failed to compile keymap \n " ) ;
return ;
}
input - > xkb . state = xkb_state_new ( input - > xkb . keymap ) ;
if ( ! input - > xkb . state ) {
fprintf ( stderr , " failed to create XKB state \n " ) ;
xkb_map_unref ( input - > xkb . keymap ) ;
input - > xkb . keymap = NULL ;
return ;
}
input - > xkb . control_mask =
1 < < xkb_map_mod_get_index ( input - > xkb . keymap , " Control " ) ;
input - > xkb . alt_mask =
1 < < xkb_map_mod_get_index ( input - > xkb . keymap , " Mod1 " ) ;
input - > xkb . shift_mask =
1 < < xkb_map_mod_get_index ( input - > xkb . keymap , " Shift " ) ;
}
static const struct wl_pointer_listener pointer_listener = {
pointer_handle_enter ,
pointer_handle_leave ,
@ -1998,6 +2043,7 @@ static const struct wl_pointer_listener pointer_listener = {
} ;
static const struct wl_keyboard_listener keyboard_listener = {
keyboard_handle_keymap ,
keyboard_handle_enter ,
keyboard_handle_leave ,
keyboard_handle_key ,
@ -3086,37 +3132,6 @@ output_get_wl_output(struct output *output)
return output - > output ;
}
static void
init_xkb ( struct input * input )
{
input - > xkb . names . rules = " evdev " ;
input - > xkb . names . model = " pc105 " ;
input - > xkb . names . layout = ( char * ) option_xkb_layout ;
input - > xkb . names . variant = ( char * ) option_xkb_variant ;
input - > xkb . names . options = ( char * ) option_xkb_options ;
input - > xkb . keymap = xkb_map_new_from_names ( input - > display - > xkb_context ,
& input - > xkb . names , 0 ) ;
if ( ! input - > xkb . keymap ) {
fprintf ( stderr , " Failed to compile keymap \n " ) ;
exit ( 1 ) ;
}
input - > xkb . state = xkb_state_new ( input - > xkb . keymap ) ;
if ( ! input - > xkb . state ) {
fprintf ( stderr , " Failed to create XKB state \n " ) ;
exit ( 1 ) ;
}
input - > xkb . control_mask =
1 < < xkb_map_mod_get_index ( input - > xkb . keymap , " Control " ) ;
input - > xkb . alt_mask =
1 < < xkb_map_mod_get_index ( input - > xkb . keymap , " Mod1 " ) ;
input - > xkb . shift_mask =
1 < < xkb_map_mod_get_index ( input - > xkb . keymap , " Shift " ) ;
}
static void
fini_xkb ( struct input * input )
{
@ -3140,8 +3155,6 @@ display_add_input(struct display *d, uint32_t id)
input - > keyboard_focus = NULL ;
wl_list_insert ( d - > input_list . prev , & input - > link ) ;
init_xkb ( input ) ;
wl_seat_add_listener ( input - > seat , & seat_listener , input ) ;
wl_seat_set_user_data ( input - > seat , input ) ;
@ -3158,6 +3171,11 @@ input_destroy(struct input *input)
input_remove_keyboard_focus ( input ) ;
input_remove_pointer_focus ( input ) ;
if ( input - > xkb . state )
xkb_state_unref ( input - > xkb . state ) ;
if ( input - > xkb . keymap )
xkb_map_unref ( input - > xkb . keymap ) ;
if ( input - > drag_offer )
data_offer_destroy ( input - > drag_offer ) ;
@ -3339,8 +3357,8 @@ display_create(int argc, char *argv[])
wl_list_init ( & d - > output_list ) ;
d - > xkb_context = xkb_context_new ( 0 ) ;
if ( ! d - > xkb_context ) {
fprintf ( stderr , " failed to initializ e XKB context\n " ) ;
if ( d - > xkb_context = = NULL ) {
fprintf ( stderr , " Failed to creat e XKB context\n " ) ;
return NULL ;
}