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-presenter-plugin"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <glib/gi18n.h>
9 : : #include <gio/gio.h>
10 : : #include <json-glib/json-glib.h>
11 : : #include <valent.h>
12 : :
13 : : #include "valent-presenter-plugin.h"
14 : :
15 : :
16 : : struct _ValentPresenterPlugin
17 : : {
18 : : ValentDevicePlugin parent_instance;
19 : :
20 : : ValentInput *input;
21 : : };
22 : :
23 [ + + + - ]: 37 : G_DEFINE_FINAL_TYPE (ValentPresenterPlugin, valent_presenter_plugin, VALENT_TYPE_DEVICE_PLUGIN)
24 : :
25 : :
26 : : static void
27 : 2 : valent_presenter_plugin_handle_presenter (ValentPresenterPlugin *self,
28 : : JsonNode *packet)
29 : : {
30 : 2 : double dx, dy;
31 : 2 : gboolean stop;
32 : :
33 [ + - ]: 2 : g_assert (VALENT_IS_PRESENTER_PLUGIN (self));
34 [ - + ]: 2 : g_assert (VALENT_IS_PACKET (packet));
35 : :
36 : : /* NOTE: these are gyroscope motion deltas, but they're translated to pointer
37 : : * deltas due to lack of a virtual "laser pointer". */
38 [ + - + - ]: 4 : if (valent_packet_get_double (packet, "dx", &dx) &&
39 : 2 : valent_packet_get_double (packet, "dy", &dy))
40 : : {
41 : 2 : valent_input_pointer_motion (self->input, dx * 1000, dy * 1000);
42 : 4 : return;
43 : : }
44 : :
45 : : /* NOTE: this signifies that no more gyroscope deltas are incoming, so the
46 : : * "laser pointer" can be turned off. */
47 [ # # ]: 0 : if (valent_packet_get_boolean (packet, "stop", &stop))
48 : : {
49 : : VALENT_NOTE ("The \"stop\" field is not supported");
50 : : return;
51 : : }
52 : : }
53 : :
54 : : static void
55 : 1 : valent_presenter_plugin_send_motion (ValentPresenterPlugin *self,
56 : : double dx,
57 : : double dy)
58 : : {
59 : 2 : g_autoptr (JsonBuilder) builder = NULL;
60 [ - + ]: 1 : g_autoptr (JsonNode) packet = NULL;
61 : :
62 [ + - ]: 1 : g_assert (VALENT_IS_PRESENTER_PLUGIN (self));
63 : :
64 : 1 : valent_packet_init (&builder, "kdeconnect.presenter");
65 : 1 : json_builder_set_member_name (builder, "dx");
66 : 1 : json_builder_add_double_value (builder, dx);
67 : 1 : json_builder_set_member_name (builder, "dy");
68 : 1 : json_builder_add_double_value (builder, dy);
69 : 1 : packet = valent_packet_end (&builder);
70 : :
71 [ + - ]: 1 : valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), packet);
72 : 1 : }
73 : :
74 : : static void
75 : 1 : valent_presenter_plugin_send_stop (ValentPresenterPlugin *self)
76 : : {
77 : 2 : g_autoptr (JsonBuilder) builder = NULL;
78 [ - + ]: 1 : g_autoptr (JsonNode) packet = NULL;
79 : :
80 [ + - ]: 1 : g_assert (VALENT_IS_PRESENTER_PLUGIN (self));
81 : :
82 : 1 : valent_packet_init (&builder, "kdeconnect.presenter");
83 : 1 : json_builder_set_member_name (builder, "stop");
84 : 1 : json_builder_add_boolean_value (builder, TRUE);
85 : 1 : packet = valent_packet_end (&builder);
86 : :
87 [ + - ]: 1 : valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), packet);
88 : 1 : }
89 : :
90 : : /*
91 : : * GActions
92 : : */
93 : : static void
94 : 13 : valent_presenter_plugin_toggle_actions (ValentPresenterPlugin *self,
95 : : gboolean available)
96 : : {
97 : 13 : GAction *action;
98 : :
99 [ + - ]: 13 : g_assert (VALENT_IS_PRESENTER_PLUGIN (self));
100 : :
101 : 13 : action = g_action_map_lookup_action (G_ACTION_MAP (self), "pointer");
102 : 13 : g_simple_action_set_enabled (G_SIMPLE_ACTION (action), available);
103 : 13 : }
104 : :
105 : : static void
106 : 2 : presenter_pointer_action (GSimpleAction *action,
107 : : GVariant *parameter,
108 : : gpointer user_data)
109 : : {
110 : 2 : ValentPresenterPlugin *self = VALENT_PRESENTER_PLUGIN (user_data);
111 : 2 : double dx = 0.0;
112 : 2 : double dy = 0.0;
113 : 2 : unsigned int mask = 0;
114 : :
115 [ + - ]: 2 : g_assert (VALENT_IS_PRESENTER_PLUGIN (self));
116 : :
117 : 2 : g_variant_get (parameter, "(ddu)", &dx, &dy, &mask);
118 : :
119 [ + + - + : 2 : if (!G_APPROX_VALUE (dx, 0.0, 0.01) || !G_APPROX_VALUE (dy, 0.0, 0.01))
+ - - + -
- - + ]
120 : 1 : valent_presenter_plugin_send_motion (self, dx, dy);
121 : :
122 [ + + ]: 2 : if (mask != 0)
123 : 1 : valent_presenter_plugin_send_stop (self);
124 : 2 : }
125 : :
126 : : static const GActionEntry actions[] = {
127 : : {"pointer", presenter_pointer_action, "(ddu)", NULL, NULL}
128 : : };
129 : :
130 : : /*
131 : : * ValentDevicePlugin
132 : : */
133 : : static void
134 : 13 : valent_presenter_plugin_update_state (ValentDevicePlugin *plugin,
135 : : ValentDeviceState state)
136 : : {
137 : 13 : ValentPresenterPlugin *self = VALENT_PRESENTER_PLUGIN (plugin);
138 : :
139 : 13 : gboolean available;
140 : :
141 [ + - ]: 13 : g_assert (VALENT_IS_PRESENTER_PLUGIN (self));
142 : :
143 : 13 : available = (state & VALENT_DEVICE_STATE_CONNECTED) != 0 &&
144 : : (state & VALENT_DEVICE_STATE_PAIRED) != 0;
145 : :
146 : 13 : valent_presenter_plugin_toggle_actions (self, available);
147 : 13 : }
148 : :
149 : : static void
150 : 2 : valent_presenter_plugin_handle_packet (ValentDevicePlugin *plugin,
151 : : const char *type,
152 : : JsonNode *packet)
153 : : {
154 : 2 : ValentPresenterPlugin *self = VALENT_PRESENTER_PLUGIN (plugin);
155 : :
156 [ + - ]: 2 : g_assert (VALENT_IS_PRESENTER_PLUGIN (self));
157 [ - + ]: 2 : g_assert (type != NULL);
158 [ - + ]: 2 : g_assert (VALENT_IS_PACKET (packet));
159 : :
160 [ + - ]: 2 : if (g_str_equal (type, "kdeconnect.presenter"))
161 : 2 : valent_presenter_plugin_handle_presenter (self, packet);
162 : : else
163 : 2 : g_assert_not_reached ();
164 : 2 : }
165 : :
166 : : /*
167 : : * GObject
168 : : */
169 : : static void
170 : 4 : valent_presenter_plugin_constructed (GObject *object)
171 : : {
172 : 4 : ValentPresenterPlugin *self = VALENT_PRESENTER_PLUGIN (object);
173 : 4 : ValentDevicePlugin *plugin = VALENT_DEVICE_PLUGIN (object);
174 : :
175 : 4 : self->input = valent_input_get_default ();
176 : 4 : g_action_map_add_action_entries (G_ACTION_MAP (plugin),
177 : : actions,
178 : : G_N_ELEMENTS (actions),
179 : : plugin);
180 : :
181 : 4 : G_OBJECT_CLASS (valent_presenter_plugin_parent_class)->constructed (object);
182 : 4 : }
183 : :
184 : : static void
185 : 1 : valent_presenter_plugin_class_init (ValentPresenterPluginClass *klass)
186 : : {
187 : 1 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
188 : 1 : ValentDevicePluginClass *plugin_class = VALENT_DEVICE_PLUGIN_CLASS (klass);
189 : :
190 : 1 : object_class->constructed = valent_presenter_plugin_constructed;
191 : :
192 : 1 : plugin_class->handle_packet = valent_presenter_plugin_handle_packet;
193 : 1 : plugin_class->update_state = valent_presenter_plugin_update_state;
194 : : }
195 : :
196 : : static void
197 : 4 : valent_presenter_plugin_init (ValentPresenterPlugin *self)
198 : : {
199 : 4 : }
200 : :
|