GCC Code Coverage Report


Directory: ./
File: panels/universal-access/cc-ua-zoom-page.c
Date: 2024-05-04 07:58:27
Exec Total Coverage
Lines: 0 179 0.0%
Functions: 0 13 0.0%
Branches: 0 115 0.0%

Line Branch Exec Source
1 /* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 *
3 * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
4 * Copyright (C) 2010 Intel, Inc
5 * Copyright 2022 Mohammed Sadiq <sadiq@sadiqpk.org>
6 * Copyright 2022 Purism SPC
7 *
8 * Licensed under the GNU General Public License Version 2
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 *
24 * Author(s):
25 * Thomas Wood <thomas.wood@intel.com>
26 * Rodrigo Moya <rodrigo@gnome.org>
27 * Mohammed Sadiq <sadiq@sadiqpk.org>
28 *
29 * SPDX-License-Identifier: GPL-2.0-or-later
30 */
31
32 #undef G_LOG_DOMAIN
33 #define G_LOG_DOMAIN "cc-ua-zoom-page"
34
35 #ifdef HAVE_CONFIG_H
36 # include "config.h"
37 #endif
38
39 #include "cc-ua-macros.h"
40 #include "cc-ua-zoom-page.h"
41
42 struct _CcUaZoomPage
43 {
44 AdwNavigationPage parent_instance;
45
46 AdwSwitchRow *desktop_zoom_row;
47 AdwSpinRow *magnify_factor_spin_row;
48 AdwComboRow *magnify_view_row;
49
50 AdwSwitchRow *magnify_outside_screen_row;
51 AdwComboRow *zoom_screen_area_row;
52 AdwComboRow *zoom_follow_behaviour_row;
53
54 AdwExpanderRow *crosshair_row;
55 AdwSwitchRow *crosshair_overlap_mouse_row;
56 GtkScale *crosshair_thickness_scale;
57 GtkScale *crosshair_length_scale;
58 GtkColorButton *crosshair_color_button;
59
60 AdwSwitchRow *color_inverted_row;
61 GtkScale *brightness_scale;
62 GtkScale *contrast_scale;
63 GtkScale *grayscale_scale;
64
65 GSettings *magnifier_settings;
66 GSettings *application_settings;
67
68 gboolean is_self_update;
69 };
70
71 G_DEFINE_TYPE (CcUaZoomPage, cc_ua_zoom_page, ADW_TYPE_NAVIGATION_PAGE)
72
73 static void
74 ua_zoom_magnifier_settings_changed_cb (CcUaZoomPage *self,
75 char *key)
76 {
77 GSettings *settings;
78 guint selected_index;
79
80 g_assert (CC_IS_UA_ZOOM_PAGE (self));
81
82 self->is_self_update = TRUE;
83 settings = self->magnifier_settings;
84
85 if (!key || g_str_equal (key, "lens-mode"))
86 {
87 gboolean lens_mode;
88
89 lens_mode = g_settings_get_boolean (settings, "lens-mode");
90
91 if (lens_mode)
92 selected_index = 0;
93 else
94 selected_index = 1;
95
96 adw_combo_row_set_selected (self->magnify_view_row, selected_index);
97 gtk_widget_set_sensitive (GTK_WIDGET (self->magnify_outside_screen_row), !lens_mode);
98 }
99
100 if (!key || g_str_equal (key, "mouse-tracking"))
101 {
102 g_autofree char *tracking = NULL;
103
104 tracking = g_settings_get_string (settings, "mouse-tracking");
105
106 if (g_strcmp0 (tracking, "proportional") == 0)
107 selected_index = 0;
108 else if (g_strcmp0 (tracking, "push") == 0)
109 selected_index = 1;
110 else
111 selected_index = 3;
112
113 adw_combo_row_set_selected (self->zoom_follow_behaviour_row, selected_index);
114 }
115
116 if (!key || g_str_equal (key, "screen-position"))
117 {
118 g_autofree char *position = NULL;
119
120 position = g_settings_get_string (settings, "screen-position");
121
122 if (g_strcmp0 (position, "top-half") == 0)
123 selected_index = 1;
124 else if (g_strcmp0 (position, "bottom-half") == 0)
125 selected_index = 2;
126 else if (g_strcmp0 (position, "left-half") == 0)
127 selected_index = 3;
128 else if (g_strcmp0 (position, "right-half") == 0)
129 selected_index = 4;
130 else
131 selected_index = 0;
132
133 adw_combo_row_set_selected (self->zoom_screen_area_row, selected_index);
134 }
135
136 if (!key || g_str_has_prefix (key, "cross-hairs-"))
137 {
138 g_autofree char *color = NULL;
139 GdkRGBA rgba;
140
141 color = g_settings_get_string (self->magnifier_settings, "cross-hairs-color");
142 gdk_rgba_parse (&rgba, color);
143
144 rgba.alpha = g_settings_get_double (self->magnifier_settings, "cross-hairs-opacity");
145 gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->crosshair_color_button), &rgba);
146 }
147
148 if (!key || g_str_has_prefix (key, "brightness-"))
149 {
150 gdouble red, green, blue, value;
151
152 red = g_settings_get_double (settings, "brightness-red");
153 green = g_settings_get_double (settings, "brightness-green");
154 blue = g_settings_get_double (settings, "brightness-blue");
155
156 if (red == green && green == blue)
157 value = red;
158 else
159 /* use NTSC conversion weights for reasonable average */
160 value = 0.299 * red + 0.587 * green + 0.114 * blue;
161
162 gtk_range_set_value (GTK_RANGE (self->brightness_scale), value);
163 }
164
165 if (!key || g_str_has_prefix (key, "contrast-"))
166 {
167 gdouble red, green, blue, value;
168
169 red = g_settings_get_double (settings, "contrast-red");
170 green = g_settings_get_double (settings, "contrast-green");
171 blue = g_settings_get_double (settings, "contrast-blue");
172
173 if (red == green && green == blue)
174 value = red;
175 else
176 /* use NTSC conversion weights for reasonable average */
177 value = 0.299 * red + 0.587 * green + 0.114 * blue;
178
179 gtk_range_set_value (GTK_RANGE (self->contrast_scale), value);
180 }
181
182 self->is_self_update = FALSE;
183 }
184
185 static void
186 ua_zoom_magnify_postion_row_changed_cb (CcUaZoomPage *self)
187 {
188 guint selected_index;
189 gboolean is_lens;
190
191 g_assert (CC_IS_UA_ZOOM_PAGE (self));
192
193 selected_index = adw_combo_row_get_selected (self->magnify_view_row);
194 is_lens = selected_index == 0;
195 gtk_widget_set_sensitive (GTK_WIDGET (self->magnify_outside_screen_row), !is_lens);
196
197 if (!self->is_self_update)
198 g_settings_set_boolean (self->magnifier_settings, "lens-mode", is_lens);
199 }
200
201 static void
202 ua_zoom_screen_area_row_changed_cb (CcUaZoomPage *self)
203 {
204 const char *position;
205 guint selected_index;
206
207 g_assert (CC_IS_UA_ZOOM_PAGE (self));
208
209 if (self->is_self_update)
210 return;
211
212 selected_index = adw_combo_row_get_selected (self->zoom_screen_area_row);
213
214 if (selected_index == 1)
215 position = "top-half";
216 else if (selected_index == 2)
217 position = "bottom-half";
218 else if (selected_index == 3)
219 position = "left-half";
220 else if (selected_index == 4)
221 position = "right-half";
222 else
223 position = "full-screen";
224
225 g_settings_set_string (self->magnifier_settings, "screen-position", position);
226 }
227
228 static void
229 ua_zoom_behaviour_row_changed_cb (CcUaZoomPage *self)
230 {
231 const char *tracking;
232 guint selected_index;
233
234 g_assert (CC_IS_UA_ZOOM_PAGE (self));
235
236 if (self->is_self_update)
237 return;
238
239 selected_index = adw_combo_row_get_selected (self->zoom_follow_behaviour_row);
240
241 if (selected_index == 0)
242 tracking = "proportional";
243 else if (selected_index == 1)
244 tracking = "push";
245 else
246 tracking = "centered";
247
248 g_settings_set_string (self->magnifier_settings, "mouse-tracking", tracking);
249 }
250
251 #define TO_HEX(x) (int) ((gdouble) x * 255.0)
252 static void
253 ua_zoom_crosshair_color_set_cb (CcUaZoomPage *self)
254 {
255 g_autofree char *color = NULL;
256 GdkRGBA rgba;
257
258 g_assert (CC_IS_UA_ZOOM_PAGE (self));
259
260 if (self->is_self_update)
261 return;
262
263 gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->crosshair_color_button), &rgba);
264 color = g_strdup_printf ("#%02x%02x%02x",
265 TO_HEX (rgba.red),
266 TO_HEX (rgba.green),
267 TO_HEX (rgba.blue));
268
269 g_settings_set_string (self->magnifier_settings, "cross-hairs-color", color);
270 g_settings_set_double (self->magnifier_settings, "cross-hairs-opacity", rgba.alpha);
271 }
272
273 static void
274 ua_zoom_brightness_value_changed_cb (CcUaZoomPage *self)
275 {
276 gdouble value;
277
278 g_assert (CC_IS_UA_ZOOM_PAGE (self));
279
280 if (self->is_self_update)
281 return;
282
283 value = gtk_range_get_value (GTK_RANGE (self->brightness_scale));
284 g_settings_set_double (self->magnifier_settings, "brightness-red", value);
285 g_settings_set_double (self->magnifier_settings, "brightness-green", value);
286 g_settings_set_double (self->magnifier_settings, "brightness-blue", value);
287 }
288
289 static void
290 ua_zoom_contrast_value_changed_cb (CcUaZoomPage *self)
291 {
292 gdouble value;
293
294 g_assert (CC_IS_UA_ZOOM_PAGE (self));
295
296 if (self->is_self_update)
297 return;
298
299 value = gtk_range_get_value (GTK_RANGE (self->contrast_scale));
300 g_settings_set_double (self->magnifier_settings, "contrast-red", value);
301 g_settings_set_double (self->magnifier_settings, "contrast-green", value);
302 g_settings_set_double (self->magnifier_settings, "contrast-blue", value);
303 }
304
305 static void
306 cc_ua_zoom_page_dispose (GObject *object)
307 {
308 CcUaZoomPage *self = (CcUaZoomPage *)object;
309
310 g_clear_object (&self->magnifier_settings);
311 g_clear_object (&self->application_settings);
312
313 G_OBJECT_CLASS (cc_ua_zoom_page_parent_class)->dispose (object);
314 }
315
316 static void
317 cc_ua_zoom_page_class_init (CcUaZoomPageClass *klass)
318 {
319 GObjectClass *object_class = G_OBJECT_CLASS (klass);
320 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
321
322 object_class->dispose = cc_ua_zoom_page_dispose;
323
324 gtk_widget_class_set_template_from_resource (widget_class,
325 "/org/gnome/control-center/"
326 "universal-access/cc-ua-zoom-page.ui");
327
328 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, desktop_zoom_row);
329 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, magnify_factor_spin_row);
330 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, magnify_view_row);
331
332 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, magnify_outside_screen_row);
333 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, zoom_screen_area_row);
334 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, zoom_follow_behaviour_row);
335
336 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, crosshair_row);
337 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, crosshair_overlap_mouse_row);
338 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, crosshair_thickness_scale);
339 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, crosshair_length_scale);
340 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, crosshair_length_scale);
341 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, crosshair_color_button);
342
343 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, color_inverted_row);
344 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, brightness_scale);
345 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, contrast_scale);
346 gtk_widget_class_bind_template_child (widget_class, CcUaZoomPage, grayscale_scale);
347
348 gtk_widget_class_bind_template_callback (widget_class, ua_zoom_magnify_postion_row_changed_cb);
349 gtk_widget_class_bind_template_callback (widget_class, ua_zoom_screen_area_row_changed_cb);
350 gtk_widget_class_bind_template_callback (widget_class, ua_zoom_behaviour_row_changed_cb);
351 gtk_widget_class_bind_template_callback (widget_class, ua_zoom_crosshair_color_set_cb);
352 gtk_widget_class_bind_template_callback (widget_class, ua_zoom_brightness_value_changed_cb);
353 gtk_widget_class_bind_template_callback (widget_class, ua_zoom_contrast_value_changed_cb);
354 }
355
356 static void
357 cc_ua_zoom_page_init (CcUaZoomPage *self)
358 {
359 gtk_widget_init_template (GTK_WIDGET (self));
360
361 self->magnifier_settings = g_settings_new (A11Y_SETTINGS ".magnifier");
362 self->application_settings = g_settings_new (APPLICATION_SETTINGS);
363
364 g_settings_bind (self->application_settings, KEY_SCREEN_MAGNIFIER_ENABLED,
365 self->desktop_zoom_row, "active",
366 G_SETTINGS_BIND_DEFAULT);
367 g_settings_bind (self->magnifier_settings, "mag-factor",
368 adw_spin_row_get_adjustment (self->magnify_factor_spin_row),
369 "value", G_SETTINGS_BIND_DEFAULT);
370 g_settings_bind (self->magnifier_settings, "scroll-at-edges",
371 self->magnify_outside_screen_row, "active",
372 G_SETTINGS_BIND_DEFAULT);
373
374 /* Cross hairs */
375 g_settings_bind (self->magnifier_settings, "show-cross-hairs",
376 self->crosshair_row, "enable-expansion",
377 G_SETTINGS_BIND_DEFAULT);
378 g_settings_bind (self->magnifier_settings, "cross-hairs-clip",
379 self->crosshair_overlap_mouse_row, "active",
380 G_SETTINGS_BIND_INVERT_BOOLEAN);
381
382 g_settings_bind (self->magnifier_settings, "cross-hairs-thickness",
383 gtk_range_get_adjustment (GTK_RANGE (self->crosshair_thickness_scale)), "value",
384 G_SETTINGS_BIND_DEFAULT);
385 g_settings_bind (self->magnifier_settings, "cross-hairs-length",
386 gtk_range_get_adjustment (GTK_RANGE (self->crosshair_length_scale)), "value",
387 G_SETTINGS_BIND_DEFAULT);
388
389 /* Cross hairs effects */
390 g_settings_bind (self->magnifier_settings, "invert-lightness",
391 self->color_inverted_row, "active",
392 G_SETTINGS_BIND_DEFAULT);
393
394 g_settings_bind (self->magnifier_settings, "color-saturation",
395 gtk_range_get_adjustment (GTK_RANGE (self->grayscale_scale)), "value",
396 G_SETTINGS_BIND_DEFAULT);
397
398 g_signal_connect_object (self->magnifier_settings, "changed",
399 G_CALLBACK (ua_zoom_magnifier_settings_changed_cb),
400 self, G_CONNECT_SWAPPED);
401 ua_zoom_magnifier_settings_changed_cb (self, NULL);
402 }
403