|  |  |  | @ -14,23 +14,70 @@ | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static const char *default_seat = "seat0"; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // TODO make me not global
 | 
			
		
	
		
			
				
					|  |  |  |  | struct sway_input_manager *input_manager; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | struct input_config *current_input_config = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static struct sway_seat *input_manager_get_seat( | 
			
		
	
		
			
				
					|  |  |  |  | 		struct sway_input_manager *input, const char *seat_name) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_seat *seat = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = 0; i < input->seats->length; ++i) { | 
			
		
	
		
			
				
					|  |  |  |  | 		seat = input->seats->items[i]; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(seat, &input->seats, link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		if (strcmp(seat->seat->name, seat_name) == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 			return seat; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	seat = sway_seat_create(input, seat_name); | 
			
		
	
		
			
				
					|  |  |  |  | 	list_add(input->seats, seat); | 
			
		
	
		
			
				
					|  |  |  |  | 	return sway_seat_create(input, seat_name); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static char *get_device_identifier(struct wlr_input_device *device) { | 
			
		
	
		
			
				
					|  |  |  |  | 	int vendor = device->vendor; | 
			
		
	
		
			
				
					|  |  |  |  | 	int product = device->product; | 
			
		
	
		
			
				
					|  |  |  |  | 	char *name = strdup(device->name); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	char *p = name; | 
			
		
	
		
			
				
					|  |  |  |  | 	for (; *p; ++p) { | 
			
		
	
		
			
				
					|  |  |  |  | 		if (*p == ' ') { | 
			
		
	
		
			
				
					|  |  |  |  | 			*p = '_'; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	sway_log(L_DEBUG, "rewritten name %s", name); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	int len = strlen(name) + sizeof(char) * 6; | 
			
		
	
		
			
				
					|  |  |  |  | 	char *identifier = malloc(len); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!identifier) { | 
			
		
	
		
			
				
					|  |  |  |  | 		sway_log(L_ERROR, "Unable to allocate unique input device name"); | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	const char *fmt = "%d:%d:%s"; | 
			
		
	
		
			
				
					|  |  |  |  | 	snprintf(identifier, len, fmt, vendor, product, name); | 
			
		
	
		
			
				
					|  |  |  |  | 	free(name); | 
			
		
	
		
			
				
					|  |  |  |  | 	return identifier; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return seat; | 
			
		
	
		
			
				
					|  |  |  |  | static struct sway_input_device *input_sway_device_from_wlr(struct sway_input_manager *input, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_input_device *device) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_input_device *sway_device = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(sway_device, &input->devices, link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		if (sway_device->wlr_device == device) { | 
			
		
	
		
			
				
					|  |  |  |  | 			return sway_device; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static struct sway_input_device *input_sway_device_from_config(struct sway_input_manager *input, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct input_config *config) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_input_device *sway_device = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(sway_device, &input->devices, link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		if (strcmp(sway_device->identifier, config->identifier) == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 			return sway_device; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void input_add_notify(struct wl_listener *listener, void *data) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -38,9 +85,27 @@ static void input_add_notify(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_container_of(listener, input, input_add); | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_input_device *device = data; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// TODO device configuration
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_input_device *sway_device = | 
			
		
	
		
			
				
					|  |  |  |  | 		calloc(1, sizeof(struct sway_input_device)); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!sway_assert(sway_device, "could not allocate input device")) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	sway_device->wlr_device = device; | 
			
		
	
		
			
				
					|  |  |  |  | 	sway_device->identifier = get_device_identifier(device); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_insert(&input->devices, &sway_device->link); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// find config
 | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = 0; i < config->input_configs->length; ++i) { | 
			
		
	
		
			
				
					|  |  |  |  | 		struct input_config *input_config = config->input_configs->items[i]; | 
			
		
	
		
			
				
					|  |  |  |  | 		if (strcmp(input_config->identifier, sway_device->identifier) == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 			sway_device->config = input_config; | 
			
		
	
		
			
				
					|  |  |  |  | 			break; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_seat *seat = input_manager_get_seat(input, default_seat); | 
			
		
	
		
			
				
					|  |  |  |  | 	sway_seat_add_device(seat, device); | 
			
		
	
		
			
				
					|  |  |  |  | 	sway_seat_add_device(seat, sway_device); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void input_remove_notify(struct wl_listener *listener, void *data) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -48,9 +113,21 @@ static void input_remove_notify(struct wl_listener *listener, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_container_of(listener, input, input_remove); | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_input_device *device = data; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// TODO device configuration
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_seat *seat = input_manager_get_seat(input, default_seat); | 
			
		
	
		
			
				
					|  |  |  |  | 	sway_seat_remove_device(seat, device); | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_input_device *sway_device = | 
			
		
	
		
			
				
					|  |  |  |  | 		input_sway_device_from_wlr(input, device); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!sway_assert(sway_device, "could not find sway device")) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_seat *seat = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(seat, &input->seats, link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		sway_seat_remove_device(seat, sway_device); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_remove(&sway_device->link); | 
			
		
	
		
			
				
					|  |  |  |  | 	free(sway_device->identifier); | 
			
		
	
		
			
				
					|  |  |  |  | 	free(sway_device); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | struct sway_input_manager *sway_input_manager_create( | 
			
		
	
	
		
			
				
					|  |  |  | @ -63,7 +140,8 @@ struct sway_input_manager *sway_input_manager_create( | 
			
		
	
		
			
				
					|  |  |  |  | 	// XXX probably don't need the full server
 | 
			
		
	
		
			
				
					|  |  |  |  | 	input->server = server; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	input->seats = create_list(); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_init(&input->devices); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_init(&input->seats); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// create the default seat
 | 
			
		
	
		
			
				
					|  |  |  |  | 	input_manager_get_seat(input, default_seat); | 
			
		
	
	
		
			
				
					|  |  |  | @ -77,69 +155,46 @@ struct sway_input_manager *sway_input_manager_create( | 
			
		
	
		
			
				
					|  |  |  |  | 	return input; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | struct input_config *new_input_config(const char* identifier) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct input_config *input = calloc(1, sizeof(struct input_config)); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!input) { | 
			
		
	
		
			
				
					|  |  |  |  | 		sway_log(L_DEBUG, "Unable to allocate input config"); | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	sway_log(L_DEBUG, "new_input_config(%s)", identifier); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!(input->identifier = strdup(identifier))) { | 
			
		
	
		
			
				
					|  |  |  |  | 		free(input); | 
			
		
	
		
			
				
					|  |  |  |  | 		sway_log(L_DEBUG, "Unable to allocate input config"); | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | bool sway_input_manager_has_focus(struct sway_input_manager *input, | 
			
		
	
		
			
				
					|  |  |  |  | 		swayc_t *container) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_seat *seat = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(seat, &input->seats, link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		if (seat->focus == container) { | 
			
		
	
		
			
				
					|  |  |  |  | 			return true; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	input->tap = INT_MIN; | 
			
		
	
		
			
				
					|  |  |  |  | 	input->drag_lock = INT_MIN; | 
			
		
	
		
			
				
					|  |  |  |  | 	input->dwt = INT_MIN; | 
			
		
	
		
			
				
					|  |  |  |  | 	input->send_events = INT_MIN; | 
			
		
	
		
			
				
					|  |  |  |  | 	input->click_method = INT_MIN; | 
			
		
	
		
			
				
					|  |  |  |  | 	input->middle_emulation = INT_MIN; | 
			
		
	
		
			
				
					|  |  |  |  | 	input->natural_scroll = INT_MIN; | 
			
		
	
		
			
				
					|  |  |  |  | 	input->accel_profile = INT_MIN; | 
			
		
	
		
			
				
					|  |  |  |  | 	input->pointer_accel = FLT_MIN; | 
			
		
	
		
			
				
					|  |  |  |  | 	input->scroll_method = INT_MIN; | 
			
		
	
		
			
				
					|  |  |  |  | 	input->left_handed = INT_MIN; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return input; | 
			
		
	
		
			
				
					|  |  |  |  | 	return false; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | char *libinput_dev_unique_id(struct libinput_device *device) { | 
			
		
	
		
			
				
					|  |  |  |  | 	int vendor = libinput_device_get_id_vendor(device); | 
			
		
	
		
			
				
					|  |  |  |  | 	int product = libinput_device_get_id_product(device); | 
			
		
	
		
			
				
					|  |  |  |  | 	char *name = strdup(libinput_device_get_name(device)); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	char *p = name; | 
			
		
	
		
			
				
					|  |  |  |  | 	for (; *p; ++p) { | 
			
		
	
		
			
				
					|  |  |  |  | 		if (*p == ' ') { | 
			
		
	
		
			
				
					|  |  |  |  | 			*p = '_'; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | void sway_input_manager_set_focus(struct sway_input_manager *input, | 
			
		
	
		
			
				
					|  |  |  |  | 		swayc_t *container) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_seat *seat ; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(seat, &input->seats, link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		sway_seat_set_focus(seat, container); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	sway_log(L_DEBUG, "rewritten name %s", name); | 
			
		
	
		
			
				
					|  |  |  |  | void sway_input_manager_apply_config(struct sway_input_manager *input, | 
			
		
	
		
			
				
					|  |  |  |  | 		struct input_config *config) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_input_device *sway_device = | 
			
		
	
		
			
				
					|  |  |  |  | 		input_sway_device_from_config(input, config); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!sway_device) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	int len = strlen(name) + sizeof(char) * 6; | 
			
		
	
		
			
				
					|  |  |  |  | 	char *identifier = malloc(len); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!identifier) { | 
			
		
	
		
			
				
					|  |  |  |  | 		sway_log(L_ERROR, "Unable to allocate unique input device name"); | 
			
		
	
		
			
				
					|  |  |  |  | 		return NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_seat *seat = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(seat, &input->seats, link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		sway_seat_remove_device(seat, sway_device); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	const char *fmt = "%d:%d:%s"; | 
			
		
	
		
			
				
					|  |  |  |  | 	snprintf(identifier, len, fmt, vendor, product, name); | 
			
		
	
		
			
				
					|  |  |  |  | 	free(name); | 
			
		
	
		
			
				
					|  |  |  |  | 	return identifier; | 
			
		
	
		
			
				
					|  |  |  |  | 	seat = input_manager_get_seat(input, default_seat); | 
			
		
	
		
			
				
					|  |  |  |  | 	sway_seat_add_device(seat, sway_device); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | bool sway_input_manager_swayc_has_focus(struct sway_input_manager *input, | 
			
		
	
		
			
				
					|  |  |  |  | 		swayc_t *container) { | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = 0; i < input->seats->length; ++i) { | 
			
		
	
		
			
				
					|  |  |  |  | 		struct sway_seat *seat = input->seats->items[i]; | 
			
		
	
		
			
				
					|  |  |  |  | 		if (seat->focus == container) { | 
			
		
	
		
			
				
					|  |  |  |  | 			return true; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | void sway_input_manager_configure_xcursor(struct sway_input_manager *input) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_seat *seat = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_list_for_each(seat, &input->seats, link) { | 
			
		
	
		
			
				
					|  |  |  |  | 		sway_seat_configure_xcursor(seat); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	return false; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
	
		
			
				
					|  |  |  | 
 |