mirror of
				https://github.com/swaywm/sway.git
				synced 2025-10-29 05:40:18 -04:00 
			
		
		
		
	Initialize keyboard in registry poll
This commit is contained in:
		
							parent
							
								
									266393a705
								
							
						
					
					
						commit
						a7710c5537
					
				
					 3 changed files with 128 additions and 0 deletions
				
			
		|  | @ -2,16 +2,70 @@ | |||
| #define _SWAY_CLIENT_REGISTRY_H | ||||
| 
 | ||||
| #include <wayland-client.h> | ||||
| #include <xkbcommon/xkbcommon.h> | ||||
| #include "wayland-desktop-shell-client-protocol.h" | ||||
| #include "wayland-swaylock-client-protocol.h" | ||||
| #include "list.h" | ||||
| 
 | ||||
| enum mod_bit { | ||||
|     MOD_SHIFT = 1<<0, | ||||
|     MOD_CAPS = 1<<1, | ||||
|     MOD_CTRL = 1<<2, | ||||
|     MOD_ALT = 1<<3, | ||||
|     MOD_MOD2 = 1<<4, | ||||
|     MOD_MOD3 = 1<<5, | ||||
|     MOD_LOGO = 1<<6, | ||||
|     MOD_MOD5 = 1<<7, | ||||
| }; | ||||
| 
 | ||||
| enum mask { | ||||
|     MASK_SHIFT, | ||||
|     MASK_CAPS, | ||||
|     MASK_CTRL, | ||||
|     MASK_ALT, | ||||
|     MASK_MOD2, | ||||
|     MASK_MOD3, | ||||
|     MASK_LOGO, | ||||
|     MASK_MOD5, | ||||
|     MASK_LAST | ||||
| }; | ||||
| 
 | ||||
| struct output_state { | ||||
|         struct wl_output *output; | ||||
|         uint32_t flags; | ||||
|         uint32_t width, height; | ||||
| }; | ||||
| 
 | ||||
| struct xkb { | ||||
|         struct xkb_state *state; | ||||
|         struct xkb_context *context; | ||||
|         struct xkb_keymap *keymap; | ||||
|         xkb_mod_mask_t masks[MASK_LAST]; | ||||
| }; | ||||
| 
 | ||||
| struct input { | ||||
|     int *repeat_fd; | ||||
| 
 | ||||
|     struct xkb xkb; | ||||
| 
 | ||||
|     xkb_keysym_t sym; | ||||
|     uint32_t code; | ||||
|     uint32_t last_code; | ||||
|     uint32_t modifiers; | ||||
| 
 | ||||
|     xkb_keysym_t repeat_sym; | ||||
|     uint32_t repeat_key; | ||||
| 
 | ||||
|     int32_t repeat_rate_sec; | ||||
|     int32_t repeat_rate_nsec; | ||||
|     int32_t repeat_delay_sec; | ||||
|     int32_t repeat_delay_nsec; | ||||
| 
 | ||||
|     struct { | ||||
|         void (*key)(enum wl_keyboard_key_state state, xkb_keysym_t sym, uint32_t code); | ||||
|     } notify; | ||||
| }; | ||||
| 
 | ||||
| struct registry { | ||||
|         struct wl_compositor *compositor; | ||||
|         struct wl_display *display; | ||||
|  | @ -22,6 +76,7 @@ struct registry { | |||
|         struct wl_shm *shm; | ||||
|         struct desktop_shell *desktop_shell; | ||||
|         struct lock *swaylock; | ||||
|         struct input *input; | ||||
|         list_t *outputs; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ include_directories( | |||
| 	${PROTOCOLS_INCLUDE_DIRS} | ||||
| 	${PANGO_INCLUDE_DIRS} | ||||
| 	${GDK_PIXBUF_INCLUDE_DIRS} | ||||
| 	${XKBCOMMON_INCLUDE_DIRS} | ||||
| ) | ||||
| 
 | ||||
| add_library(sway-wayland | ||||
|  | @ -17,4 +18,5 @@ target_link_libraries(sway-wayland | |||
| 	sway-protocols | ||||
| 	${PANGO_LIBRARIES} | ||||
| 	${GDK_PIXBUF_LIBRARIES} | ||||
| 	${XKBCOMMON_LIBRARIES} | ||||
| 	) | ||||
|  |  | |||
|  | @ -1,6 +1,10 @@ | |||
| #include <wayland-client.h> | ||||
| #include <xkbcommon/xkbcommon.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/mman.h> | ||||
| #include <sys/timerfd.h> | ||||
| #include "wayland-desktop-shell-client-protocol.h" | ||||
| #include "wayland-swaylock-client-protocol.h" | ||||
| #include "client/registry.h" | ||||
|  | @ -38,8 +42,73 @@ static const struct wl_output_listener output_listener = { | |||
| 	.scale = display_handle_scale | ||||
| }; | ||||
| 
 | ||||
| const char *XKB_MASK_NAMES[MASK_LAST] = { | ||||
|     XKB_MOD_NAME_SHIFT, | ||||
|     XKB_MOD_NAME_CAPS, | ||||
|     XKB_MOD_NAME_CTRL, | ||||
|     XKB_MOD_NAME_ALT, | ||||
|     "Mod2", | ||||
|     "Mod3", | ||||
|     XKB_MOD_NAME_LOGO, | ||||
|     "Mod5", | ||||
| }; | ||||
| 
 | ||||
| const enum mod_bit XKB_MODS[MASK_LAST] = { | ||||
|     MOD_SHIFT, | ||||
|     MOD_CAPS, | ||||
|     MOD_CTRL, | ||||
|     MOD_ALT, | ||||
|     MOD_MOD2, | ||||
|     MOD_MOD3, | ||||
|     MOD_LOGO, | ||||
|     MOD_MOD5 | ||||
| }; | ||||
| 
 | ||||
| static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, | ||||
| 		uint32_t format, int fd, uint32_t size) { | ||||
| 	// Keyboard errors are abort-worthy because you wouldn't be able to unlock your screen otherwise.
 | ||||
| 
 | ||||
| 	struct registry *registry = data; | ||||
| 	if (!data) { | ||||
| 		close(fd); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { | ||||
| 		close(fd); | ||||
| 		sway_abort("Unknown keymap format %d, aborting", format); | ||||
| 	} | ||||
| 
 | ||||
| 	char *map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); | ||||
| 	if (map_str == MAP_FAILED) { | ||||
| 		close(fd); | ||||
| 		sway_abort("Unable to initialized shared keyboard memory, aborting"); | ||||
| 	} | ||||
| 
 | ||||
| 	struct xkb_keymap *keymap = xkb_keymap_new_from_string(registry->input->xkb.context, | ||||
| 			map_str, XKB_KEYMAP_FORMAT_TEXT_V1, 0); | ||||
| 	munmap(map_str, size); | ||||
| 	close(fd); | ||||
| 
 | ||||
| 	if (!keymap) { | ||||
| 		sway_abort("Failed to compile keymap, aborting"); | ||||
| 	} | ||||
| 
 | ||||
| 	struct xkb_state *state = xkb_state_new(keymap); | ||||
| 	if (!state) { | ||||
| 		xkb_keymap_unref(keymap); | ||||
| 		sway_abort("Failed to create xkb state, aborting"); | ||||
| 	} | ||||
| 
 | ||||
| 	xkb_keymap_unref(registry->input->xkb.keymap); | ||||
| 	xkb_state_unref(registry->input->xkb.state); | ||||
| 	registry->input->xkb.keymap = keymap; | ||||
| 	registry->input->xkb.state = state; | ||||
| 
 | ||||
| 	int i; | ||||
| 	for (i = 0; i < MASK_LAST; ++i) { | ||||
| 		registry->input->xkb.masks[i] = 1 << xkb_keymap_mod_get_index(registry->input->xkb.keymap, XKB_MASK_NAMES[i]); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, | ||||
|  | @ -115,6 +184,8 @@ struct registry *registry_poll(void) { | |||
| 	struct registry *registry = malloc(sizeof(struct registry)); | ||||
| 	memset(registry, 0, sizeof(struct registry)); | ||||
| 	registry->outputs = create_list(); | ||||
| 	registry->input = calloc(sizeof(struct input), 1); | ||||
| 	registry->input->xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); | ||||
| 
 | ||||
| 	registry->display = wl_display_connect(NULL); | ||||
| 	if (!registry->display) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Drew DeVault
						Drew DeVault