Bug Summary

File:cdk/wayland/cdkscreen-wayland.c
Warning:line 1286, column 45
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cdkscreen-wayland.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/cdk/wayland -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../.. -D G_LOG_DOMAIN="Cdk" -D G_LOG_USE_STRUCTURED=1 -D CDK_COMPILATION -I ../.. -I ../../cdk -I ../../cdk -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/cdk/wayland -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-09-19-172934-43638-1 -x c cdkscreen-wayland.c
1/*
2 * Copyright © 2010 Intel Corporation
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library 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 GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "config.h"
19
20#include <stdlib.h>
21#include <string.h>
22
23#include <glib.h>
24#include <gio/gio.h>
25#include "cdkscreenprivate.h"
26#include "cdkvisualprivate.h"
27#include "cdkdisplay.h"
28#include "cdkdisplay-wayland.h"
29#include "cdkmonitor-wayland.h"
30#include "cdkwayland.h"
31#include "cdkprivate-wayland.h"
32#include "cdk-private.h"
33
34#include "wm-button-layout-translation.h"
35
36typedef struct _CdkWaylandScreen CdkWaylandScreen;
37typedef struct _CdkWaylandScreenClass CdkWaylandScreenClass;
38
39#define CDK_TYPE_WAYLAND_SCREEN(_cdk_wayland_screen_get_type ()) (_cdk_wayland_screen_get_type ())
40#define CDK_WAYLAND_SCREEN(object)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((object)), ((_cdk_wayland_screen_get_type ()
))))))
(G_TYPE_CHECK_INSTANCE_CAST ((object), CDK_TYPE_WAYLAND_SCREEN, CdkWaylandScreen)(((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((_cdk_wayland_screen_get_type ())))))
)
41#define CDK_WAYLAND_SCREEN_CLASS(klass)((((CdkWaylandScreenClass*) (void *) g_type_check_class_cast (
(GTypeClass*) ((klass)), ((_cdk_wayland_screen_get_type ())))
)))
(G_TYPE_CHECK_CLASS_CAST ((klass), CDK_TYPE_WAYLAND_SCREEN, CdkWaylandScreenClass)(((CdkWaylandScreenClass*) (void *) g_type_check_class_cast (
(GTypeClass*) ((klass)), ((_cdk_wayland_screen_get_type ())))
))
)
42#define CDK_IS_WAYLAND_SCREEN(object)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(object)); GType __t = ((_cdk_wayland_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; }))))
(G_TYPE_CHECK_INSTANCE_TYPE ((object), CDK_TYPE_WAYLAND_SCREEN)((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) (
(object)); GType __t = ((_cdk_wayland_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))
)
43#define CDK_IS_WAYLAND_SCREEN_CLASS(klass)(((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass
)); GType __t = ((_cdk_wayland_screen_get_type ())); gboolean
__r; if (!__class) __r = (0); else if (__class->g_type ==
__t) __r = (!(0)); else __r = g_type_check_class_is_a (__class
, __t); __r; }))))
(G_TYPE_CHECK_CLASS_TYPE ((klass), CDK_TYPE_WAYLAND_SCREEN)((__extension__ ({ GTypeClass *__class = (GTypeClass*) ((klass
)); GType __t = ((_cdk_wayland_screen_get_type ())); gboolean
__r; if (!__class) __r = (0); else if (__class->g_type ==
__t) __r = (!(0)); else __r = g_type_check_class_is_a (__class
, __t); __r; })))
)
44#define CDK_WAYLAND_SCREEN_GET_CLASS(obj)((((CdkWaylandScreenClass*) (((GTypeInstance*) ((obj)))->g_class
))))
(G_TYPE_INSTANCE_GET_CLASS ((obj), CDK_TYPE_WAYLAND_SCREEN, CdkWaylandScreenClass)(((CdkWaylandScreenClass*) (((GTypeInstance*) ((obj)))->g_class
)))
)
45
46typedef struct {
47 gboolean antialias;
48 gboolean hinting;
49 gint dpi;
50 const gchar *rgba;
51 const gchar *hintstyle;
52} GsdXftSettings;
53
54typedef struct {
55 guint fontconfig_timestamp;
56 gchar *modules;
57} GsdExtSettings;
58
59struct _CdkWaylandScreen
60{
61 CdkScreen parent_instance;
62
63 CdkDisplay *display;
64 CdkWindow *root_window;
65
66 int width, height;
67 int width_mm, height_mm;
68
69 /* Visual Part */
70 CdkVisual *visual;
71
72 GHashTable *settings;
73 GsdXftSettings xft_settings;
74 GsdExtSettings dbus_settings;
75 GDBusProxy *settings_portal;
76
77 GDBusProxy *dbus_proxy;
78 GCancellable *dbus_cancellable;
79 gulong dbus_setting_change_id;
80
81 guint32 shell_capabilities;
82};
83
84struct _CdkWaylandScreenClass
85{
86 CdkScreenClass parent_class;
87};
88
89#define OUTPUT_VERSION_WITH_DONE2 2
90#define NO_XDG_OUTPUT_DONE_SINCE_VERSION3 3
91
92#define CTK_SETTINGS_DBUS_PATH"/org/ctk/Settings" "/org/ctk/Settings"
93#define CTK_SETTINGS_DBUS_NAME"org.ctk.Settings" "org.ctk.Settings"
94
95GType _cdk_wayland_screen_get_type (void);
96
97G_DEFINE_TYPE (CdkWaylandScreen, _cdk_wayland_screen, CDK_TYPE_SCREEN)static void _cdk_wayland_screen_init (CdkWaylandScreen *self)
; static void _cdk_wayland_screen_class_init (CdkWaylandScreenClass
*klass); static GType _cdk_wayland_screen_get_type_once (void
); static gpointer _cdk_wayland_screen_parent_class = ((void*
)0); static gint CdkWaylandScreen_private_offset; static void
_cdk_wayland_screen_class_intern_init (gpointer klass) { _cdk_wayland_screen_parent_class
= g_type_class_peek_parent (klass); if (CdkWaylandScreen_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CdkWaylandScreen_private_offset
); _cdk_wayland_screen_class_init ((CdkWaylandScreenClass*) klass
); } __attribute__ ((__unused__)) static inline gpointer _cdk_wayland_screen_get_instance_private
(CdkWaylandScreen *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CdkWaylandScreen_private_offset)))); } GType _cdk_wayland_screen_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= _cdk_wayland_screen_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType _cdk_wayland_screen_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((cdk_screen_get_type ()), g_intern_static_string ("CdkWaylandScreen"
), sizeof (CdkWaylandScreenClass), (GClassInitFunc)(void (*)(
void)) _cdk_wayland_screen_class_intern_init, sizeof (CdkWaylandScreen
), (GInstanceInitFunc)(void (*)(void)) _cdk_wayland_screen_init
, (GTypeFlags) 0); { {{};} } return g_define_type_id; }
98
99static void
100cdk_wayland_screen_dispose (GObject *object)
101{
102 CdkWaylandScreen *screen_wayland = CDK_WAYLAND_SCREEN (object)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((object)), ((_cdk_wayland_screen_get_type ()
))))))
;
103
104 if (screen_wayland->dbus_proxy && screen_wayland->dbus_setting_change_id > 0)
105 {
106 g_signal_handler_disconnect (screen_wayland->dbus_proxy,
107 screen_wayland->dbus_setting_change_id);
108 screen_wayland->dbus_setting_change_id = 0;
109 }
110
111 g_cancellable_cancel (screen_wayland->dbus_cancellable);
112
113 if (screen_wayland->root_window)
114 _cdk_window_destroy (screen_wayland->root_window, FALSE(0));
115
116 G_OBJECT_CLASS (_cdk_wayland_screen_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((_cdk_wayland_screen_parent_class)), (((GType) ((20) <<
(2))))))))
->dispose (object);
117}
118
119static void
120cdk_wayland_screen_finalize (GObject *object)
121{
122 CdkWaylandScreen *screen_wayland = CDK_WAYLAND_SCREEN (object)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((object)), ((_cdk_wayland_screen_get_type ()
))))))
;
123
124 g_clear_object (&screen_wayland->dbus_proxy)do { _Static_assert (sizeof *((&screen_wayland->dbus_proxy
)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&screen_wayland->dbus_proxy))) _pp = ((&screen_wayland
->dbus_proxy)); __typeof__ (*((&screen_wayland->dbus_proxy
))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref
) (_ptr); } while (0)
;
125 g_clear_object (&screen_wayland->dbus_cancellable)do { _Static_assert (sizeof *((&screen_wayland->dbus_cancellable
)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&screen_wayland->dbus_cancellable))) _pp = ((&
screen_wayland->dbus_cancellable)); __typeof__ (*((&screen_wayland
->dbus_cancellable))) _ptr = *_pp; *_pp = ((void*)0); if (
_ptr) (g_object_unref) (_ptr); } while (0)
;
126
127 if (screen_wayland->root_window)
128 g_object_unref (screen_wayland->root_window);
129
130 g_object_unref (screen_wayland->visual);
131
132 if (screen_wayland->settings)
133 g_hash_table_destroy (screen_wayland->settings);
134
135 g_clear_object (&screen_wayland->settings_portal)do { _Static_assert (sizeof *((&screen_wayland->settings_portal
)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&screen_wayland->settings_portal))) _pp = ((&screen_wayland
->settings_portal)); __typeof__ (*((&screen_wayland->
settings_portal))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (
g_object_unref) (_ptr); } while (0)
;
136
137 g_free (screen_wayland->dbus_settings.modules);
138
139 G_OBJECT_CLASS (_cdk_wayland_screen_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((_cdk_wayland_screen_parent_class)), (((GType) ((20) <<
(2))))))))
->finalize (object);
140}
141
142static CdkDisplay *
143cdk_wayland_screen_get_display (CdkScreen *screen)
144{
145 return CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
->display;
146}
147
148static gint
149cdk_wayland_screen_get_width (CdkScreen *screen)
150{
151 return CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
->width;
152}
153
154static gint
155cdk_wayland_screen_get_height (CdkScreen *screen)
156{
157 return CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
->height;
158}
159
160static gint
161cdk_wayland_screen_get_width_mm (CdkScreen *screen)
162{
163 return CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
->width_mm;
164}
165
166static gint
167cdk_wayland_screen_get_height_mm (CdkScreen *screen)
168{
169 return CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
->height_mm;
170}
171
172static gint
173cdk_wayland_screen_get_number (CdkScreen *screen G_GNUC_UNUSED__attribute__ ((__unused__)))
174{
175 return 0;
176}
177
178static CdkWindow *
179cdk_wayland_screen_get_root_window (CdkScreen *screen)
180{
181 return CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
->root_window;
182}
183
184static CdkVisual *
185cdk_wayland_screen_get_system_visual (CdkScreen * screen)
186{
187 return (CdkVisual *) CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
->visual;
188}
189
190static CdkVisual *
191cdk_wayland_screen_get_rgba_visual (CdkScreen *screen)
192{
193 return (CdkVisual *) CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
->visual;
194}
195
196static gboolean
197cdk_wayland_screen_is_composited (CdkScreen *screen G_GNUC_UNUSED__attribute__ ((__unused__)))
198{
199 return TRUE(!(0));
200}
201
202static gchar *
203cdk_wayland_screen_make_display_name (CdkScreen *screen)
204{
205 return g_strdup (cdk_display_get_name (CDK_WAYLAND_SCREEN (screen)->display))g_strdup_inline (cdk_display_get_name (((((CdkWaylandScreen*)
(void *) g_type_check_instance_cast ((GTypeInstance*) ((screen
)), ((_cdk_wayland_screen_get_type ()))))))->display))
;
206}
207
208static CdkWindow *
209cdk_wayland_screen_get_active_window (CdkScreen *screen G_GNUC_UNUSED__attribute__ ((__unused__)))
210{
211 return NULL((void*)0);
212}
213
214static GList *
215cdk_wayland_screen_get_window_stack (CdkScreen *screen G_GNUC_UNUSED__attribute__ ((__unused__)))
216{
217 return NULL((void*)0);
218}
219
220static void
221cdk_wayland_screen_broadcast_client_message (CdkScreen *screen G_GNUC_UNUSED__attribute__ ((__unused__)),
222 CdkEvent *event G_GNUC_UNUSED__attribute__ ((__unused__)))
223{
224}
225
226static void
227notify_setting (CdkScreen *screen,
228 const gchar *setting)
229{
230 CdkEvent event;
231
232 event.type = CDK_SETTING;
233 event.setting.window = cdk_screen_get_root_window (screen);
234 event.setting.send_event = FALSE(0);
235 event.setting.action = CDK_SETTING_ACTION_CHANGED;
236 event.setting.name = (gchar *)setting;
237 cdk_event_put (&event);
238}
239
240typedef enum
241{
242 GSD_FONT_ANTIALIASING_MODE_NONE,
243 GSD_FONT_ANTIALIASING_MODE_GRAYSCALE,
244 GSD_FONT_ANTIALIASING_MODE_RGBA
245} GsdFontAntialiasingMode;
246
247static int
248get_antialiasing (const char *s)
249{
250 const char *names[] = { "none", "grayscale", "rgba" };
251 int i;
252
253 for (i = 0; i < G_N_ELEMENTS (names)(sizeof (names) / sizeof ((names)[0])); i++)
254 if (strcmp (s, names[i]) == 0)
255 return i;
256
257 return 0;
258}
259
260typedef enum
261{
262 GSD_FONT_HINTING_NONE,
263 GSD_FONT_HINTING_SLIGHT,
264 GSD_FONT_HINTING_MEDIUM,
265 GSD_FONT_HINTING_FULL
266} GsdFontHinting;
267
268static int
269get_hinting (const char *s)
270{
271 const char *names[] = { "none", "slight", "medium", "full" };
272 int i;
273
274 for (i = 0; i < G_N_ELEMENTS (names)(sizeof (names) / sizeof ((names)[0])); i++)
275 if (strcmp (s, names[i]) == 0)
276 return i;
277
278 return 0;
279}
280
281typedef enum
282{
283 GSD_FONT_RGBA_ORDER_RGBA,
284 GSD_FONT_RGBA_ORDER_RGB,
285 GSD_FONT_RGBA_ORDER_BGR,
286 GSD_FONT_RGBA_ORDER_VRGB,
287 GSD_FONT_RGBA_ORDER_VBGR
288} GsdFontRgbaOrder;
289
290static int
291get_order (const char *s)
292{
293 const char *names[] = { "rgba", "rgb", "bgr", "vrgb", "vbgr" };
294 int i;
295
296 for (i = 0; i < G_N_ELEMENTS (names)(sizeof (names) / sizeof ((names)[0])); i++)
297 if (strcmp (s, names[i]) == 0)
298 return i;
299
300 return 0;
301}
302
303static gdouble
304get_dpi_from_gsettings (CdkWaylandScreen *screen_wayland)
305{
306 GSettings *settings;
307 gdouble factor;
308
309 settings = g_hash_table_lookup (screen_wayland->settings,
310 "org.gnome.desktop.interface");
311 if (settings != NULL((void*)0))
312 factor = g_settings_get_double (settings, "text-scaling-factor");
313 else
314 factor = 1.0;
315
316 return 96.0 * factor;
317}
318
319/* When using the Settings portal, we cache the value in
320 * the fallback member, and we ignore the valid field
321 */
322typedef struct _TranslationEntry TranslationEntry;
323struct _TranslationEntry {
324 gboolean valid;
325 const gchar *schema;
326 const gchar *key;
327 const gchar *setting;
328 GType type;
329 union {
330 const char *s;
331 gint i;
332 gboolean b;
333 } fallback;
334};
335
336static TranslationEntry * find_translation_entry_by_schema (const char *schema,
337 const char *key);
338static void
339update_xft_settings (CdkScreen *screen)
340{
341 CdkWaylandScreen *screen_wayland = CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
;
342 GsdFontAntialiasingMode antialiasing;
343 GsdFontHinting hinting;
344 GsdFontRgbaOrder order;
345 gboolean use_rgba = FALSE(0);
346 GsdXftSettings xft_settings;
347 double dpi;
348
349 if (screen_wayland->settings_portal)
350 {
351 TranslationEntry *entry;
352
353 entry = find_translation_entry_by_schema ("org.gnome.desktop.interface", "font-antialiasing");
354
355 if (entry->valid)
356 {
357 antialiasing = entry->fallback.i;
358
359 entry = find_translation_entry_by_schema ("org.gnome.desktop.interface", "font-hinting");
360 hinting = entry->fallback.i;
361
362 entry = find_translation_entry_by_schema ("org.gnome.desktop.interface", "font-rgba-order");
363 order = entry->fallback.i;
364 }
365 else
366 {
367 entry = find_translation_entry_by_schema ("org.gnome.settings-daemon.plugins.xsettings", "antialiasing");
368 antialiasing = entry->fallback.i;
369
370 entry = find_translation_entry_by_schema ("org.gnome.settings-daemon.plugins.xsettings", "hinting");
371 hinting = entry->fallback.i;
372
373 entry = find_translation_entry_by_schema ("org.gnome.settings-daemon.plugins.xsettings", "rgba-order");
374 order = entry->fallback.i;
375 }
376
377 entry = find_translation_entry_by_schema ("org.gnome.desktop.interface", "text-scaling-factor");
378 dpi = 96.0 * entry->fallback.i / 65536.0 * 1024; /* Xft wants 1/1024th of an inch */
379 }
380 else
381 {
382 TranslationEntry *entry;
383 GSettings *settings;
384
385 entry = find_translation_entry_by_schema ("org.gnome.desktop.interface", "font-antialiasing");
386
387 if (entry && entry->valid)
388 {
389 settings = g_hash_table_lookup (screen_wayland->settings,
390 "org.gnome.desktop.interface");
391 antialiasing = g_settings_get_enum (settings, "font-antialiasing");
392 hinting = g_settings_get_enum (settings, "font-hinting");
393 order = g_settings_get_enum (settings, "font-rgba-order");
394 }
395 else if (g_hash_table_contains (screen_wayland->settings,
396 "org.gnome.settings-daemon.plugins.xsettings"))
397 {
398 settings = g_hash_table_lookup (screen_wayland->settings,
399 "org.gnome.settings-daemon.plugins.xsettings");
400 antialiasing = g_settings_get_enum (settings, "antialiasing");
401 hinting = g_settings_get_enum (settings, "hinting");
402 order = g_settings_get_enum (settings, "rgba-order");
403 }
404 else
405 {
406 antialiasing = GSD_FONT_ANTIALIASING_MODE_GRAYSCALE;
407 hinting = GSD_FONT_HINTING_MEDIUM;
408 order = GSD_FONT_RGBA_ORDER_RGB;
409 }
410
411 dpi = get_dpi_from_gsettings (screen_wayland) * 1024;
412 }
413
414 xft_settings.antialias = (antialiasing != GSD_FONT_ANTIALIASING_MODE_NONE);
415 xft_settings.hinting = (hinting != GSD_FONT_HINTING_NONE);
416 xft_settings.dpi = dpi;
417 xft_settings.rgba = "rgb";
418 xft_settings.hintstyle = "hintfull";
419
420 switch (hinting)
421 {
422 case GSD_FONT_HINTING_NONE:
423 xft_settings.hintstyle = "hintnone";
424 break;
425 case GSD_FONT_HINTING_SLIGHT:
426 xft_settings.hintstyle = "hintslight";
427 break;
428 case GSD_FONT_HINTING_MEDIUM:
429 xft_settings.hintstyle = "hintmedium";
430 break;
431 case GSD_FONT_HINTING_FULL:
432 xft_settings.hintstyle = "hintfull";
433 break;
434 }
435
436 switch (order)
437 {
438 case GSD_FONT_RGBA_ORDER_RGBA:
439 xft_settings.rgba = "rgba";
440 break;
441 case GSD_FONT_RGBA_ORDER_RGB:
442 xft_settings.rgba = "rgb";
443 break;
444 case GSD_FONT_RGBA_ORDER_BGR:
445 xft_settings.rgba = "bgr";
446 break;
447 case GSD_FONT_RGBA_ORDER_VRGB:
448 xft_settings.rgba = "vrgb";
449 break;
450 case GSD_FONT_RGBA_ORDER_VBGR:
451 xft_settings.rgba = "vbgr";
452 break;
453 }
454
455 switch (antialiasing)
456 {
457 case GSD_FONT_ANTIALIASING_MODE_NONE:
458 xft_settings.antialias = FALSE(0);
459 break;
460 case GSD_FONT_ANTIALIASING_MODE_GRAYSCALE:
461 xft_settings.antialias = TRUE(!(0));
462 break;
463 case GSD_FONT_ANTIALIASING_MODE_RGBA:
464 xft_settings.antialias = TRUE(!(0));
465 use_rgba = TRUE(!(0));
466 }
467
468 if (!use_rgba)
469 xft_settings.rgba = "none";
470
471 if (screen_wayland->xft_settings.antialias != xft_settings.antialias)
472 {
473 screen_wayland->xft_settings.antialias = xft_settings.antialias;
474 notify_setting (screen, "ctk-xft-antialias");
475 }
476
477 if (screen_wayland->xft_settings.hinting != xft_settings.hinting)
478 {
479 screen_wayland->xft_settings.hinting = xft_settings.hinting;
480 notify_setting (screen, "ctk-xft-hinting");
481 }
482
483 if (screen_wayland->xft_settings.hintstyle != xft_settings.hintstyle)
484 {
485 screen_wayland->xft_settings.hintstyle = xft_settings.hintstyle;
486 notify_setting (screen, "ctk-xft-hintstyle");
487 }
488
489 if (screen_wayland->xft_settings.rgba != xft_settings.rgba)
490 {
491 screen_wayland->xft_settings.rgba = xft_settings.rgba;
492 notify_setting (screen, "ctk-xft-rgba");
493 }
494
495 if (screen_wayland->xft_settings.dpi != xft_settings.dpi)
496 {
497 double dpi = xft_settings.dpi / 1024.;
498 const char *scale_env;
499
500 screen_wayland->xft_settings.dpi = xft_settings.dpi;
501
502 scale_env = g_getenv ("CDK_DPI_SCALE");
503 if (scale_env)
504 {
505 double scale;
506
507 scale = g_ascii_strtod (scale_env, NULL((void*)0));
508 if (scale != 0 && dpi > 0)
509 dpi *= scale;
510 }
511
512 _cdk_screen_set_resolution (screen, dpi);
513
514 notify_setting (screen, "ctk-xft-dpi");
515 }
516}
517
518#define WM_SETTINGS_SCHEMA"org.gnome.desktop.wm.preferences" "org.gnome.desktop.wm.preferences"
519#define CLASSIC_WM_SETTINGS_SCHEMA"org.gnome.shell.extensions.classic-overrides" "org.gnome.shell.extensions.classic-overrides"
520
521static TranslationEntry translations[] = {
522 { FALSE(0), "org.gnome.desktop.interface", "ctk-theme", "ctk-theme-name" , G_TYPE_STRING((GType) ((16) << (2))), { .s = "Advaita" } },
523 { FALSE(0), "org.gnome.desktop.interface", "ctk-key-theme", "ctk-key-theme-name" , G_TYPE_STRING((GType) ((16) << (2))), { .s = "Default" } },
524 { FALSE(0), "org.gnome.desktop.interface", "icon-theme", "ctk-icon-theme-name", G_TYPE_STRING((GType) ((16) << (2))), { .s = "gnome" } },
525 { FALSE(0), "org.gnome.desktop.interface", "cursor-theme", "ctk-cursor-theme-name", G_TYPE_STRING((GType) ((16) << (2))), { .s = "Advaita" } },
526 { FALSE(0), "org.gnome.desktop.interface", "cursor-size", "ctk-cursor-theme-size", G_TYPE_INT((GType) ((6) << (2))), { .i = 32 } },
527 { FALSE(0), "org.gnome.desktop.interface", "font-name", "ctk-font-name", G_TYPE_STRING((GType) ((16) << (2))), { .s = "Cantarell 11" } },
528 { FALSE(0), "org.gnome.desktop.interface", "cursor-blink", "ctk-cursor-blink", G_TYPE_BOOLEAN((GType) ((5) << (2))), { .b = TRUE(!(0)) } },
529 { FALSE(0), "org.gnome.desktop.interface", "cursor-blink-time", "ctk-cursor-blink-time", G_TYPE_INT((GType) ((6) << (2))), { .i = 1200 } },
530 { FALSE(0), "org.gnome.desktop.interface", "cursor-blink-timeout", "ctk-cursor-blink-timeout", G_TYPE_INT((GType) ((6) << (2))), { .i = 3600 } },
531 { FALSE(0), "org.gnome.desktop.interface", "ctk-im-module", "ctk-im-module", G_TYPE_STRING((GType) ((16) << (2))), { .s = "simple" } },
532 { FALSE(0), "org.gnome.desktop.interface", "enable-animations", "ctk-enable-animations", G_TYPE_BOOLEAN((GType) ((5) << (2))), { .b = TRUE(!(0)) } },
533 { FALSE(0), "org.gnome.desktop.interface", "ctk-enable-primary-paste", "ctk-enable-primary-paste", G_TYPE_BOOLEAN((GType) ((5) << (2))), { .b = TRUE(!(0)) } },
534 { FALSE(0), "org.gnome.desktop.interface", "overlay-scrolling", "ctk-overlay-scrolling", G_TYPE_BOOLEAN((GType) ((5) << (2))), { .b = TRUE(!(0)) } },
535 { FALSE(0), "org.gnome.desktop.peripherals.mouse", "double-click", "ctk-double-click-time", G_TYPE_INT((GType) ((6) << (2))), { .i = 400 } },
536 { FALSE(0), "org.gnome.desktop.peripherals.mouse", "drag-threshold", "ctk-dnd-drag-threshold", G_TYPE_INT((GType) ((6) << (2))), {.i = 8 } },
537 { FALSE(0), "org.gnome.settings-daemon.peripherals.mouse", "double-click", "ctk-double-click-time", G_TYPE_INT((GType) ((6) << (2))), { .i = 400 } },
538 { FALSE(0), "org.gnome.settings-daemon.peripherals.mouse", "drag-threshold", "ctk-dnd-drag-threshold", G_TYPE_INT((GType) ((6) << (2))), {.i = 8 } },
539 { FALSE(0), "org.gnome.desktop.sound", "theme-name", "ctk-sound-theme-name", G_TYPE_STRING((GType) ((16) << (2))), { .s = "freedesktop" } },
540 { FALSE(0), "org.gnome.desktop.sound", "event-sounds", "ctk-enable-event-sounds", G_TYPE_BOOLEAN((GType) ((5) << (2))), { .b = TRUE(!(0)) } },
541 { FALSE(0), "org.gnome.desktop.sound", "input-feedback-sounds", "ctk-enable-input-feedback-sounds", G_TYPE_BOOLEAN((GType) ((5) << (2))), { . b = FALSE(0) } },
542 { FALSE(0), "org.gnome.desktop.privacy", "recent-files-max-age", "ctk-recent-files-max-age", G_TYPE_INT((GType) ((6) << (2))), { .i = 30 } },
543 { FALSE(0), "org.gnome.desktop.privacy", "remember-recent-files", "ctk-recent-files-enabled", G_TYPE_BOOLEAN((GType) ((5) << (2))), { .b = TRUE(!(0)) } },
544 { FALSE(0), WM_SETTINGS_SCHEMA"org.gnome.desktop.wm.preferences", "button-layout", "ctk-decoration-layout", G_TYPE_STRING((GType) ((16) << (2))), { .s = "menu:close" } },
545 { FALSE(0), CLASSIC_WM_SETTINGS_SCHEMA"org.gnome.shell.extensions.classic-overrides", "button-layout", "ctk-decoration-layout", G_TYPE_STRING((GType) ((16) << (2))), { .s = "menu:close" } },
546 { FALSE(0), "org.gnome.desktop.interface", "font-antialiasing", "ctk-xft-antialias", G_TYPE_NONE((GType) ((1) << (2))), { .i = 0 } },
547 { FALSE(0), "org.gnome.desktop.interface", "font-hinting", "ctk-xft-hinting", G_TYPE_NONE((GType) ((1) << (2))), { .i = 0 } },
548 { FALSE(0), "org.gnome.desktop.interface", "font-hinting", "ctk-xft-hintstyle", G_TYPE_NONE((GType) ((1) << (2))), { .i = 0 } },
549 { FALSE(0), "org.gnome.desktop.interface", "font-rgba-order", "ctk-xft-rgba", G_TYPE_NONE((GType) ((1) << (2))), { .i = 0 } },
550 { FALSE(0), "org.gnome.settings-daemon.plugins.xsettings", "antialiasing", "ctk-xft-antialias", G_TYPE_NONE((GType) ((1) << (2))), { .i = 0 } },
551 { FALSE(0), "org.gnome.settings-daemon.plugins.xsettings", "hinting", "ctk-xft-hinting", G_TYPE_NONE((GType) ((1) << (2))), { .i = 0 } },
552 { FALSE(0), "org.gnome.settings-daemon.plugins.xsettings", "hinting", "ctk-xft-hintstyle", G_TYPE_NONE((GType) ((1) << (2))), { .i = 0 } },
553 { FALSE(0), "org.gnome.settings-daemon.plugins.xsettings", "rgba-order", "ctk-xft-rgba", G_TYPE_NONE((GType) ((1) << (2))), { .i = 0 } },
554 { FALSE(0), "org.gnome.desktop.interface", "text-scaling-factor", "ctk-xft-dpi" , G_TYPE_NONE((GType) ((1) << (2))), { .i = 0 } },
555 { FALSE(0), "org.gnome.desktop.wm.preferences", "action-double-click-titlebar", "ctk-titlebar-double-click", G_TYPE_STRING((GType) ((16) << (2))), { .s = "toggle-maximize" } },
556 { FALSE(0), "org.gnome.desktop.wm.preferences", "action-middle-click-titlebar", "ctk-titlebar-middle-click", G_TYPE_STRING((GType) ((16) << (2))), { .s = "none" } },
557 { FALSE(0), "org.gnome.desktop.wm.preferences", "action-right-click-titlebar", "ctk-titlebar-right-click", G_TYPE_STRING((GType) ((16) << (2))), { .s = "menu" } },
558 { FALSE(0), "org.gnome.desktop.a11y", "always-show-text-caret", "ctk-keynav-use-caret", G_TYPE_BOOLEAN((GType) ((5) << (2))), { .b = FALSE(0) } },
559 { FALSE(0), "org.gnome.fontconfig", "serial", "ctk-fontconfig-timestamp", G_TYPE_INT((GType) ((6) << (2))), { .i = 0 } }
560};
561
562static TranslationEntry *
563find_translation_entry_by_schema (const char *schema,
564 const gchar *key)
565{
566 guint i;
567
568 for (i = 0; i < G_N_ELEMENTS (translations)(sizeof (translations) / sizeof ((translations)[0])); i++)
569 {
570 if (g_str_equal (schema, translations[i].schema)(strcmp ((const char *) (schema), (const char *) (translations
[i].schema)) == 0)
&&
571 g_str_equal (key, translations[i].key)(strcmp ((const char *) (key), (const char *) (translations[i
].key)) == 0)
)
572 return &translations[i];
573 }
574
575 return NULL((void*)0);
576}
577
578static TranslationEntry *
579find_translation_entry_by_key (GSettings *settings,
580 const char *key)
581{
582 char *schema;
583 TranslationEntry *entry;
584
585 g_object_get (settings, "schema", &schema, NULL((void*)0));
586 entry = find_translation_entry_by_schema (schema, key);
587 g_free (schema);
588
589 return entry;
590}
591
592static TranslationEntry *
593find_translation_entry_by_setting (const gchar *setting)
594{
595 guint i;
596
597 for (i = 0; i < G_N_ELEMENTS (translations)(sizeof (translations) / sizeof ((translations)[0])); i++)
598 {
599 if (g_str_equal (setting, translations[i].setting)(strcmp ((const char *) (setting), (const char *) (translations
[i].setting)) == 0)
)
600 return &translations[i];
601 }
602
603 return NULL((void*)0);
604}
605
606static void
607settings_changed (GSettings *settings,
608 const gchar *key,
609 CdkScreen *screen)
610{
611 TranslationEntry *entry;
612
613 entry = find_translation_entry_by_key (settings, key);
614
615 if (entry != NULL((void*)0))
616 {
617 if (entry->type != G_TYPE_NONE((GType) ((1) << (2))))
618 notify_setting (screen, entry->setting);
619 else
620 update_xft_settings (screen);
621 }
622}
623
624static void
625apply_portal_setting (TranslationEntry *entry,
626 GVariant *value,
627 CdkScreen *screen)
628{
629 switch (entry->type)
630 {
631 case G_TYPE_STRING((GType) ((16) << (2))):
632 entry->fallback.s = g_intern_string (g_variant_get_string (value, NULL((void*)0)));
633 break;
634 case G_TYPE_INT((GType) ((6) << (2))):
635 entry->fallback.i = g_variant_get_int32 (value);
636 break;
637 case G_TYPE_BOOLEAN((GType) ((5) << (2))):
638 entry->fallback.b = g_variant_get_boolean (value);
639 break;
640 case G_TYPE_NONE((GType) ((1) << (2))):
641 if (strcmp (entry->key, "antialiasing") == 0 ||
642 strcmp (entry->key, "font-antialiasing") == 0)
643 entry->fallback.i = get_antialiasing (g_variant_get_string (value, NULL((void*)0)));
644 else if (strcmp (entry->key, "hinting") == 0 ||
645 strcmp (entry->key, "font-hinting") == 0)
646 entry->fallback.i = get_hinting (g_variant_get_string (value, NULL((void*)0)));
647 else if (strcmp (entry->key, "rgba-order") == 0 ||
648 strcmp (entry->key, "font-rgba-order") == 0)
649 entry->fallback.i = get_order (g_variant_get_string (value, NULL((void*)0)));
650 else if (strcmp (entry->key, "text-scaling-factor") == 0)
651 entry->fallback.i = (int) (g_variant_get_double (value) * 65536.0);
652 update_xft_settings (screen);
653 break;
654 default:
655 break;
656 }
657}
658
659static void
660settings_portal_changed (GDBusProxy *proxy G_GNUC_UNUSED__attribute__ ((__unused__)),
661 const char *sender_name G_GNUC_UNUSED__attribute__ ((__unused__)),
662 const char *signal_name,
663 GVariant *parameters,
664 CdkScreen *screen)
665{
666 if (strcmp (signal_name, "SettingChanged") == 0)
667 {
668 const char *namespace;
669 const char *name;
670 GVariant *value;
671 TranslationEntry *entry;
672
673 g_variant_get (parameters, "(&s&sv)", &namespace, &name, &value);
674
675 entry = find_translation_entry_by_schema (namespace, name);
676 if (entry != NULL((void*)0))
677 {
678 char *a = g_variant_print (value, FALSE(0));
679 g_debug ("Using changed portal setting %s %s: %s", namespace, name, a);
680 g_free (a);
681 apply_portal_setting (entry, value, screen);
682 notify_setting (screen, entry->setting);
683 }
684 else
685 g_debug ("Ignoring portal setting %s %s", namespace, name);
686
687 g_variant_unref (value);
688 }
689}
690
691static void fontconfig_dbus_proxy_open_cb (GObject *object,
692 GAsyncResult *result,
693 gpointer user_data);
694
695#define PORTAL_BUS_NAME"org.freedesktop.portal.Desktop" "org.freedesktop.portal.Desktop"
696#define PORTAL_OBJECT_PATH"/org/freedesktop/portal/desktop" "/org/freedesktop/portal/desktop"
697#define PORTAL_SETTINGS_INTERFACE"org.freedesktop.portal.Settings" "org.freedesktop.portal.Settings"
698
699static void
700init_settings (CdkScreen *screen)
701{
702 CdkWaylandScreen *screen_wayland = CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
;
703 GSettingsSchemaSource *source;
704 GSettingsSchema *schema;
705 GSettings *settings;
706 gint i;
707
708 if (cdk_should_use_portal ())
709 {
710 GVariant *ret;
711 GError *error = NULL((void*)0);
712 const char *schema;
713 GVariant *val;
714 GVariantIter *iter;
715 const char *patterns[] = { "org.gnome.*", NULL((void*)0) };
716
717 screen_wayland->settings_portal = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
718 G_DBUS_PROXY_FLAGS_NONE,
719 NULL((void*)0),
720 PORTAL_BUS_NAME"org.freedesktop.portal.Desktop",
721 PORTAL_OBJECT_PATH"/org/freedesktop/portal/desktop",
722 PORTAL_SETTINGS_INTERFACE"org.freedesktop.portal.Settings",
723 NULL((void*)0),
724 &error);
725 if (error)
726 {
727 g_warning ("Settings portal not found: %s", error->message);
728 g_error_free (error);
729
730 goto fallback;
731 }
732
733 ret = g_dbus_proxy_call_sync (screen_wayland->settings_portal,
734 "ReadAll",
735 g_variant_new ("(^as)", patterns),
736 G_DBUS_CALL_FLAGS_NONE,
737 G_MAXINT2147483647,
738 NULL((void*)0),
739 &error);
740 if (error)
741 {
742 g_warning ("Failed to read portal settings: %s", error->message);
743 g_error_free (error);
744 g_clear_object (&screen_wayland->settings_portal)do { _Static_assert (sizeof *((&screen_wayland->settings_portal
)) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&screen_wayland->settings_portal))) _pp = ((&screen_wayland
->settings_portal)); __typeof__ (*((&screen_wayland->
settings_portal))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (
g_object_unref) (_ptr); } while (0)
;
745
746 goto fallback;
747 }
748
749 g_variant_get (ret, "(a{sa{sv}})", &iter);
750
751 while (g_variant_iter_loop (iter, "{s@a{sv}}", &schema, &val))
752 {
753 GVariantIter *iter2 = g_variant_iter_new (val);
754 const char *key;
755 GVariant *v;
756
757 while (g_variant_iter_loop (iter2, "{sv}", &key, &v))
758 {
759 TranslationEntry *entry = find_translation_entry_by_schema (schema, key);
760 if (entry)
761 {
762 char *a = g_variant_print (v, FALSE(0));
763 g_debug ("Using portal setting for %s %s: %s\n", schema, key, a);
764 g_free (a);
765 entry->valid = TRUE(!(0));
766 apply_portal_setting (entry, v, screen);
767 }
768 else
769 {
770 g_debug ("Ignoring portal setting for %s %s", schema, key);
771 }
772 }
773 g_variant_iter_free (iter2);
774 }
775 g_variant_iter_free (iter);
776
777 g_variant_unref (ret);
778
779 g_signal_connect (screen_wayland->settings_portal, "g-signal",g_signal_connect_data ((screen_wayland->settings_portal), (
"g-signal"), (((GCallback) (settings_portal_changed))), (screen_wayland
), ((void*)0), (GConnectFlags) 0)
780 G_CALLBACK (settings_portal_changed), screen_wayland)g_signal_connect_data ((screen_wayland->settings_portal), (
"g-signal"), (((GCallback) (settings_portal_changed))), (screen_wayland
), ((void*)0), (GConnectFlags) 0)
;
781
782 return;
783
784fallback:
785 g_debug ("Failed to use Settings portal; falling back to gsettings");
786 }
787
788 screen_wayland->dbus_cancellable = g_cancellable_new ();
789 g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
790 G_DBUS_PROXY_FLAGS_NONE,
791 NULL((void*)0),
792 CTK_SETTINGS_DBUS_NAME"org.ctk.Settings",
793 CTK_SETTINGS_DBUS_PATH"/org/ctk/Settings",
794 CTK_SETTINGS_DBUS_NAME"org.ctk.Settings",
795 screen_wayland->dbus_cancellable,
796 fontconfig_dbus_proxy_open_cb,
797 screen_wayland);
798
799 screen_wayland->settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL((void*)0), g_object_unref);
800
801 source = g_settings_schema_source_get_default ();
802 if (source == NULL((void*)0))
803 return;
804
805 for (i = 0; i < G_N_ELEMENTS (translations)(sizeof (translations) / sizeof ((translations)[0])); i++)
806 {
807 schema = g_settings_schema_source_lookup (source, translations[i].schema, TRUE(!(0)));
808 if (!schema)
809 continue;
810
811 if (g_hash_table_lookup (screen_wayland->settings, (gpointer)translations[i].schema) == NULL((void*)0))
812 {
813 settings = g_settings_new_full (schema, NULL((void*)0), NULL((void*)0));
814 g_signal_connect (settings, "changed",g_signal_connect_data ((settings), ("changed"), (((GCallback)
(settings_changed))), (screen), ((void*)0), (GConnectFlags) 0
)
815 G_CALLBACK (settings_changed), screen)g_signal_connect_data ((settings), ("changed"), (((GCallback)
(settings_changed))), (screen), ((void*)0), (GConnectFlags) 0
)
;
816 g_hash_table_insert (screen_wayland->settings, (gpointer)translations[i].schema, settings);
817 }
818
819 if (g_settings_schema_has_key (schema, translations[i].key))
820 translations[i].valid = TRUE(!(0));
821
822 g_settings_schema_unref (schema);
823 }
824
825 update_xft_settings (screen);
826}
827
828static void
829ctk_shell_handle_capabilities (void *data,
830 struct ctk_shell1 *shell G_GNUC_UNUSED__attribute__ ((__unused__)),
831 uint32_t capabilities)
832{
833 CdkScreen *screen = data;
834 CdkWaylandScreen *screen_wayland = CDK_WAYLAND_SCREEN (data)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((data)), ((_cdk_wayland_screen_get_type ()))
))))
;
835
836 screen_wayland->shell_capabilities = capabilities;
837
838 notify_setting (screen, "ctk-shell-shows-app-menu");
839 notify_setting (screen, "ctk-shell-shows-menubar");
840 notify_setting (screen, "ctk-shell-shows-desktop");
841}
842
843struct ctk_shell1_listener cdk_screen_ctk_shell_listener = {
844 ctk_shell_handle_capabilities
845};
846
847void
848_cdk_wayland_screen_set_has_ctk_shell (CdkScreen *screen)
849{
850 CdkWaylandDisplay *display_wayland =
851 CDK_WAYLAND_DISPLAY (CDK_WAYLAND_SCREEN (screen)->display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWaylandScreen*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type
()))))))->display)), ((cdk_wayland_display_get_type()))))
))
;
852
853 ctk_shell1_add_listener (display_wayland->ctk_shell,
854 &cdk_screen_ctk_shell_listener,
855 screen);
856}
857
858static void
859set_value_from_entry (CdkScreen *screen,
860 TranslationEntry *entry,
861 GValue *value)
862{
863 CdkWaylandScreen *screen_wayland = CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
;
864 GSettings *settings;
865
866 if (screen_wayland->settings_portal)
867 {
868 switch (entry->type)
869 {
870 case G_TYPE_STRING((GType) ((16) << (2))):
871 g_value_set_string (value, entry->fallback.s);
872 break;
873 case G_TYPE_INT((GType) ((6) << (2))):
874 if (g_str_equal (entry->setting, "ctk-fontconfig-timestamp")(strcmp ((const char *) (entry->setting), (const char *) (
"ctk-fontconfig-timestamp")) == 0)
)
875 g_value_set_uint (value, (guint)entry->fallback.i);
876 else
877 g_value_set_int (value, entry->fallback.i);
878 break;
879 case G_TYPE_BOOLEAN((GType) ((5) << (2))):
880 g_value_set_boolean (value, entry->fallback.b);
881 break;
882 case G_TYPE_NONE((GType) ((1) << (2))):
883 if (g_str_equal (entry->setting, "ctk-xft-antialias")(strcmp ((const char *) (entry->setting), (const char *) (
"ctk-xft-antialias")) == 0)
)
884 g_value_set_int (value, screen_wayland->xft_settings.antialias);
885 else if (g_str_equal (entry->setting, "ctk-xft-hinting")(strcmp ((const char *) (entry->setting), (const char *) (
"ctk-xft-hinting")) == 0)
)
886 g_value_set_int (value, screen_wayland->xft_settings.hinting);
887 else if (g_str_equal (entry->setting, "ctk-xft-hintstyle")(strcmp ((const char *) (entry->setting), (const char *) (
"ctk-xft-hintstyle")) == 0)
)
888 g_value_set_static_string (value, screen_wayland->xft_settings.hintstyle);
889 else if (g_str_equal (entry->setting, "ctk-xft-rgba")(strcmp ((const char *) (entry->setting), (const char *) (
"ctk-xft-rgba")) == 0)
)
890 g_value_set_static_string (value, screen_wayland->xft_settings.rgba);
891 else if (g_str_equal (entry->setting, "ctk-xft-dpi")(strcmp ((const char *) (entry->setting), (const char *) (
"ctk-xft-dpi")) == 0)
)
892 g_value_set_int (value, screen_wayland->xft_settings.dpi);
893 else
894 g_assert_not_reached ()do { g_assertion_message_expr ("Cdk", "cdkscreen-wayland.c", 894
, ((const char*) (__func__)), ((void*)0)); } while (0)
;
895 break;
896 default:
897 g_assert_not_reached ()do { g_assertion_message_expr ("Cdk", "cdkscreen-wayland.c", 897
, ((const char*) (__func__)), ((void*)0)); } while (0)
;
898 break;
899 }
900
901 return;
902 }
903
904 settings = (GSettings *)g_hash_table_lookup (screen_wayland->settings, entry->schema);
905 switch (entry->type)
906 {
907 case G_TYPE_STRING((GType) ((16) << (2))):
908 if (settings && entry->valid)
909 {
910 gchar *s;
911 s = g_settings_get_string (settings, entry->key);
912 g_value_set_string (value, s);
913 g_free (s);
914 }
915 else
916 {
917 g_value_set_static_string (value, entry->fallback.s);
918 }
919 break;
920 case G_TYPE_INT((GType) ((6) << (2))):
921 if (g_str_equal (entry->setting, "ctk-fontconfig-timestamp")(strcmp ((const char *) (entry->setting), (const char *) (
"ctk-fontconfig-timestamp")) == 0)
)
922 g_value_set_uint (value, screen_wayland->dbus_settings.fontconfig_timestamp);
923 else
924 g_value_set_int (value, settings && entry->valid
925 ? g_settings_get_int (settings, entry->key)
926 : entry->fallback.i);
927 break;
928 case G_TYPE_BOOLEAN((GType) ((5) << (2))):
929 g_value_set_boolean (value, settings && entry->valid
930 ? g_settings_get_boolean (settings, entry->key)
931 : entry->fallback.b);
932 break;
933 case G_TYPE_NONE((GType) ((1) << (2))):
934 if (g_str_equal (entry->setting, "ctk-xft-antialias")(strcmp ((const char *) (entry->setting), (const char *) (
"ctk-xft-antialias")) == 0)
)
935 g_value_set_int (value, screen_wayland->xft_settings.antialias);
936 else if (g_str_equal (entry->setting, "ctk-xft-hinting")(strcmp ((const char *) (entry->setting), (const char *) (
"ctk-xft-hinting")) == 0)
)
937 g_value_set_int (value, screen_wayland->xft_settings.hinting);
938 else if (g_str_equal (entry->setting, "ctk-xft-hintstyle")(strcmp ((const char *) (entry->setting), (const char *) (
"ctk-xft-hintstyle")) == 0)
)
939 g_value_set_static_string (value, screen_wayland->xft_settings.hintstyle);
940 else if (g_str_equal (entry->setting, "ctk-xft-rgba")(strcmp ((const char *) (entry->setting), (const char *) (
"ctk-xft-rgba")) == 0)
)
941 g_value_set_static_string (value, screen_wayland->xft_settings.rgba);
942 else if (g_str_equal (entry->setting, "ctk-xft-dpi")(strcmp ((const char *) (entry->setting), (const char *) (
"ctk-xft-dpi")) == 0)
)
943 g_value_set_int (value, screen_wayland->xft_settings.dpi);
944 else
945 g_assert_not_reached ()do { g_assertion_message_expr ("Cdk", "cdkscreen-wayland.c", 945
, ((const char*) (__func__)), ((void*)0)); } while (0)
;
946 break;
947 default:
948 g_assert_not_reached ()do { g_assertion_message_expr ("Cdk", "cdkscreen-wayland.c", 948
, ((const char*) (__func__)), ((void*)0)); } while (0)
;
949 }
950}
951
952static void
953set_decoration_layout_from_entry (CdkScreen *screen,
954 TranslationEntry *entry,
955 GValue *value)
956{
957 CdkWaylandScreen *screen_wayland = CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
;
958 GSettings *settings = NULL((void*)0);
959 const char *session;
960
961 if (screen_wayland->settings_portal)
962 {
963 g_value_set_string (value, entry->fallback.s);
964 return;
965 }
966
967 /* Hack: until we get session-dependent defaults in GSettings,
968 * swap out the usual schema for the "classic" one when
969 * running in classic mode
970 */
971 session = g_getenv ("XDG_CURRENT_DESKTOP");
972 if (session && strstr (session, "GNOME-Classic"))
973 settings = (GSettings *)g_hash_table_lookup (screen_wayland->settings, CLASSIC_WM_SETTINGS_SCHEMA"org.gnome.shell.extensions.classic-overrides");
974
975 if (settings == NULL((void*)0))
976 settings = (GSettings *)g_hash_table_lookup (screen_wayland->settings, WM_SETTINGS_SCHEMA"org.gnome.desktop.wm.preferences");
977
978 if (settings)
979 {
980 gchar *s = g_settings_get_string (settings, entry->key);
981
982 translate_wm_button_layout_to_ctk (s);
983 g_value_set_string (value, s);
984
985 g_free (s);
986 }
987 else
988 {
989 g_value_set_static_string (value, entry->fallback.s);
990 }
991}
992
993static gboolean
994set_capability_setting (CdkScreen *screen,
995 GValue *value,
996 enum ctk_shell1_capability test)
997{
998 CdkWaylandScreen *wayland_screen = CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
;
999
1000 g_value_set_boolean (value, (wayland_screen->shell_capabilities & test) == test);
1001
1002 return TRUE(!(0));
1003}
1004
1005static gboolean
1006cdk_wayland_screen_get_setting (CdkScreen *screen,
1007 const gchar *name,
1008 GValue *value)
1009{
1010 CdkWaylandScreen *wayland_screen = CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
;
1011 TranslationEntry *entry;
1012
1013 g_return_val_if_fail (CDK_IS_SCREEN (screen), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((cdk_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_SCREEN (screen)"); return ((0)); } } while (0)
;
1014
1015 if (wayland_screen->settings != NULL((void*)0) &&
1016 g_hash_table_size (wayland_screen->settings) == 0)
1017 return FALSE(0);
1018
1019 entry = find_translation_entry_by_setting (name);
1020 if (entry != NULL((void*)0))
1021 {
1022 if (strcmp (name, "ctk-decoration-layout") == 0)
1023 set_decoration_layout_from_entry (screen, entry, value);
1024 else
1025 set_value_from_entry (screen, entry, value);
1026 return TRUE(!(0));
1027 }
1028
1029 if (strcmp (name, "ctk-shell-shows-app-menu") == 0)
1030 return set_capability_setting (screen, value,
1031 CTK_SHELL1_CAPABILITY_GLOBAL_APP_MENU);
1032
1033 if (strcmp (name, "ctk-shell-shows-menubar") == 0)
1034 return set_capability_setting (screen, value,
1035 CTK_SHELL1_CAPABILITY_GLOBAL_MENU_BAR);
1036
1037 if (strcmp (name, "ctk-shell-shows-desktop") == 0)
1038 return set_capability_setting (screen, value,
1039 CTK_SHELL1_CAPABILITY_DESKTOP_ICONS);
1040
1041 if (strcmp (name, "ctk-dialogs-use-header") == 0)
1042 {
1043 g_value_set_boolean (value, TRUE(!(0)));
1044 return TRUE(!(0));
1045 }
1046
1047 if (strcmp (name, "ctk-fontconfig-timestamp") == 0)
1048 {
1049 g_value_set_uint (value, wayland_screen->dbus_settings.fontconfig_timestamp);
1050 return TRUE(!(0));
1051 }
1052
1053 if (strcmp (name, "ctk-modules") == 0)
1054 {
1055 g_value_set_string (value, wayland_screen->dbus_settings.modules);
1056 return TRUE(!(0));
1057 }
1058
1059 return FALSE(0);
1060}
1061
1062typedef struct _CdkWaylandVisual CdkWaylandVisual;
1063typedef struct _CdkWaylandVisualClass CdkWaylandVisualClass;
1064
1065struct _CdkWaylandVisual
1066{
1067 CdkVisual visual;
1068};
1069
1070struct _CdkWaylandVisualClass
1071{
1072 CdkVisualClass parent_class;
1073};
1074
1075GType _cdk_wayland_visual_get_type (void);
1076
1077G_DEFINE_TYPE (CdkWaylandVisual, _cdk_wayland_visual, CDK_TYPE_VISUAL)static void _cdk_wayland_visual_init (CdkWaylandVisual *self)
; static void _cdk_wayland_visual_class_init (CdkWaylandVisualClass
*klass); static GType _cdk_wayland_visual_get_type_once (void
); static gpointer _cdk_wayland_visual_parent_class = ((void*
)0); static gint CdkWaylandVisual_private_offset; static void
_cdk_wayland_visual_class_intern_init (gpointer klass) { _cdk_wayland_visual_parent_class
= g_type_class_peek_parent (klass); if (CdkWaylandVisual_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CdkWaylandVisual_private_offset
); _cdk_wayland_visual_class_init ((CdkWaylandVisualClass*) klass
); } __attribute__ ((__unused__)) static inline gpointer _cdk_wayland_visual_get_instance_private
(CdkWaylandVisual *self) { return (((gpointer) ((guint8*) (self
) + (glong) (CdkWaylandVisual_private_offset)))); } GType _cdk_wayland_visual_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= _cdk_wayland_visual_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType _cdk_wayland_visual_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((cdk_visual_get_type ()), g_intern_static_string ("CdkWaylandVisual"
), sizeof (CdkWaylandVisualClass), (GClassInitFunc)(void (*)(
void)) _cdk_wayland_visual_class_intern_init, sizeof (CdkWaylandVisual
), (GInstanceInitFunc)(void (*)(void)) _cdk_wayland_visual_init
, (GTypeFlags) 0); { {{};} } return g_define_type_id; }
1078
1079static void
1080_cdk_wayland_visual_class_init (CdkWaylandVisualClass *klass G_GNUC_UNUSED__attribute__ ((__unused__)))
1081{
1082}
1083
1084static void
1085_cdk_wayland_visual_init (CdkWaylandVisual *visual G_GNUC_UNUSED__attribute__ ((__unused__)))
1086{
1087}
1088
1089static gint
1090cdk_wayland_screen_visual_get_best_depth (CdkScreen *screen G_GNUC_UNUSED__attribute__ ((__unused__)))
1091{
1092 return 32;
1093}
1094
1095static CdkVisualType
1096cdk_wayland_screen_visual_get_best_type (CdkScreen *screen G_GNUC_UNUSED__attribute__ ((__unused__)))
1097{
1098 return CDK_VISUAL_TRUE_COLOR;
1099}
1100
1101static CdkVisual*
1102cdk_wayland_screen_visual_get_best (CdkScreen *screen)
1103{
1104 return CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
->visual;
1105}
1106
1107static CdkVisual*
1108cdk_wayland_screen_visual_get_best_with_depth (CdkScreen *screen,
1109 gint depth)
1110{
1111 if (depth == 32)
1112 return CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
->visual;
1113 else
1114 return NULL((void*)0);
1115}
1116
1117static CdkVisual*
1118cdk_wayland_screen_visual_get_best_with_type (CdkScreen *screen,
1119 CdkVisualType visual_type)
1120{
1121 if (visual_type == CDK_VISUAL_TRUE_COLOR)
1122 return CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
->visual;
1123 else
1124 return NULL((void*)0);
1125}
1126
1127static CdkVisual*
1128cdk_wayland_screen_visual_get_best_with_both (CdkScreen *screen,
1129 gint depth,
1130 CdkVisualType visual_type)
1131{
1132 if (depth == 32 && visual_type == CDK_VISUAL_TRUE_COLOR)
1133 return CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
->visual;
1134 else
1135 return NULL((void*)0);
1136}
1137
1138static void
1139cdk_wayland_screen_query_depths (CdkScreen *screen G_GNUC_UNUSED__attribute__ ((__unused__)),
1140 gint **depths,
1141 gint *count)
1142{
1143 static gint static_depths[] = { 32 };
1144
1145 *count = G_N_ELEMENTS(static_depths)(sizeof (static_depths) / sizeof ((static_depths)[0]));
1146 *depths = static_depths;
1147}
1148
1149static void
1150cdk_wayland_screen_query_visual_types (CdkScreen *screen G_GNUC_UNUSED__attribute__ ((__unused__)),
1151 CdkVisualType **visual_types,
1152 gint *count)
1153{
1154 static CdkVisualType static_visual_types[] = { CDK_VISUAL_TRUE_COLOR };
1155
1156 *count = G_N_ELEMENTS(static_visual_types)(sizeof (static_visual_types) / sizeof ((static_visual_types)
[0]))
;
1157 *visual_types = static_visual_types;
1158}
1159
1160static GList *
1161cdk_wayland_screen_list_visuals (CdkScreen *screen)
1162{
1163 GList *list;
1164 CdkWaylandScreen *screen_wayland;
1165
1166 g_return_val_if_fail (CDK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((cdk_screen_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_SCREEN (screen)"); return (((void*)0)); } } while
(0)
;
1167 screen_wayland = CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
;
1168
1169 list = g_list_append (NULL((void*)0), screen_wayland->visual);
1170
1171 return list;
1172}
1173
1174#define CDK_TYPE_WAYLAND_VISUAL(_cdk_wayland_visual_get_type ()) (_cdk_wayland_visual_get_type ())
1175#define CDK_WAYLAND_VISUAL(object)((((CdkWaylandVisual*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((object)), ((_cdk_wayland_visual_get_type ()
))))))
(G_TYPE_CHECK_INSTANCE_CAST ((object), CDK_TYPE_WAYLAND_VISUAL, CdkWaylandVisual)(((CdkWaylandVisual*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((_cdk_wayland_visual_get_type ())))))
)
1176
1177/* Currently, the Wayland backend only ever uses ARGB8888.
1178 */
1179static CdkVisual *
1180cdk_wayland_visual_new (CdkScreen *screen)
1181{
1182 CdkVisual *visual;
1183
1184 visual = g_object_new (CDK_TYPE_WAYLAND_VISUAL(_cdk_wayland_visual_get_type ()), NULL((void*)0));
1185 visual->screen = CDK_SCREEN (screen)((((CdkScreen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), ((cdk_screen_get_type ()))))))
;
1186 visual->type = CDK_VISUAL_TRUE_COLOR;
1187 visual->depth = 32;
1188 visual->red_mask = 0xff0000;
1189 visual->green_mask = 0x00ff00;
1190 visual->blue_mask = 0x0000ff;
1191 visual->bits_per_rgb = 8;
1192
1193 return visual;
1194}
1195
1196static void
1197dbus_properties_change_cb (GDBusProxy *proxy G_GNUC_UNUSED__attribute__ ((__unused__)),
1198 GVariant *changed_properties,
1199 const gchar* const *invalidated_properties G_GNUC_UNUSED__attribute__ ((__unused__)),
1200 gpointer user_data)
1201{
1202 CdkWaylandScreen *screen_wayland = user_data;
1203 GVariant *value;
1204 gint64 timestamp;
1205
1206 if (g_variant_n_children (changed_properties) <= 0)
1207 return;
1208
1209 value = g_variant_lookup_value (changed_properties,
1210 "FontconfigTimestamp",
1211 G_VARIANT_TYPE_INT64((const GVariantType *) "x"));
1212
1213 if (value != NULL((void*)0))
1214 {
1215 timestamp = g_variant_get_int64 (value);
1216 timestamp = timestamp / G_TIME_SPAN_SECOND((1000000L));
1217
1218 if (timestamp > 0 && timestamp <= G_MAXUINT(2147483647 *2U +1U))
1219 screen_wayland->dbus_settings.fontconfig_timestamp = (guint)timestamp;
1220 else if (timestamp > G_MAXUINT(2147483647 *2U +1U))
1221 g_warning ("Could not handle fontconfig update: timestamp out of bound");
1222
1223 notify_setting (CDK_SCREEN (screen_wayland)((((CdkScreen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen_wayland)), ((cdk_screen_get_type ()))))))
, "ctk-fontconfig-timestamp");
1224
1225 g_variant_unref (value);
1226 }
1227
1228 value = g_variant_lookup_value (changed_properties,
1229 "Modules",
1230 G_VARIANT_TYPE_STRING((const GVariantType *) "s"));
1231
1232 if (value != NULL((void*)0))
1233 {
1234 g_free (screen_wayland->dbus_settings.modules);
1235
1236 screen_wayland->dbus_settings.modules = g_variant_dup_string (value, NULL((void*)0));
1237
1238 notify_setting (CDK_SCREEN (screen_wayland)((((CdkScreen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen_wayland)), ((cdk_screen_get_type ()))))))
, "ctk-modules");
1239
1240 g_variant_unref (value);
1241 }
1242}
1243
1244static void
1245fontconfig_dbus_proxy_open_cb (GObject *object G_GNUC_UNUSED__attribute__ ((__unused__)),
1246 GAsyncResult *result,
1247 gpointer user_data)
1248{
1249 CdkWaylandScreen *screen_wayland = user_data;
1250 GDBusProxy *proxy;
1251 GVariant *value;
1252 gint64 timestamp;
1253
1254 proxy = g_dbus_proxy_new_for_bus_finish (result, NULL((void*)0));
1255
1256 if (proxy == NULL((void*)0))
1257 return;
1258
1259 screen_wayland->dbus_proxy = proxy;
1260 screen_wayland->dbus_setting_change_id =
1261 g_signal_connect (screen_wayland->dbus_proxy,g_signal_connect_data ((screen_wayland->dbus_proxy), ("g-properties-changed"
), (((GCallback) (dbus_properties_change_cb))), (screen_wayland
), ((void*)0), (GConnectFlags) 0)
1262 "g-properties-changed",g_signal_connect_data ((screen_wayland->dbus_proxy), ("g-properties-changed"
), (((GCallback) (dbus_properties_change_cb))), (screen_wayland
), ((void*)0), (GConnectFlags) 0)
1263 G_CALLBACK (dbus_properties_change_cb),g_signal_connect_data ((screen_wayland->dbus_proxy), ("g-properties-changed"
), (((GCallback) (dbus_properties_change_cb))), (screen_wayland
), ((void*)0), (GConnectFlags) 0)
1264 screen_wayland)g_signal_connect_data ((screen_wayland->dbus_proxy), ("g-properties-changed"
), (((GCallback) (dbus_properties_change_cb))), (screen_wayland
), ((void*)0), (GConnectFlags) 0)
;
1265
1266 value = g_dbus_proxy_get_cached_property (screen_wayland->dbus_proxy,
1267 "FontconfigTimestamp");
1268
1269 if (value && g_variant_is_of_type (value, G_VARIANT_TYPE_INT64((const GVariantType *) "x")))
1270 {
1271 timestamp = g_variant_get_int64 (value);
1272 timestamp = timestamp / G_TIME_SPAN_SECOND((1000000L));
1273
1274 if (timestamp > 0 && timestamp <= G_MAXUINT(2147483647 *2U +1U))
1275 screen_wayland->dbus_settings.fontconfig_timestamp = (guint)timestamp;
1276 else if (timestamp > G_MAXUINT(2147483647 *2U +1U))
1277 g_warning ("Could not handle fontconfig init: timestamp out of bound");
1278 }
1279
1280 if (value != NULL((void*)0))
1281 g_variant_unref (value);
1282
1283 value = g_dbus_proxy_get_cached_property (screen_wayland->dbus_proxy,
1284 "Modules");
1285
1286 if (value && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING((const GVariantType *) "s")))
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
1287 {
1288 g_free (screen_wayland->dbus_settings.modules);
1289
1290 screen_wayland->dbus_settings.modules = g_variant_dup_string (value, NULL((void*)0));
1291 }
1292
1293 if (value != NULL((void*)0))
1294 g_variant_unref (value);
1295}
1296
1297CdkScreen *
1298_cdk_wayland_screen_new (CdkDisplay *display)
1299{
1300 CdkScreen *screen;
1301 CdkWaylandScreen *screen_wayland;
1302
1303 screen = g_object_new (CDK_TYPE_WAYLAND_SCREEN(_cdk_wayland_screen_get_type ()), NULL((void*)0));
1304
1305 screen_wayland = CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
;
1306 screen_wayland->display = display;
1307 screen_wayland->width = 0;
1308 screen_wayland->height = 0;
1309
1310 screen_wayland->visual = cdk_wayland_visual_new (screen);
1311
1312 screen_wayland->root_window =
1313 _cdk_wayland_screen_create_root_window (screen,
1314 screen_wayland->width,
1315 screen_wayland->height);
1316
1317 init_settings (screen);
1318
1319 return screen;
1320}
1321
1322static void
1323_cdk_wayland_screen_class_init (CdkWaylandScreenClass *klass)
1324{
1325 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
1326 CdkScreenClass *screen_class = CDK_SCREEN_CLASS (klass)((((CdkScreenClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), ((cdk_screen_get_type ()))))))
;
1327
1328 object_class->dispose = cdk_wayland_screen_dispose;
1329 object_class->finalize = cdk_wayland_screen_finalize;
1330
1331 screen_class->get_display = cdk_wayland_screen_get_display;
1332 screen_class->get_width = cdk_wayland_screen_get_width;
1333 screen_class->get_height = cdk_wayland_screen_get_height;
1334 screen_class->get_width_mm = cdk_wayland_screen_get_width_mm;
1335 screen_class->get_height_mm = cdk_wayland_screen_get_height_mm;
1336 screen_class->get_number = cdk_wayland_screen_get_number;
1337 screen_class->get_root_window = cdk_wayland_screen_get_root_window;
1338 screen_class->get_system_visual = cdk_wayland_screen_get_system_visual;
1339 screen_class->get_rgba_visual = cdk_wayland_screen_get_rgba_visual;
1340 screen_class->is_composited = cdk_wayland_screen_is_composited;
1341 screen_class->make_display_name = cdk_wayland_screen_make_display_name;
1342 screen_class->get_active_window = cdk_wayland_screen_get_active_window;
1343 screen_class->get_window_stack = cdk_wayland_screen_get_window_stack;
1344 screen_class->broadcast_client_message = cdk_wayland_screen_broadcast_client_message;
1345 screen_class->get_setting = cdk_wayland_screen_get_setting;
1346 screen_class->visual_get_best_depth = cdk_wayland_screen_visual_get_best_depth;
1347 screen_class->visual_get_best_type = cdk_wayland_screen_visual_get_best_type;
1348 screen_class->visual_get_best = cdk_wayland_screen_visual_get_best;
1349 screen_class->visual_get_best_with_depth = cdk_wayland_screen_visual_get_best_with_depth;
1350 screen_class->visual_get_best_with_type = cdk_wayland_screen_visual_get_best_with_type;
1351 screen_class->visual_get_best_with_both = cdk_wayland_screen_visual_get_best_with_both;
1352 screen_class->query_depths = cdk_wayland_screen_query_depths;
1353 screen_class->query_visual_types = cdk_wayland_screen_query_visual_types;
1354 screen_class->list_visuals = cdk_wayland_screen_list_visuals;
1355}
1356
1357static void
1358_cdk_wayland_screen_init (CdkWaylandScreen *screen_wayland G_GNUC_UNUSED__attribute__ ((__unused__)))
1359{
1360}
1361
1362static void
1363update_screen_size (CdkWaylandScreen *screen_wayland)
1364{
1365 CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (screen_wayland->display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((screen_wayland->display)), ((cdk_wayland_display_get_type
()))))))
;
1366 gboolean emit_changed = FALSE(0);
1367 gint width, height;
1368 gint width_mm, height_mm;
1369 int i;
1370
1371 width = height = 0;
1372 width_mm = height_mm = 0;
1373 for (i = 0; i < display_wayland->monitors->len; i++)
1374 {
1375 CdkMonitor *monitor = display_wayland->monitors->pdata[i];
1376
1377 /* XXX: Largely assuming here that monitor areas
1378 * are contiguous and never overlap.
1379 */
1380 if (monitor->geometry.x > 0)
1381 width_mm += monitor->width_mm;
1382 else
1383 width_mm = MAX (width_mm, monitor->width_mm)(((width_mm) > (monitor->width_mm)) ? (width_mm) : (monitor
->width_mm))
;
1384
1385 if (monitor->geometry.y > 0)
1386 height_mm += monitor->height_mm;
1387 else
1388 height_mm = MAX (height_mm, monitor->height_mm)(((height_mm) > (monitor->height_mm)) ? (height_mm) : (
monitor->height_mm))
;
1389
1390 width = MAX (width, monitor->geometry.x + monitor->geometry.width)(((width) > (monitor->geometry.x + monitor->geometry
.width)) ? (width) : (monitor->geometry.x + monitor->geometry
.width))
;
1391 height = MAX (height, monitor->geometry.y + monitor->geometry.height)(((height) > (monitor->geometry.y + monitor->geometry
.height)) ? (height) : (monitor->geometry.y + monitor->
geometry.height))
;
1392 }
1393
1394 if (screen_wayland->width_mm != width_mm ||
1395 screen_wayland->height_mm != height_mm)
1396 {
1397 emit_changed = TRUE(!(0));
1398 screen_wayland->width_mm = width_mm;
1399 screen_wayland->height_mm = height_mm;
1400 }
1401
1402 if (screen_wayland->width != width ||
1403 screen_wayland->height != height)
1404 {
1405 emit_changed = TRUE(!(0));
1406 screen_wayland->width = width;
1407 screen_wayland->height = height;
1408 }
1409
1410 if (emit_changed)
1411 g_signal_emit_by_name (screen_wayland, "size-changed");
1412}
1413
1414#ifdef G_ENABLE_DEBUG1
1415
1416static const char *
1417subpixel_to_string (int layout)
1418{
1419 int i;
1420 struct { int layout; const char *name; } layouts[] = {
1421 { WL_OUTPUT_SUBPIXEL_UNKNOWN, "unknown" },
1422 { WL_OUTPUT_SUBPIXEL_NONE, "none" },
1423 { WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB, "rgb" },
1424 { WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR, "bgr" },
1425 { WL_OUTPUT_SUBPIXEL_VERTICAL_RGB, "vrgb" },
1426 { WL_OUTPUT_SUBPIXEL_VERTICAL_BGR, "vbgr" },
1427 { 0xffffffff, NULL((void*)0) }
1428 };
1429
1430 for (i = 0; layouts[i].name; i++)
1431 {
1432 if (layouts[i].layout == layout)
1433 return layouts[i].name;
1434 }
1435 return NULL((void*)0);
1436}
1437
1438static const char *
1439transform_to_string (int transform)
1440{
1441 int i;
1442 struct { int transform; const char *name; } transforms[] = {
1443 { WL_OUTPUT_TRANSFORM_NORMAL, "normal" },
1444 { WL_OUTPUT_TRANSFORM_90, "90" },
1445 { WL_OUTPUT_TRANSFORM_180, "180" },
1446 { WL_OUTPUT_TRANSFORM_270, "270" },
1447 { WL_OUTPUT_TRANSFORM_FLIPPED, "flipped" },
1448 { WL_OUTPUT_TRANSFORM_FLIPPED_90, "flipped 90" },
1449 { WL_OUTPUT_TRANSFORM_FLIPPED_180, "flipped 180" },
1450 { WL_OUTPUT_TRANSFORM_FLIPPED_270, "flipped 270" },
1451 { 0xffffffff, NULL((void*)0) }
1452 };
1453
1454 for (i = 0; transforms[i].name; i++)
1455 {
1456 if (transforms[i].transform == transform)
1457 return transforms[i].name;
1458 }
1459 return NULL((void*)0);
1460}
1461
1462#endif
1463
1464static gboolean
1465screen_has_xdg_output_support (CdkScreen *screen)
1466{
1467 CdkDisplay *display = cdk_screen_get_display (screen);
1468 CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((display)), ((cdk_wayland_display_get_type(
)))))))
;
1469
1470 return (display_wayland->xdg_output_manager != NULL((void*)0));
1471}
1472
1473static gboolean
1474monitor_has_xdg_output (CdkWaylandMonitor *monitor)
1475{
1476 return (monitor->xdg_output != NULL((void*)0));
1477}
1478
1479static gboolean
1480should_update_monitor (CdkWaylandMonitor *monitor)
1481{
1482 return (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
->geometry.width != 0 &&
1483 monitor->version < OUTPUT_VERSION_WITH_DONE2);
1484}
1485
1486static gboolean
1487should_expect_xdg_output_done (CdkWaylandMonitor *monitor)
1488{
1489 CdkDisplay *display = CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
->display;
1490 CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((display)), ((cdk_wayland_display_get_type(
)))))))
;
1491
1492 return (monitor_has_xdg_output (monitor) &&
1493 display_wayland->xdg_output_version < NO_XDG_OUTPUT_DONE_SINCE_VERSION3);
1494}
1495
1496static void
1497apply_monitor_change (CdkWaylandMonitor *monitor)
1498{
1499 CdkDisplay *display = CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
->display;
1500 CdkWaylandScreen *screen_wayland = CDK_WAYLAND_SCREEN (cdk_display_get_default_screen (display))((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((cdk_display_get_default_screen (display))),
((_cdk_wayland_screen_get_type ()))))))
;
1501
1502 CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("monitor %d changed position %d %d, size %d %d", monitor->
id, monitor->x, monitor->y, monitor->width, monitor->
height); }; } while (0)
1503 g_message ("monitor %d changed position %d %d, size %d %d",do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("monitor %d changed position %d %d, size %d %d", monitor->
id, monitor->x, monitor->y, monitor->width, monitor->
height); }; } while (0)
1504 monitor->id,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("monitor %d changed position %d %d, size %d %d", monitor->
id, monitor->x, monitor->y, monitor->width, monitor->
height); }; } while (0)
1505 monitor->x, monitor->y,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("monitor %d changed position %d %d, size %d %d", monitor->
id, monitor->x, monitor->y, monitor->width, monitor->
height); }; } while (0)
1506 monitor->width, monitor->height))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("monitor %d changed position %d %d, size %d %d", monitor->
id, monitor->x, monitor->y, monitor->width, monitor->
height); }; } while (0)
;
1507
1508 cdk_monitor_set_position (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
, monitor->x, monitor->y);
1509 cdk_monitor_set_size (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
, monitor->width, monitor->height);
1510 cdk_monitor_set_connector (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
, monitor->name);
1511 monitor->wl_output_done = FALSE(0);
1512 monitor->xdg_output_done = FALSE(0);
1513
1514 g_signal_emit_by_name (screen_wayland, "monitors-changed");
1515 update_screen_size (screen_wayland);
1516}
1517
1518static void
1519xdg_output_handle_logical_position (void *data,
1520 struct zxdg_output_v1 *xdg_output G_GNUC_UNUSED__attribute__ ((__unused__)),
1521 int32_t x,
1522 int32_t y)
1523{
1524 CdkWaylandMonitor *monitor = (CdkWaylandMonitor *) data;
1525
1526 CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle logical position xdg-output %d, position %d %d", monitor
->id, x, y); }; } while (0)
1527 g_message ("handle logical position xdg-output %d, position %d %d",do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle logical position xdg-output %d, position %d %d", monitor
->id, x, y); }; } while (0)
1528 monitor->id, x, y))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle logical position xdg-output %d, position %d %d", monitor
->id, x, y); }; } while (0)
;
1529 monitor->x = x;
1530 monitor->y = y;
1531}
1532
1533static void
1534xdg_output_handle_logical_size (void *data,
1535 struct zxdg_output_v1 *xdg_output G_GNUC_UNUSED__attribute__ ((__unused__)),
1536 int32_t width,
1537 int32_t height)
1538{
1539 CdkWaylandMonitor *monitor = (CdkWaylandMonitor *) data;
1540
1541 CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle logical size xdg-output %d, size %d %d", monitor->
id, width, height); }; } while (0)
1542 g_message ("handle logical size xdg-output %d, size %d %d",do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle logical size xdg-output %d, size %d %d", monitor->
id, width, height); }; } while (0)
1543 monitor->id, width, height))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle logical size xdg-output %d, size %d %d", monitor->
id, width, height); }; } while (0)
;
1544 monitor->width = width;
1545 monitor->height = height;
1546}
1547
1548static void
1549xdg_output_handle_done (void *data,
1550 struct zxdg_output_v1 *xdg_output G_GNUC_UNUSED__attribute__ ((__unused__)))
1551{
1552 CdkWaylandMonitor *monitor = (CdkWaylandMonitor *) data;
1553
1554 CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle done xdg-output %d", monitor->id); }; } while (0
)
1555 g_message ("handle done xdg-output %d", monitor->id))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle done xdg-output %d", monitor->id); }; } while (0
)
;
1556
1557 monitor->xdg_output_done = TRUE(!(0));
1558 if (monitor->wl_output_done && should_expect_xdg_output_done (monitor))
1559 apply_monitor_change (monitor);
1560}
1561
1562static void
1563xdg_output_handle_name (void *data,
1564 struct zxdg_output_v1 *xdg_output G_GNUC_UNUSED__attribute__ ((__unused__)),
1565 const char *name)
1566{
1567 CdkWaylandMonitor *monitor = (CdkWaylandMonitor *) data;
1568
1569 CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle name xdg-output %d", monitor->id); }; } while (0
)
1570 g_message ("handle name xdg-output %d", monitor->id))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle name xdg-output %d", monitor->id); }; } while (0
)
;
1571
1572 monitor->name = g_strdup (name)g_strdup_inline (name);
1573}
1574
1575static void
1576xdg_output_handle_description (void *data,
1577 struct zxdg_output_v1 *xdg_output G_GNUC_UNUSED__attribute__ ((__unused__)),
1578 const char *description G_GNUC_UNUSED__attribute__ ((__unused__)))
1579{
1580#ifdef G_ENABLE_DEBUG1
1581 CdkWaylandMonitor *monitor = (CdkWaylandMonitor *) data;
1582
1583 CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle description xdg-output %d", monitor->id); }; } while
(0)
1584 g_message ("handle description xdg-output %d", monitor->id))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle description xdg-output %d", monitor->id); }; } while
(0)
;
1585#endif
1586}
1587
1588static const struct zxdg_output_v1_listener xdg_output_listener = {
1589 xdg_output_handle_logical_position,
1590 xdg_output_handle_logical_size,
1591 xdg_output_handle_done,
1592 xdg_output_handle_name,
1593 xdg_output_handle_description,
1594};
1595
1596static void
1597cdk_wayland_screen_get_xdg_output (CdkWaylandMonitor *monitor)
1598{
1599 CdkDisplay *display = CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
->display;
1600 CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((display)), ((cdk_wayland_display_get_type(
)))))))
;
1601
1602 CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("get xdg-output for monitor %d", monitor->id); }; } while
(0)
1603 g_message ("get xdg-output for monitor %d", monitor->id))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("get xdg-output for monitor %d", monitor->id); }; } while
(0)
;
1604
1605 monitor->xdg_output =
1606 zxdg_output_manager_v1_get_xdg_output (display_wayland->xdg_output_manager,
1607 monitor->output);
1608
1609 zxdg_output_v1_add_listener (monitor->xdg_output,
1610 &xdg_output_listener,
1611 monitor);
1612}
1613
1614static void
1615output_handle_geometry (void *data,
1616 struct wl_output *wl_output G_GNUC_UNUSED__attribute__ ((__unused__)),
1617 int x,
1618 int y,
1619 int physical_width,
1620 int physical_height,
1621 int subpixel,
1622 const char *make,
1623 const char *model,
1624 int32_t transform)
1625{
1626 CdkWaylandMonitor *monitor = (CdkWaylandMonitor *)data;
1627
1628 CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle geometry output %d, position %d %d, phys. size %d %d, subpixel layout %s, manufacturer %s, model %s, transform %s"
, monitor->id, x, y, physical_width, physical_height, subpixel_to_string
(subpixel), make, model, transform_to_string (transform)); }
; } while (0)
1629 g_message ("handle geometry output %d, position %d %d, phys. size %d %d, subpixel layout %s, manufacturer %s, model %s, transform %s",do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle geometry output %d, position %d %d, phys. size %d %d, subpixel layout %s, manufacturer %s, model %s, transform %s"
, monitor->id, x, y, physical_width, physical_height, subpixel_to_string
(subpixel), make, model, transform_to_string (transform)); }
; } while (0)
1630 monitor->id, x, y, physical_width, physical_height, subpixel_to_string (subpixel), make, model, transform_to_string (transform)))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle geometry output %d, position %d %d, phys. size %d %d, subpixel layout %s, manufacturer %s, model %s, transform %s"
, monitor->id, x, y, physical_width, physical_height, subpixel_to_string
(subpixel), make, model, transform_to_string (transform)); }
; } while (0)
;
1631
1632 monitor->x = x;
1633 monitor->y = y;
1634 cdk_monitor_set_physical_size (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
, physical_width, physical_height);
1635 cdk_monitor_set_subpixel_layout (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
, subpixel);
1636 cdk_monitor_set_manufacturer (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
, make);
1637 cdk_monitor_set_model (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
, model);
1638
1639 if (should_update_monitor (monitor) || !monitor_has_xdg_output (monitor))
1640 apply_monitor_change (monitor);
1641}
1642
1643static void
1644output_handle_done (void *data,
1645 struct wl_output *wl_output G_GNUC_UNUSED__attribute__ ((__unused__)))
1646{
1647 CdkWaylandMonitor *monitor = (CdkWaylandMonitor *)data;
1648
1649 CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle done output %d", monitor->id); }; } while (0)
1650 g_message ("handle done output %d", monitor->id))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle done output %d", monitor->id); }; } while (0)
;
1651
1652 monitor->wl_output_done = TRUE(!(0));
1653
1654 if (!should_expect_xdg_output_done (monitor) || monitor->xdg_output_done)
1655 apply_monitor_change (monitor);
1656}
1657
1658static void
1659output_handle_scale (void *data,
1660 struct wl_output *wl_output G_GNUC_UNUSED__attribute__ ((__unused__)),
1661 int32_t scale)
1662{
1663 CdkWaylandMonitor *monitor = (CdkWaylandMonitor *)data;
1664 CdkRectangle previous_geometry;
1665 int previous_scale;
1666 int width;
1667 int height;
1668
1669 CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle scale output %d, scale %d", monitor->id, scale);
}; } while (0)
1670 g_message ("handle scale output %d, scale %d", monitor->id, scale))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle scale output %d, scale %d", monitor->id, scale);
}; } while (0)
;
1671
1672 cdk_monitor_get_geometry (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
, &previous_geometry);
1673 previous_scale = cdk_monitor_get_scale_factor (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
);
1674
1675 /* Set the scale from wl_output protocol, regardless of xdg-output support */
1676 cdk_monitor_set_scale_factor (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
, scale);
1677
1678 if (monitor_has_xdg_output (monitor))
1679 return;
1680
1681 width = previous_geometry.width * previous_scale;
1682 height = previous_geometry.height * previous_scale;
1683
1684 monitor->width = width / scale;
1685 monitor->height = height / scale;
1686
1687 if (should_update_monitor (monitor))
1688 apply_monitor_change (monitor);
1689}
1690
1691static void
1692output_handle_mode (void *data,
1693 struct wl_output *wl_output G_GNUC_UNUSED__attribute__ ((__unused__)),
1694 uint32_t flags,
1695 int width,
1696 int height,
1697 int refresh)
1698{
1699 CdkWaylandMonitor *monitor = (CdkWaylandMonitor *)data;
1700 int scale;
1701
1702 CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle mode output %d, size %d %d, rate %d", monitor->id
, width, height, refresh); }; } while (0)
1703 g_message ("handle mode output %d, size %d %d, rate %d",do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle mode output %d, size %d %d, rate %d", monitor->id
, width, height, refresh); }; } while (0)
1704 monitor->id, width, height, refresh))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("handle mode output %d, size %d %d, rate %d", monitor->id
, width, height, refresh); }; } while (0)
;
1705
1706 if ((flags & WL_OUTPUT_MODE_CURRENT) == 0)
1707 return;
1708
1709 scale = cdk_monitor_get_scale_factor (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
);
1710 monitor->width = width / scale;
1711 monitor->height = height / scale;
1712 cdk_monitor_set_refresh_rate (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
, refresh);
1713
1714 if (should_update_monitor (monitor) || !monitor_has_xdg_output (monitor))
1715 apply_monitor_change (monitor);
1716}
1717
1718static const struct wl_output_listener output_listener =
1719{
1720 .geometry = output_handle_geometry,
1721 .mode = output_handle_mode,
1722 .done = output_handle_done,
1723 .scale = output_handle_scale,
1724};
1725
1726void
1727_cdk_wayland_screen_add_output (CdkScreen *screen,
1728 guint32 id,
1729 struct wl_output *output,
1730 guint32 version)
1731{
1732 CdkDisplay *display = cdk_screen_get_display (screen);
1733 CdkWaylandMonitor *monitor;
1734
1735 monitor = g_object_new (CDK_TYPE_WAYLAND_MONITOR(cdk_wayland_monitor_get_type ()),
1736 "display", display,
1737 NULL((void*)0));
1738
1739 monitor->id = id;
1740 monitor->output = output;
1741 monitor->version = version;
1742
1743 g_ptr_array_add (CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((display)), ((cdk_wayland_display_get_type(
)))))))
->monitors, monitor);
1744 cdk_display_monitor_added (display, CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
);
1745 wl_output_add_listener (output, &output_listener, monitor);
1746
1747 CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("xdg_output_manager %p", ((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((display)), ((cdk_wayland_display_get_type
()))))))->xdg_output_manager); }; } while (0)
1748 g_message ("xdg_output_manager %p",do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("xdg_output_manager %p", ((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((display)), ((cdk_wayland_display_get_type
()))))))->xdg_output_manager); }; } while (0)
1749 CDK_WAYLAND_DISPLAY (display)->xdg_output_manager))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("xdg_output_manager %p", ((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((display)), ((cdk_wayland_display_get_type
()))))))->xdg_output_manager); }; } while (0)
;
1750
1751 if (screen_has_xdg_output_support (screen))
1752 cdk_wayland_screen_get_xdg_output (monitor);
1753}
1754
1755struct wl_output *
1756_cdk_wayland_screen_get_wl_output (CdkScreen *screen,
1757 gint monitor_num)
1758{
1759 CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (CDK_WAYLAND_SCREEN (screen)->display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((((((CdkWaylandScreen*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type
()))))))->display)), ((cdk_wayland_display_get_type()))))
))
;
1760 CdkWaylandMonitor *monitor;
1761
1762 monitor = display_wayland->monitors->pdata[monitor_num];
1763
1764 return monitor->output;
1765}
1766
1767static CdkWaylandMonitor *
1768get_monitor_for_id (CdkWaylandScreen *screen_wayland,
1769 guint32 id)
1770{
1771 CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (screen_wayland->display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((screen_wayland->display)), ((cdk_wayland_display_get_type
()))))))
;
1772 int i;
1773
1774 for (i = 0; i < display_wayland->monitors->len; i++)
1775 {
1776 CdkWaylandMonitor *monitor = display_wayland->monitors->pdata[i];
1777
1778 if (monitor->id == id)
1779 return monitor;
1780 }
1781
1782 return NULL((void*)0);
1783}
1784
1785static CdkWaylandMonitor *
1786get_monitor_for_output (CdkWaylandScreen *screen_wayland,
1787 struct wl_output *output)
1788{
1789 CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (screen_wayland->display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((screen_wayland->display)), ((cdk_wayland_display_get_type
()))))))
;
1790 int i;
1791
1792 for (i = 0; i < display_wayland->monitors->len; i++)
1793 {
1794 CdkWaylandMonitor *monitor = display_wayland->monitors->pdata[i];
1795
1796 if (monitor->output == output)
1797 return monitor;
1798 }
1799
1800 return NULL((void*)0);
1801}
1802
1803void
1804_cdk_wayland_screen_remove_output (CdkScreen *screen,
1805 guint32 id)
1806{
1807 CdkWaylandScreen *screen_wayland = CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
;
1808 CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (screen_wayland->display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((screen_wayland->display)), ((cdk_wayland_display_get_type
()))))))
;
1809 CdkWaylandMonitor *monitor;
1810
1811 monitor = get_monitor_for_id (screen_wayland, id);
1812 if (monitor != NULL((void*)0))
1813 {
1814 g_object_ref (monitor)((__typeof__ (monitor)) (g_object_ref) (monitor));
1815 g_ptr_array_remove (display_wayland->monitors, monitor);
1816 cdk_display_monitor_removed (CDK_DISPLAY (display_wayland)((((CdkDisplay*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((display_wayland)), ((cdk_display_get_type ()))))))
, CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
);
1817 g_object_unref (monitor);
1818 g_signal_emit_by_name (screen_wayland, "monitors-changed");
1819 update_screen_size (screen_wayland);
1820 }
1821}
1822
1823int
1824_cdk_wayland_screen_get_output_refresh_rate (CdkScreen *screen,
1825 struct wl_output *output)
1826{
1827 CdkWaylandScreen *screen_wayland = CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
;
1828 CdkWaylandMonitor *monitor;
1829
1830 monitor = get_monitor_for_output (screen_wayland, output);
1831 if (monitor != NULL((void*)0))
1832 return cdk_monitor_get_refresh_rate (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
);
1833
1834 return 0;
1835}
1836
1837guint32
1838_cdk_wayland_screen_get_output_scale (CdkScreen *screen,
1839 struct wl_output *output)
1840{
1841 CdkWaylandScreen *screen_wayland = CDK_WAYLAND_SCREEN (screen)((((CdkWaylandScreen*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((screen)), ((_cdk_wayland_screen_get_type ()
))))))
;
1842 CdkWaylandMonitor *monitor;
1843
1844 monitor = get_monitor_for_output (screen_wayland, output);
1845 if (monitor != NULL((void*)0))
1846 return cdk_monitor_get_scale_factor (CDK_MONITOR (monitor)((((CdkMonitor*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((monitor)), ((cdk_monitor_get_type ()))))))
);
1847
1848 return 0;
1849}
1850
1851void
1852_cdk_wayland_screen_init_xdg_output (CdkScreen *screen)
1853{
1854 CdkDisplay *display = cdk_screen_get_display (screen);
1855 CdkWaylandDisplay *display_wayland = CDK_WAYLAND_DISPLAY (display)((((CdkWaylandDisplay*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((display)), ((cdk_wayland_display_get_type(
)))))))
;
1856 int i;
1857
1858 CDK_NOTE (MISC,do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("init xdg-output support, %d monitor(s) already present", display_wayland
->monitors->len); }; } while (0)
1859 g_message ("init xdg-output support, %d monitor(s) already present",do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("init xdg-output support, %d monitor(s) already present", display_wayland
->monitors->len); }; } while (0)
1860 display_wayland->monitors->len))do { if ((_cdk_debug_flags & CDK_DEBUG_MISC)) { g_message
("init xdg-output support, %d monitor(s) already present", display_wayland
->monitors->len); }; } while (0)
;
1861
1862 for (i = 0; i < display_wayland->monitors->len; i++)
1863 cdk_wayland_screen_get_xdg_output (display_wayland->monitors->pdata[i]);
1864}