Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #define G_LOG_DOMAIN "valent-mousepad-plugin"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <glib/gi18n.h>
9 : : #include <gdk/gdk.h>
10 : : #include <gio/gio.h>
11 : : #include <gtk/gtk.h>
12 : : #include <json-glib/json-glib.h>
13 : : #include <valent.h>
14 : :
15 : : #include "valent-mousepad-device.h"
16 : : #include "valent-mousepad-keydef.h"
17 : : #include "valent-mousepad-plugin.h"
18 : :
19 : :
20 : : struct _ValentMousepadPlugin
21 : : {
22 : : ValentDevicePlugin parent_instance;
23 : :
24 : : ValentInput *input;
25 : : ValentMousepadDevice *controller;
26 : :
27 : : unsigned int local_state : 1;
28 : : unsigned int remote_state : 1;
29 : : };
30 : :
31 : : static void valent_mousepad_plugin_send_echo (ValentMousepadPlugin *self,
32 : : JsonNode *packet);
33 : :
34 [ + + + - ]: 80 : G_DEFINE_FINAL_TYPE (ValentMousepadPlugin, valent_mousepad_plugin, VALENT_TYPE_DEVICE_PLUGIN)
35 : :
36 : :
37 : : static GdkModifierType
38 : 4 : event_to_mask (JsonObject *body)
39 : : {
40 : 4 : GdkModifierType mask = 0;
41 : :
42 [ + + ]: 4 : if (json_object_get_boolean_member_with_default (body, "alt", FALSE))
43 : 1 : mask |= GDK_ALT_MASK;
44 : :
45 [ + + ]: 4 : if (json_object_get_boolean_member_with_default (body, "ctrl", FALSE))
46 : 1 : mask |= GDK_CONTROL_MASK;
47 : :
48 [ + + ]: 4 : if (json_object_get_boolean_member_with_default (body, "shift", FALSE))
49 : 1 : mask |= GDK_SHIFT_MASK;
50 : :
51 [ + + ]: 4 : if (json_object_get_boolean_member_with_default (body, "super", FALSE))
52 : 1 : mask |= GDK_SUPER_MASK;
53 : :
54 : 4 : return mask;
55 : : }
56 : :
57 : : static inline void
58 : 2 : keyboard_mask (ValentInput *input,
59 : : unsigned int mask,
60 : : gboolean lock)
61 : : {
62 [ + - ]: 2 : if (mask & GDK_ALT_MASK)
63 : 2 : valent_input_keyboard_keysym (input, GDK_KEY_Alt_L, lock);
64 : :
65 [ + - ]: 2 : if (mask & GDK_CONTROL_MASK)
66 : 2 : valent_input_keyboard_keysym (input, GDK_KEY_Control_L, lock);
67 : :
68 [ + - ]: 2 : if (mask & GDK_SHIFT_MASK)
69 : 2 : valent_input_keyboard_keysym (input, GDK_KEY_Shift_L, lock);
70 : :
71 [ + - ]: 2 : if (mask & GDK_SUPER_MASK)
72 : 2 : valent_input_keyboard_keysym (input, GDK_KEY_Super_L, lock);
73 : 2 : }
74 : :
75 : : /*
76 : : * Packet Handlers
77 : : */
78 : : static void
79 : 12 : valent_mousepad_plugin_handle_mousepad_request (ValentMousepadPlugin *self,
80 : : JsonNode *packet)
81 : : {
82 : 12 : JsonObject *body;
83 : 12 : const char *key;
84 : 12 : int64_t keycode;
85 : :
86 [ + - ]: 12 : g_assert (VALENT_IS_MOUSEPAD_PLUGIN (self));
87 [ - + ]: 12 : g_assert (VALENT_IS_PACKET (packet));
88 : :
89 : 12 : body = valent_packet_get_body (packet);
90 : :
91 : : /* Pointer movement */
92 [ + + - + ]: 12 : if (json_object_has_member (body, "dx") || json_object_has_member (body, "dy"))
93 : : {
94 : 2 : double dx, dy;
95 : :
96 : 2 : dx = json_object_get_double_member_with_default (body, "dx", 0.0);
97 : 2 : dy = json_object_get_double_member_with_default (body, "dy", 0.0);
98 : :
99 [ + + ]: 2 : if (valent_packet_check_field (packet, "scroll"))
100 : 1 : valent_input_pointer_axis (self->input, dx, dy);
101 : : else
102 : 1 : valent_input_pointer_motion (self->input, dx, dy);
103 : : }
104 : :
105 : : /* Keyboard Event */
106 [ + + ]: 10 : else if (valent_packet_get_string (packet, "key", &key))
107 : : {
108 : 3 : GdkModifierType mask;
109 : 3 : const char *next;
110 : 3 : gunichar codepoint;
111 : :
112 : : /* Lock modifiers */
113 [ + + ]: 3 : if ((mask = event_to_mask (body)) != 0)
114 : 1 : keyboard_mask (self->input, mask, TRUE);
115 : :
116 : : /* Input each keysym */
117 : 3 : next = key;
118 : :
119 [ + + ]: 9 : while ((codepoint = g_utf8_get_char (next)) != 0)
120 : : {
121 : 6 : uint32_t keysym;
122 : :
123 : 6 : keysym = gdk_unicode_to_keyval (codepoint);
124 : 6 : valent_input_keyboard_keysym (self->input, keysym, TRUE);
125 : 6 : valent_input_keyboard_keysym (self->input, keysym, FALSE);
126 : :
127 : 6 : next = g_utf8_next_char (next);
128 : : }
129 : :
130 : : /* Unlock modifiers */
131 [ + + ]: 3 : if (mask != 0)
132 : 1 : keyboard_mask (self->input, mask, FALSE);
133 : :
134 : : /* Send ack, if requested */
135 [ - + ]: 3 : if (valent_packet_check_field (packet, "sendAck"))
136 : 0 : valent_mousepad_plugin_send_echo (self, packet);
137 : : }
138 [ + + ]: 7 : else if (valent_packet_get_int (packet, "specialKey", &keycode))
139 : : {
140 : 1 : GdkModifierType mask;
141 : 1 : uint32_t keyval;
142 : :
143 [ + - - + ]: 1 : if ((keyval = valent_mousepad_keycode_to_keyval (keycode)) == 0)
144 : : {
145 : 0 : g_debug ("%s(): expected \"specialKey\" field holding a keycode",
146 : : G_STRFUNC);
147 : 0 : return;
148 : : }
149 : :
150 : : /* Lock modifiers */
151 [ - + ]: 1 : if ((mask = event_to_mask (body)) != 0)
152 : 0 : keyboard_mask (self->input, mask, TRUE);
153 : :
154 : : /* Input each keysym */
155 : 1 : valent_input_keyboard_keysym (self->input, keyval, TRUE);
156 : 1 : valent_input_keyboard_keysym (self->input, keyval, FALSE);
157 : :
158 : : /* Unlock modifiers */
159 [ - + ]: 1 : if (mask != 0)
160 : 0 : keyboard_mask (self->input, mask, FALSE);
161 : :
162 : : /* Send ack, if requested */
163 [ - + ]: 1 : if (valent_packet_check_field (packet, "sendAck"))
164 : 0 : valent_mousepad_plugin_send_echo (self, packet);
165 : : }
166 : :
167 [ + + ]: 6 : else if (valent_packet_check_field (packet, "singleclick"))
168 : : {
169 : 1 : valent_input_pointer_button (self->input, VALENT_POINTER_PRIMARY, TRUE);
170 : 1 : valent_input_pointer_button (self->input, VALENT_POINTER_PRIMARY, FALSE);
171 : : }
172 : :
173 [ + + ]: 5 : else if (valent_packet_check_field (packet, "doubleclick"))
174 : : {
175 : 1 : valent_input_pointer_button (self->input, VALENT_POINTER_PRIMARY, TRUE);
176 : 1 : valent_input_pointer_button (self->input, VALENT_POINTER_PRIMARY, FALSE);
177 : 1 : valent_input_pointer_button (self->input, VALENT_POINTER_PRIMARY, TRUE);
178 : 1 : valent_input_pointer_button (self->input, VALENT_POINTER_PRIMARY, FALSE);
179 : : }
180 : :
181 [ + + ]: 4 : else if (valent_packet_check_field (packet, "middleclick"))
182 : : {
183 : 1 : valent_input_pointer_button (self->input, VALENT_POINTER_MIDDLE, TRUE);
184 : 1 : valent_input_pointer_button (self->input, VALENT_POINTER_MIDDLE, FALSE);
185 : : }
186 : :
187 [ + + ]: 3 : else if (valent_packet_check_field (packet, "rightclick"))
188 : : {
189 : 1 : valent_input_pointer_button (self->input, VALENT_POINTER_SECONDARY, TRUE);
190 : 1 : valent_input_pointer_button (self->input, VALENT_POINTER_SECONDARY, FALSE);
191 : : }
192 : :
193 [ + + ]: 2 : else if (valent_packet_check_field (packet, "singlehold"))
194 : : {
195 : 1 : valent_input_pointer_button (self->input, VALENT_POINTER_PRIMARY, TRUE);
196 : : }
197 : :
198 : : /* Not used by kdeconnect-android, hold is released with a regular click */
199 [ + - ]: 1 : else if (valent_packet_check_field (packet, "singlerelease"))
200 : : {
201 : 1 : valent_input_pointer_button (self->input, VALENT_POINTER_PRIMARY, FALSE);
202 : : }
203 : :
204 : : else
205 : : {
206 : 0 : g_debug ("%s: unknown input", G_STRFUNC);
207 : : }
208 : : }
209 : :
210 : : static void
211 : 1 : valent_mousepad_plugin_handle_mousepad_echo (ValentMousepadPlugin *self,
212 : : JsonNode *packet)
213 : : {
214 [ + - ]: 1 : g_assert (VALENT_IS_MOUSEPAD_PLUGIN (self));
215 [ - + ]: 1 : g_assert (VALENT_IS_PACKET (packet));
216 : :
217 : 1 : VALENT_NOTE ("Not implemented");
218 : 1 : }
219 : :
220 : : static void
221 : 2 : valent_mousepad_plugin_handle_mousepad_keyboardstate (ValentMousepadPlugin *self,
222 : : JsonNode *packet)
223 : : {
224 : 2 : gboolean state;
225 : :
226 [ + - ]: 2 : g_assert (VALENT_IS_MOUSEPAD_PLUGIN (self));
227 [ - + ]: 2 : g_assert (VALENT_IS_PACKET (packet));
228 : :
229 : : /* Update the remote keyboard state */
230 [ - + ]: 2 : if (!valent_packet_get_boolean (packet, "state", &state))
231 : : {
232 : 0 : g_debug ("%s(): expected \"state\" field holding a boolean",
233 : : G_STRFUNC);
234 : 0 : return;
235 : : }
236 : :
237 [ + - ]: 2 : if (self->remote_state != state)
238 : : {
239 : 2 : GAction *action;
240 : :
241 : 2 : self->remote_state = state;
242 : 2 : action = g_action_map_lookup_action (G_ACTION_MAP (self), "event");
243 : 2 : g_simple_action_set_enabled (G_SIMPLE_ACTION (action), self->remote_state);
244 : :
245 [ + - + - ]: 2 : if (self->remote_state && self->controller == NULL)
246 : 2 : {
247 : 2 : ValentDevice *device = NULL;
248 : :
249 : 2 : device = valent_extension_get_object (VALENT_EXTENSION (self));
250 : 2 : self->controller = g_object_new (VALENT_TYPE_MOUSEPAD_DEVICE,
251 : : "device", device,
252 : : "object", device,
253 : : NULL);
254 : 2 : valent_input_export_adapter (self->input,
255 : : VALENT_INPUT_ADAPTER (self->controller));
256 : : }
257 [ # # # # ]: 0 : else if (!self->remote_state && self->controller != NULL)
258 : : {
259 : 0 : valent_input_unexport_adapter (self->input,
260 : : VALENT_INPUT_ADAPTER (self->controller));
261 [ - - ]: 2 : g_clear_object (&self->controller);
262 : : }
263 : : }
264 : : }
265 : :
266 : : /*
267 : : * Packet Providers
268 : : */
269 : : static void
270 : 3 : valent_mousepad_plugin_mousepad_request_keyboard (ValentMousepadPlugin *self,
271 : : uint32_t keyval,
272 : : GdkModifierType mask)
273 : : {
274 : 3 : g_autoptr (JsonBuilder) builder = NULL;
275 [ - - - + ]: 3 : g_autoptr (JsonNode) packet = NULL;
276 : 3 : uint32_t special_key = 0;
277 : :
278 [ + - ]: 3 : g_assert (VALENT_IS_MOUSEPAD_PLUGIN (self));
279 : :
280 : 3 : valent_packet_init (&builder, "kdeconnect.mousepad.request");
281 : :
282 [ + + ]: 3 : if ((special_key = valent_mousepad_keyval_to_keycode (keyval)) != 0)
283 : : {
284 : 1 : json_builder_set_member_name (builder, "specialKey");
285 : 1 : json_builder_add_int_value (builder, special_key);
286 : : }
287 : : else
288 : : {
289 [ - - ]: 2 : g_autoptr (GError) error = NULL;
290 [ - - - + ]: 2 : g_autofree char *key = NULL;
291 : 2 : gunichar wc;
292 : :
293 : 2 : wc = gdk_keyval_to_unicode (keyval);
294 : 2 : key = g_ucs4_to_utf8 (&wc, 1, NULL, NULL, &error);
295 : :
296 [ - + ]: 2 : if (key == NULL)
297 : : {
298 : 0 : g_warning ("Converting %s to string: %s",
299 : : gdk_keyval_name (keyval),
300 : : error->message);
301 : 0 : return;
302 : : }
303 : :
304 : 2 : json_builder_set_member_name (builder, "key");
305 : 2 : json_builder_add_string_value (builder, key);
306 : : }
307 : :
308 [ + + ]: 3 : if (mask & GDK_ALT_MASK)
309 : : {
310 : 1 : json_builder_set_member_name (builder, "alt");
311 : 1 : json_builder_add_boolean_value (builder, TRUE);
312 : : }
313 : :
314 [ + + ]: 3 : if (mask & GDK_CONTROL_MASK)
315 : : {
316 : 1 : json_builder_set_member_name (builder, "ctrl");
317 : 1 : json_builder_add_boolean_value (builder, TRUE);
318 : : }
319 : :
320 [ + + ]: 3 : if (mask & GDK_SHIFT_MASK)
321 : : {
322 : 1 : json_builder_set_member_name (builder, "shift");
323 : 1 : json_builder_add_boolean_value (builder, TRUE);
324 : : }
325 : :
326 [ + + ]: 3 : if (mask & GDK_SUPER_MASK)
327 : : {
328 : 1 : json_builder_set_member_name (builder, "super");
329 : 1 : json_builder_add_boolean_value (builder, TRUE);
330 : : }
331 : :
332 : 3 : packet = valent_packet_end (&builder);
333 : :
334 [ + - ]: 3 : valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), packet);
335 : : }
336 : :
337 : : static void
338 : 2 : valent_mousepad_plugin_mousepad_request_pointer (ValentMousepadPlugin *self,
339 : : double dx,
340 : : double dy,
341 : : gboolean axis)
342 : : {
343 : 4 : g_autoptr (JsonBuilder) builder = NULL;
344 [ - + ]: 2 : g_autoptr (JsonNode) packet = NULL;
345 : :
346 [ + - ]: 2 : g_assert (VALENT_IS_MOUSEPAD_PLUGIN (self));
347 : :
348 : 2 : valent_packet_init (&builder, "kdeconnect.mousepad.request");
349 : :
350 : 2 : json_builder_set_member_name (builder, "dx");
351 : 2 : json_builder_add_double_value (builder, dx);
352 : 2 : json_builder_set_member_name (builder, "dy");
353 : 2 : json_builder_add_double_value (builder, dy);
354 : :
355 [ + + ]: 2 : if (axis)
356 : : {
357 : 1 : json_builder_set_member_name (builder, "scroll");
358 : 1 : json_builder_add_boolean_value (builder, TRUE);
359 : : }
360 : :
361 : 2 : packet = valent_packet_end (&builder);
362 : :
363 [ + - ]: 2 : valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), packet);
364 : 2 : }
365 : :
366 : : static void
367 : 0 : valent_mousepad_plugin_send_echo (ValentMousepadPlugin *self,
368 : : JsonNode *packet)
369 : : {
370 : 0 : g_autoptr (JsonBuilder) builder = NULL;
371 [ # # ]: 0 : g_autoptr (JsonNode) response = NULL;
372 : 0 : JsonObjectIter iter;
373 : 0 : const char *name;
374 : 0 : JsonNode *node;
375 : :
376 [ # # ]: 0 : g_assert (VALENT_IS_MOUSEPAD_PLUGIN (self));
377 : :
378 : 0 : valent_packet_init (&builder, "kdeconnect.mousepad.echo");
379 : :
380 : 0 : json_object_iter_init (&iter, valent_packet_get_body (packet));
381 : :
382 [ # # ]: 0 : while (json_object_iter_next (&iter, &name, &node))
383 : : {
384 [ # # ]: 0 : if (g_strcmp0 (name, "sendAck") == 0)
385 : 0 : continue;
386 : :
387 : 0 : json_builder_set_member_name (builder, name);
388 : 0 : json_builder_add_value (builder, json_node_ref (node));
389 : : }
390 : :
391 : 0 : json_builder_set_member_name (builder, "isAck");
392 : 0 : json_builder_add_boolean_value (builder, TRUE);
393 : :
394 : 0 : response = valent_packet_end (&builder);
395 : :
396 [ # # ]: 0 : valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), response);
397 : 0 : }
398 : :
399 : : static void
400 : 5 : valent_mousepad_plugin_mousepad_keyboardstate (ValentMousepadPlugin *self)
401 : : {
402 : 5 : g_autoptr (JsonBuilder) builder = NULL;
403 [ - - - + ]: 5 : g_autoptr (JsonNode) packet = NULL;
404 : :
405 [ + - - - ]: 5 : g_return_if_fail (VALENT_IS_MOUSEPAD_PLUGIN (self));
406 : :
407 : 5 : valent_packet_init (&builder, "kdeconnect.mousepad.keyboardstate");
408 : 5 : json_builder_set_member_name (builder, "state");
409 : 5 : json_builder_add_boolean_value (builder, TRUE);
410 : 5 : packet = valent_packet_end (&builder);
411 : :
412 [ + - ]: 5 : valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), packet);
413 : : }
414 : :
415 : : /*
416 : : * GActions
417 : : */
418 : : static void
419 : 16 : valent_mousepad_plugin_toggle_actions (ValentMousepadPlugin *self,
420 : : gboolean available)
421 : : {
422 : 16 : GAction *action;
423 : :
424 [ + - ]: 16 : g_assert (VALENT_IS_MOUSEPAD_PLUGIN (self));
425 : :
426 : 16 : action = g_action_map_lookup_action (G_ACTION_MAP (self), "event");
427 [ + + ]: 32 : g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
428 [ + - ]: 5 : available && self->remote_state);
429 : 16 : }
430 : :
431 : : static void
432 : 5 : mousepad_event_action (GSimpleAction *action,
433 : : GVariant *parameter,
434 : : gpointer user_data)
435 : : {
436 : 5 : ValentMousepadPlugin *self = VALENT_MOUSEPAD_PLUGIN (user_data);
437 : 5 : GVariantDict dict;
438 : 5 : double dx, dy;
439 : 5 : uint32_t keysym;
440 : :
441 [ + - ]: 5 : g_assert (VALENT_IS_MOUSEPAD_PLUGIN (self));
442 [ - + ]: 5 : g_return_if_fail (self->remote_state);
443 : :
444 : 5 : g_variant_dict_init (&dict, parameter);
445 : :
446 [ + + + - ]: 7 : if (g_variant_dict_lookup (&dict, "dx", "d", &dx) &&
447 : 2 : g_variant_dict_lookup (&dict, "dy", "d", &dy))
448 : 2 : {
449 : 2 : gboolean scroll = FALSE;
450 : :
451 : 2 : g_variant_dict_lookup (&dict, "scroll", "b", &scroll);
452 : 2 : valent_mousepad_plugin_mousepad_request_pointer (self, dx, dy, scroll);
453 : : }
454 [ + - ]: 3 : else if (g_variant_dict_lookup (&dict, "keysym", "u", &keysym))
455 : : {
456 : 3 : GdkModifierType mask = 0;
457 : :
458 : 3 : g_variant_dict_lookup (&dict, "mask", "u", &mask);
459 : 3 : valent_mousepad_plugin_mousepad_request_keyboard (self, keysym, mask);
460 : : }
461 : : else
462 : 0 : g_warning ("%s(): unknown event type", G_STRFUNC);
463 : :
464 : 5 : g_variant_dict_clear (&dict);
465 : : }
466 : :
467 : : static const GActionEntry actions[] = {
468 : : {"event", mousepad_event_action, "a{sv}", NULL, NULL}
469 : : };
470 : :
471 : : /*
472 : : * ValentDevicePlugin
473 : : */
474 : : static void
475 : 16 : valent_mousepad_plugin_update_state (ValentDevicePlugin *plugin,
476 : : ValentDeviceState state)
477 : : {
478 : 16 : ValentMousepadPlugin *self = VALENT_MOUSEPAD_PLUGIN (plugin);
479 : 16 : gboolean available;
480 : :
481 [ + - ]: 16 : g_assert (VALENT_IS_MOUSEPAD_PLUGIN (self));
482 : :
483 : 16 : available = (state & VALENT_DEVICE_STATE_CONNECTED) != 0 &&
484 : : (state & VALENT_DEVICE_STATE_PAIRED) != 0;
485 : :
486 [ + + ]: 16 : if (available)
487 : 5 : valent_mousepad_plugin_mousepad_keyboardstate (self);
488 : : else
489 : 11 : self->remote_state = FALSE;
490 : :
491 [ + - + + ]: 16 : if (!self->remote_state && self->controller != NULL)
492 : : {
493 : 2 : valent_input_unexport_adapter (self->input,
494 : : VALENT_INPUT_ADAPTER (self->controller));
495 [ + - ]: 2 : g_clear_object (&self->controller);
496 : : }
497 : :
498 : 16 : valent_mousepad_plugin_toggle_actions (self, available);
499 : 16 : }
500 : :
501 : : static void
502 : 15 : valent_mousepad_plugin_handle_packet (ValentDevicePlugin *plugin,
503 : : const char *type,
504 : : JsonNode *packet)
505 : : {
506 : 15 : ValentMousepadPlugin *self = VALENT_MOUSEPAD_PLUGIN (plugin);
507 : :
508 [ + - ]: 15 : g_assert (VALENT_IS_MOUSEPAD_PLUGIN (self));
509 [ - + ]: 15 : g_assert (type != NULL);
510 [ - + ]: 15 : g_assert (VALENT_IS_PACKET (packet));
511 : :
512 : : /* A request to simulate input */
513 [ + + ]: 15 : if (g_str_equal (type, "kdeconnect.mousepad.request"))
514 : 12 : valent_mousepad_plugin_handle_mousepad_request (self, packet);
515 : :
516 : : /* A confirmation of input we requested */
517 [ + + ]: 3 : else if (g_str_equal (type, "kdeconnect.mousepad.echo"))
518 : 1 : valent_mousepad_plugin_handle_mousepad_echo (self, packet);
519 : :
520 : : /* The remote keyboard is ready/not ready for input */
521 [ + - ]: 2 : else if (g_str_equal (type, "kdeconnect.mousepad.keyboardstate"))
522 : 2 : valent_mousepad_plugin_handle_mousepad_keyboardstate (self, packet);
523 : :
524 : : else
525 : 0 : g_assert_not_reached ();
526 : 15 : }
527 : :
528 : : /*
529 : : * ValentObject
530 : : */
531 : : static void
532 : 10 : valent_mousepad_plugin_destroy (ValentObject *object)
533 : : {
534 : 10 : ValentMousepadPlugin *self = VALENT_MOUSEPAD_PLUGIN (object);
535 : :
536 [ - + ]: 10 : if (self->controller != NULL)
537 : : {
538 : 0 : valent_input_unexport_adapter (valent_input_get_default (),
539 : : VALENT_INPUT_ADAPTER (self->controller));
540 [ # # ]: 0 : g_clear_object (&self->controller);
541 : : }
542 : :
543 : 10 : VALENT_OBJECT_CLASS (valent_mousepad_plugin_parent_class)->destroy (object);
544 : 10 : }
545 : :
546 : : /*
547 : : * GObject
548 : : */
549 : : static void
550 : 5 : valent_mousepad_plugin_constructed (GObject *object)
551 : : {
552 : 5 : ValentDevicePlugin *plugin = VALENT_DEVICE_PLUGIN (object);
553 : :
554 : 5 : g_action_map_add_action_entries (G_ACTION_MAP (plugin),
555 : : actions,
556 : : G_N_ELEMENTS (actions),
557 : : plugin);
558 : :
559 : 5 : G_OBJECT_CLASS (valent_mousepad_plugin_parent_class)->constructed (object);
560 : 5 : }
561 : :
562 : : static void
563 : 1 : valent_mousepad_plugin_class_init (ValentMousepadPluginClass *klass)
564 : : {
565 : 1 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
566 : 1 : ValentObjectClass *vobject_class = VALENT_OBJECT_CLASS (klass);
567 : 1 : ValentDevicePluginClass *plugin_class = VALENT_DEVICE_PLUGIN_CLASS (klass);
568 : :
569 : 1 : object_class->constructed = valent_mousepad_plugin_constructed;
570 : :
571 : 1 : vobject_class->destroy = valent_mousepad_plugin_destroy;
572 : :
573 : 1 : plugin_class->handle_packet = valent_mousepad_plugin_handle_packet;
574 : 1 : plugin_class->update_state = valent_mousepad_plugin_update_state;
575 : : }
576 : :
577 : : static void
578 : 5 : valent_mousepad_plugin_init (ValentMousepadPlugin *self)
579 : : {
580 : 5 : self->input = valent_input_get_default ();
581 : 5 : }
582 : :
|