|  |  | @ -32,9 +32,6 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | #include "shared.h" |  |  |  | #include "shared.h" | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <assert.h> |  |  |  | #include <assert.h> | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // TODO: move to common header?
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | int os_create_anonymous_file(off_t size); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | struct sample_state; |  |  |  | struct sample_state; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | struct example_xdg_surface_v6 { |  |  |  | struct example_xdg_surface_v6 { | 
			
		
	
	
		
		
			
				
					|  |  | @ -75,13 +72,9 @@ struct sample_state { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_xdg_shell_v6 *xdg_shell; |  |  |  | 	struct wlr_xdg_shell_v6 *xdg_shell; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_data_device_manager *data_device_manager; |  |  |  | 	struct wlr_data_device_manager *data_device_manager; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wl_resource *focus; |  |  |  | 	struct wl_resource *focus; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wl_listener keyboard_bound; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_xwayland *xwayland; |  |  |  | 	struct wlr_xwayland *xwayland; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_gamma_control_manager *gamma_control_manager; |  |  |  | 	struct wlr_gamma_control_manager *gamma_control_manager; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	bool mod_down; |  |  |  | 	bool mod_down; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int keymap_fd; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	size_t keymap_size; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	uint32_t serial; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct motion_context motion_context; |  |  |  | 	struct motion_context motion_context; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -335,61 +328,11 @@ static void handle_keyboard_key(struct keyboard_state *keyboard, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		uint32_t keycode, xkb_keysym_t sym, enum wlr_key_state key_state) { |  |  |  | 		uint32_t keycode, xkb_keysym_t sym, enum wlr_key_state key_state) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct compositor_state *state = keyboard->compositor; |  |  |  | 	struct compositor_state *state = keyboard->compositor; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct sample_state *sample = state->data; |  |  |  | 	struct sample_state *sample = state->data; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wl_resource *res = NULL; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_seat_handle *seat_handle = NULL; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wl_list_for_each(res, &sample->wlr_compositor->surfaces, link) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (res) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		seat_handle = wlr_seat_handle_for_client(sample->wl_seat, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			wl_resource_get_client(res)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (res != sample->focus && seat_handle && seat_handle->keyboard) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		struct wl_array keys; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wl_array_init(&keys); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		uint32_t serial = wl_display_next_serial(state->display); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wl_keyboard_send_enter(seat_handle->keyboard, serial, res, &keys); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		sample->focus = res; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (seat_handle && seat_handle->keyboard) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		uint32_t depressed = xkb_state_serialize_mods(keyboard->xkb_state, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			XKB_STATE_MODS_DEPRESSED); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		uint32_t latched = xkb_state_serialize_mods(keyboard->xkb_state, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			XKB_STATE_MODS_LATCHED); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		uint32_t locked = xkb_state_serialize_mods(keyboard->xkb_state, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			XKB_STATE_MODS_LOCKED); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		uint32_t group = xkb_state_serialize_layout(keyboard->xkb_state, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			XKB_STATE_LAYOUT_EFFECTIVE); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		uint32_t modifiers_serial = wl_display_next_serial(state->display); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		uint32_t key_serial = wl_display_next_serial(state->display); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wl_keyboard_send_modifiers(seat_handle->keyboard, modifiers_serial, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			depressed, latched, locked, group); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wl_keyboard_send_key(seat_handle->keyboard, key_serial, 0, keycode, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			key_state); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (sym == XKB_KEY_Super_L || sym == XKB_KEY_Super_R) { |  |  |  | 	if (sym == XKB_KEY_Super_L || sym == XKB_KEY_Super_R) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		sample->mod_down = key_state == WLR_KEY_PRESSED; |  |  |  | 		sample->mod_down = key_state == WLR_KEY_PRESSED; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void handle_keyboard_bound(struct wl_listener *listener, void *data) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_seat_handle *handle = data; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct sample_state *state = |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wl_container_of(listener, state, keyboard_bound); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wl_keyboard_send_keymap(handle->keyboard, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		state->keymap_fd, state->keymap_size); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (wl_resource_get_version(handle->keyboard) >= 2) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		wl_keyboard_send_repeat_info(handle->keyboard, 25, 600); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static struct wlr_xdg_surface_v6 *example_xdg_surface_at( |  |  |  | static struct wlr_xdg_surface_v6 *example_xdg_surface_at( | 
			
		
	
		
		
			
				
					
					|  |  |  | 		struct sample_state *sample, int lx, int ly) { |  |  |  | 		struct sample_state *sample, int lx, int ly) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct wlr_xdg_surface_v6 *xdg_surface; |  |  |  | 	struct wlr_xdg_surface_v6 *xdg_surface; | 
			
		
	
	
		
		
			
				
					|  |  | @ -550,6 +493,25 @@ static void handle_input_add(struct compositor_state *state, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		example_config_configure_cursor(sample->config, sample->cursor, |  |  |  | 		example_config_configure_cursor(sample->config, sample->cursor, | 
			
		
	
		
		
			
				
					
					|  |  |  | 			sample->compositor); |  |  |  | 			sample->compositor); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (device->type == WLR_INPUT_DEVICE_KEYBOARD) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		struct xkb_rule_names rules; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		memset(&rules, 0, sizeof(rules)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		rules.rules = getenv("XKB_DEFAULT_RULES"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		rules.model = getenv("XKB_DEFAULT_MODEL"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		rules.layout = getenv("XKB_DEFAULT_LAYOUT"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		rules.variant = getenv("XKB_DEFAULT_VARIANT"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		rules.options = getenv("XKB_DEFAULT_OPTIONS"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		if (!context) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			wlr_log(L_ERROR, "Failed to create XKB context"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 			exit(1); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 				context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		xkb_context_unref(context); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		wlr_seat_attach_keyboard(sample->wl_seat, device); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void handle_output_add(struct output_state *ostate) { |  |  |  | static void handle_output_add(struct output_state *ostate) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -669,35 +631,25 @@ int main(int argc, char *argv[]) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	state.wl_seat = wlr_seat_create(compositor.display, "seat0"); |  |  |  | 	state.wl_seat = wlr_seat_create(compositor.display, "seat0"); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	assert(state.wl_seat); |  |  |  | 	assert(state.wl_seat); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	state.keyboard_bound.notify = handle_keyboard_bound; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wl_signal_add(&state.wl_seat->events.keyboard_bound, &state.keyboard_bound); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_seat_set_capabilities(state.wl_seat, WL_SEAT_CAPABILITY_KEYBOARD |  |  |  | 	wlr_seat_set_capabilities(state.wl_seat, WL_SEAT_CAPABILITY_KEYBOARD | 
			
		
	
		
		
			
				
					
					|  |  |  | 		| WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); |  |  |  | 		| WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	struct keyboard_state *kbstate; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wl_list_for_each(kbstate, &compositor.keyboards, link) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		char *keymap = xkb_keymap_get_as_string(kbstate->keymap, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			XKB_KEYMAP_FORMAT_TEXT_V1); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		state.keymap_size = strlen(keymap); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		state.keymap_fd = os_create_anonymous_file(state.keymap_size); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		void *ptr = |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 			mmap(NULL, state.keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 				state.keymap_fd, 0); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		strcpy(ptr, keymap); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		free(keymap); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 		break; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	state.xwayland = wlr_xwayland_create(compositor.display, |  |  |  | 	state.xwayland = wlr_xwayland_create(compositor.display, | 
			
		
	
		
		
			
				
					
					|  |  |  | 		state.wlr_compositor); |  |  |  | 		state.wlr_compositor); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	compositor.keyboard_key_cb = handle_keyboard_key; |  |  |  | 	compositor.keyboard_key_cb = handle_keyboard_key; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (!wlr_backend_start(compositor.backend)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		wlr_log(L_ERROR, "Failed to start backend"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		wlr_backend_destroy(compositor.backend); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		exit(1); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wl_display_run(compositor.display); |  |  |  | 	wl_display_run(compositor.display); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wl_list_remove(&state.new_xdg_surface_v6.link); |  |  |  | 	wl_list_remove(&state.new_xdg_surface_v6.link); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_xwayland_destroy(state.xwayland); |  |  |  | 	wlr_xwayland_destroy(state.xwayland); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	close(state.keymap_fd); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_seat_destroy(state.wl_seat); |  |  |  | 	wlr_seat_destroy(state.wl_seat); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_gamma_control_manager_destroy(state.gamma_control_manager); |  |  |  | 	wlr_gamma_control_manager_destroy(state.gamma_control_manager); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	wlr_data_device_manager_destroy(state.data_device_manager); |  |  |  | 	wlr_data_device_manager_destroy(state.data_device_manager); | 
			
		
	
	
		
		
			
				
					|  |  | 
 |