1919#include "../settings.h"
2020#include "wl_ctx.h"
2121
22+ #include <xkbcommon/xkbcommon.h>
23+ #include <sys/mman.h>
24+ #include <unistd.h>
25+
26+ static struct xkb_context * xkb_context = NULL ;
27+ static struct xkb_state * xkb_state = NULL ;
28+
2229static void touch_handle_motion (void * data , struct wl_touch * wl_touch ,
2330 uint32_t time , int32_t id ,
2431 wl_fixed_t surface_x , wl_fixed_t surface_y ) {
@@ -46,7 +53,6 @@ static void touch_handle_down(void *data, struct wl_touch *wl_touch,
4653static void touch_handle_up (void * data , struct wl_touch * wl_touch ,
4754 uint32_t serial , uint32_t time , int32_t id ) {
4855 struct dunst_seat * seat = data ;
49-
5056 if (id >= MAX_TOUCHPOINTS ) {
5157 return ;
5258 }
@@ -99,7 +105,6 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
99105 uint32_t serial , uint32_t time , uint32_t button ,
100106 uint32_t button_state ) {
101107 struct dunst_seat * seat = data ;
102-
103108 input_handle_click (button , button_state , seat -> pointer .x , seat -> pointer .y );
104109}
105110
@@ -119,6 +124,116 @@ static const struct wl_pointer_listener pointer_listener = {
119124 .axis = pointer_handle_axis ,
120125};
121126
127+ static void keyboard_handle_keymap (void * data , struct wl_keyboard * keyboard ,
128+ uint32_t format , int32_t fd , uint32_t size ) {
129+
130+ struct dunst_seat * seat = data ;
131+ (void )seat ;
132+
133+ if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 ) {
134+ close (fd );
135+ return ;
136+ }
137+
138+ char * keymap_str = mmap (NULL , size , PROT_READ , MAP_SHARED , fd , 0 );
139+ if (keymap_str == MAP_FAILED ) {
140+ close (fd );
141+ return ;
142+ }
143+
144+ if (!xkb_context )
145+ xkb_context = xkb_context_new (XKB_CONTEXT_NO_FLAGS );
146+
147+ struct xkb_keymap * keymap = xkb_keymap_new_from_string (xkb_context ,
148+ keymap_str , XKB_KEYMAP_FORMAT_TEXT_V1 , XKB_KEYMAP_COMPILE_NO_FLAGS );
149+
150+ munmap (keymap_str , size );
151+ close (fd );
152+
153+ if (!keymap )
154+ return ;
155+
156+ if (xkb_state )
157+ xkb_state_unref (xkb_state );
158+
159+ xkb_state = xkb_state_new (keymap );
160+ xkb_keymap_unref (keymap );
161+ }
162+
163+ static void keyboard_handle_enter (void * data , struct wl_keyboard * keyboard ,
164+ uint32_t serial , struct wl_surface * surface ,
165+ struct wl_array * keys ) {
166+
167+ struct dunst_seat * seat = data ;
168+ (void )seat ;
169+ }
170+
171+ static void keyboard_handle_leave (void * data , struct wl_keyboard * keyboard ,
172+ uint32_t serial , struct wl_surface * surface ) {
173+
174+ struct dunst_seat * seat = data ;
175+ (void )seat ;
176+ }
177+
178+ static void keyboard_handle_key (void * data , struct wl_keyboard * keyboard ,
179+ uint32_t serial , uint32_t time , uint32_t key , uint32_t state ) {
180+
181+ struct dunst_seat * seat = data ;
182+ (void )seat ;
183+
184+ if (!xkb_state )
185+ return ;
186+
187+ uint32_t keycode = key + 8 ; // XKB uses evdev + 8 keycode convention
188+ xkb_keysym_t keysym = xkb_state_key_get_one_sym (xkb_state , keycode );
189+
190+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED ) {
191+ input_handle_key (keysym , true);
192+ } else {
193+ input_handle_key (keysym , false);
194+ }
195+ }
196+
197+ static void keyboard_handle_modifiers (void * data , struct wl_keyboard * keyboard ,
198+ uint32_t serial , uint32_t mods_depressed , uint32_t mods_latched ,
199+ uint32_t mods_locked , uint32_t group ) {
200+ if (!xkb_state )
201+ return ;
202+
203+ xkb_state_update_mask (xkb_state , mods_depressed , mods_latched ,
204+ mods_locked , 0 , 0 , group );
205+ }
206+
207+ static void keyboard_handle_repeat_info (void * data , struct wl_keyboard * keyboard ,
208+ int32_t rate , int32_t delay ) {
209+ // store the repeat info if needed
210+ // rate: repeat times per second
211+ // delay: delay in milliseconds
212+ LOG_D ("Keyboard repeat info - rate: %d, delay: %d" , rate , delay );
213+ }
214+
215+ static const struct wl_keyboard_listener keyboard_listener = {
216+ .keymap = keyboard_handle_keymap ,
217+ .enter = keyboard_handle_enter ,
218+ .leave = keyboard_handle_leave ,
219+ .key = keyboard_handle_key ,
220+ .modifiers = keyboard_handle_modifiers ,
221+ .repeat_info = keyboard_handle_repeat_info ,
222+ };
223+
224+ // cleanup xkb resources
225+ void cleanup_keyboard_resources (void ) {
226+ if (xkb_state ) {
227+ xkb_state_unref (xkb_state );
228+ xkb_state = NULL ;
229+ }
230+
231+ if (xkb_context ) {
232+ xkb_context_unref (xkb_context );
233+ xkb_context = NULL ;
234+ }
235+ }
236+
122237static void destroy_seat_pointer (struct dunst_seat * seat ) {
123238 wl_pointer_release (seat -> pointer .wl_pointer );
124239 seat -> pointer .wl_pointer = NULL ;
@@ -129,6 +244,11 @@ static void destroy_seat_touch(struct dunst_seat *seat) {
129244 seat -> touch .wl_touch = NULL ;
130245}
131246
247+ static void destroy_seat_keyboard (struct dunst_seat * seat ) {
248+ wl_keyboard_release (seat -> keyboard .wl_keyboard );
249+ seat -> keyboard .wl_keyboard = NULL ;
250+ }
251+
132252void destroy_seat (struct dunst_seat * seat ) {
133253 if (seat == NULL ) {
134254 return ;
@@ -170,12 +290,15 @@ void destroy_seat(struct dunst_seat *seat) {
170290 seat -> name = NULL ;
171291
172292 g_free (seat );
293+
294+ if (wl_list_empty (& ctx .seats )) {
295+ cleanup_keyboard_resources ();
296+ }
173297}
174298
175299static void seat_handle_capabilities (void * data , struct wl_seat * wl_seat ,
176300 uint32_t capabilities ) {
177301 struct dunst_seat * seat = data ;
178-
179302 if (capabilities & WL_SEAT_CAPABILITY_POINTER ) {
180303 if (seat -> pointer .wl_pointer == NULL ) {
181304 seat -> pointer .wl_pointer = wl_seat_get_pointer (wl_seat );
@@ -195,6 +318,16 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
195318 } else if (seat -> touch .wl_touch != NULL ) {
196319 destroy_seat_touch (seat );
197320 }
321+
322+ if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD ) {
323+ if (seat -> keyboard .wl_keyboard == NULL ) {
324+ seat -> keyboard .wl_keyboard = wl_seat_get_keyboard (wl_seat );
325+ wl_keyboard_add_listener (seat -> keyboard .wl_keyboard ,
326+ & keyboard_listener , seat );
327+ }
328+ } else if (seat -> keyboard .wl_keyboard != NULL ) {
329+ destroy_seat_keyboard (seat );
330+ }
198331}
199332
200333static void seat_handle_name (void * data , struct wl_seat * wl_seat , const char * name ) {
0 commit comments