GCC Code Coverage Report


Directory: ./
File: panels/wacom/cc-wacom-tool.c
Date: 2024-05-04 07:58:27
Exec Total Coverage
Lines: 0 152 0.0%
Functions: 0 21 0.0%
Branches: 0 82 0.0%

Line Branch Exec Source
1 /*
2 * Copyright © 2016 Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Carlos Garnacho <carlosg@gnome.org>
18 *
19 */
20
21 #include "config.h"
22
23 #include "cc-wacom-tool.h"
24
25 #include <glib/gi18n.h>
26
27 enum {
28 PROP_0,
29 PROP_SERIAL,
30 PROP_ID,
31 PROP_DEVICE,
32 N_PROPS
33 };
34
35 static GParamSpec *props[N_PROPS] = { 0 };
36
37 typedef struct _CcWacomTool CcWacomTool;
38
39 struct _CcWacomTool {
40 GObject parent_instance;
41 guint64 serial;
42 guint64 id;
43
44 CcWacomDevice *device; /* Only set for tools with no serial */
45
46 GSettings *settings;
47 const WacomStylus *wstylus;
48 };
49
50 static void cc_wacom_tool_initable_iface_init (GInitableIface *iface);
51
52 G_DEFINE_TYPE_WITH_CODE (CcWacomTool, cc_wacom_tool, G_TYPE_OBJECT,
53 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
54 cc_wacom_tool_initable_iface_init))
55
56 static void
57 cc_wacom_tool_init (CcWacomTool *tool)
58 {
59 }
60
61 static void
62 cc_wacom_tool_set_property (GObject *object,
63 guint prop_id,
64 const GValue *value,
65 GParamSpec *pspec)
66 {
67 CcWacomTool *tool = CC_WACOM_TOOL (object);
68
69 switch (prop_id) {
70 case PROP_SERIAL:
71 tool->serial = g_value_get_uint64 (value);
72 break;
73 case PROP_ID:
74 tool->id = g_value_get_uint64 (value);
75 break;
76 case PROP_DEVICE:
77 tool->device = g_value_get_object (value);
78 break;
79 default:
80 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
81 break;
82 }
83 }
84
85 static void
86 cc_wacom_tool_get_property (GObject *object,
87 guint prop_id,
88 GValue *value,
89 GParamSpec *pspec)
90 {
91 CcWacomTool *tool = CC_WACOM_TOOL (object);
92
93 switch (prop_id) {
94 case PROP_SERIAL:
95 g_value_set_uint64 (value, tool->serial);
96 break;
97 case PROP_ID:
98 g_value_set_uint64 (value, tool->id);
99 break;
100 case PROP_DEVICE:
101 g_value_set_object (value, tool->device);
102 break;
103 default:
104 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
105 break;
106 }
107 }
108
109 static void
110 cc_wacom_tool_finalize (GObject *object)
111 {
112 CcWacomTool *tool = CC_WACOM_TOOL (object);
113
114 g_clear_object (&tool->settings);
115
116 G_OBJECT_CLASS (cc_wacom_tool_parent_class)->finalize (object);
117 }
118
119 static void
120 cc_wacom_tool_class_init (CcWacomToolClass *klass)
121 {
122 GObjectClass *object_class = G_OBJECT_CLASS (klass);
123
124 object_class->set_property = cc_wacom_tool_set_property;
125 object_class->get_property = cc_wacom_tool_get_property;
126 object_class->finalize = cc_wacom_tool_finalize;
127
128 props[PROP_SERIAL] =
129 g_param_spec_uint64 ("serial",
130 "serial",
131 "serial",
132 0, G_MAXUINT64, 0,
133 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
134 props[PROP_ID] =
135 g_param_spec_uint64 ("id",
136 "id",
137 "id",
138 0, G_MAXUINT64, 0,
139 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
140 props[PROP_DEVICE] =
141 g_param_spec_object ("device",
142 "device",
143 "device",
144 CC_TYPE_WACOM_DEVICE,
145 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
146
147 g_object_class_install_properties (object_class, N_PROPS, props);
148 }
149
150 static const WacomStylus *
151 find_stylus_for_id (WacomDeviceDatabase *wacom_db,
152 CcWacomTool *tool)
153 {
154 const WacomStylus *eraser;
155 const gint *all_ids;
156 gint n_supported;
157 gint i;
158
159 eraser = libwacom_stylus_get_for_id (wacom_db, tool->id);
160 if (!libwacom_stylus_is_eraser (eraser) ||
161 libwacom_stylus_get_eraser_type (eraser) == WACOM_ERASER_BUTTON)
162 return eraser;
163
164 all_ids = cc_wacom_device_get_supported_tools (tool->device, &n_supported);
165 for (i = 0; i < n_supported; i++) {
166 const WacomStylus *stylus;
167 const gint *paired_ids;
168 gint n_paired;
169 gint j;
170
171 if (all_ids[i] == tool->id)
172 continue;
173
174 stylus = libwacom_stylus_get_for_id (wacom_db, all_ids[i]);
175 paired_ids = libwacom_stylus_get_paired_ids (stylus, &n_paired);
176 for (j = 0; j < n_paired; j++) {
177 if (paired_ids[j] == tool->id) {
178 return libwacom_stylus_get_for_id (wacom_db, all_ids[i]);
179 }
180 }
181 }
182
183 return eraser;
184 }
185
186 static gboolean
187 cc_wacom_tool_initable_init (GInitable *initable,
188 GCancellable *cancellable,
189 GError **error)
190 {
191 CcWacomTool *tool = CC_WACOM_TOOL (initable);
192 WacomDeviceDatabase *wacom_db;
193 gchar *path;
194
195 wacom_db = cc_wacom_device_database_get ();
196
197 if (tool->id == 0 && tool->device) {
198 const gint *ids;
199 gint n_supported;
200
201 ids = cc_wacom_device_get_supported_tools (tool->device, &n_supported);
202 if (n_supported > 0)
203 tool->id = ids[0];
204 }
205
206 if (tool->id == 0) {
207 tool->wstylus = libwacom_stylus_get_for_id (wacom_db, 0xfffff);
208 } else {
209 tool->wstylus = find_stylus_for_id (wacom_db, tool);
210 if (tool->wstylus)
211 tool->id = libwacom_stylus_get_id (tool->wstylus);
212 }
213
214 if (!tool->wstylus) {
215 g_set_error (error, 0, 0, "Stylus description not found");
216 return FALSE;
217 }
218
219 if (tool->serial == 0) {
220 const gchar *vendor, *product;
221 GsdDevice *gsd_device;
222
223 gsd_device = cc_wacom_device_get_device (tool->device);
224 gsd_device_get_device_ids (gsd_device, &vendor, &product);
225 path = g_strdup_printf ("/org/gnome/desktop/peripherals/stylus/default-%s:%s/",
226 vendor, product);
227 } else {
228 path = g_strdup_printf ("/org/gnome/desktop/peripherals/stylus/%lx/", tool->serial);
229 }
230
231 tool->settings = g_settings_new_with_path ("org.gnome.desktop.peripherals.tablet.stylus",
232 path);
233 g_free (path);
234
235 return TRUE;
236 }
237
238 static void
239 cc_wacom_tool_initable_iface_init (GInitableIface *iface)
240 {
241 iface->init = cc_wacom_tool_initable_init;
242 }
243
244 CcWacomTool *
245 cc_wacom_tool_new (guint64 serial,
246 guint64 id,
247 CcWacomDevice *device)
248 {
249 g_return_val_if_fail (serial != 0 || CC_IS_WACOM_DEVICE (device), NULL);
250
251 return g_initable_new (CC_TYPE_WACOM_TOOL,
252 NULL, NULL,
253 "serial", serial,
254 "id", id,
255 "device", device,
256 NULL);
257 }
258
259 guint64
260 cc_wacom_tool_get_serial (CcWacomTool *tool)
261 {
262 g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), 0);
263
264 return tool->serial;
265 }
266
267 guint64
268 cc_wacom_tool_get_id (CcWacomTool *tool)
269 {
270 g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), 0);
271
272 return tool->id;
273 }
274
275 const gchar *
276 cc_wacom_tool_get_name (CcWacomTool *tool)
277 {
278 g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), NULL);
279
280 return libwacom_stylus_get_name (tool->wstylus);
281 }
282
283 static const char *
284 get_icon_name_from_type (const WacomStylus *wstylus)
285 {
286 WacomStylusType type = libwacom_stylus_get_type (wstylus);
287
288 switch (type) {
289 case WSTYLUS_INKING:
290 case WSTYLUS_STROKE:
291 /* The stroke pen is the same as the inking pen with
292 * a different nib */
293 return "wacom-stylus-inking";
294 case WSTYLUS_AIRBRUSH:
295 return "wacom-stylus-airbrush";
296 case WSTYLUS_MARKER:
297 return "wacom-stylus-art-pen";
298 case WSTYLUS_CLASSIC:
299 return "wacom-stylus-classic";
300 case WSTYLUS_3D:
301 return "wacom-stylus-3btn-no-eraser";
302 case WSTYLUS_MOBILE:
303 return "wacom-stylus-mobile";
304 default:
305 if (!libwacom_stylus_has_eraser (wstylus)) {
306 if (libwacom_stylus_get_num_buttons (wstylus) >= 3)
307 return "wacom-stylus-3btn-no-eraser";
308 else
309 return "wacom-stylus-no-eraser";
310 }
311 else {
312 if (libwacom_stylus_get_num_buttons (wstylus) >= 3)
313 return "wacom-stylus-3btn";
314 else
315 return "wacom-stylus";
316 }
317 }
318 }
319
320 const gchar *
321 cc_wacom_tool_get_icon_name (CcWacomTool *tool)
322 {
323 g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), NULL);
324
325 return get_icon_name_from_type (tool->wstylus);
326 }
327
328 GSettings *
329 cc_wacom_tool_get_settings (CcWacomTool *tool)
330 {
331 g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), NULL);
332
333 return tool->settings;
334 }
335
336 guint
337 cc_wacom_tool_get_num_buttons (CcWacomTool *tool)
338 {
339 g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), 0);
340
341 return libwacom_stylus_get_num_buttons (tool->wstylus);
342 }
343
344 gboolean
345 cc_wacom_tool_get_has_paired_eraser (CcWacomTool *tool)
346 {
347 g_return_val_if_fail (CC_IS_WACOM_TOOL (tool), FALSE);
348
349 /* True if there is some other tool that is an eraser and
350 * is physically associated with this tool */
351 return libwacom_stylus_has_eraser (tool->wstylus);
352 }
353
354 const gchar *
355 cc_wacom_tool_get_description (CcWacomTool *tool)
356 {
357 WacomAxisTypeFlags axes;
358
359 axes = libwacom_stylus_get_axes (tool->wstylus);
360
361 if ((~axes & (WACOM_AXIS_TYPE_TILT | WACOM_AXIS_TYPE_PRESSURE | WACOM_AXIS_TYPE_SLIDER)) == 0)
362 return _("Airbrush stylus with pressure, tilt, and integrated slider");
363 else if ((~axes & (WACOM_AXIS_TYPE_TILT | WACOM_AXIS_TYPE_PRESSURE | WACOM_AXIS_TYPE_ROTATION_Z)) == 0)
364 return _("Art pen with pressure, tilt, and rotation");
365 else if ((~axes & (WACOM_AXIS_TYPE_TILT | WACOM_AXIS_TYPE_PRESSURE)) == 0)
366 return _("Stylus with pressure and tilt");
367 else if ((~axes & WACOM_AXIS_TYPE_PRESSURE) == 0)
368 return _("Stylus with pressure");
369
370 return NULL;
371 }
372