Bug Summary

File:_build/../libvnck/screen.c
Warning:line 1087, column 3
Value stored to 'current_col' is never read

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 screen.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 -fdebug-compilation-dir=/rootdir/_build -fcoverage-compilation-dir=/rootdir/_build -resource-dir /usr/lib/llvm-19/lib/clang/19 -I libvnck/libvnck-3.so.0.3.0.p -I libvnck -I ../libvnck -I . -I .. -I /usr/include/cairo -I /usr/include/libpng16 -I /usr/include/freetype2 -I /usr/include/pixman-1 -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/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -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 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/startup-notification-1.0 -D _FILE_OFFSET_BITS=64 -D G_LOG_DOMAIN="Vnck" -D VNCK_I_KNOW_THIS_IS_UNSTABLE -D VNCK_LOCALEDIR="/usr/local/share/locale" -D VNCK_COMPILATION -D SN_API_NOT_YET_FROZEN=1 -internal-isystem /usr/lib/llvm-19/lib/clang/19/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 -O0 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcolor-diagnostics -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.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/2025-08-10-111922-9461-1 -x c ../libvnck/screen.c
1/* screen object */
2
3/*
4 * Copyright (C) 2001 Havoc Pennington
5 * Copyright (C) 2003 Kim Woelders
6 * Copyright (C) 2003 Red Hat, Inc.
7 * Copyright (C) 2006-2007 Vincent Untz
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 */
22
23#undef VNCK_DISABLE_DEPRECATED
24
25#include <config.h>
26
27#include <glib/gi18n-lib.h>
28#include "screen.h"
29#include "window.h"
30#include "workspace.h"
31#include "application.h"
32#include "class-group.h"
33#include "xutils.h"
34#include "private.h"
35#include <cdk/cdk.h>
36#include <cdk/cdkx.h>
37#include <string.h>
38#include <stdlib.h>
39
40/**
41 * SECTION:screen
42 * @short_description: an object representing a screen.
43 * @see_also: #VnckWindow, #VnckWorkspace
44 * @stability: Unstable
45 *
46 * The #VnckScreen represents a physical screen. A screen may consist of
47 * multiple monitors which are merged to form a large screen area. The
48 * #VnckScreen is at the bottom of the libvnck stack of objects: #VnckWorkspace
49 * objects exist a #VnckScreen and #VnckWindow objects are displayed on a
50 * #VnckWorkspace.
51 *
52 * The #VnckScreen corresponds to the notion of
53 * <classname>CdkScreen</classname> in CDK.
54 *
55 * The #VnckScreen objects are always owned by libvnck and must not be
56 * referenced or unreferenced.
57 */
58
59#define _NET_WM_ORIENTATION_HORZ0 0
60#define _NET_WM_ORIENTATION_VERT1 1
61
62#define _NET_WM_TOPLEFT0 0
63#define _NET_WM_TOPRIGHT1 1
64#define _NET_WM_BOTTOMRIGHT2 2
65#define _NET_WM_BOTTOMLEFT3 3
66
67static VnckScreen** screens = NULL((void*)0);
68
69struct _VnckScreenPrivate
70{
71 int number;
72 Window xroot;
73 Screen *xscreen;
74
75 int orig_event_mask;
76
77 /* in map order */
78 GList *mapped_windows;
79 /* in stacking order */
80 GList *stacked_windows;
81 /* in 0-to-N order */
82 GList *workspaces;
83
84 /* previously_active_window is used in tandem with active_window to
85 * determine return status of vnck_window_is_most_recently_actived().
86 * These are usually shared for all screens, although this is not guaranteed
87 * to be true.
88 */
89 VnckWindow *active_window;
90 VnckWindow *previously_active_window;
91
92 VnckWorkspace *active_workspace;
93
94 /* Provides the sorting order number for the next window, to make
95 * sure windows remain sorted in the order they appear.
96 */
97 gint window_order;
98
99 Pixmap bg_pixmap;
100
101 char *wm_name;
102
103 guint update_handler;
104
105#ifdef HAVE_STARTUP_NOTIFICATION1
106 SnDisplay *sn_display;
107#endif
108
109 guint showing_desktop : 1;
110
111 guint vertical_workspaces : 1;
112 _VnckLayoutCorner starting_corner;
113 gint rows_of_workspaces;
114 gint columns_of_workspaces;
115
116 /* if you add flags, be sure to set them
117 * when we create the screen so we get an initial update
118 */
119 guint need_update_stack_list : 1;
120 guint need_update_workspace_list : 1;
121 guint need_update_viewport_settings : 1;
122 guint need_update_active_workspace : 1;
123 guint need_update_active_window : 1;
124 guint need_update_workspace_layout : 1;
125 guint need_update_workspace_names : 1;
126 guint need_update_bg_pixmap : 1;
127 guint need_update_showing_desktop : 1;
128 guint need_update_wm : 1;
129};
130
131G_DEFINE_TYPE_WITH_PRIVATE (VnckScreen, vnck_screen, G_TYPE_OBJECT)static void vnck_screen_init (VnckScreen *self); static void vnck_screen_class_init
(VnckScreenClass *klass); static GType vnck_screen_get_type_once
(void); static gpointer vnck_screen_parent_class = ((void*)0
); static gint VnckScreen_private_offset; static void vnck_screen_class_intern_init
(gpointer klass) { vnck_screen_parent_class = g_type_class_peek_parent
(klass); if (VnckScreen_private_offset != 0) g_type_class_adjust_private_offset
(klass, &VnckScreen_private_offset); vnck_screen_class_init
((VnckScreenClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer vnck_screen_get_instance_private (VnckScreen
*self) { return (((gpointer) ((guint8*) (self) + (glong) (VnckScreen_private_offset
)))); } GType vnck_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
= vnck_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 vnck_screen_get_type_once (void)
{ GType g_define_type_id = g_type_register_static_simple (((
GType) ((20) << (2))), g_intern_static_string ("VnckScreen"
), sizeof (VnckScreenClass), (GClassInitFunc)(void (*)(void))
vnck_screen_class_intern_init, sizeof (VnckScreen), (GInstanceInitFunc
)(void (*)(void)) vnck_screen_init, (GTypeFlags) 0); { {{ VnckScreen_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (VnckScreenPrivate
)); };} } return g_define_type_id; }
;
132
133enum {
134 ACTIVE_WINDOW_CHANGED,
135 ACTIVE_WORKSPACE_CHANGED,
136 WINDOW_STACKING_CHANGED,
137 WINDOW_OPENED,
138 WINDOW_CLOSED,
139 WORKSPACE_CREATED,
140 WORKSPACE_DESTROYED,
141 APPLICATION_OPENED,
142 APPLICATION_CLOSED,
143 CLASS_GROUP_OPENED,
144 CLASS_GROUP_CLOSED,
145 BACKGROUND_CHANGED,
146 SHOWING_DESKTOP_CHANGED,
147 VIEWPORTS_CHANGED,
148 WM_CHANGED,
149 LAST_SIGNAL
150};
151
152static void vnck_screen_finalize (GObject *object);
153
154static void update_client_list (VnckScreen *screen);
155static void update_workspace_list (VnckScreen *screen);
156static void update_viewport_settings (VnckScreen *screen);
157static void update_active_workspace (VnckScreen *screen);
158static void update_active_window (VnckScreen *screen);
159static void update_workspace_layout (VnckScreen *screen);
160static void update_workspace_names (VnckScreen *screen);
161static void update_showing_desktop (VnckScreen *screen);
162
163static void queue_update (VnckScreen *screen);
164static void unqueue_update (VnckScreen *screen);
165static void do_update_now (VnckScreen *screen);
166
167static void emit_active_window_changed (VnckScreen *screen);
168static void emit_active_workspace_changed (VnckScreen *screen,
169 VnckWorkspace *previous_space);
170static void emit_window_stacking_changed (VnckScreen *screen);
171static void emit_window_opened (VnckScreen *screen,
172 VnckWindow *window);
173static void emit_window_closed (VnckScreen *screen,
174 VnckWindow *window);
175static void emit_workspace_created (VnckScreen *screen,
176 VnckWorkspace *space);
177static void emit_workspace_destroyed (VnckScreen *screen,
178 VnckWorkspace *space);
179static void emit_application_opened (VnckScreen *screen,
180 VnckApplication *app);
181static void emit_application_closed (VnckScreen *screen,
182 VnckApplication *app);
183static void emit_class_group_opened (VnckScreen *screen,
184 VnckClassGroup *class_group);
185static void emit_class_group_closed (VnckScreen *screen,
186 VnckClassGroup *class_group);
187static void emit_background_changed (VnckScreen *screen);
188static void emit_showing_desktop_changed (VnckScreen *screen);
189static void emit_viewports_changed (VnckScreen *screen);
190static void emit_wm_changed (VnckScreen *screen);
191
192static guint signals[LAST_SIGNAL] = { 0 };
193
194static void
195vnck_screen_init (VnckScreen *screen)
196{
197 screen->priv = vnck_screen_get_instance_private (screen);
198
199 screen->priv->number = -1;
200 screen->priv->starting_corner = VNCK_LAYOUT_CORNER_TOPLEFT;
201 screen->priv->rows_of_workspaces = 1;
202 screen->priv->columns_of_workspaces = -1;
203}
204
205static void
206vnck_screen_class_init (VnckScreenClass *klass)
207{
208 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
209
210 _vnck_init ();
211
212 object_class->finalize = vnck_screen_finalize;
213
214 /**
215 * VnckScreen::active-window-changed:
216 * @screen: the #VnckScreen which emitted the signal.
217 * @previously_active_window: the previously active #VnckWindow before this
218 * change.
219 *
220 * Emitted when the active window on @screen has changed.
221 */
222 signals[ACTIVE_WINDOW_CHANGED] =
223 g_signal_new ("active_window_changed",
224 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
225 G_SIGNAL_RUN_LAST,
226 G_STRUCT_OFFSET (VnckScreenClass, active_window_changed)((glong) __builtin_offsetof(VnckScreenClass, active_window_changed
))
,
227 NULL((void*)0), NULL((void*)0), NULL((void*)0),
228 G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_WINDOW(vnck_window_get_type ()));
229
230 /**
231 * VnckScreen::active-workspace-changed:
232 * @screen: the #VnckScreen which emitted the signal.
233 * @previously_active_space: the previously active #VnckWorkspace before this
234 * change.
235 *
236 * Emitted when the active workspace on @screen has changed.
237 */
238 signals[ACTIVE_WORKSPACE_CHANGED] =
239 g_signal_new ("active_workspace_changed",
240 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
241 G_SIGNAL_RUN_LAST,
242 G_STRUCT_OFFSET (VnckScreenClass, active_workspace_changed)((glong) __builtin_offsetof(VnckScreenClass, active_workspace_changed
))
,
243 NULL((void*)0), NULL((void*)0), NULL((void*)0),
244 G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_WORKSPACE(vnck_workspace_get_type ()));
245
246 /**
247 * VnckScreen::window-stacking-changed:
248 * @screen: the #VnckScreen which emitted the signal.
249 *
250 * Emitted when the stacking order of #VnckWindow on @screen has changed.
251 */
252 signals[WINDOW_STACKING_CHANGED] =
253 g_signal_new ("window_stacking_changed",
254 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
255 G_SIGNAL_RUN_LAST,
256 G_STRUCT_OFFSET (VnckScreenClass, window_stacking_changed)((glong) __builtin_offsetof(VnckScreenClass, window_stacking_changed
))
,
257 NULL((void*)0), NULL((void*)0), NULL((void*)0),
258 G_TYPE_NONE((GType) ((1) << (2))), 0);
259
260 /**
261 * VnckScreen::window-opened:
262 * @screen: the #VnckScreen which emitted the signal.
263 * @window: the opened #VnckWindow.
264 *
265 * Emitted when a new #VnckWindow is opened on @screen.
266 */
267 signals[WINDOW_OPENED] =
268 g_signal_new ("window_opened",
269 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
270 G_SIGNAL_RUN_LAST,
271 G_STRUCT_OFFSET (VnckScreenClass, window_opened)((glong) __builtin_offsetof(VnckScreenClass, window_opened)),
272 NULL((void*)0), NULL((void*)0), NULL((void*)0),
273 G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_WINDOW(vnck_window_get_type ()));
274
275 /**
276 * VnckScreen::window-closed:
277 * @screen: the #VnckScreen which emitted the signal.
278 * @window: the closed #VnckWindow.
279 *
280 * Emitted when a #VnckWindow is closed on @screen.
281 */
282 signals[WINDOW_CLOSED] =
283 g_signal_new ("window_closed",
284 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
285 G_SIGNAL_RUN_LAST,
286 G_STRUCT_OFFSET (VnckScreenClass, window_closed)((glong) __builtin_offsetof(VnckScreenClass, window_closed)),
287 NULL((void*)0), NULL((void*)0), NULL((void*)0),
288 G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_WINDOW(vnck_window_get_type ()));
289
290 /**
291 * VnckScreen::workspace-created:
292 * @screen: the #VnckScreen which emitted the signal.
293 * @space: the workspace that has been created.
294 *
295 * Emitted when a #VnckWorkspace is created on @screen.
296 */
297 signals[WORKSPACE_CREATED] =
298 g_signal_new ("workspace_created",
299 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
300 G_SIGNAL_RUN_LAST,
301 G_STRUCT_OFFSET (VnckScreenClass, workspace_created)((glong) __builtin_offsetof(VnckScreenClass, workspace_created
))
,
302 NULL((void*)0), NULL((void*)0), NULL((void*)0),
303 G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_WORKSPACE(vnck_workspace_get_type ()));
304
305 /**
306 * VnckScreen::workspace-destroyed:
307 * @screen: the #VnckScreen which emitted the signal.
308 * @space: the workspace that has been destroyed.
309 *
310 * Emitted when a #VnckWorkspace is destroyed on @screen.
311 */
312 signals[WORKSPACE_DESTROYED] =
313 g_signal_new ("workspace_destroyed",
314 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
315 G_SIGNAL_RUN_LAST,
316 G_STRUCT_OFFSET (VnckScreenClass, workspace_destroyed)((glong) __builtin_offsetof(VnckScreenClass, workspace_destroyed
))
,
317 NULL((void*)0), NULL((void*)0), NULL((void*)0),
318 G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_WORKSPACE(vnck_workspace_get_type ()));
319
320 /**
321 * VnckScreen::application-opened:
322 * @screen: the #VnckScreen which emitted the signal.
323 * @app: the opened #VnckApplication.
324 *
325 * Emitted when a new #VnckApplication is opened on @screen.
326 */
327 signals[APPLICATION_OPENED] =
328 g_signal_new ("application_opened",
329 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
330 G_SIGNAL_RUN_LAST,
331 G_STRUCT_OFFSET (VnckScreenClass, application_opened)((glong) __builtin_offsetof(VnckScreenClass, application_opened
))
,
332 NULL((void*)0), NULL((void*)0), NULL((void*)0),
333 G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_APPLICATION(vnck_application_get_type ()));
334
335 /**
336 * VnckScreen::application-closed:
337 * @screen: the #VnckScreen which emitted the signal.
338 * @app: the closed #VnckApplication.
339 *
340 * Emitted when a #VnckApplication is closed on @screen.
341 */
342 signals[APPLICATION_CLOSED] =
343 g_signal_new ("application_closed",
344 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
345 G_SIGNAL_RUN_LAST,
346 G_STRUCT_OFFSET (VnckScreenClass, application_closed)((glong) __builtin_offsetof(VnckScreenClass, application_closed
))
,
347 NULL((void*)0), NULL((void*)0), NULL((void*)0),
348 G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_APPLICATION(vnck_application_get_type ()));
349
350 /**
351 * VnckScreen::class-group-opened:
352 * @screen: the #VnckScreen which emitted the signal.
353 * @class_group: the opened #VnckClassGroup.
354 *
355 * Emitted when a new #VnckClassGroup is opened on @screen.
356 *
357 * Since: 2.20
358 */
359 signals[CLASS_GROUP_OPENED] =
360 g_signal_new ("class_group_opened",
361 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
362 G_SIGNAL_RUN_LAST,
363 G_STRUCT_OFFSET (VnckScreenClass, class_group_opened)((glong) __builtin_offsetof(VnckScreenClass, class_group_opened
))
,
364 NULL((void*)0), NULL((void*)0), NULL((void*)0),
365 G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_CLASS_GROUP(vnck_class_group_get_type ()));
366
367 /**
368 * VnckScreen::class-group-closed:
369 * @screen: the #VnckScreen which emitted the signal.
370 * @class_group: the closed #VnckClassGroup.
371 *
372 * Emitted when a #VnckClassGroup is closed on @screen.
373 *
374 * Since: 2.20
375 */
376 signals[CLASS_GROUP_CLOSED] =
377 g_signal_new ("class_group_closed",
378 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
379 G_SIGNAL_RUN_LAST,
380 G_STRUCT_OFFSET (VnckScreenClass, class_group_closed)((glong) __builtin_offsetof(VnckScreenClass, class_group_closed
))
,
381 NULL((void*)0), NULL((void*)0), NULL((void*)0),
382 G_TYPE_NONE((GType) ((1) << (2))), 1, VNCK_TYPE_CLASS_GROUP(vnck_class_group_get_type ()));
383
384 /**
385 * VnckScreen::background-changed:
386 * @screen: the #VnckScreen which emitted the signal.
387 *
388 * Emitted when the background on the root window of @screen has changed.
389 */
390 signals[BACKGROUND_CHANGED] =
391 g_signal_new ("background_changed",
392 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
393 G_SIGNAL_RUN_LAST,
394 G_STRUCT_OFFSET (VnckScreenClass, background_changed)((glong) __builtin_offsetof(VnckScreenClass, background_changed
))
,
395 NULL((void*)0), NULL((void*)0), NULL((void*)0),
396 G_TYPE_NONE((GType) ((1) << (2))), 0);
397
398 /**
399 * VnckScreen::showing-desktop-changed:
400 * @screen: the #VnckScreen which emitted the signal.
401 *
402 * Emitted when "showing the desktop" mode of @screen is toggled.
403 *
404 * Since: 2.20
405 */
406 signals[SHOWING_DESKTOP_CHANGED] =
407 g_signal_new ("showing_desktop_changed",
408 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
409 G_SIGNAL_RUN_LAST,
410 G_STRUCT_OFFSET (VnckScreenClass, showing_desktop_changed)((glong) __builtin_offsetof(VnckScreenClass, showing_desktop_changed
))
,
411 NULL((void*)0), NULL((void*)0), NULL((void*)0),
412 G_TYPE_NONE((GType) ((1) << (2))), 0);
413
414 /**
415 * VnckScreen::viewports-changed:
416 * @screen: the #VnckScreen which emitted the signal.
417 *
418 * Emitted when a viewport position has changed in a #VnckWorkspace of
419 * @screen or when a #VnckWorkspace of @screen gets or loses its viewport.
420 *
421 * Since: 2.20
422 */
423 signals[VIEWPORTS_CHANGED] =
424 g_signal_new ("viewports_changed",
425 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
426 G_SIGNAL_RUN_LAST,
427 G_STRUCT_OFFSET (VnckScreenClass, viewports_changed)((glong) __builtin_offsetof(VnckScreenClass, viewports_changed
))
,
428 NULL((void*)0), NULL((void*)0), NULL((void*)0),
429 G_TYPE_NONE((GType) ((1) << (2))), 0);
430
431 /**
432 * VnckScreen::window-manager-changed:
433 * @screen: the #VnckScreen which emitted the signal.
434 *
435 * Emitted when the window manager on @screen has changed.
436 *
437 * Since: 2.20
438 */
439 signals[WM_CHANGED] =
440 g_signal_new ("window_manager_changed",
441 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
442 G_SIGNAL_RUN_LAST,
443 G_STRUCT_OFFSET (VnckScreenClass, window_manager_changed)((glong) __builtin_offsetof(VnckScreenClass, window_manager_changed
))
,
444 NULL((void*)0), NULL((void*)0), NULL((void*)0),
445 G_TYPE_NONE((GType) ((1) << (2))), 0);
446}
447
448static void
449vnck_screen_finalize (GObject *object)
450{
451 VnckScreen *screen;
452 GList *tmp;
453 gpointer weak_pointer;
454
455 screen = VNCK_SCREEN (object)((((VnckScreen*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((object)), ((vnck_screen_get_type ()))))))
;
456
457 _vnck_select_input (screen->priv->xscreen,
458 screen->priv->xroot,
459 screen->priv->orig_event_mask,
460 FALSE(0));
461
462 unqueue_update (screen);
463
464 for (tmp = screen->priv->stacked_windows; tmp; tmp = tmp->next)
465 {
466 screen->priv->mapped_windows = g_list_remove (screen->priv->mapped_windows,
467 tmp->data);
468 _vnck_window_destroy (VNCK_WINDOW (tmp->data)((((VnckWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp->data)), ((vnck_window_get_type ()))))))
);
469 }
470
471 for (tmp = screen->priv->mapped_windows; tmp; tmp = tmp->next)
472 _vnck_window_destroy (VNCK_WINDOW (tmp->data)((((VnckWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp->data)), ((vnck_window_get_type ()))))))
);
473
474 for (tmp = screen->priv->workspaces; tmp; tmp = tmp->next)
475 g_object_unref (tmp->data);
476
477 g_list_free (screen->priv->mapped_windows);
478 screen->priv->mapped_windows = NULL((void*)0);
479 g_list_free (screen->priv->stacked_windows);
480 screen->priv->stacked_windows = NULL((void*)0);
481
482 g_list_free (screen->priv->workspaces);
483 screen->priv->workspaces = NULL((void*)0);
484
485 weak_pointer = &screen->priv->active_window;
486 if (screen->priv->active_window != NULL((void*)0))
487 g_object_remove_weak_pointer (G_OBJECT (screen->priv->active_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen->priv->active_window)), (((GType) ((20) <<
(2))))))))
,
488 weak_pointer);
489 screen->priv->active_window = NULL((void*)0);
490
491 weak_pointer = &screen->priv->previously_active_window;
492 if (screen->priv->previously_active_window != NULL((void*)0))
493 g_object_remove_weak_pointer (G_OBJECT (screen->priv->previously_active_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen->priv->previously_active_window)), (((GType
) ((20) << (2))))))))
,
494 weak_pointer);
495 screen->priv->previously_active_window = NULL((void*)0);
496
497 g_free (screen->priv->wm_name);
498 screen->priv->wm_name = NULL((void*)0);
499
500 screens[screen->priv->number] = NULL((void*)0);
501
502#ifdef HAVE_STARTUP_NOTIFICATION1
503 sn_display_unref (screen->priv->sn_display);
504 screen->priv->sn_display = NULL((void*)0);
505#endif
506
507 G_OBJECT_CLASS (vnck_screen_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((vnck_screen_parent_class)), (((GType) ((20) << (2)
)))))))
->finalize (object);
508}
509
510#ifdef HAVE_STARTUP_NOTIFICATION1
511static void
512sn_error_trap_push (SnDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__)),
513 Display *xdisplay)
514{
515 _vnck_error_trap_push (xdisplay);
516}
517
518static void
519sn_error_trap_pop (SnDisplay *display G_GNUC_UNUSED__attribute__ ((__unused__)),
520 Display *xdisplay)
521{
522 _vnck_error_trap_pop (xdisplay);
523}
524#endif /* HAVE_STARTUP_NOTIFICATION */
525
526static void
527vnck_screen_construct (Display *display,
528 VnckScreen *screen,
529 int number)
530{
531 /* Create the initial state of the screen. */
532 screen->priv->xroot = RootWindow (display, number)((&((_XPrivDisplay)(display))->screens[number])->root
)
;
533 screen->priv->xscreen = ScreenOfDisplay (display, number)(&((_XPrivDisplay)(display))->screens[number]);
534 screen->priv->number = number;
535
536#ifdef HAVE_STARTUP_NOTIFICATION1
537 screen->priv->sn_display = sn_display_new (display,
538 sn_error_trap_push,
539 sn_error_trap_pop);
540#endif
541
542 screen->priv->bg_pixmap = None0L;
543
544 screen->priv->orig_event_mask = _vnck_select_input (screen->priv->xscreen,
545 screen->priv->xroot,
546 PropertyChangeMask(1L<<22),
547 TRUE(!(0)));
548
549 screen->priv->need_update_workspace_list = TRUE(!(0));
550 screen->priv->need_update_stack_list = TRUE(!(0));
551 screen->priv->need_update_viewport_settings = TRUE(!(0));
552 screen->priv->need_update_active_workspace = TRUE(!(0));
553 screen->priv->need_update_active_window = TRUE(!(0));
554 screen->priv->need_update_workspace_layout = TRUE(!(0));
555 screen->priv->need_update_workspace_names = TRUE(!(0));
556 screen->priv->need_update_bg_pixmap = TRUE(!(0));
557 screen->priv->need_update_showing_desktop = TRUE(!(0));
558 screen->priv->need_update_wm = TRUE(!(0));
559
560 queue_update (screen);
561}
562
563/**
564 * vnck_screen_get:
565 * @index: screen number, starting from 0.
566 *
567 * Gets the #VnckScreen for a given screen on the default display.
568 *
569 * Return value: (transfer none): the #VnckScreen for screen @index, or %NULL
570 * if no such screen exists. The returned #VnckScreen is owned by libvnck and
571 * must not be referenced or unreferenced.
572 **/
573VnckScreen*
574vnck_screen_get (int index)
575{
576 Display *display;
577
578 display = _vnck_get_default_display ();
579
580 g_return_val_if_fail (display != NULL, NULL)do { if ((display != ((void*)0))) { } else { g_return_if_fail_warning
("Vnck", ((const char*) (__func__)), "display != NULL"); return
(((void*)0)); } } while (0)
;
581
582 if (index >= ScreenCount (display)(((_XPrivDisplay)(display))->nscreens))
583 return NULL((void*)0);
584
585 if (screens == NULL((void*)0))
586 {
587 screens = g_new0 (VnckScreen*, ScreenCount (display))((VnckScreen* *) g_malloc0_n (((((_XPrivDisplay)(display))->
nscreens)), sizeof (VnckScreen*)))
;
588 _vnck_event_filter_init ();
589 }
590
591 if (screens[index] == NULL((void*)0))
592 {
593 screens[index] = g_object_new (VNCK_TYPE_SCREEN(vnck_screen_get_type ()), NULL((void*)0));
594
595 vnck_screen_construct (display, screens[index], index);
596 }
597
598 return screens[index];
599}
600
601VnckScreen*
602_vnck_screen_get_existing (int number)
603{
604 Display *display;
605
606 display = _vnck_get_default_display ();
607
608 g_return_val_if_fail (display != NULL, NULL)do { if ((display != ((void*)0))) { } else { g_return_if_fail_warning
("Vnck", ((const char*) (__func__)), "display != NULL"); return
(((void*)0)); } } while (0)
;
609 g_return_val_if_fail (number < ScreenCount (display), NULL)do { if ((number < (((_XPrivDisplay)(display))->nscreens
))) { } else { g_return_if_fail_warning ("Vnck", ((const char
*) (__func__)), "number < ScreenCount (display)"); return (
((void*)0)); } } while (0)
;
610
611 if (screens != NULL((void*)0))
612 return screens[number];
613 else
614 return NULL((void*)0);
615}
616
617/**
618 * vnck_screen_get_default:
619 *
620 * Gets the default #VnckScreen on the default display.
621 *
622 * Return value: (transfer none) (nullable): the default #VnckScreen. The returned
623 * #VnckScreen is owned by libvnck and must not be referenced or unreferenced. This
624 * can return %NULL if not on X11.
625 **/
626VnckScreen*
627vnck_screen_get_default (void)
628{
629 int default_screen;
630 Display *default_display = _vnck_get_default_display ();
631
632 if (default_display == NULL((void*)0))
633 return NULL((void*)0);
634
635 default_screen = DefaultScreen (default_display)(((_XPrivDisplay)(default_display))->default_screen);
636
637 return vnck_screen_get (default_screen);
638}
639
640/**
641 * vnck_screen_get_for_root:
642 * @root_window_id: an X window ID.
643 *
644 * Gets the #VnckScreen for the root window at @root_window_id, or
645 * %NULL if no #VnckScreen exists for this root window.
646 *
647 * This function does not work if vnck_screen_get() was not called for the
648 * sought #VnckScreen before, and returns %NULL.
649 *
650 * Return value: (transfer none): the #VnckScreen for the root window at
651 * @root_window_id, or %NULL. The returned #VnckScreen is owned by libvnck and
652 * must not be referenced or unreferenced.
653 **/
654VnckScreen*
655vnck_screen_get_for_root (gulong root_window_id)
656{
657 int i;
658 Display *display;
659
660 if (screens == NULL((void*)0))
661 return NULL((void*)0);
662
663 i = 0;
664 display = _vnck_get_default_display ();
665
666 while (i < ScreenCount (display)(((_XPrivDisplay)(display))->nscreens))
667 {
668 if (screens[i] != NULL((void*)0) && screens[i]->priv->xroot == root_window_id)
669 return screens[i];
670
671 ++i;
672 }
673
674 return NULL((void*)0);
675}
676
677/**
678 * vnck_screen_get_number:
679 * @screen: a #VnckScreen.
680 *
681 * Gets the index of @screen on the display to which it belongs. The first
682 * #VnckScreen has an index of 0.
683 *
684 * Return value: the index of @space on @screen, or -1 on errors.
685 *
686 * Since: 2.20
687 **/
688int
689vnck_screen_get_number (VnckScreen *screen)
690{
691 g_return_val_if_fail (VNCK_IS_SCREEN (screen), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (-1); } } while (0)
;
692
693 return screen->priv->number;
694}
695
696/**
697 * vnck_screen_get_workspaces:
698 * @screen: a #VnckScreen.
699 *
700 * Gets the list of #VnckWorkspace on @screen. The list is ordered: the
701 * first element in the list is the first #VnckWorkspace, etc..
702 *
703 * Return value: (element-type VnckWorkspace) (transfer none): the list of
704 * #VnckWorkspace on @screen. The list should not be modified nor freed, as it
705 * is owned by @screen.
706 *
707 * Since: 2.20
708 **/
709GList*
710vnck_screen_get_workspaces (VnckScreen *screen)
711{
712 g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while
(0)
;
713
714 return screen->priv->workspaces;
715}
716
717/**
718 * vnck_screen_get_workspace:
719 * @screen: a #VnckScreen.
720 * @workspace: a workspace index, starting from 0.
721 *
722 * Gets the #VnckWorkspace numbered @workspace on @screen.
723 *
724 * Return value: (transfer none): the #VnckWorkspace numbered @workspace on
725 * @screen, or %NULL if no such workspace exists. The returned #VnckWorkspace
726 * is owned by libvnck and must not be referenced or unreferenced.
727 **/
728VnckWorkspace*
729vnck_screen_get_workspace (VnckScreen *screen,
730 int workspace)
731{
732 GList *list;
733
734 g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while
(0)
;
735
736 /* We trust this function with property-provided numbers, it
737 * must reliably return NULL on bad data
738 */
739 list = g_list_nth (screen->priv->workspaces, workspace);
740
741 if (list == NULL((void*)0))
742 return NULL((void*)0);
743
744 return VNCK_WORKSPACE (list->data)((((VnckWorkspace*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((list->data)), ((vnck_workspace_get_type ()))))))
;
745}
746
747/**
748 * vnck_screen_get_active_workspace:
749 * @screen: a #VnckScreen.
750 *
751 * Gets the active #VnckWorkspace on @screen. May return %NULL sometimes,
752 * if libvnck is in a weird state due to the asynchronous nature of the
753 * interaction with the window manager.
754 *
755 * Return value: (transfer none): the active #VnckWorkspace on @screen, or
756 * %NULL. The returned #VnckWorkspace is owned by libvnck and must not be
757 * referenced or unreferenced.
758 **/
759VnckWorkspace*
760vnck_screen_get_active_workspace (VnckScreen *screen)
761{
762 g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while
(0)
;
763
764 return screen->priv->active_workspace;
765}
766
767/**
768 * vnck_screen_get_active_window:
769 * @screen: a #VnckScreen.
770 *
771 * Gets the active #VnckWindow on @screen. May return %NULL sometimes, since
772 * not all window managers guarantee that a window is always active.
773 *
774 * Return value: (transfer none): the active #VnckWindow on @screen, or %NULL.
775 * The returned #VnckWindow is owned by libvnck and must not be referenced or
776 * unreferenced.
777 **/
778VnckWindow*
779vnck_screen_get_active_window (VnckScreen *screen)
780{
781 g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while
(0)
;
782
783 return screen->priv->active_window;
784}
785
786/**
787 * vnck_screen_get_previously_active_window:
788 * @screen: a #VnckScreen.
789 *
790 * Gets the previously active #VnckWindow on @screen. May return %NULL
791 * sometimes, since not all window managers guarantee that a window is always
792 * active.
793 *
794 * Return value: (transfer none): the previously active #VnckWindow on @screen,
795 * or %NULL. The returned #VnckWindow is owned by libvnck and must not be
796 * referenced or unreferenced.
797 *
798 * Since: 2.8
799 **/
800VnckWindow*
801vnck_screen_get_previously_active_window (VnckScreen *screen)
802{
803 g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while
(0)
;
804
805 return screen->priv->previously_active_window;
806}
807
808/**
809 * vnck_screen_get_windows:
810 * @screen: a #VnckScreen.
811 *
812 * Gets the list of #VnckWindow on @screen. The list is not in a defined
813 * order, but should be "stable" (windows should not be reordered in it).
814 * However, the stability of the list is established by the window manager, so
815 * don't blame libvnck if it breaks down.
816 *
817 * Return value: (element-type VnckWindow) (transfer none): the list of
818 * #VnckWindow on @screen, or %NULL if there is no window on @screen. The list
819 * should not be modified nor freed, as it is owned by @screen.
820 **/
821GList*
822vnck_screen_get_windows (VnckScreen *screen)
823{
824 g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while
(0)
;
825
826 return screen->priv->mapped_windows;
827}
828
829/**
830 * vnck_screen_get_windows_stacked:
831 * @screen: a #VnckScreen.
832 *
833 * Gets the list of #VnckWindow on @screen in bottom-to-top order.
834 *
835 * Return value: (element-type VnckWindow) (transfer none): the list of
836 * #VnckWindow in stacking order on @screen, or %NULL if there is no window on
837 * @screen. The list should not be modified nor freed, as it is owned by
838 * @screen.
839 **/
840GList*
841vnck_screen_get_windows_stacked (VnckScreen *screen)
842{
843 g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while
(0)
;
844
845 return screen->priv->stacked_windows;
846}
847
848/**
849 * _vnck_screen_get_cdk_screen:
850 * @screen: a #VnckScreen.
851 *
852 * Gets the <classname>CdkScreen</classname referring to the same screen as
853 * @screen.
854 *
855 * Return value: the <classname>CdkScreen</classname referring to the same
856 * screen as @screen.
857 **/
858CdkScreen *
859_vnck_screen_get_cdk_screen (VnckScreen *screen)
860{
861 Display *display;
862 CdkDisplay *cdkdisplay;
863
864 g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while
(0)
;
865
866 display = DisplayOfScreen (screen->priv->xscreen)((screen->priv->xscreen)->display);
867 cdkdisplay = _vnck_cdk_display_lookup_from_display (display);
868 if (!cdkdisplay)
869 return NULL((void*)0);
870
871 if (screen->priv->number != 0)
872 return NULL((void*)0);
873
874 return cdk_display_get_default_screen (cdkdisplay);
875}
876
877/**
878 * vnck_screen_force_update:
879 * @screen: a #VnckScreen.
880 *
881 * Synchronously and immediately updates the list of #VnckWindow on @screen.
882 * This bypasses the standard update mechanism, where the list of #VnckWindow
883 * is updated in the idle loop.
884 *
885 * This is usually a bad idea for both performance and correctness reasons (to
886 * get things right, you need to write model-view code that tracks changes, not
887 * get a static list of open windows). However, this function can be useful for
888 * small applications that just do something and then exit.
889 **/
890void
891vnck_screen_force_update (VnckScreen *screen)
892{
893 g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return; } } while (0)
;
894
895 do_update_now (screen);
896}
897
898/**
899 * vnck_screen_get_workspace_count:
900 * @screen: a #VnckScreen.
901 *
902 * Gets the number of #VnckWorkspace on @screen.
903 *
904 * Return value: the number of #VnckWorkspace on @screen.
905 **/
906int
907vnck_screen_get_workspace_count (VnckScreen *screen)
908{
909 g_return_val_if_fail (VNCK_IS_SCREEN (screen), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (0); } } while (0)
;
910
911 return g_list_length (screen->priv->workspaces);
912}
913
914/**
915 * vnck_screen_change_workspace_count:
916 * @screen: a #VnckScreen.
917 * @count: the number of #VnckWorkspace to request.
918 *
919 * Asks the window manager to change the number of #VnckWorkspace on @screen.
920 *
921 * Since: 2.2
922 **/
923void
924vnck_screen_change_workspace_count (VnckScreen *screen,
925 int count)
926{
927 Display *display;
928 XEvent xev;
929
930 g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return; } } while (0)
;
931 g_return_if_fail (count >= 1)do { if ((count >= 1)) { } else { g_return_if_fail_warning
("Vnck", ((const char*) (__func__)), "count >= 1"); return
; } } while (0)
;
932
933 display = DisplayOfScreen (screen->priv->xscreen)((screen->priv->xscreen)->display);
934
935 xev.xclient.type = ClientMessage33;
936 xev.xclient.serial = 0;
937 xev.xclient.window = screen->priv->xroot;
938 xev.xclient.send_event = True1;
939 xev.xclient.display = display;
940 xev.xclient.message_type = _vnck_atom_get ("_NET_NUMBER_OF_DESKTOPS")cdk_x11_get_xatom_by_name ("_NET_NUMBER_OF_DESKTOPS");
941 xev.xclient.format = 32;
942 xev.xclient.data.l[0] = count;
943
944 _vnck_error_trap_push (display);
945 XSendEvent (display,
946 screen->priv->xroot,
947 False0,
948 SubstructureRedirectMask(1L<<20) | SubstructureNotifyMask(1L<<19),
949 &xev);
950 _vnck_error_trap_pop (display);
951}
952
953void
954_vnck_screen_process_property_notify (VnckScreen *screen,
955 XEvent *xevent)
956{
957 /* most frequently-changed properties first */
958 if (xevent->xproperty.atom ==
959 _vnck_atom_get ("_NET_ACTIVE_WINDOW")cdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW"))
960 {
961 screen->priv->need_update_active_window = TRUE(!(0));
962 queue_update (screen);
963 }
964 else if (xevent->xproperty.atom ==
965 _vnck_atom_get ("_NET_CURRENT_DESKTOP")cdk_x11_get_xatom_by_name ("_NET_CURRENT_DESKTOP"))
966 {
967 screen->priv->need_update_active_workspace = TRUE(!(0));
968 queue_update (screen);
969 }
970 else if (xevent->xproperty.atom ==
971 _vnck_atom_get ("_NET_CLIENT_LIST_STACKING")cdk_x11_get_xatom_by_name ("_NET_CLIENT_LIST_STACKING") ||
972 xevent->xproperty.atom ==
973 _vnck_atom_get ("_NET_CLIENT_LIST")cdk_x11_get_xatom_by_name ("_NET_CLIENT_LIST"))
974 {
975 screen->priv->need_update_stack_list = TRUE(!(0));
976 queue_update (screen);
977 }
978 else if (xevent->xproperty.atom ==
979 _vnck_atom_get ("_NET_DESKTOP_VIEWPORT")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_VIEWPORT"))
980 {
981 screen->priv->need_update_viewport_settings = TRUE(!(0));
982 queue_update (screen);
983 }
984 else if (xevent->xproperty.atom ==
985 _vnck_atom_get ("_NET_DESKTOP_GEOMETRY")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_GEOMETRY"))
986 {
987 screen->priv->need_update_viewport_settings = TRUE(!(0));
988 queue_update (screen);
989 }
990 else if (xevent->xproperty.atom ==
991 _vnck_atom_get ("_NET_NUMBER_OF_DESKTOPS")cdk_x11_get_xatom_by_name ("_NET_NUMBER_OF_DESKTOPS"))
992 {
993 screen->priv->need_update_workspace_list = TRUE(!(0));
994 queue_update (screen);
995 }
996 else if (xevent->xproperty.atom ==
997 _vnck_atom_get ("_NET_DESKTOP_LAYOUT")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_LAYOUT"))
998 {
999 screen->priv->need_update_workspace_layout = TRUE(!(0));
1000 queue_update (screen);
1001 }
1002 else if (xevent->xproperty.atom ==
1003 _vnck_atom_get ("_NET_DESKTOP_NAMES")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_NAMES"))
1004 {
1005 screen->priv->need_update_workspace_names = TRUE(!(0));
1006 queue_update (screen);
1007 }
1008 else if (xevent->xproperty.atom ==
1009 _vnck_atom_get ("_XROOTPMAP_ID")cdk_x11_get_xatom_by_name ("_XROOTPMAP_ID"))
1010 {
1011 screen->priv->need_update_bg_pixmap = TRUE(!(0));
1012 queue_update (screen);
1013 }
1014 else if (xevent->xproperty.atom ==
1015 _vnck_atom_get ("_NET_SHOWING_DESKTOP")cdk_x11_get_xatom_by_name ("_NET_SHOWING_DESKTOP"))
1016 {
1017 screen->priv->need_update_showing_desktop = TRUE(!(0));
1018 queue_update (screen);
1019 }
1020 else if (xevent->xproperty.atom ==
1021 _vnck_atom_get ("_NET_SUPPORTING_WM_CHECK")cdk_x11_get_xatom_by_name ("_NET_SUPPORTING_WM_CHECK"))
1022 {
1023 screen->priv->need_update_wm = TRUE(!(0));
1024 queue_update (screen);
1025 }
1026}
1027
1028/**
1029 * vnck_screen_calc_workspace_layout:
1030 * @screen: a #VnckScreen.
1031 * @num_workspaces: the number of #VnckWorkspace on @screen, or -1 to let
1032 * vnck_screen_calc_workspace_layout() find this number.
1033 * @space_index: the index of a #VnckWorkspace.
1034 * @layout: return location for the layout of #VnckWorkspace with additional
1035 * information.
1036 *
1037 * Calculates the layout of #VnckWorkspace, with additional information like
1038 * the row and column of the #VnckWorkspace with index @space_index.
1039 *
1040 * Since: 2.12
1041 * Deprecated:2.20:
1042 */
1043/* TODO: when we make this private, remove num_workspaces since we can get it
1044 * from screen! */
1045void
1046vnck_screen_calc_workspace_layout (VnckScreen *screen,
1047 int num_workspaces,
1048 int space_index,
1049 VnckWorkspaceLayout *layout)
1050{
1051 int rows, cols;
1052 int grid_area;
1053 int *grid;
1054 int i, r, c;
1055 int current_row, current_col;
1056
1057 g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return; } } while (0)
;
1058 g_return_if_fail (layout != NULL)do { if ((layout != ((void*)0))) { } else { g_return_if_fail_warning
("Vnck", ((const char*) (__func__)), "layout != NULL"); return
; } } while (0)
;
1059
1060 if (num_workspaces < 0)
1061 num_workspaces = vnck_screen_get_workspace_count (screen);
1062
1063 rows = screen->priv->rows_of_workspaces;
1064 cols = screen->priv->columns_of_workspaces;
1065
1066 if (rows <= 0 && cols <= 0)
1067 cols = num_workspaces;
1068
1069 if (rows <= 0)
1070 rows = num_workspaces / cols + ((num_workspaces % cols) > 0 ? 1 : 0);
1071 if (cols <= 0)
1072 cols = num_workspaces / rows + ((num_workspaces % rows) > 0 ? 1 : 0);
1073
1074 /* paranoia */
1075 if (rows < 1)
1076 rows = 1;
1077 if (cols < 1)
1078 cols = 1;
1079
1080 g_assert (rows != 0 && cols != 0)do { if (rows != 0 && cols != 0) ; else g_assertion_message_expr
("Vnck", "../libvnck/screen.c", 1080, ((const char*) (__func__
)), "rows != 0 && cols != 0"); } while (0)
;
1081
1082 grid_area = rows * cols;
1083
1084 grid = g_new (int, grid_area)((int *) g_malloc_n ((grid_area), sizeof (int)));
1085
1086 current_row = -1;
1087 current_col = -1;
Value stored to 'current_col' is never read
1088 i = 0;
1089
1090 switch (screen->priv->starting_corner)
1091 {
1092 case VNCK_LAYOUT_CORNER_TOPLEFT:
1093 if (screen->priv->vertical_workspaces)
1094 {
1095 c = 0;
1096 while (c < cols)
1097 {
1098 r = 0;
1099 while (r < rows)
1100 {
1101 grid[r*cols+c] = i;
1102 ++i;
1103 ++r;
1104 }
1105 ++c;
1106 }
1107 }
1108 else
1109 {
1110 r = 0;
1111 while (r < rows)
1112 {
1113 c = 0;
1114 while (c < cols)
1115 {
1116 grid[r*cols+c] = i;
1117 ++i;
1118 ++c;
1119 }
1120 ++r;
1121 }
1122 }
1123 break;
1124 case VNCK_LAYOUT_CORNER_TOPRIGHT:
1125 if (screen->priv->vertical_workspaces)
1126 {
1127 c = cols - 1;
1128 while (c >= 0)
1129 {
1130 r = 0;
1131 while (r < rows)
1132 {
1133 grid[r*cols+c] = i;
1134 ++i;
1135 ++r;
1136 }
1137 --c;
1138 }
1139 }
1140 else
1141 {
1142 r = 0;
1143 while (r < rows)
1144 {
1145 c = cols - 1;
1146 while (c >= 0)
1147 {
1148 grid[r*cols+c] = i;
1149 ++i;
1150 --c;
1151 }
1152 ++r;
1153 }
1154 }
1155 break;
1156 case VNCK_LAYOUT_CORNER_BOTTOMLEFT:
1157 if (screen->priv->vertical_workspaces)
1158 {
1159 c = 0;
1160 while (c < cols)
1161 {
1162 r = rows - 1;
1163 while (r >= 0)
1164 {
1165 grid[r*cols+c] = i;
1166 ++i;
1167 --r;
1168 }
1169 ++c;
1170 }
1171 }
1172 else
1173 {
1174 r = rows - 1;
1175 while (r >= 0)
1176 {
1177 c = 0;
1178 while (c < cols)
1179 {
1180 grid[r*cols+c] = i;
1181 ++i;
1182 ++c;
1183 }
1184 --r;
1185 }
1186 }
1187 break;
1188 case VNCK_LAYOUT_CORNER_BOTTOMRIGHT:
1189 if (screen->priv->vertical_workspaces)
1190 {
1191 c = cols - 1;
1192 while (c >= 0)
1193 {
1194 r = rows - 1;
1195 while (r >= 0)
1196 {
1197 grid[r*cols+c] = i;
1198 ++i;
1199 --r;
1200 }
1201 --c;
1202 }
1203 }
1204 else
1205 {
1206 r = rows - 1;
1207 while (r >= 0)
1208 {
1209 c = cols - 1;
1210 while (c >= 0)
1211 {
1212 grid[r*cols+c] = i;
1213 ++i;
1214 --c;
1215 }
1216 --r;
1217 }
1218 }
1219 break;
1220 default:
1221 break;
1222 }
1223
1224 current_row = 0;
1225 current_col = 0;
1226 r = 0;
1227 while (r < rows)
1228 {
1229 c = 0;
1230 while (c < cols)
1231 {
1232 if (grid[r*cols+c] == space_index)
1233 {
1234 current_row = r;
1235 current_col = c;
1236 }
1237 else if (grid[r*cols+c] >= num_workspaces)
1238 {
1239 /* flag nonexistent spaces with -1 */
1240 grid[r*cols+c] = -1;
1241 }
1242 ++c;
1243 }
1244 ++r;
1245 }
1246 layout->rows = rows;
1247 layout->cols = cols;
1248 layout->grid = grid;
1249 layout->grid_area = grid_area;
1250 layout->current_row = current_row;
1251 layout->current_col = current_col;
1252}
1253
1254/**
1255 * vnck_screen_free_workspace_layout:
1256 * @layout: a #VnckWorkspaceLayout.
1257 *
1258 * Frees the content of @layout. This does not free @layout itself, so you
1259 * might want to free @layout yourself after calling this.
1260 *
1261 * Since: 2.12
1262 * Deprecated:2.20:
1263 */
1264void
1265vnck_screen_free_workspace_layout (VnckWorkspaceLayout *layout)
1266{
1267 g_return_if_fail (layout != NULL)do { if ((layout != ((void*)0))) { } else { g_return_if_fail_warning
("Vnck", ((const char*) (__func__)), "layout != NULL"); return
; } } while (0)
;
1268
1269 g_free (layout->grid);
1270}
1271
1272static void
1273set_active_window (VnckScreen *screen,
1274 VnckWindow *window)
1275{
1276 gpointer weak_pointer;
1277
1278 weak_pointer = &screen->priv->active_window;
1279
1280 /* we need the weak pointer since the active window might be shared between
1281 * two screens, and so the value for one screen might become invalid when
1282 * the window is destroyed on another screen */
1283 if (screen->priv->active_window != NULL((void*)0))
1284 g_object_remove_weak_pointer (G_OBJECT (screen->priv->active_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen->priv->active_window)), (((GType) ((20) <<
(2))))))))
,
1285 weak_pointer);
1286
1287 screen->priv->active_window = window;
1288 if (screen->priv->active_window != NULL((void*)0))
1289 g_object_add_weak_pointer (G_OBJECT (screen->priv->active_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen->priv->active_window)), (((GType) ((20) <<
(2))))))))
,
1290 weak_pointer);
1291}
1292
1293static void
1294set_previously_active_window (VnckScreen *screen,
1295 VnckWindow *window)
1296{
1297 gpointer weak_pointer;
1298
1299 weak_pointer = &screen->priv->previously_active_window;
1300
1301 /* we need the weak pointer since the active window might be shared between
1302 * two screens, and so the value for one screen might become invalid when
1303 * the window is destroyed on another screen */
1304 if (screen->priv->previously_active_window != NULL((void*)0))
1305 g_object_remove_weak_pointer (G_OBJECT (screen->priv->previously_active_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen->priv->previously_active_window)), (((GType
) ((20) << (2))))))))
,
1306 weak_pointer);
1307
1308 screen->priv->previously_active_window = window;
1309 if (screen->priv->previously_active_window != NULL((void*)0))
1310 g_object_add_weak_pointer (G_OBJECT (screen->priv->previously_active_window)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen->priv->previously_active_window)), (((GType
) ((20) << (2))))))))
,
1311 weak_pointer);
1312}
1313
1314static gboolean
1315lists_equal (GList *a,
1316 GList *b)
1317{
1318 GList *a_iter;
1319 GList *b_iter;
1320
1321 a_iter = a;
1322 b_iter = b;
1323
1324 while (a_iter && b_iter)
1325 {
1326 if (a_iter->data != b_iter->data)
1327 return FALSE(0);
1328
1329 a_iter = a_iter->next;
1330 b_iter = b_iter->next;
1331 }
1332
1333 if (a_iter || b_iter)
1334 return FALSE(0);
1335
1336 return TRUE(!(0));
1337}
1338
1339static int
1340wincmp (const void *a,
1341 const void *b)
1342{
1343 const Window *aw = a;
1344 const Window *bw = b;
1345
1346 if (*aw < *bw)
1347 return -1;
1348 else if (*aw > *bw)
1349 return 1;
1350 else
1351 return 0;
1352}
1353
1354static gboolean
1355arrays_contain_same_windows (Window *a,
1356 int a_len,
1357 Window *b,
1358 int b_len)
1359{
1360 Window *a_tmp;
1361 Window *b_tmp;
1362 gboolean result;
1363
1364 if (a_len != b_len)
1365 return FALSE(0);
1366
1367 if (a_len == 0)
1368 return TRUE(!(0)); /* both are empty */
1369
1370 a_tmp = g_new (Window, a_len)((Window *) g_malloc_n ((a_len), sizeof (Window)));
1371 b_tmp = g_new (Window, b_len)((Window *) g_malloc_n ((b_len), sizeof (Window)));
1372
1373 memcpy (a_tmp, a, a_len * sizeof (Window));
1374 memcpy (b_tmp, b, b_len * sizeof (Window));
1375
1376 qsort (a_tmp, a_len, sizeof (Window), wincmp);
1377 qsort (b_tmp, b_len, sizeof (Window), wincmp);
1378
1379 result = memcmp (a_tmp, b_tmp, sizeof (Window) * a_len) == 0;
1380
1381 g_free (a_tmp);
1382 g_free (b_tmp);
1383
1384 return result;
1385}
1386
1387static void
1388update_client_list (VnckScreen *screen)
1389{
1390 /* stacking order */
1391 Window *stack;
1392 int stack_length;
1393 /* mapping order */
1394 Window *mapping;
1395 int mapping_length;
1396 GList *new_stack_list;
1397 GList *new_list;
1398 GList *created;
1399 GList *closed;
1400 GList *created_apps, *closed_apps;
1401 GList *created_class_groups, *closed_class_groups;
1402 GList *tmp;
1403 int i;
1404 GHashTable *new_hash;
1405 static int reentrancy_guard = 0;
1406 gboolean active_changed;
1407 gboolean stack_changed;
1408 gboolean list_changed;
1409
1410 g_return_if_fail (reentrancy_guard == 0)do { if ((reentrancy_guard == 0)) { } else { g_return_if_fail_warning
("Vnck", ((const char*) (__func__)), "reentrancy_guard == 0"
); return; } } while (0)
;
1411
1412 if (!screen->priv->need_update_stack_list)
1413 return;
1414
1415 ++reentrancy_guard;
1416
1417 screen->priv->need_update_stack_list = FALSE(0);
1418
1419 stack = NULL((void*)0);
1420 stack_length = 0;
1421 _vnck_get_window_list (screen->priv->xscreen,
1422 screen->priv->xroot,
1423 _vnck_atom_get ("_NET_CLIENT_LIST_STACKING")cdk_x11_get_xatom_by_name ("_NET_CLIENT_LIST_STACKING"),
1424 &stack,
1425 &stack_length);
1426
1427 mapping = NULL((void*)0);
1428 mapping_length = 0;
1429 _vnck_get_window_list (screen->priv->xscreen,
1430 screen->priv->xroot,
1431 _vnck_atom_get ("_NET_CLIENT_LIST")cdk_x11_get_xatom_by_name ("_NET_CLIENT_LIST"),
1432 &mapping,
1433 &mapping_length);
1434
1435 if (!arrays_contain_same_windows (stack, stack_length,
1436 mapping, mapping_length))
1437 {
1438 /* Don't update until we're in a consistent state */
1439 g_free (stack);
1440 g_free (mapping);
1441 --reentrancy_guard;
1442 return;
1443 }
1444
1445 created = NULL((void*)0);
1446 closed = NULL((void*)0);
1447 created_apps = NULL((void*)0);
1448 closed_apps = NULL((void*)0);
1449 created_class_groups = NULL((void*)0);
1450 closed_class_groups = NULL((void*)0);
1451
1452 new_hash = g_hash_table_new (NULL((void*)0), NULL((void*)0));
1453
1454 new_list = NULL((void*)0);
1455 i = 0;
1456 while (i < mapping_length)
1457 {
1458 VnckWindow *window;
1459
1460 window = vnck_window_get (mapping[i]);
1461
1462 if (window == NULL((void*)0))
1463 {
1464 Window leader;
1465 VnckApplication *app;
1466 const char *res_class;
1467 VnckClassGroup *class_group;
1468
1469 window = _vnck_window_create (mapping[i],
1470 screen,
1471 screen->priv->window_order++);
1472
1473 created = g_list_prepend (created, window);
1474
1475 /* Application */
1476
1477 leader = vnck_window_get_group_leader (window);
1478
1479 app = vnck_application_get (leader);
1480 if (app == NULL((void*)0))
1481 {
1482 app = _vnck_application_create (leader, screen);
1483 created_apps = g_list_prepend (created_apps, app);
1484 }
1485
1486 _vnck_application_add_window (app, window);
1487
1488 /* Class group */
1489
1490 res_class = vnck_window_get_class_group_name (window);
1491
1492 class_group = vnck_class_group_get (res_class);
1493 if (class_group == NULL((void*)0))
1494 {
1495 class_group = _vnck_class_group_create (screen, res_class);
1496 created_class_groups = g_list_prepend (created_class_groups, class_group);
1497 }
1498
1499 _vnck_class_group_add_window (class_group, window);
1500 }
1501
1502 new_list = g_list_prepend (new_list, window);
1503
1504 g_hash_table_insert (new_hash, window, window);
1505
1506 ++i;
1507 }
1508
1509 /* put list back in order */
1510 new_list = g_list_reverse (new_list);
1511
1512 /* Now we need to find windows in the old list that aren't
1513 * in this new list
1514 */
1515 tmp = screen->priv->mapped_windows;
1516 while (tmp != NULL((void*)0))
1517 {
1518 VnckWindow *window = tmp->data;
1519
1520 if (g_hash_table_lookup (new_hash, window) == NULL((void*)0))
1521 {
1522 VnckApplication *app;
1523 VnckClassGroup *class_group;
1524
1525 closed = g_list_prepend (closed, window);
1526
1527 /* Remove from the app */
1528
1529 app = vnck_window_get_application (window);
1530 _vnck_application_remove_window (app, window);
1531
1532 if (vnck_application_get_windows (app) == NULL((void*)0))
1533 closed_apps = g_list_prepend (closed_apps, app);
1534
1535 /* Remove from the class group */
1536
1537 class_group = vnck_window_get_class_group (window);
1538 _vnck_class_group_remove_window (class_group, window);
1539
1540 if (vnck_class_group_get_windows (class_group) == NULL((void*)0))
1541 closed_class_groups = g_list_prepend (closed_class_groups, class_group);
1542 }
1543
1544 tmp = tmp->next;
1545 }
1546
1547 g_hash_table_destroy (new_hash);
1548
1549 /* Now get the mapping in list form */
1550 new_stack_list = NULL((void*)0);
1551 i = 0;
1552 while (i < stack_length)
1553 {
1554 VnckWindow *window;
1555
1556 window = vnck_window_get (stack[i]);
1557
1558 g_assert (window != NULL)do { if (window != ((void*)0)) ; else g_assertion_message_expr
("Vnck", "../libvnck/screen.c", 1558, ((const char*) (__func__
)), "window != NULL"); } while (0)
;
1559
1560 new_stack_list = g_list_prepend (new_stack_list, window);
1561
1562 ++i;
1563 }
1564
1565 g_free (stack);
1566 g_free (mapping);
1567
1568 /* put list back in order */
1569 new_stack_list = g_list_reverse (new_stack_list);
1570
1571 /* Now new_stack_list becomes screen->priv->stack_windows, new_list
1572 * becomes screen->priv->mapped_windows, and we emit the opened/closed
1573 * signals as appropriate
1574 */
1575
1576 stack_changed = !lists_equal (screen->priv->stacked_windows, new_stack_list);
1577 list_changed = !lists_equal (screen->priv->mapped_windows, new_list);
1578
1579 if (!(stack_changed || list_changed))
1580 {
1581 g_assert (created == NULL)do { if (created == ((void*)0)) ; else g_assertion_message_expr
("Vnck", "../libvnck/screen.c", 1581, ((const char*) (__func__
)), "created == NULL"); } while (0)
;
1582 g_assert (closed == NULL)do { if (closed == ((void*)0)) ; else g_assertion_message_expr
("Vnck", "../libvnck/screen.c", 1582, ((const char*) (__func__
)), "closed == NULL"); } while (0)
;
1583 g_assert (created_apps == NULL)do { if (created_apps == ((void*)0)) ; else g_assertion_message_expr
("Vnck", "../libvnck/screen.c", 1583, ((const char*) (__func__
)), "created_apps == NULL"); } while (0)
;
1584 g_assert (closed_apps == NULL)do { if (closed_apps == ((void*)0)) ; else g_assertion_message_expr
("Vnck", "../libvnck/screen.c", 1584, ((const char*) (__func__
)), "closed_apps == NULL"); } while (0)
;
1585 g_assert (created_class_groups == NULL)do { if (created_class_groups == ((void*)0)) ; else g_assertion_message_expr
("Vnck", "../libvnck/screen.c", 1585, ((const char*) (__func__
)), "created_class_groups == NULL"); } while (0)
;
1586 g_assert (closed_class_groups == NULL)do { if (closed_class_groups == ((void*)0)) ; else g_assertion_message_expr
("Vnck", "../libvnck/screen.c", 1586, ((const char*) (__func__
)), "closed_class_groups == NULL"); } while (0)
;
1587 g_list_free (new_stack_list);
1588 g_list_free (new_list);
1589 --reentrancy_guard;
1590 return;
1591 }
1592
1593 g_list_free (screen->priv->mapped_windows);
1594 g_list_free (screen->priv->stacked_windows);
1595 screen->priv->mapped_windows = new_list;
1596 screen->priv->stacked_windows = new_stack_list;
1597
1598 /* Here we could get reentrancy if someone ran the main loop in
1599 * signal callbacks; though that would be a bit pathological, so we
1600 * don't handle it, but we do warn about it using reentrancy_guard
1601 */
1602
1603 /* Sequence is: class_group_opened, application_opened, window_opened,
1604 * window_closed, application_closed, class_group_closed. We have to do all
1605 * window list changes BEFORE doing any other signals, so that any observers
1606 * have valid state for the window structure before they take further action
1607 */
1608 for (tmp = created_class_groups; tmp; tmp = tmp->next)
1609 emit_class_group_opened (screen, VNCK_CLASS_GROUP (tmp->data)((((VnckClassGroup*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp->data)), ((vnck_class_group_get_type ()))))))
);
1610
1611 for (tmp = created_apps; tmp; tmp = tmp->next)
1612 emit_application_opened (screen, VNCK_APPLICATION (tmp->data)((((VnckApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp->data)), ((vnck_application_get_type ()))))))
);
1613
1614 for (tmp = created; tmp; tmp = tmp->next)
1615 emit_window_opened (screen, VNCK_WINDOW (tmp->data)((((VnckWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp->data)), ((vnck_window_get_type ()))))))
);
1616
1617 active_changed = FALSE(0);
1618 for (tmp = closed; tmp; tmp = tmp->next)
1619 {
1620 VnckWindow *window;
1621
1622 window = VNCK_WINDOW (tmp->data)((((VnckWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp->data)), ((vnck_window_get_type ()))))))
;
1623
1624 if (window == screen->priv->previously_active_window)
1625 {
1626 set_previously_active_window (screen, NULL((void*)0));
1627 }
1628
1629 if (window == screen->priv->active_window)
1630 {
1631 set_previously_active_window (screen, screen->priv->active_window);
1632 set_active_window (screen, NULL((void*)0));
1633 active_changed = TRUE(!(0));
1634 }
1635
1636 emit_window_closed (screen, window);
1637 }
1638
1639 for (tmp = closed_apps; tmp; tmp = tmp->next)
1640 emit_application_closed (screen, VNCK_APPLICATION (tmp->data)((((VnckApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp->data)), ((vnck_application_get_type ()))))))
);
1641
1642 for (tmp = closed_class_groups; tmp; tmp = tmp->next)
1643 emit_class_group_closed (screen, VNCK_CLASS_GROUP (tmp->data)((((VnckClassGroup*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp->data)), ((vnck_class_group_get_type ()))))))
);
1644
1645 if (stack_changed)
1646 emit_window_stacking_changed (screen);
1647
1648 if (active_changed)
1649 emit_active_window_changed (screen);
1650
1651 /* Now free the closed windows */
1652 for (tmp = closed; tmp; tmp = tmp->next)
1653 _vnck_window_destroy (VNCK_WINDOW (tmp->data)((((VnckWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp->data)), ((vnck_window_get_type ()))))))
);
1654
1655 /* Free the closed apps */
1656 for (tmp = closed_apps; tmp; tmp = tmp->next)
1657 _vnck_application_destroy (VNCK_APPLICATION (tmp->data)((((VnckApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp->data)), ((vnck_application_get_type ()))))))
);
1658
1659 /* Free the closed class groups */
1660 for (tmp = closed_class_groups; tmp; tmp = tmp->next)
1661 _vnck_class_group_destroy (VNCK_CLASS_GROUP (tmp->data)((((VnckClassGroup*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp->data)), ((vnck_class_group_get_type ()))))))
);
1662
1663 g_list_free (closed);
1664 g_list_free (created);
1665 g_list_free (closed_apps);
1666 g_list_free (created_apps);
1667 g_list_free (closed_class_groups);
1668 g_list_free (created_class_groups);
1669
1670 --reentrancy_guard;
1671
1672 /* Maybe the active window is now valid if it wasn't */
1673 if (screen->priv->active_window == NULL((void*)0))
1674 {
1675 screen->priv->need_update_active_window = TRUE(!(0));
1676 queue_update (screen);
1677 }
1678}
1679
1680static void
1681update_workspace_list (VnckScreen *screen)
1682{
1683 int n_spaces;
1684 int old_n_spaces;
1685 GList *tmp;
1686 GList *deleted;
1687 GList *created;
1688 static int reentrancy_guard = 0;
1689
1690 g_return_if_fail (reentrancy_guard == 0)do { if ((reentrancy_guard == 0)) { } else { g_return_if_fail_warning
("Vnck", ((const char*) (__func__)), "reentrancy_guard == 0"
); return; } } while (0)
;
1691
1692 if (!screen->priv->need_update_workspace_list)
1693 return;
1694
1695 screen->priv->need_update_workspace_list = FALSE(0);
1696
1697 ++reentrancy_guard;
1698
1699 n_spaces = 0;
1700 if (!_vnck_get_cardinal (screen->priv->xscreen,
1701 screen->priv->xroot,
1702 _vnck_atom_get ("_NET_NUMBER_OF_DESKTOPS")cdk_x11_get_xatom_by_name ("_NET_NUMBER_OF_DESKTOPS"),
1703 &n_spaces))
1704 n_spaces = 1;
1705
1706 if (n_spaces <= 0)
1707 {
1708 g_warning ("Someone set a weird number of desktops in _NET_NUMBER_OF_DESKTOPS, assuming the value is 1\n");
1709 n_spaces = 1;
1710 }
1711
1712 old_n_spaces = g_list_length (screen->priv->workspaces);
1713
1714 deleted = NULL((void*)0);
1715 created = NULL((void*)0);
1716
1717 if (old_n_spaces == n_spaces)
1718 {
1719 --reentrancy_guard;
1720 return; /* nothing changed */
1721 }
1722 else if (old_n_spaces > n_spaces)
1723 {
1724 /* Need to delete some workspaces */
1725 deleted = g_list_nth (screen->priv->workspaces, n_spaces);
1726 if (deleted->prev)
1727 deleted->prev->next = NULL((void*)0);
1728 deleted->prev = NULL((void*)0);
1729
1730 if (deleted == screen->priv->workspaces)
1731 screen->priv->workspaces = NULL((void*)0);
1732 }
1733 else
1734 {
1735 int i;
1736
1737 g_assert (old_n_spaces < n_spaces)do { if (old_n_spaces < n_spaces) ; else g_assertion_message_expr
("Vnck", "../libvnck/screen.c", 1737, ((const char*) (__func__
)), "old_n_spaces < n_spaces"); } while (0)
;
1738
1739 /* Need to create some workspaces */
1740 i = 0;
1741 while (i < (n_spaces - old_n_spaces))
1742 {
1743 VnckWorkspace *space;
1744
1745 space = _vnck_workspace_create (old_n_spaces + i, screen);
1746
1747 screen->priv->workspaces = g_list_append (screen->priv->workspaces,
1748 space);
1749
1750 created = g_list_prepend (created, space);
1751
1752 ++i;
1753 }
1754
1755 created = g_list_reverse (created);
1756 }
1757
1758 /* Here we allow reentrancy, going into the main
1759 * loop could confuse us
1760 */
1761 tmp = deleted;
1762 while (tmp != NULL((void*)0))
1763 {
1764 VnckWorkspace *space = VNCK_WORKSPACE (tmp->data)((((VnckWorkspace*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp->data)), ((vnck_workspace_get_type ()))))))
;
1765
1766 if (space == screen->priv->active_workspace)
1767 {
1768 screen->priv->active_workspace = NULL((void*)0);
1769 emit_active_workspace_changed (screen, space);
1770 }
1771
1772 emit_workspace_destroyed (screen, space);
1773
1774 tmp = tmp->next;
1775 }
1776
1777 tmp = created;
1778 while (tmp != NULL((void*)0))
1779 {
1780 emit_workspace_created (screen, VNCK_WORKSPACE (tmp->data)((((VnckWorkspace*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tmp->data)), ((vnck_workspace_get_type ()))))))
);
1781
1782 tmp = tmp->next;
1783 }
1784 g_list_free (created);
1785
1786 tmp = deleted;
1787 while (tmp != NULL((void*)0))
1788 {
1789 g_object_unref (tmp->data);
1790
1791 tmp = tmp->next;
1792 }
1793 g_list_free (deleted);
1794
1795 /* Active workspace property may now be interpretable,
1796 * if it was a number larger than the active count previously
1797 */
1798 if (screen->priv->active_workspace == NULL((void*)0))
1799 {
1800 screen->priv->need_update_active_workspace = TRUE(!(0));
1801 queue_update (screen);
1802 }
1803
1804 --reentrancy_guard;
1805}
1806
1807static void
1808update_viewport_settings (VnckScreen *screen)
1809{
1810 int i, n_spaces;
1811 VnckWorkspace *space;
1812 gulong *p_coord;
1813 int n_coord;
1814 gboolean do_update;
1815 int space_width, space_height;
1816 gboolean got_viewport_prop;
1817
1818 if (!screen->priv->need_update_viewport_settings)
1819 return;
1820
1821 screen->priv->need_update_viewport_settings = FALSE(0);
1822
1823 do_update = FALSE(0);
1824
1825 n_spaces = vnck_screen_get_workspace_count (screen);
1826
1827 /* If no property, use the screen's size */
1828 space_width = vnck_screen_get_width (screen);
1829 space_height = vnck_screen_get_height (screen);
1830
1831 p_coord = NULL((void*)0);
1832 n_coord = 0;
1833 if (_vnck_get_cardinal_list (screen->priv->xscreen,
1834 screen->priv->xroot,
1835 _vnck_atom_get ("_NET_DESKTOP_GEOMETRY")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_GEOMETRY"),
1836 &p_coord, &n_coord) &&
1837 p_coord != NULL((void*)0))
1838 {
1839 if (n_coord == 2)
1840 {
1841 space_width = p_coord[0];
1842 space_height = p_coord[1];
1843
1844 if (space_width < vnck_screen_get_width (screen))
1845 space_width = vnck_screen_get_width (screen);
1846
1847 if (space_height < vnck_screen_get_height (screen))
1848 space_height = vnck_screen_get_height (screen);
1849 }
1850
1851 g_free (p_coord);
1852 }
1853
1854 for (i = 0; i < n_spaces; i++)
1855 {
1856 space = vnck_screen_get_workspace (screen, i);
1857 g_assert (space != NULL)do { if (space != ((void*)0)) ; else g_assertion_message_expr
("Vnck", "../libvnck/screen.c", 1857, ((const char*) (__func__
)), "space != NULL"); } while (0)
;
1858
1859 if (_vnck_workspace_set_geometry (space, space_width, space_height))
1860 do_update = TRUE(!(0));
1861 }
1862
1863 got_viewport_prop = FALSE(0);
1864
1865 p_coord = NULL((void*)0);
1866 n_coord = 0;
1867 if (_vnck_get_cardinal_list (screen->priv->xscreen,
1868 screen->priv->xroot,
1869 _vnck_atom_get ("_NET_DESKTOP_VIEWPORT")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_VIEWPORT"),
1870 &p_coord, &n_coord) &&
1871 p_coord != NULL((void*)0))
1872 {
1873 if (n_coord == 2 * n_spaces)
1874 {
1875 int screen_width, screen_height;
1876
1877 got_viewport_prop = TRUE(!(0));
1878
1879 screen_width = vnck_screen_get_width (screen);
1880 screen_height = vnck_screen_get_height (screen);
1881
1882 for (i = 0; i < n_spaces; i++)
1883 {
1884 int x = 2 * i;
1885 int y = 2 * i + 1;
1886
1887 space = vnck_screen_get_workspace (screen, i);
1888 g_assert (space != NULL)do { if (space != ((void*)0)) ; else g_assertion_message_expr
("Vnck", "../libvnck/screen.c", 1888, ((const char*) (__func__
)), "space != NULL"); } while (0)
;
1889
1890 /* p_coord[x] is unsigned, and thus >= 0 */
1891 if ((int) p_coord[x] > space_width - screen_width)
1892 p_coord[x] = space_width - screen_width;
1893
1894 /* p_coord[y] is unsigned, and thus >= 0 */
1895 if ((int) p_coord[y] > space_height - screen_height)
1896 p_coord[y] = space_height - screen_height;
1897
1898 if (_vnck_workspace_set_viewport (space,
1899 p_coord[x], p_coord[y]))
1900 do_update = TRUE(!(0));
1901 }
1902 }
1903
1904 g_free (p_coord);
1905 }
1906
1907 if (!got_viewport_prop)
1908 {
1909 for (i = 0; i < n_spaces; i++)
1910 {
1911 space = vnck_screen_get_workspace (screen, i);
1912 g_assert (space != NULL)do { if (space != ((void*)0)) ; else g_assertion_message_expr
("Vnck", "../libvnck/screen.c", 1912, ((const char*) (__func__
)), "space != NULL"); } while (0)
;
1913
1914 if (_vnck_workspace_set_viewport (space, 0, 0))
1915 do_update = TRUE(!(0));
1916 }
1917 }
1918
1919 if (do_update)
1920 emit_viewports_changed (screen);
1921}
1922
1923static void
1924update_active_workspace (VnckScreen *screen)
1925{
1926 int number;
1927 VnckWorkspace *previous_space;
1928 VnckWorkspace *space;
1929
1930 if (!screen->priv->need_update_active_workspace)
1931 return;
1932
1933 screen->priv->need_update_active_workspace = FALSE(0);
1934
1935 number = 0;
1936 if (!_vnck_get_cardinal (screen->priv->xscreen,
1937 screen->priv->xroot,
1938 _vnck_atom_get ("_NET_CURRENT_DESKTOP")cdk_x11_get_xatom_by_name ("_NET_CURRENT_DESKTOP"),
1939 &number))
1940 number = -1;
1941
1942 space = vnck_screen_get_workspace (screen, number);
1943
1944 if (space == screen->priv->active_workspace)
1945 return;
1946
1947 previous_space = screen->priv->active_workspace;
1948 screen->priv->active_workspace = space;
1949
1950 emit_active_workspace_changed (screen, previous_space);
1951}
1952
1953static void
1954update_active_window (VnckScreen *screen)
1955{
1956 VnckWindow *window;
1957 Window xwindow;
1958
1959 if (!screen->priv->need_update_active_window)
1960 return;
1961
1962 screen->priv->need_update_active_window = FALSE(0);
1963
1964 xwindow = None0L;
1965 _vnck_get_window (screen->priv->xscreen,
1966 screen->priv->xroot,
1967 _vnck_atom_get ("_NET_ACTIVE_WINDOW")cdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW"),
1968 &xwindow);
1969
1970 window = vnck_window_get (xwindow);
1971
1972 if (window == screen->priv->active_window)
1973 return;
1974
1975 set_previously_active_window (screen, screen->priv->active_window);
1976 set_active_window (screen, window);
1977
1978 emit_active_window_changed (screen);
1979}
1980
1981static void
1982update_workspace_layout (VnckScreen *screen)
1983{
1984 gulong *list;
1985 int n_items;
1986
1987 if (!screen->priv->need_update_workspace_layout)
1988 return;
1989
1990 screen->priv->need_update_workspace_layout = FALSE(0);
1991
1992 list = NULL((void*)0);
1993 n_items = 0;
1994 if (_vnck_get_cardinal_list (screen->priv->xscreen,
1995 screen->priv->xroot,
1996 _vnck_atom_get ("_NET_DESKTOP_LAYOUT")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_LAYOUT"),
1997 &list,
1998 &n_items))
1999 {
2000 if (n_items == 3 || n_items == 4)
2001 {
2002 int cols, rows;
2003
2004 switch (list[0])
2005 {
2006 case _NET_WM_ORIENTATION_HORZ0:
2007 screen->priv->vertical_workspaces = FALSE(0);
2008 break;
2009 case _NET_WM_ORIENTATION_VERT1:
2010 screen->priv->vertical_workspaces = TRUE(!(0));
2011 break;
2012 default:
2013 g_warning ("Someone set a weird orientation in _NET_DESKTOP_LAYOUT\n");
2014 break;
2015 }
2016
2017 cols = list[1];
2018 rows = list[2];
2019
2020 if (rows <= 0 && cols <= 0)
2021 {
2022 g_warning ("Columns = %d rows = %d in _NET_DESKTOP_LAYOUT makes no sense\n", rows, cols);
2023 }
2024 else
2025 {
2026 int num_workspaces;
2027
2028 num_workspaces = vnck_screen_get_workspace_count (screen);
2029
2030 if (rows > 0)
2031 screen->priv->rows_of_workspaces = rows;
2032 else
2033 screen->priv->rows_of_workspaces =
2034 num_workspaces / cols
2035 + ((num_workspaces % cols) > 0 ? 1 : 0);
2036
2037 if (cols > 0)
2038 screen->priv->columns_of_workspaces = cols;
2039 else
2040 screen->priv->columns_of_workspaces =
2041 num_workspaces / rows
2042 + ((num_workspaces % rows) > 0 ? 1 : 0);
2043 }
2044 if (n_items == 4)
2045 {
2046 switch (list[3])
2047 {
2048 case _NET_WM_TOPLEFT0:
2049 screen->priv->starting_corner = VNCK_LAYOUT_CORNER_TOPLEFT;
2050 break;
2051 case _NET_WM_TOPRIGHT1:
2052 screen->priv->starting_corner = VNCK_LAYOUT_CORNER_TOPRIGHT;
2053 break;
2054 case _NET_WM_BOTTOMRIGHT2:
2055 screen->priv->starting_corner = VNCK_LAYOUT_CORNER_BOTTOMRIGHT;
2056 break;
2057 case _NET_WM_BOTTOMLEFT3:
2058 screen->priv->starting_corner = VNCK_LAYOUT_CORNER_BOTTOMLEFT;
2059 break;
2060 default:
2061 g_warning ("Someone set a weird starting corner in _NET_DESKTOP_LAYOUT\n");
2062 break;
2063 }
2064 }
2065 else
2066 screen->priv->starting_corner = VNCK_LAYOUT_CORNER_TOPLEFT;
2067 }
2068 else
2069 {
2070 g_warning ("Someone set _NET_DESKTOP_LAYOUT to %d integers instead of 4 (3 is accepted for backwards compat)\n", n_items);
2071 }
2072 g_free (list);
2073 }
2074}
2075
2076static void
2077update_workspace_names (VnckScreen *screen)
2078{
2079 char **names;
2080 int i;
2081 GList *tmp;
2082 GList *copy;
2083
2084 if (!screen->priv->need_update_workspace_names)
2085 return;
2086
2087 screen->priv->need_update_workspace_names = FALSE(0);
2088
2089 names = _vnck_get_utf8_list (screen->priv->xscreen,
2090 screen->priv->xroot,
2091 _vnck_atom_get ("_NET_DESKTOP_NAMES")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_NAMES"));
2092
2093 copy = g_list_copy (screen->priv->workspaces);
2094
2095 i = 0;
2096 tmp = copy;
2097 while (tmp != NULL((void*)0))
2098 {
2099 if (names && names[i])
2100 {
2101 _vnck_workspace_update_name (tmp->data, names[i]);
2102 ++i;
2103 }
2104 else
2105 _vnck_workspace_update_name (tmp->data, NULL((void*)0));
2106
2107 tmp = tmp->next;
2108 }
2109
2110 g_strfreev (names);
2111
2112 g_list_free (copy);
2113}
2114
2115static void
2116update_bg_pixmap (VnckScreen *screen)
2117{
2118 Pixmap p;
2119
2120 if (!screen->priv->need_update_bg_pixmap)
2121 return;
2122
2123 screen->priv->need_update_bg_pixmap = FALSE(0);
2124
2125 p = None0L;
2126 _vnck_get_pixmap (screen->priv->xscreen,
2127 screen->priv->xroot,
2128 _vnck_atom_get ("_XROOTPMAP_ID")cdk_x11_get_xatom_by_name ("_XROOTPMAP_ID"),
2129 &p);
2130 /* may have failed, so p may still be None */
2131
2132 screen->priv->bg_pixmap = p;
2133
2134 emit_background_changed (screen);
2135}
2136
2137static void
2138update_showing_desktop (VnckScreen *screen)
2139{
2140 int showing_desktop;
2141
2142 if (!screen->priv->need_update_showing_desktop)
2143 return;
2144
2145 screen->priv->need_update_showing_desktop = FALSE(0);
2146
2147 showing_desktop = FALSE(0);
2148 _vnck_get_cardinal (screen->priv->xscreen,
2149 screen->priv->xroot,
2150 _vnck_atom_get ("_NET_SHOWING_DESKTOP")cdk_x11_get_xatom_by_name ("_NET_SHOWING_DESKTOP"),
2151 &showing_desktop);
2152
2153 screen->priv->showing_desktop = showing_desktop != 0;
2154
2155 emit_showing_desktop_changed (screen);
2156}
2157
2158static void
2159update_wm (VnckScreen *screen)
2160{
2161 Window wm_window;
2162
2163 if (!screen->priv->need_update_wm)
2164 return;
2165
2166 screen->priv->need_update_wm = FALSE(0);
2167
2168 wm_window = None0L;
2169 _vnck_get_window (screen->priv->xscreen,
2170 screen->priv->xroot,
2171 _vnck_atom_get ("_NET_SUPPORTING_WM_CHECK")cdk_x11_get_xatom_by_name ("_NET_SUPPORTING_WM_CHECK"),
2172 &wm_window);
2173
2174 g_free (screen->priv->wm_name);
2175
2176 if (wm_window != None0L)
2177 screen->priv->wm_name = _vnck_get_utf8_property (screen->priv->xscreen,
2178 wm_window,
2179 _vnck_atom_get ("_NET_WM_NAME")cdk_x11_get_xatom_by_name ("_NET_WM_NAME"));
2180 else
2181 screen->priv->wm_name = NULL((void*)0);
2182
2183 emit_wm_changed (screen);
2184}
2185
2186static void
2187do_update_now (VnckScreen *screen)
2188{
2189 if (screen->priv->update_handler)
2190 {
2191 g_source_remove (screen->priv->update_handler);
2192 screen->priv->update_handler = 0;
2193 }
2194
2195 /* if number of workspaces changes, we have to
2196 * update the per-workspace information as well
2197 * in case the WM changed the per-workspace info
2198 * first and number of spaces second.
2199 */
2200 if (screen->priv->need_update_workspace_list)
2201 {
2202 screen->priv->need_update_viewport_settings = TRUE(!(0));
2203 screen->priv->need_update_workspace_names = TRUE(!(0));
2204 }
2205
2206 /* First get our big-picture state in order */
2207 update_workspace_list (screen);
2208 update_client_list (screen);
2209
2210 /* Then note any smaller-scale changes */
2211 update_active_workspace (screen);
2212 update_viewport_settings (screen);
2213 update_active_window (screen);
2214 update_workspace_layout (screen);
2215 update_workspace_names (screen);
2216 update_showing_desktop (screen);
2217 update_wm (screen);
2218
2219 update_bg_pixmap (screen);
2220}
2221
2222static gboolean
2223update_idle (gpointer data)
2224{
2225 VnckScreen *screen;
2226
2227 screen = data;
2228
2229 screen->priv->update_handler = 0;
2230
2231 do_update_now (screen);
2232
2233 return FALSE(0);
2234}
2235
2236static void
2237queue_update (VnckScreen *screen)
2238{
2239 if (screen->priv->update_handler != 0)
2240 return;
2241
2242 screen->priv->update_handler = g_idle_add (update_idle, screen);
2243}
2244
2245static void
2246unqueue_update (VnckScreen *screen)
2247{
2248 if (screen->priv->update_handler != 0)
2249 {
2250 g_source_remove (screen->priv->update_handler);
2251 screen->priv->update_handler = 0;
2252 }
2253}
2254
2255static void
2256emit_active_window_changed (VnckScreen *screen)
2257{
2258 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2259 signals[ACTIVE_WINDOW_CHANGED],
2260 0, screen->priv->previously_active_window);
2261}
2262
2263static void
2264emit_active_workspace_changed (VnckScreen *screen,
2265 VnckWorkspace *previous_space)
2266{
2267 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2268 signals[ACTIVE_WORKSPACE_CHANGED],
2269 0, previous_space);
2270}
2271
2272static void
2273emit_window_stacking_changed (VnckScreen *screen)
2274{
2275 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2276 signals[WINDOW_STACKING_CHANGED],
2277 0);
2278}
2279
2280static void
2281emit_window_opened (VnckScreen *screen,
2282 VnckWindow *window)
2283{
2284 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2285 signals[WINDOW_OPENED],
2286 0, window);
2287}
2288
2289static void
2290emit_window_closed (VnckScreen *screen,
2291 VnckWindow *window)
2292{
2293 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2294 signals[WINDOW_CLOSED],
2295 0, window);
2296}
2297
2298static void
2299emit_workspace_created (VnckScreen *screen,
2300 VnckWorkspace *space)
2301{
2302 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2303 signals[WORKSPACE_CREATED],
2304 0, space);
2305}
2306
2307static void
2308emit_workspace_destroyed (VnckScreen *screen,
2309 VnckWorkspace *space)
2310{
2311 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2312 signals[WORKSPACE_DESTROYED],
2313 0, space);
2314}
2315
2316static void
2317emit_application_opened (VnckScreen *screen,
2318 VnckApplication *app)
2319{
2320 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2321 signals[APPLICATION_OPENED],
2322 0, app);
2323}
2324
2325static void
2326emit_application_closed (VnckScreen *screen,
2327 VnckApplication *app)
2328{
2329 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2330 signals[APPLICATION_CLOSED],
2331 0, app);
2332}
2333
2334static void
2335emit_class_group_opened (VnckScreen *screen,
2336 VnckClassGroup *class_group)
2337{
2338 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2339 signals[CLASS_GROUP_OPENED],
2340 0, class_group);
2341}
2342
2343static void
2344emit_class_group_closed (VnckScreen *screen,
2345 VnckClassGroup *class_group)
2346{
2347 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2348 signals[CLASS_GROUP_CLOSED],
2349 0, class_group);
2350}
2351
2352static void
2353emit_background_changed (VnckScreen *screen)
2354{
2355 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2356 signals[BACKGROUND_CHANGED],
2357 0);
2358}
2359
2360static void
2361emit_showing_desktop_changed (VnckScreen *screen)
2362{
2363 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2364 signals[SHOWING_DESKTOP_CHANGED],
2365 0);
2366}
2367
2368static void
2369emit_viewports_changed (VnckScreen *screen)
2370{
2371 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2372 signals[VIEWPORTS_CHANGED],
2373 0);
2374}
2375
2376static void
2377emit_wm_changed (VnckScreen *screen)
2378{
2379 g_signal_emit (G_OBJECT (screen)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((screen)), (((GType) ((20) << (2))))))))
,
2380 signals[WM_CHANGED],
2381 0);
2382}
2383
2384/**
2385 * vnck_screen_get_window_manager_name:
2386 * @screen: a #VnckScreen.
2387 *
2388 * Gets the name of the window manager.
2389 *
2390 * Return value: the name of the window manager, or %NULL if the window manager
2391 * does not comply with the <ulink
2392 * url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html">EWMH</ulink>
2393 * specification.
2394 *
2395 * Since: 2.20
2396 */
2397const char *
2398vnck_screen_get_window_manager_name (VnckScreen *screen)
2399{
2400 g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while
(0)
;
2401
2402 return screen->priv->wm_name;
2403}
2404
2405/**
2406 * vnck_screen_net_wm_supports:
2407 * @screen: a #VnckScreen.
2408 * @atom: a property atom.
2409 *
2410 * Gets whether the window manager for @screen supports a certain hint from
2411 * the <ulink
2412 * url="http://standards.freedesktop.org/wm-spec/wm-spec-latest.html">Extended
2413 * Window Manager Hints specification</ulink> (EWMH).
2414 *
2415 * When using this function, keep in mind that the window manager can change
2416 * over time; so you should not use this function in a way that impacts
2417 * persistent application state. A common bug is that your application can
2418 * start up before the window manager does when the user logs in, and before
2419 * the window manager starts vnck_screen_net_wm_supports() will return %FALSE
2420 * for every property.
2421 *
2422 * See also cdk_x11_screen_supports_net_wm_hint() in CDK.
2423 *
2424 * Return value: %TRUE if the window manager for @screen supports the @atom
2425 * hint, %FALSE otherwise.
2426 */
2427gboolean
2428vnck_screen_net_wm_supports (VnckScreen *screen,
2429 const char *atom)
2430{
2431 g_return_val_if_fail (VNCK_IS_SCREEN (screen), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return ((0)); } } while (0)
;
2432
2433 return cdk_x11_screen_supports_net_wm_hint (_vnck_screen_get_cdk_screen (screen),
2434 cdk_atom_intern (atom, FALSE(0)));
2435}
2436
2437/**
2438 * vnck_screen_get_background_pixmap:
2439 * @screen: a #VnckScreen.
2440 *
2441 * Gets the X window ID of the background pixmap of @screen.
2442 *
2443 * Returns: the X window ID of the background pixmap of @screen.
2444 */
2445gulong
2446vnck_screen_get_background_pixmap (VnckScreen *screen)
2447{
2448 g_return_val_if_fail (VNCK_IS_SCREEN (screen), None)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (0L); } } while (0)
;
2449
2450 return screen->priv->bg_pixmap;
2451}
2452
2453/**
2454 * vnck_screen_get_width:
2455 * @screen: a #VnckScreen.
2456 *
2457 * Gets the width of @screen.
2458 *
2459 * Returns: the width of @screen.
2460 */
2461int
2462vnck_screen_get_width (VnckScreen *screen)
2463{
2464 g_return_val_if_fail (VNCK_IS_SCREEN (screen), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (0); } } while (0)
;
2465
2466 return WidthOfScreen (screen->priv->xscreen)((screen->priv->xscreen)->width);
2467}
2468
2469/**
2470 * vnck_screen_get_height:
2471 * @screen: a #VnckScreen.
2472 *
2473 * Gets the height of @screen.
2474 *
2475 * Returns: the height of @screen.
2476 */
2477int
2478vnck_screen_get_height (VnckScreen *screen)
2479{
2480 g_return_val_if_fail (VNCK_IS_SCREEN (screen), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (0); } } while (0)
;
2481
2482 return HeightOfScreen (screen->priv->xscreen)((screen->priv->xscreen)->height);
2483}
2484
2485Screen *
2486_vnck_screen_get_xscreen (VnckScreen *screen)
2487{
2488 return screen->priv->xscreen;
2489}
2490
2491/**
2492 * vnck_screen_get_workspace_layout:
2493 * @screen: a #VnckScreen.
2494 * @orientation: return location for the orientation used in the #VnckWorkspace
2495 * layout. See vnck_pager_set_orientation() for more information.
2496 * @rows: return location for the number of rows in the #VnckWorkspace layout.
2497 * @columns: return location for the number of columns in the #VnckWorkspace
2498 * layout.
2499 * @starting_corner: return location for the starting corner in the
2500 * #VnckWorkspace layout (i.e. the corner containing the first #VnckWorkspace).
2501 *
2502 * Gets the layout of #VnckWorkspace on @screen.
2503 */
2504/* TODO: when we are sure about this API, add this function,
2505 * VnckLayoutOrientation, VnckLayoutCorner and a "layout-changed" signal. But
2506 * to make it really better, use a VnckScreenLayout struct. We might also want
2507 * to wait for deprecation of VnckWorkspaceLayout. */
2508void
2509_vnck_screen_get_workspace_layout (VnckScreen *screen,
2510 _VnckLayoutOrientation *orientation,
2511 int *rows,
2512 int *columns,
2513 _VnckLayoutCorner *starting_corner)
2514{
2515 g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return; } } while (0)
;
2516
2517 if (orientation)
2518 *orientation = screen->priv->vertical_workspaces ?
2519 VNCK_LAYOUT_ORIENTATION_VERTICAL :
2520 VNCK_LAYOUT_ORIENTATION_HORIZONTAL;
2521
2522 if (rows)
2523 *rows = screen->priv->rows_of_workspaces;
2524
2525 if (columns)
2526 *columns = screen->priv->columns_of_workspaces;
2527
2528 if (starting_corner)
2529 *starting_corner = screen->priv->starting_corner;
2530}
2531
2532/**
2533 * vnck_screen_try_set_workspace_layout:
2534 * @screen: a #VnckScreen.
2535 * @current_token: a token. Use 0 if you do not called
2536 * vnck_screen_try_set_workspace_layout() before, or if you did not keep the
2537 * old token.
2538 * @rows: the number of rows to use for the #VnckWorkspace layout.
2539 * @columns: the number of columns to use for the #VnckWorkspace layout.
2540 *
2541 * Tries to modify the layout of #VnckWorkspace on @screen. To do this, tries
2542 * to acquire ownership of the layout. If the current process is the owner of
2543 * the layout, @current_token is used to determine if the caller is the owner
2544 * (there might be more than one part of the same process trying to set the
2545 * layout). Since no more than one application should set this property of
2546 * @screen at a time, setting the layout is not guaranteed to work.
2547 *
2548 * If @rows is 0, the actual number of rows will be determined based on
2549 * @columns and the number of #VnckWorkspace. If @columns is 0, the actual
2550 * number of columns will be determined based on @rows and the number of
2551 * #VnckWorkspace. @rows and @columns must not be 0 at the same time.
2552 *
2553 * You have to release the ownership of the layout with
2554 * vnck_screen_release_workspace_layout() when you do not need it anymore.
2555 *
2556 * Return value: a token to use for future calls to
2557 * vnck_screen_try_set_workspace_layout() and to
2558 * vnck_screen_release_workspace_layout(), or 0 if the layout could not be set.
2559 */
2560int
2561vnck_screen_try_set_workspace_layout (VnckScreen *screen,
2562 int current_token,
2563 int rows,
2564 int columns)
2565{
2566 int retval;
2567
2568 g_return_val_if_fail (VNCK_IS_SCREEN (screen),do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (0); } } while (0)
2569 VNCK_NO_MANAGER_TOKEN)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (0); } } while (0)
;
2570 g_return_val_if_fail (rows != 0 || columns != 0,do { if ((rows != 0 || columns != 0)) { } else { g_return_if_fail_warning
("Vnck", ((const char*) (__func__)), "rows != 0 || columns != 0"
); return (0); } } while (0)
2571 VNCK_NO_MANAGER_TOKEN)do { if ((rows != 0 || columns != 0)) { } else { g_return_if_fail_warning
("Vnck", ((const char*) (__func__)), "rows != 0 || columns != 0"
); return (0); } } while (0)
;
2572
2573 retval = _vnck_try_desktop_layout_manager (screen->priv->xscreen, current_token);
2574
2575 if (retval != VNCK_NO_MANAGER_TOKEN0)
2576 {
2577 _vnck_set_desktop_layout (screen->priv->xscreen, rows, columns);
2578 }
2579
2580 return retval;
2581}
2582
2583/**
2584 * vnck_screen_release_workspace_layout:
2585 * @screen: a #VnckScreen.
2586 * @current_token: the token obtained through
2587 * vnck_screen_try_set_workspace_layout().
2588 *
2589 * Releases the ownership of the layout of #VnckWorkspace on @screen.
2590 * @current_token is used to verify that the caller is the owner of the layout.
2591 * If the verification fails, nothing happens.
2592 */
2593void
2594vnck_screen_release_workspace_layout (VnckScreen *screen,
2595 int current_token)
2596{
2597 g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return; } } while (0)
;
2598
2599 _vnck_release_desktop_layout_manager (screen->priv->xscreen,
2600 current_token);
2601
2602}
2603
2604/**
2605 * vnck_screen_get_showing_desktop:
2606 * @screen: a #VnckScreen.
2607 *
2608 * Gets whether @screen is in the "showing the desktop" mode. This mode is
2609 * changed when a #VnckScreen::showing-desktop-changed signal gets emitted.
2610 *
2611 * Return value: %TRUE if @window is fullscreen, %FALSE otherwise.
2612 *
2613 * Since: 2.2
2614 **/
2615gboolean
2616vnck_screen_get_showing_desktop (VnckScreen *screen)
2617{
2618 g_return_val_if_fail (VNCK_IS_SCREEN (screen), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return ((0)); } } while (0)
;
2619
2620 return screen->priv->showing_desktop;
2621}
2622
2623/**
2624 * vnck_screen_toggle_showing_desktop:
2625 * @screen: a #VnckScreen.
2626 * @show: whether to activate the "showing the desktop" mode on @screen.
2627 *
2628 * Asks the window manager to set the "showing the desktop" mode on @screen
2629 * according to @show.
2630 *
2631 * Since: 2.2
2632 **/
2633void
2634vnck_screen_toggle_showing_desktop (VnckScreen *screen,
2635 gboolean show)
2636{
2637 g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return; } } while (0)
;
2638
2639 _vnck_toggle_showing_desktop (screen->priv->xscreen,
2640 show);
2641}
2642
2643
2644/**
2645 * vnck_screen_move_viewport:
2646 * @screen: a #VnckScreen.
2647 * @x: X offset in pixels of viewport.
2648 * @y: Y offset in pixels of viewport.
2649 *
2650 * Asks the window manager to move the viewport of the current #VnckWorkspace
2651 * on @screen.
2652 *
2653 * Since: 2.4
2654 */
2655void
2656vnck_screen_move_viewport (VnckScreen *screen,
2657 int x,
2658 int y)
2659{
2660 g_return_if_fail (VNCK_IS_SCREEN (screen))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return; } } while (0)
;
2661 g_return_if_fail (x >= 0)do { if ((x >= 0)) { } else { g_return_if_fail_warning ("Vnck"
, ((const char*) (__func__)), "x >= 0"); return; } } while
(0)
;
2662 g_return_if_fail (y >= 0)do { if ((y >= 0)) { } else { g_return_if_fail_warning ("Vnck"
, ((const char*) (__func__)), "y >= 0"); return; } } while
(0)
;
2663
2664 _vnck_change_viewport (screen->priv->xscreen, x, y);
2665}
2666
2667#ifdef HAVE_STARTUP_NOTIFICATION1
2668SnDisplay*
2669_vnck_screen_get_sn_display (VnckScreen *screen)
2670{
2671 g_return_val_if_fail (VNCK_IS_SCREEN (screen), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((screen)); GType __t = ((vnck_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 ("Vnck", ((const char*) (__func__
)), "VNCK_IS_SCREEN (screen)"); return (((void*)0)); } } while
(0)
;
2672
2673 return screen->priv->sn_display;
2674}
2675#endif /* HAVE_STARTUP_NOTIFICATION */
2676
2677void
2678_vnck_screen_change_workspace_name (VnckScreen *screen,
2679 int number,
2680 const char *name)
2681{
2682 int n_spaces;
2683 char **names;
2684 int i;
2685
2686 n_spaces = vnck_screen_get_workspace_count (screen);
2687
2688 names = g_new0 (char*, n_spaces + 1)((char* *) g_malloc0_n ((n_spaces + 1), sizeof (char*)));
2689
2690 i = 0;
2691 while (i < n_spaces)
2692 {
2693 if (i == number)
2694 names[i] = (char*) name;
2695 else
2696 {
2697 VnckWorkspace *workspace;
2698 workspace = vnck_screen_get_workspace (screen, i);
2699 if (workspace)
2700 names[i] = (char*) vnck_workspace_get_name (workspace);
2701 else
2702 names[i] = (char*) ""; /* maybe this should be a g_warning() */
2703 }
2704
2705 ++i;
2706 }
2707
2708 _vnck_set_utf8_list (screen->priv->xscreen,
2709 screen->priv->xroot,
2710 _vnck_atom_get ("_NET_DESKTOP_NAMES")cdk_x11_get_xatom_by_name ("_NET_DESKTOP_NAMES"),
2711 names);
2712
2713 g_free (names);
2714}
2715
2716void
2717_vnck_screen_shutdown_all (void)
2718{
2719 int i;
2720 Display *display;
2721
2722 if (screens == NULL((void*)0))
2723 return;
2724
2725 display = _vnck_get_default_display ();
2726
2727 for (i = 0; i < ScreenCount (display)(((_XPrivDisplay)(display))->nscreens); ++i)
2728 {
2729 if (screens[i] != NULL((void*)0)) {
2730 g_object_unref (screens[i]);
2731 screens[i] = NULL((void*)0);
2732 }
2733 }
2734
2735 g_free (screens);
2736 screens = NULL((void*)0);
2737}