Merging upstream version 0.7.0 (Closes: #493243, #510888, #567617, #699414, #709777...
[debian/lxpanel.git] / src / ev.c
1 /*
2 * fb-background-monitor.c:
3 *
4 * Copyright (C) 2001, 2002 Ian McKellar <yakk@yakk.net>
5 * 2002 Sun Microsystems, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 * Authors:
23 * Ian McKellar <yakk@yakk.net>
24 * Mark McLoughlin <mark@skynet.ie>
25 */
26
27 #include <glib.h>
28 #include <glib-object.h>
29 #include <gdk/gdk.h>
30 #include <gdk/gdkx.h>
31 #include <X11/Xlib.h>
32 #include <X11/Xatom.h>
33
34 #include "ev.h"
35 #include "misc.h"
36
37 //#define DEBUG
38 #include "dbg.h"
39
40
41 struct _FbEvClass {
42 GObjectClass parent_class;
43 void *dummy;
44 void (*current_desktop)(FbEv *ev, gpointer p);
45 void (*active_window)(FbEv *ev, gpointer p);
46 void (*number_of_desktops)(FbEv *ev, gpointer p);
47 void (*desktop_names)(FbEv *ev, gpointer p);
48 void (*client_list)(FbEv *ev, gpointer p);
49 void (*client_list_stacking)(FbEv *ev, gpointer p);
50 };
51
52 struct _FbEv {
53 GObject parent_instance;
54
55 int current_desktop;
56 int number_of_desktops;
57 char **desktop_names;
58 Window active_window;
59 Window *client_list;
60 Window *client_list_stacking;
61
62 Window xroot;
63 Atom id;
64 GC gc;
65 Display *dpy;
66 Pixmap pixmap;
67 };
68
69 static void fb_ev_class_init (FbEvClass *klass);
70 static void fb_ev_init (FbEv *monitor);
71 static void fb_ev_finalize (GObject *object);
72
73 static void ev_current_desktop(FbEv *ev, gpointer p);
74 static void ev_active_window(FbEv *ev, gpointer p);
75 static void ev_number_of_desktops(FbEv *ev, gpointer p);
76 static void ev_desktop_names(FbEv *ev, gpointer p);
77 static void ev_client_list(FbEv *ev, gpointer p);
78 static void ev_client_list_stacking(FbEv *ev, gpointer p);
79
80 static guint signals [LAST_SIGNAL] = { 0 };
81
82
83 GType
84 fb_ev_get_type (void)
85 {
86 static GType object_type = 0;
87
88 if (!object_type) {
89 static const GTypeInfo object_info = {
90 sizeof (FbEvClass),
91 (GBaseInitFunc) NULL,
92 (GBaseFinalizeFunc) NULL,
93 (GClassInitFunc) fb_ev_class_init,
94 NULL, /* class_finalize */
95 NULL, /* class_data */
96 sizeof (FbEv),
97 0, /* n_preallocs */
98 (GInstanceInitFunc) fb_ev_init,
99 };
100
101 object_type = g_type_register_static (
102 G_TYPE_OBJECT, "FbEv", &object_info, 0);
103 }
104
105 return object_type;
106 }
107
108
109
110 static void
111 fb_ev_class_init (FbEvClass *klass)
112 {
113 GObjectClass *object_class = G_OBJECT_CLASS (klass);
114
115 signals [EV_CURRENT_DESKTOP] =
116 g_signal_new ("current_desktop",
117 G_OBJECT_CLASS_TYPE (object_class),
118 G_SIGNAL_RUN_FIRST,
119 G_STRUCT_OFFSET (FbEvClass, current_desktop),
120 NULL, NULL,
121 g_cclosure_marshal_VOID__VOID,
122 G_TYPE_NONE, 0);
123 signals [EV_NUMBER_OF_DESKTOPS] =
124 g_signal_new ("number_of_desktops",
125 G_OBJECT_CLASS_TYPE (object_class),
126 G_SIGNAL_RUN_FIRST,
127 G_STRUCT_OFFSET (FbEvClass, number_of_desktops),
128 NULL, NULL,
129 g_cclosure_marshal_VOID__VOID,
130 G_TYPE_NONE, 0);
131 signals [EV_DESKTOP_NAMES] =
132 g_signal_new ("desktop_names",
133 G_OBJECT_CLASS_TYPE (object_class),
134 G_SIGNAL_RUN_FIRST,
135 G_STRUCT_OFFSET (FbEvClass, desktop_names),
136 NULL, NULL,
137 g_cclosure_marshal_VOID__VOID,
138 G_TYPE_NONE, 0);
139 signals [EV_ACTIVE_WINDOW] =
140 g_signal_new ("active_window",
141 G_OBJECT_CLASS_TYPE (object_class),
142 G_SIGNAL_RUN_FIRST,
143 G_STRUCT_OFFSET (FbEvClass, active_window),
144 NULL, NULL,
145 g_cclosure_marshal_VOID__VOID,
146 G_TYPE_NONE, 0);
147 signals [EV_DESTROY_WINDOW] =
148 g_signal_new ("destroy_window",
149 G_OBJECT_CLASS_TYPE (object_class),
150 G_SIGNAL_RUN_FIRST,
151 G_STRUCT_OFFSET (FbEvClass, active_window),
152 NULL, NULL,
153 g_cclosure_marshal_VOID__POINTER,
154 G_TYPE_NONE, 1, G_TYPE_POINTER);
155 signals [EV_CLIENT_LIST_STACKING] =
156 g_signal_new ("client_list_stacking",
157 G_OBJECT_CLASS_TYPE (object_class),
158 G_SIGNAL_RUN_FIRST,
159 G_STRUCT_OFFSET (FbEvClass, client_list_stacking),
160 NULL, NULL,
161 g_cclosure_marshal_VOID__VOID,
162 G_TYPE_NONE, 0);
163 signals [EV_CLIENT_LIST] =
164 g_signal_new ("client_list",
165 G_OBJECT_CLASS_TYPE (object_class),
166 G_SIGNAL_RUN_FIRST,
167 G_STRUCT_OFFSET (FbEvClass, client_list),
168 NULL, NULL,
169 g_cclosure_marshal_VOID__VOID,
170 G_TYPE_NONE, 0);
171 object_class->finalize = fb_ev_finalize;
172
173 klass->current_desktop = ev_current_desktop;
174 klass->active_window = ev_active_window;
175 klass->number_of_desktops = ev_number_of_desktops;
176 klass->desktop_names = ev_desktop_names;
177 klass->client_list = ev_client_list;
178 klass->client_list_stacking = ev_client_list_stacking;
179 }
180
181 static void
182 fb_ev_init (FbEv *ev)
183 {
184 ev->number_of_desktops = -1;
185 ev->current_desktop = -1;
186 ev->active_window = None;
187 ev->client_list_stacking = NULL;
188 ev->client_list = NULL;
189 }
190
191
192 FbEv *
193 fb_ev_new()
194 {
195 return g_object_new (FB_TYPE_EV, NULL);
196 }
197
198 static void
199 fb_ev_finalize (GObject *object)
200 {
201 //FbEv *ev;
202
203 //ev = FB_EV (object);
204 //XFreeGC(ev->dpy, ev->gc);
205 }
206
207 void
208 fb_ev_emit(FbEv *ev, int signal)
209 {
210 DBG("signal=%d\n", signal);
211 g_assert(signal >=0 && signal < LAST_SIGNAL);
212 DBG("\n");
213 if( signal == EV_ACTIVE_WINDOW )
214 {
215 Window* win = None;
216 ev->active_window = None;
217 win = (Window*)get_xaproperty (GDK_ROOT_WINDOW(), a_NET_ACTIVE_WINDOW, XA_WINDOW, 0);
218 if (win) {
219 ev->active_window = *win;
220 /* g_debug( "WIN: %p", *win ); */
221 XFree (win);
222 }
223 }
224 g_signal_emit(ev, signals [signal], 0);
225 }
226
227 void fb_ev_emit_destroy(FbEv *ev, Window win)
228 {
229 g_signal_emit(ev, signals [EV_DESTROY_WINDOW], 0, win );
230 }
231
232 static void
233 ev_current_desktop(FbEv *ev, gpointer p)
234 {
235 ENTER;
236 ev->current_desktop = -1;
237 RET();
238 }
239
240 static void
241 ev_active_window(FbEv *ev, gpointer p)
242 {
243 ENTER;
244 // ev->active_window = None; // Wrecks fb_ev_active window
245 RET();
246 }
247
248 static void
249 ev_number_of_desktops(FbEv *ev, gpointer p)
250 {
251 ENTER;
252 ev->number_of_desktops = -1;
253 RET();
254 }
255
256 static void
257 ev_desktop_names(FbEv *ev, gpointer p)
258 {
259 ENTER;
260 if (ev->desktop_names) {
261 g_strfreev (ev->desktop_names);
262 ev->desktop_names = NULL;
263 }
264 RET();
265 }
266 static void
267 ev_client_list(FbEv *ev, gpointer p)
268 {
269 ENTER;
270 if (ev->client_list) {
271 XFree(ev->client_list);
272 ev->client_list = NULL;
273 }
274 RET();
275 }
276
277 static void
278 ev_client_list_stacking(FbEv *ev, gpointer p)
279 {
280 ENTER;
281 if (ev->client_list_stacking) {
282 XFree(ev->client_list_stacking);
283 ev->client_list_stacking = NULL;
284 }
285 RET();
286 }
287
288 int
289 fb_ev_current_desktop(FbEv *ev)
290 {
291 ENTER;
292 if (ev->current_desktop == -1) {
293 guint32 *data;
294
295 data = get_xaproperty (GDK_ROOT_WINDOW(), a_NET_CURRENT_DESKTOP, XA_CARDINAL, 0);
296 if (data) {
297 ev->current_desktop = *data;
298 XFree (data);
299 } else
300 ev->current_desktop = 0;
301 }
302 RET(ev->current_desktop);
303 }
304
305 int
306 fb_ev_number_of_desktops(FbEv *ev)
307 {
308 ENTER;
309 if (ev->number_of_desktops == -1) {
310 guint32 *data;
311
312 data = get_xaproperty (GDK_ROOT_WINDOW(), a_NET_NUMBER_OF_DESKTOPS, XA_CARDINAL, 0);
313 if (data) {
314 ev->number_of_desktops = *data;
315 XFree (data);
316 } else
317 ev->number_of_desktops = 0;
318 }
319 RET(ev->number_of_desktops);
320
321 }
322
323 Window *fb_ev_active_window(FbEv *ev)
324 {
325 return &ev->active_window;
326 }
327
328 Window *fb_ev_client_list(FbEv *ev)
329 {
330 return ev->client_list;
331 }
332
333 Window *fb_ev_client_list_stacking(FbEv *ev)
334 {
335 return ev->client_list_stacking;
336 }
337