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-device"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <gio/gio.h>
9 : : #include <gdk/gdk.h>
10 : : #include <gtk/gtk.h>
11 : : #include <valent.h>
12 : :
13 : : #include "valent-mousepad-device.h"
14 : : #include "valent-mousepad-keydef.h"
15 : :
16 : : #define DEFAULT_DOUBLE_CLICK_TIME (400)
17 : : #define DEFAULT_LONG_PRESS_TIME (500)
18 : :
19 : :
20 : : struct _ValentMousepadDevice
21 : : {
22 : : ValentInputAdapter parent_instance;
23 : :
24 : : ValentDevice *device;
25 : : GtkSettings *settings;
26 : :
27 : : /* keyboard */
28 : : GArray *keyboard_keys;
29 : : GdkModifierType keyboard_modifiers;
30 : : unsigned int keyboard_flush_id;
31 : :
32 : : /* pointer */
33 : : unsigned int pointer_button;
34 : : unsigned int pointer_presses;
35 : : unsigned int pointer_releases;
36 : : unsigned int pointer_doubleclick_id;
37 : : unsigned int pointer_longpress_id;
38 : :
39 : : int double_click_time;
40 : : int long_press_time;
41 : : };
42 : :
43 [ + + + - ]: 6 : G_DEFINE_FINAL_TYPE (ValentMousepadDevice, valent_mousepad_device, VALENT_TYPE_INPUT_ADAPTER)
44 : :
45 : :
46 : : enum {
47 : : PROP_0,
48 : : PROP_DEVICE,
49 : : N_PROPERTIES
50 : : };
51 : :
52 : : static GParamSpec *properties[N_PROPERTIES] = { NULL, };
53 : :
54 : :
55 : : /*
56 : : * Keyboard
57 : : */
58 : : static inline gboolean
59 : 0 : valent_mousepad_device_update_modifiers (ValentMousepadDevice *self,
60 : : uint32_t keysym,
61 : : gboolean state)
62 : : {
63 [ # # # # : 0 : switch (keysym)
# # ]
64 : : {
65 : 0 : case GDK_KEY_Alt_L:
66 : : case GDK_KEY_Alt_R:
67 : 0 : self->keyboard_modifiers = state
68 : 0 : ? self->keyboard_modifiers | GDK_ALT_MASK
69 [ # # ]: 0 : : self->keyboard_modifiers & ~GDK_ALT_MASK;
70 : 0 : return TRUE;
71 : :
72 : 0 : case GDK_KEY_Control_L:
73 : : case GDK_KEY_Control_R:
74 : 0 : self->keyboard_modifiers = state
75 : 0 : ? self->keyboard_modifiers | GDK_CONTROL_MASK
76 [ # # ]: 0 : : self->keyboard_modifiers & ~GDK_CONTROL_MASK;
77 : 0 : return TRUE;
78 : :
79 : 0 : case GDK_KEY_Shift_L:
80 : : case GDK_KEY_Shift_R:
81 : 0 : self->keyboard_modifiers = state
82 : 0 : ? self->keyboard_modifiers | GDK_SHIFT_MASK
83 [ # # ]: 0 : : self->keyboard_modifiers & ~GDK_SHIFT_MASK;
84 : 0 : return TRUE;
85 : :
86 : 0 : case GDK_KEY_Super_L:
87 : : case GDK_KEY_Super_R:
88 : 0 : self->keyboard_modifiers = state
89 : 0 : ? self->keyboard_modifiers | GDK_SUPER_MASK
90 [ # # ]: 0 : : self->keyboard_modifiers & ~GDK_SUPER_MASK;
91 : 0 : return TRUE;
92 : :
93 : : /* Return TRUE for known modifiers, even if unsupported */
94 : : case GDK_KEY_Overlay1_Enable:
95 : : case GDK_KEY_Overlay2_Enable:
96 : : case GDK_KEY_Caps_Lock:
97 : : case GDK_KEY_Shift_Lock:
98 : : case GDK_KEY_Meta_L:
99 : : case GDK_KEY_Meta_R:
100 : : case GDK_KEY_Hyper_L:
101 : : case GDK_KEY_Hyper_R:
102 : : case GDK_KEY_Mode_switch:
103 : : case GDK_KEY_ISO_Level3_Shift:
104 : : case GDK_KEY_ISO_Level3_Latch:
105 : : case GDK_KEY_ISO_Level5_Shift:
106 : : case GDK_KEY_ISO_Level5_Latch:
107 : : VALENT_NOTE ("skipping %s", gdk_keyval_name (keysym));
108 : : return TRUE;
109 : :
110 : : default:
111 : : return FALSE;
112 : : }
113 : : }
114 : :
115 : : static gboolean
116 : 0 : valent_mousepad_device_keyboard_flush (gpointer data)
117 : : {
118 : 0 : ValentMousepadDevice *self = VALENT_MOUSEPAD_DEVICE (data);
119 : 0 : g_autoptr (JsonBuilder) builder = NULL;
120 [ # # ]: 0 : g_autoptr (JsonNode) packet = NULL;
121 [ # # ]: 0 : g_autoptr (GString) key = NULL;
122 : 0 : uint32_t special_key = 0;
123 : 0 : unsigned int n_handled = 0;
124 : :
125 [ # # ]: 0 : if (self->keyboard_keys->len == 0)
126 : : {
127 : 0 : self->keyboard_flush_id = 0;
128 : 0 : return G_SOURCE_REMOVE;
129 : : }
130 : :
131 [ # # ]: 0 : for (unsigned int len = self->keyboard_keys->len; n_handled < len; n_handled++)
132 : : {
133 : 0 : uint32_t *keysym = &g_array_index (self->keyboard_keys, uint32_t, n_handled);
134 : :
135 [ # # ]: 0 : if ((special_key = valent_mousepad_keyval_to_keycode (*keysym)) != 0)
136 : : {
137 : : /* If there are keys to be sent, they need to be sent first */
138 [ # # ]: 0 : if (key != NULL)
139 : 0 : special_key = 0;
140 : :
141 : : /* Otherwise, we need to send the current key and modifiers */
142 : 0 : n_handled++;
143 : 0 : break;
144 : : }
145 : : else
146 : : {
147 : 0 : gunichar wc = gdk_keyval_to_unicode (*keysym);
148 : :
149 [ # # ]: 0 : if (wc == 0)
150 : : {
151 : 0 : g_debug ("%s(): failed to convert keysym \"%u\" to unicode",
152 : : G_STRFUNC, *keysym);
153 : 0 : continue;
154 : : }
155 : :
156 [ # # ]: 0 : if (key == NULL)
157 : 0 : key = g_string_new (NULL);
158 : :
159 : 0 : g_string_append_unichar (key, wc);
160 : : }
161 : : }
162 : 0 : g_array_remove_range (self->keyboard_keys, 0, n_handled);
163 : :
164 : : /* Build the packet */
165 : 0 : valent_packet_init (&builder, "kdeconnect.mousepad.request");
166 : :
167 [ # # ]: 0 : if (key != NULL)
168 : : {
169 : 0 : json_builder_set_member_name (builder, "key");
170 : 0 : json_builder_add_string_value (builder, key->str);
171 : : }
172 [ # # ]: 0 : else if (special_key != 0)
173 : : {
174 : 0 : json_builder_set_member_name (builder, "specialKey");
175 : 0 : json_builder_add_int_value (builder, special_key);
176 : : }
177 : :
178 : : /* Check our supported modifiers */
179 [ # # ]: 0 : if ((self->keyboard_modifiers & GDK_ALT_MASK) != 0)
180 : : {
181 : 0 : json_builder_set_member_name (builder, "alt");
182 : 0 : json_builder_add_boolean_value (builder, TRUE);
183 : : }
184 : :
185 [ # # ]: 0 : if ((self->keyboard_modifiers & GDK_CONTROL_MASK) != 0)
186 : : {
187 : 0 : json_builder_set_member_name (builder, "ctrl");
188 : 0 : json_builder_add_boolean_value (builder, TRUE);
189 : : }
190 : :
191 [ # # ]: 0 : if ((self->keyboard_modifiers & GDK_SHIFT_MASK) != 0)
192 : : {
193 : 0 : json_builder_set_member_name (builder, "shift");
194 : 0 : json_builder_add_boolean_value (builder, TRUE);
195 : : }
196 : :
197 [ # # ]: 0 : if ((self->keyboard_modifiers & GDK_SUPER_MASK) != 0)
198 : : {
199 : 0 : json_builder_set_member_name (builder, "super");
200 : 0 : json_builder_add_boolean_value (builder, TRUE);
201 : : }
202 : :
203 : : /* Request acknowledgment of the event (disabled until it can be received) */
204 : : #if 0
205 : : json_builder_set_member_name (builder, "sendAck");
206 : : json_builder_add_boolean_value (builder, TRUE);
207 : : #endif
208 : :
209 : 0 : packet = valent_packet_end (&builder);
210 : 0 : valent_device_send_packet (self->device, packet, NULL, NULL, NULL);
211 : :
212 : : /* Clear the source if there's nothing left queued */
213 [ # # ]: 0 : if (self->keyboard_keys->len == 0)
214 : : {
215 : 0 : self->keyboard_flush_id = 0;
216 : 0 : return G_SOURCE_REMOVE;
217 : : }
218 : :
219 : : return G_SOURCE_CONTINUE;
220 : : }
221 : :
222 : : static inline void
223 : 2 : valent_mousepad_device_keyboard_reset (ValentMousepadDevice *self)
224 : : {
225 [ + - ]: 2 : g_assert (VALENT_IS_MOUSEPAD_DEVICE (self));
226 : :
227 : 2 : g_array_remove_range (self->keyboard_keys, 0, self->keyboard_keys->len);
228 [ - + ]: 2 : g_clear_handle_id (&self->keyboard_flush_id, g_source_remove);
229 : 2 : }
230 : :
231 : : /*
232 : : * Pointer
233 : : */
234 : : static inline gboolean
235 : 2 : valent_mousepad_device_pointer_reset (ValentMousepadDevice *self)
236 : : {
237 : 2 : self->pointer_button = 0;
238 : 2 : self->pointer_presses = 0;
239 : 2 : self->pointer_releases = 0;
240 [ - + ]: 2 : g_clear_handle_id (&self->pointer_doubleclick_id, g_source_remove);
241 [ - + ]: 2 : g_clear_handle_id (&self->pointer_longpress_id, g_source_remove);
242 : :
243 : 2 : return G_SOURCE_REMOVE;
244 : : }
245 : :
246 : : static inline gboolean
247 : 0 : valent_mousepad_device_pointer_flush (gpointer data)
248 : : {
249 : 0 : ValentMousepadDevice *self = VALENT_MOUSEPAD_DEVICE (data);
250 : 0 : g_autoptr (JsonBuilder) builder = NULL;
251 [ # # ]: 0 : g_autoptr (JsonNode) packet = NULL;
252 : :
253 [ # # ]: 0 : g_assert (VALENT_IS_MOUSEPAD_DEVICE (self));
254 : :
255 : : /* Ignore unpaired releases */
256 [ # # ]: 0 : if (self->pointer_presses < self->pointer_releases)
257 : 0 : return valent_mousepad_device_pointer_reset (self);
258 : :
259 [ # # # # ]: 0 : if (self->pointer_presses == 1 && self->pointer_releases == 1)
260 : : {
261 : 0 : valent_packet_init (&builder, "kdeconnect.mousepad.request");
262 : :
263 [ # # # # ]: 0 : switch (self->pointer_button)
264 : : {
265 : 0 : case VALENT_POINTER_PRIMARY:
266 : 0 : json_builder_set_member_name (builder, "singleclick");
267 : 0 : json_builder_add_boolean_value (builder, TRUE);
268 : 0 : break;
269 : :
270 : 0 : case VALENT_POINTER_MIDDLE:
271 : 0 : json_builder_set_member_name (builder, "middleclick");
272 : 0 : json_builder_add_boolean_value (builder, TRUE);
273 : 0 : break;
274 : :
275 : 0 : case VALENT_POINTER_SECONDARY:
276 : 0 : json_builder_set_member_name (builder, "rightclick");
277 : 0 : json_builder_add_boolean_value (builder, TRUE);
278 : 0 : break;
279 : :
280 : 0 : default:
281 : 0 : g_debug ("%s: unknown pointer button %u",
282 : : G_STRFUNC,
283 : : self->pointer_button);
284 : : }
285 : :
286 : 0 : packet = valent_packet_end (&builder);
287 : : }
288 [ # # ]: 0 : else if (self->pointer_button == VALENT_POINTER_PRIMARY && self->pointer_presses == 2)
289 : : {
290 : 0 : valent_packet_init (&builder, "kdeconnect.mousepad.request");
291 : 0 : json_builder_set_member_name (builder, "doubleclick");
292 : 0 : json_builder_add_boolean_value (builder, TRUE);
293 : 0 : packet = valent_packet_end (&builder);
294 : : }
295 : :
296 [ # # ]: 0 : if (packet != NULL)
297 : : {
298 : 0 : valent_device_send_packet (self->device, packet, NULL, NULL, NULL);
299 : 0 : valent_mousepad_device_pointer_reset (self);
300 : : }
301 : :
302 : 0 : return G_SOURCE_REMOVE;
303 : : }
304 : :
305 : : static inline gboolean
306 : 0 : valent_mousepad_device_pointer_longpress (gpointer data)
307 : : {
308 : 0 : ValentMousepadDevice *self = VALENT_MOUSEPAD_DEVICE (data);
309 : 0 : g_autoptr (JsonBuilder) builder = NULL;
310 [ # # ]: 0 : g_autoptr (JsonNode) packet = NULL;
311 : :
312 [ # # ]: 0 : g_assert (VALENT_IS_MOUSEPAD_DEVICE (self));
313 : :
314 : 0 : valent_packet_init (&builder, "kdeconnect.mousepad.request");
315 : 0 : json_builder_set_member_name (builder, "singlehold");
316 : 0 : json_builder_add_boolean_value (builder, TRUE);
317 : 0 : packet = valent_packet_end (&builder);
318 : :
319 : 0 : valent_device_send_packet (self->device, packet, NULL, NULL, NULL);
320 : :
321 [ # # ]: 0 : return valent_mousepad_device_pointer_reset (self);
322 : : }
323 : :
324 : : static void
325 : 0 : on_pointer_settings_changed (GtkSettings *settings,
326 : : GParamSpec *pspec,
327 : : ValentMousepadDevice *self)
328 : : {
329 [ # # ]: 0 : g_assert (VALENT_IS_MOUSEPAD_DEVICE (self));
330 : :
331 : 0 : g_object_get (settings,
332 : : "gtk-double-click-time", &self->double_click_time,
333 : : "gtk-long-press-time", &self->long_press_time,
334 : : NULL);
335 : 0 : }
336 : :
337 : : /*
338 : : * ValentInputAdapter
339 : : */
340 : : static void
341 : 0 : valent_mousepad_device_keyboard_keysym (ValentInputAdapter *adapter,
342 : : uint32_t keysym,
343 : : gboolean state)
344 : : {
345 : 0 : ValentMousepadDevice *self = VALENT_MOUSEPAD_DEVICE (adapter);
346 : :
347 [ # # ]: 0 : g_assert (VALENT_IS_MOUSEPAD_DEVICE (self));
348 [ # # ]: 0 : g_return_if_fail (keysym != 0);
349 : :
350 : : /* Track modifiers, but don't send anything */
351 [ # # ]: 0 : if (valent_mousepad_device_update_modifiers (self, keysym, state))
352 : : return;
353 : :
354 : : // TODO: the KDE Connect protocol doesn't support press and release states
355 : : // for keyboard input, so only key presses are sent. A solution might
356 : : // involve matching presses and releases, or an extant convention.
357 [ # # ]: 0 : if (!state)
358 : : return;
359 : :
360 : 0 : g_array_append_val (self->keyboard_keys, keysym);
361 : :
362 : : /* If there are modifiers set, the key should be sent immediately */
363 [ # # ]: 0 : if ((self->keyboard_modifiers & GDK_MODIFIER_MASK) != 0)
364 : : {
365 : 0 : valent_mousepad_device_keyboard_flush (self);
366 : 0 : return;
367 : : }
368 : :
369 : : /* Flush in an idle callback, in case key presses can be sent as a string */
370 [ # # ]: 0 : if (self->keyboard_flush_id == 0)
371 : 0 : self->keyboard_flush_id = g_idle_add (valent_mousepad_device_keyboard_flush,
372 : : self);
373 : : }
374 : :
375 : : static void
376 : 0 : valent_mousepad_device_pointer_axis (ValentInputAdapter *adapter,
377 : : double dx,
378 : : double dy)
379 : : {
380 : 0 : ValentMousepadDevice *self = VALENT_MOUSEPAD_DEVICE (adapter);
381 : 0 : g_autoptr (JsonBuilder) builder = NULL;
382 [ # # ]: 0 : g_autoptr (JsonNode) packet = NULL;
383 : :
384 [ # # ]: 0 : g_assert (VALENT_IS_MOUSEPAD_DEVICE (self));
385 : :
386 : 0 : valent_packet_init (&builder, "kdeconnect.mousepad.request");
387 : 0 : json_builder_set_member_name (builder, "dx");
388 : 0 : json_builder_add_double_value (builder, dx);
389 : 0 : json_builder_set_member_name (builder, "dy");
390 : 0 : json_builder_add_double_value (builder, dy);
391 : 0 : json_builder_set_member_name (builder, "scroll");
392 : 0 : json_builder_add_boolean_value (builder, TRUE);
393 : 0 : packet = valent_packet_end (&builder);
394 : :
395 [ # # ]: 0 : valent_device_send_packet (self->device, packet, NULL, NULL, NULL);
396 : 0 : }
397 : :
398 : : static void
399 : 0 : valent_mousepad_device_pointer_button (ValentInputAdapter *adapter,
400 : : unsigned int button,
401 : : gboolean state)
402 : : {
403 : 0 : ValentMousepadDevice *self = VALENT_MOUSEPAD_DEVICE (adapter);
404 : :
405 [ # # ]: 0 : if (self->pointer_button != button)
406 : : {
407 : 0 : self->pointer_button = button;
408 : 0 : self->pointer_presses = 0;
409 : 0 : self->pointer_releases = 0;
410 : : }
411 : :
412 [ # # ]: 0 : if (state)
413 : : {
414 : 0 : self->pointer_presses += 1;
415 : :
416 : : /* Any button press removes the double click timer; the event will either
417 : : * be accepted or rejected based on the current button state. */
418 [ # # ]: 0 : g_clear_handle_id (&self->pointer_doubleclick_id, g_source_remove);
419 : : }
420 : : else
421 : : {
422 : 0 : self->pointer_releases += 1;
423 : : }
424 : :
425 : : /* Any button event removes the long press timer; the event is accepted if the
426 : : * timeout elapses with the primary button being the only button pressed. */
427 [ # # ]: 0 : g_clear_handle_id (&self->pointer_longpress_id, g_source_remove);
428 : :
429 : : /* Handle the first press and release for the primary button, to prevent
430 : : * flushing the double click state on the first release. */
431 [ # # ]: 0 : if (self->pointer_button == VALENT_POINTER_PRIMARY && self->pointer_presses == 1)
432 : : {
433 : : /* Double click and long press events both start with the press event */
434 [ # # ]: 0 : if (self->pointer_releases == 0)
435 : : {
436 : : // TODO: what if double-click time < long-press time?
437 : : /* If the timeout elapses, a "singleclick" packet will be sent */
438 : 0 : self->pointer_doubleclick_id =
439 : 0 : g_timeout_add (self->double_click_time,
440 : : valent_mousepad_device_pointer_flush,
441 : : self);
442 : 0 : g_source_set_name_by_id (self->pointer_doubleclick_id,
443 : : "valent_mousepad_device_pointer_flush");
444 : :
445 : : /* If the timeout elapses, a "singlehold" packet will be sent */
446 : 0 : self->pointer_longpress_id =
447 : 0 : g_timeout_add (self->long_press_time,
448 : : valent_mousepad_device_pointer_longpress,
449 : : self);
450 : 0 : g_source_set_name_by_id (self->pointer_longpress_id,
451 : : "valent_mousepad_device_pointer_longpress");
452 : : }
453 : : }
454 : : else
455 : : {
456 : 0 : valent_mousepad_device_pointer_flush (self);
457 : : }
458 : 0 : }
459 : :
460 : : static void
461 : 0 : valent_mousepad_device_pointer_motion (ValentInputAdapter *adapter,
462 : : double dx,
463 : : double dy)
464 : : {
465 : 0 : ValentMousepadDevice *self = VALENT_MOUSEPAD_DEVICE (adapter);
466 : 0 : g_autoptr (JsonBuilder) builder = NULL;
467 [ # # ]: 0 : g_autoptr (JsonNode) packet = NULL;
468 : :
469 [ # # ]: 0 : g_assert (VALENT_IS_MOUSEPAD_DEVICE (self));
470 : :
471 : 0 : valent_packet_init (&builder, "kdeconnect.mousepad.request");
472 : 0 : json_builder_set_member_name (builder, "dx");
473 : 0 : json_builder_add_double_value (builder, dx);
474 : 0 : json_builder_set_member_name (builder, "dy");
475 : 0 : json_builder_add_double_value (builder, dy);
476 : 0 : packet = valent_packet_end (&builder);
477 : :
478 : 0 : valent_device_send_packet (self->device, packet, NULL, NULL, NULL);
479 [ # # ]: 0 : valent_mousepad_device_pointer_reset (self);
480 : 0 : }
481 : :
482 : : #if 0
483 : : static void
484 : : valent_mousepad_device_pointer_release (ValentInputRemote *self)
485 : : {
486 : : g_autoptr (JsonBuilder) builder = NULL;
487 : : g_autoptr (JsonNode) packet = NULL;
488 : :
489 : : valent_packet_init (&builder, "kdeconnect.mousepad.request");
490 : : json_builder_set_member_name (builder, "singlerelease");
491 : : json_builder_add_boolean_value (builder, TRUE);
492 : : packet = valent_packet_end (&builder);
493 : :
494 : : valent_device_send_packet (self->device, packet, NULL, NULL, NULL);
495 : : }
496 : : #endif
497 : :
498 : : /*
499 : : * ValentObject
500 : : */
501 : : static void
502 : 2 : valent_mousepad_device_destroy (ValentObject *object)
503 : : {
504 : 2 : ValentMousepadDevice *self = VALENT_MOUSEPAD_DEVICE (object);
505 : :
506 [ - + ]: 2 : if (self->settings != NULL)
507 : : {
508 : 0 : g_signal_handlers_disconnect_by_data (self->settings, self);
509 : 0 : self->settings = NULL;
510 : : }
511 : :
512 : 2 : valent_mousepad_device_keyboard_reset (self);
513 : 2 : valent_mousepad_device_pointer_reset (self);
514 : :
515 : 2 : VALENT_OBJECT_CLASS (valent_mousepad_device_parent_class)->destroy (object);
516 : 2 : }
517 : :
518 : : /*
519 : : * GObject
520 : : */
521 : : static void
522 : 2 : valent_mousepad_device_finalize (GObject *object)
523 : : {
524 : 2 : ValentMousepadDevice *self = VALENT_MOUSEPAD_DEVICE (object);
525 : :
526 [ + - ]: 2 : g_clear_object (&self->device);
527 [ + - ]: 2 : g_clear_pointer (&self->keyboard_keys, g_array_unref);
528 : :
529 : 2 : G_OBJECT_CLASS (valent_mousepad_device_parent_class)->finalize (object);
530 : 2 : }
531 : :
532 : : static void
533 : 0 : valent_mousepad_device_get_property (GObject *object,
534 : : guint prop_id,
535 : : GValue *value,
536 : : GParamSpec *pspec)
537 : : {
538 : 0 : ValentMousepadDevice *self = VALENT_MOUSEPAD_DEVICE (object);
539 : :
540 [ # # ]: 0 : switch (prop_id)
541 : : {
542 : 0 : case PROP_DEVICE:
543 : 0 : g_value_set_object (value, self->device);
544 : 0 : break;
545 : :
546 : 0 : default:
547 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
548 : : }
549 : 0 : }
550 : :
551 : : static void
552 : 2 : valent_mousepad_device_set_property (GObject *object,
553 : : guint prop_id,
554 : : const GValue *value,
555 : : GParamSpec *pspec)
556 : : {
557 : 2 : ValentMousepadDevice *self = VALENT_MOUSEPAD_DEVICE (object);
558 : :
559 [ + - ]: 2 : switch (prop_id)
560 : : {
561 : 2 : case PROP_DEVICE:
562 : 2 : self->device = g_value_dup_object (value);
563 : 2 : break;
564 : :
565 : 0 : default:
566 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
567 : : }
568 : 2 : }
569 : :
570 : : static void
571 : 1 : valent_mousepad_device_class_init (ValentMousepadDeviceClass *klass)
572 : : {
573 : 1 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
574 : 1 : ValentObjectClass *vobject_class = VALENT_OBJECT_CLASS (klass);
575 : 1 : ValentInputAdapterClass *input_class = VALENT_INPUT_ADAPTER_CLASS (klass);
576 : 1 : object_class->finalize = valent_mousepad_device_finalize;
577 : 1 : object_class->get_property = valent_mousepad_device_get_property;
578 : 1 : object_class->set_property = valent_mousepad_device_set_property;
579 : :
580 : 1 : vobject_class->destroy = valent_mousepad_device_destroy;
581 : :
582 : 1 : input_class->keyboard_keysym = valent_mousepad_device_keyboard_keysym;
583 : 1 : input_class->pointer_axis = valent_mousepad_device_pointer_axis;
584 : 1 : input_class->pointer_button = valent_mousepad_device_pointer_button;
585 : 1 : input_class->pointer_motion = valent_mousepad_device_pointer_motion;
586 : :
587 : : /**
588 : : * ValentMousepadDevice:device:
589 : : *
590 : : * The [class@Valent.Device] this controller is for.
591 : : */
592 : 2 : properties [PROP_DEVICE] =
593 : 1 : g_param_spec_object ("device", NULL, NULL,
594 : : VALENT_TYPE_DEVICE,
595 : : (G_PARAM_READWRITE |
596 : : G_PARAM_CONSTRUCT_ONLY |
597 : : G_PARAM_EXPLICIT_NOTIFY |
598 : : G_PARAM_STATIC_STRINGS));
599 : :
600 : 1 : g_object_class_install_properties (object_class, N_PROPERTIES, properties);
601 : 1 : }
602 : :
603 : : static void
604 : 2 : valent_mousepad_device_init (ValentMousepadDevice *self)
605 : : {
606 : 2 : self->keyboard_keys = g_array_new (FALSE, FALSE, sizeof (uint32_t));
607 : 2 : self->double_click_time = DEFAULT_DOUBLE_CLICK_TIME;
608 : 2 : self->long_press_time = DEFAULT_LONG_PRESS_TIME;
609 : :
610 [ - + ]: 2 : if (gtk_is_initialized ())
611 : : {
612 : 0 : self->settings = gtk_settings_get_default ();
613 : 0 : g_signal_connect_object (self->settings,
614 : : "notify::gtk-double-click-time",
615 : : G_CALLBACK (on_pointer_settings_changed),
616 : : self, 0);
617 : 0 : on_pointer_settings_changed (self->settings, NULL, self);
618 : : }
619 : 2 : }
620 : :
621 : : /**
622 : : * valent_mousepad_device_new:
623 : : * @device: a `ValentDevice`
624 : : *
625 : : * Get the `ValentMousepadDevice` instance.
626 : : *
627 : : * Returns: (transfer full) (nullable): a `ValentMousepadDevice`
628 : : */
629 : : ValentMousepadDevice *
630 : 0 : valent_mousepad_device_new (ValentDevice *device)
631 : : {
632 : 0 : return g_object_new (VALENT_TYPE_MOUSEPAD_DEVICE,
633 : : "device", device,
634 : : NULL);
635 : : }
636 : :
637 : : /**
638 : : * valent_media_player_update_packet:
639 : : * @player: a `ValentMousepadDevice`
640 : : * @packet: a KDE Connect packet
641 : : *
642 : : * A convenience method for updating the internal state of the player from a
643 : : * `kdeconnect.mousepad` packet.
644 : : */
645 : : void
646 : 0 : valent_mousepad_device_handle_packet (ValentMousepadDevice *player,
647 : : JsonNode *packet)
648 : : {
649 : 0 : }
|