summaryrefslogtreecommitdiffstats
path: root/sway/input/input-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input/input-manager.c')
-rw-r--r--sway/input/input-manager.c139
1 files changed, 101 insertions, 38 deletions
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index b07a733e..1950b6d9 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -18,12 +18,13 @@ static const char *default_seat = "seat0";
18struct sway_input_manager *input_manager; 18struct sway_input_manager *input_manager;
19 19
20struct input_config *current_input_config = NULL; 20struct input_config *current_input_config = NULL;
21struct seat_config *current_seat_config = NULL;
21 22
22static struct sway_seat *input_manager_get_seat( 23static struct sway_seat *input_manager_get_seat(
23 struct sway_input_manager *input, const char *seat_name) { 24 struct sway_input_manager *input, const char *seat_name) {
24 struct sway_seat *seat = NULL; 25 struct sway_seat *seat = NULL;
25 wl_list_for_each(seat, &input->seats, link) { 26 wl_list_for_each(seat, &input->seats, link) {
26 if (strcmp(seat->seat->name, seat_name) == 0) { 27 if (strcmp(seat->wlr_seat->name, seat_name) == 0) {
27 return seat; 28 return seat;
28 } 29 }
29 } 30 }
@@ -58,56 +59,88 @@ static char *get_device_identifier(struct wlr_input_device *device) {
58 return identifier; 59 return identifier;
59} 60}
60 61
61static struct sway_input_device *input_sway_device_from_wlr(struct sway_input_manager *input, 62static struct sway_input_device *input_sway_device_from_wlr(
62 struct wlr_input_device *device) { 63 struct sway_input_manager *input, struct wlr_input_device *device) {
63 struct sway_input_device *sway_device = NULL; 64 struct sway_input_device *input_device = NULL;
64 wl_list_for_each(sway_device, &input->devices, link) { 65 wl_list_for_each(input_device, &input->devices, link) {
65 if (sway_device->wlr_device == device) { 66 if (input_device->wlr_device == device) {
66 return sway_device; 67 return input_device;
67 } 68 }
68 } 69 }
69 return NULL; 70 return NULL;
70} 71}
71 72
72static struct sway_input_device *input_sway_device_from_config(struct sway_input_manager *input, 73static struct sway_input_device *input_sway_device_from_config(
73 struct input_config *config) { 74 struct sway_input_manager *input, struct input_config *config) {
74 struct sway_input_device *sway_device = NULL; 75 struct sway_input_device *input_device = NULL;
75 wl_list_for_each(sway_device, &input->devices, link) { 76 wl_list_for_each(input_device, &input->devices, link) {
76 if (strcmp(sway_device->identifier, config->identifier) == 0) { 77 if (strcmp(input_device->identifier, config->identifier) == 0) {
77 return sway_device; 78 return input_device;
78 } 79 }
79 } 80 }
80 return NULL; 81 return NULL;
81} 82}
82 83
84static struct sway_input_device *input_sway_device_from_identifier(
85 struct sway_input_manager *input, char *identifier) {
86 struct sway_input_device *input_device = NULL;
87 wl_list_for_each(input_device, &input->devices, link) {
88 if (strcmp(input_device->identifier, identifier) == 0) {
89 return input_device;
90 }
91 }
92 return NULL;
93}
94
95static bool input_has_seat_configuration(struct sway_input_manager *input) {
96 struct sway_seat *seat = NULL;
97 wl_list_for_each(seat, &input->seats, link) {
98 if (seat->config) {
99 return true;
100 }
101 }
102
103 return false;
104}
105
83static void input_add_notify(struct wl_listener *listener, void *data) { 106static void input_add_notify(struct wl_listener *listener, void *data) {
84 struct sway_input_manager *input = 107 struct sway_input_manager *input =
85 wl_container_of(listener, input, input_add); 108 wl_container_of(listener, input, input_add);
86 struct wlr_input_device *device = data; 109 struct wlr_input_device *device = data;
87 110
88 struct sway_input_device *sway_device = 111 struct sway_input_device *input_device =
89 calloc(1, sizeof(struct sway_input_device)); 112 calloc(1, sizeof(struct sway_input_device));
90 if (!sway_assert(sway_device, "could not allocate input device")) { 113 if (!sway_assert(input_device, "could not allocate input device")) {
91 return; 114 return;
92 } 115 }
93 116
94 sway_device->wlr_device = device; 117 input_device->wlr_device = device;
95 sway_device->identifier = get_device_identifier(device); 118 input_device->identifier = get_device_identifier(device);
96 wl_list_insert(&input->devices, &sway_device->link); 119 wl_list_insert(&input->devices, &input_device->link);
97 120
98 // find config 121 // find config
99 for (int i = 0; i < config->input_configs->length; ++i) { 122 for (int i = 0; i < config->input_configs->length; ++i) {
100 struct input_config *input_config = config->input_configs->items[i]; 123 struct input_config *input_config = config->input_configs->items[i];
101 if (strcmp(input_config->identifier, sway_device->identifier) == 0) { 124 if (strcmp(input_config->identifier, input_device->identifier) == 0) {
102 sway_device->config = input_config; 125 input_device->config = input_config;
103 break; 126 break;
104 } 127 }
105 } 128 }
106 129
107 const char *seat_name = 130 struct sway_seat *seat = NULL;
108 (sway_device->config ? sway_device->config->seat : default_seat); 131 if (!input_has_seat_configuration(input)) {
109 struct sway_seat *seat = input_manager_get_seat(input, seat_name); 132 seat = input_manager_get_seat(input, default_seat);
110 sway_seat_add_device(seat, sway_device); 133 sway_seat_add_device(seat, input_device);
134 return;
135 }
136
137 wl_list_for_each(seat, &input->seats, link) {
138 if (seat->config &&
139 (seat_config_get_attachment(seat->config, input_device->identifier) ||
140 seat_config_get_attachment(seat->config, "*"))) {
141 sway_seat_add_device(seat, input_device);
142 }
143 }
111} 144}
112 145
113static void input_remove_notify(struct wl_listener *listener, void *data) { 146static void input_remove_notify(struct wl_listener *listener, void *data) {
@@ -115,21 +148,21 @@ static void input_remove_notify(struct wl_listener *listener, void *data) {
115 wl_container_of(listener, input, input_remove); 148 wl_container_of(listener, input, input_remove);
116 struct wlr_input_device *device = data; 149 struct wlr_input_device *device = data;
117 150
118 struct sway_input_device *sway_device = 151 struct sway_input_device *input_device =
119 input_sway_device_from_wlr(input, device); 152 input_sway_device_from_wlr(input, device);
120 153
121 if (!sway_assert(sway_device, "could not find sway device")) { 154 if (!sway_assert(input_device, "could not find sway device")) {
122 return; 155 return;
123 } 156 }
124 157
125 struct sway_seat *seat = NULL; 158 struct sway_seat *seat = NULL;
126 wl_list_for_each(seat, &input->seats, link) { 159 wl_list_for_each(seat, &input->seats, link) {
127 sway_seat_remove_device(seat, sway_device); 160 sway_seat_remove_device(seat, input_device);
128 } 161 }
129 162
130 wl_list_remove(&sway_device->link); 163 wl_list_remove(&input_device->link);
131 free(sway_device->identifier); 164 free(input_device->identifier);
132 free(sway_device); 165 free(input_device);
133} 166}
134 167
135struct sway_input_manager *sway_input_manager_create( 168struct sway_input_manager *sway_input_manager_create(
@@ -139,7 +172,6 @@ struct sway_input_manager *sway_input_manager_create(
139 if (!input) { 172 if (!input) {
140 return NULL; 173 return NULL;
141 } 174 }
142 // XXX probably don't need the full server
143 input->server = server; 175 input->server = server;
144 176
145 wl_list_init(&input->devices); 177 wl_list_init(&input->devices);
@@ -177,22 +209,53 @@ void sway_input_manager_set_focus(struct sway_input_manager *input,
177 } 209 }
178} 210}
179 211
180void sway_input_manager_apply_config(struct sway_input_manager *input, 212void sway_input_manager_apply_input_config(struct sway_input_manager *input,
181 struct input_config *input_config) { 213 struct input_config *input_config) {
182 struct sway_input_device *sway_device = 214 struct sway_input_device *input_device =
183 input_sway_device_from_config(input, input_config); 215 input_sway_device_from_config(input, input_config);
184 if (!sway_device) { 216 if (!input_device) {
185 return; 217 return;
186 } 218 }
219 input_device->config = input_config;
187 220
188 struct sway_seat *seat = NULL; 221 struct sway_seat *seat = NULL;
189 wl_list_for_each(seat, &input->seats, link) { 222 wl_list_for_each(seat, &input->seats, link) {
190 sway_seat_remove_device(seat, sway_device); 223 sway_seat_configure_device(seat, input_device);
224 }
225}
226
227void sway_input_manager_apply_seat_config(struct sway_input_manager *input,
228 struct seat_config *seat_config) {
229 struct sway_seat *seat = input_manager_get_seat(input, seat_config->name);
230 // the old config is invalid so clear it
231 sway_seat_set_config(seat, NULL);
232
233 // clear devices
234 struct sway_input_device *input_device = NULL;
235 wl_list_for_each(input_device, &input->devices, link) {
236 sway_seat_remove_device(seat, input_device);
237 }
238
239 if (seat_config_get_attachment(seat_config, "*")) {
240 wl_list_for_each(input_device, &input->devices, link) {
241 sway_seat_add_device(seat, input_device);
242 }
243 } else {
244 for (int i = 0; i < seat_config->attachments->length; ++i) {
245 struct seat_attachment_config *attachment =
246 seat_config->attachments->items[i];
247
248 struct sway_input_device *device =
249 input_sway_device_from_identifier(input,
250 attachment->identifier);
251
252 if (device) {
253 sway_seat_add_device(seat, device);
254 }
255 }
191 } 256 }
192 257
193 const char *seat_name = (input_config->seat ? input_config->seat : default_seat); 258 sway_seat_set_config(seat, seat_config);
194 seat = input_manager_get_seat(input, seat_name);
195 sway_seat_add_device(seat, sway_device);
196} 259}
197 260
198void sway_input_manager_configure_xcursor(struct sway_input_manager *input) { 261void sway_input_manager_configure_xcursor(struct sway_input_manager *input) {