Merging upstream version 0.8.0 (Closes: #639729, #761971).
[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 /* it is created in main.c */
70 FbEv *fbev = NULL;
71
72 static void fb_ev_class_init (FbEvClass *klass);
73 static void fb_ev_init (FbEv *monitor);
74 static void fb_ev_finalize (GObject *object);
75
76 static void ev_current_desktop(FbEv *ev, gpointer p);
77 static void ev_active_window(FbEv *ev, gpointer p);
78 static void ev_number_of_desktops(FbEv *ev, gpointer p);
79 static void ev_desktop_names(FbEv *ev, gpointer p);
80 static void ev_client_list(FbEv *ev, gpointer p);
81 static void ev_client_list_stacking(FbEv *ev, gpointer p);
82
83 static guint signals [LAST_SIGNAL] = { 0 };
84
85
86 GType
87 fb_ev_get_type (void)
88 {
89 static GType object_type = 0;
90
91 if (!object_type) {
92 static const GTypeInfo object_info = {
93 sizeof (FbEvClass),
94 (GBaseInitFunc) NULL,
95 (GBaseFinalizeFunc) NULL,
96 (GClassInitFunc) fb_ev_class_init,
97 NULL, /* class_finalize */
98 NULL, /* class_data */
99 sizeof (FbEv),
100 0, /* n_preallocs */
101 (GInstanceInitFunc) fb_ev_init,
102 };
103
104 object_type = g_type_register_static (
105 G_TYPE_OBJECT, "FbEv", &object_info, 0);
106 }
107
108 return object_type;
109 }
110
111
112
113 static void
114 fb_ev_class_init (FbEvClass *klass)
115 {
116 GObjectClass *object_class = G_OBJECT_CLASS (klass);
117
118 signals [EV_CURRENT_DESKTOP] =
119 g_signal_new ("current_desktop",
120 G_OBJECT_CLASS_TYPE (object_class),
121 G_SIGNAL_RUN_FIRST,
122 G_STRUCT_OFFSET (FbEvClass, current_desktop),
123 NULL, NULL,
124 g_cclosure_marshal_VOID__VOID,
125 G_TYPE_NONE, 0);
126 signals [EV_NUMBER_OF_DESKTOPS] =
127 g_signal_new ("number_of_desktops",
128 G_OBJECT_CLASS_TYPE (object_class),
129 G_SIGNAL_RUN_FIRST,
130 G_STRUCT_OFFSET (FbEvClass, number_of_desktops),
131 NULL, NULL,
132 g_cclosure_marshal_VOID__VOID,
133 G_TYPE_NONE, 0);
134 signals [EV_DESKTOP_NAMES] =
135 g_signal_new ("desktop_names",
136 G_OBJECT_CLASS_TYPE (object_class),
137 G_SIGNAL_RUN_FIRST,
138 G_STRUCT_OFFSET (FbEvClass, desktop_names),
139 NULL, NULL,
140 g_cclosure_marshal_VOID__VOID,
141 G_TYPE_NONE, 0);
142 signals [EV_ACTIVE_WINDOW] =
143 g_signal_new ("active_window",
144 G_OBJECT_CLASS_TYPE (object_class),
145 G_SIGNAL_RUN_FIRST,
146 G_STRUCT_OFFSET (FbEvClass, active_window),
147 NULL, NULL,
148 g_cclosure_marshal_VOID__VOID,
149 G_TYPE_NONE, 0);
150 signals [EV_DESTROY_WINDOW] =
151 g_signal_new ("destroy_window",
152 G_OBJECT_CLASS_TYPE (object_class),
153 G_SIGNAL_RUN_FIRST,
154 G_STRUCT_OFFSET (FbEvClass, active_window),
155 NULL, NULL,
156 g_cclosure_marshal_VOID__POINTER,
157 G_TYPE_NONE, 1, G_TYPE_POINTER);
158 signals [EV_CLIENT_LIST_STACKING] =
159 g_signal_new ("client_list_stacking",
160 G_OBJECT_CLASS_TYPE (object_class),
161 G_SIGNAL_RUN_FIRST,
162 G_STRUCT_OFFSET (FbEvClass, client_list_stacking),
163 NULL, NULL,
164 g_cclosure_marshal_VOID__VOID,
165 G_TYPE_NONE, 0);
166 signals [EV_CLIENT_LIST] =
167 g_signal_new ("client_list",
168 G_OBJECT_CLASS_TYPE (object_class),
169 G_SIGNAL_RUN_FIRST,
170 G_STRUCT_OFFSET (FbEvClass, client_list),
171 NULL, NULL,
172 g_cclosure_marshal_VOID__VOID,
173 G_TYPE_NONE, 0);
174 object_class->finalize = fb_ev_finalize;
175
176 klass->current_desktop = ev_current_desktop;
177 klass->active_window = ev_active_window;
178 klass->number_of_desktops = ev_number_of_desktops;
179 klass->desktop_names = ev_desktop_names;
180 klass->client_list = ev_client_list;
181 klass->client_list_stacking = ev_client_list_stacking;
182 }
183
184 static void
185 fb_ev_init (FbEv *ev)
186 {
187 ev->number_of_desktops = -1;
188 ev->current_desktop = -1;
189 ev->active_window = None;
190 ev->client_list_stacking = NULL;
191 ev->client_list = NULL;
192 }
193
194
195 FbEv *
196 fb_ev_new()
197 {
198 return g_object_new (FB_TYPE_EV, NULL);
199 }
200
201 static void
202 fb_ev_finalize (GObject *object)
203 {
204 //FbEv *ev;
205
206 //ev = FB_EV (object);
207 //XFreeGC(ev->dpy, ev->gc);
208 }
209
210 void
211 fb_ev_emit(FbEv *ev, int signal)
212 {
213 DBG("signal=%d\n", signal);
214 g_assert(signal >=0 && signal < LAST_SIGNAL);
215 DBG("\n");
216 if( signal == EV_ACTIVE_WINDOW )
217 {
218 Window* win = None;
219 ev->active_window = None;
220 win = (Window*)get_xaproperty (GDK_ROOT_WINDOW(), a_NET_ACTIVE_WINDOW, XA_WINDOW, 0);
221 if (win) {
222 ev->active_window = *win;
223 /* g_debug( "WIN: %p", *win ); */
224 XFree (win);
225 }
226 }
227 g_signal_emit(ev, signals [signal], 0);
228 }
229
230 void fb_ev_emit_destroy(FbEv *ev, Window win)
231 {
232 g_signal_emit(ev, signals [EV_DESTROY_WINDOW], 0, win );
233 }
234
235 static void
236 ev_current_desktop(FbEv *ev, gpointer p)
237 {
238 ENTER;
239 ev->current_desktop = -1;
240 RET();
241 }
242
243 static void
244 ev_active_window(FbEv *ev, gpointer p)
245 {
246 ENTER;
247 // ev->active_window = None; // Wrecks fb_ev_active window
248 RET();
249 }
250
251 static void
252 ev_number_of_desktops(FbEv *ev, gpointer p)
253 {
254 ENTER;
255 ev->number_of_desktops = -1;
256 RET();
257 }
258
259 static void
260 ev_desktop_names(FbEv *ev, gpointer p)
261 {
262 ENTER;
263 if (ev->desktop_names) {
264 g_strfreev (ev->desktop_names);
265 ev->desktop_names = NULL;
266 }
267 RET();
268 }
269 static void
270 ev_client_list(FbEv *ev, gpointer p)
271 {
272 ENTER;
273 if (ev->client_list) {
274 XFree(ev->client_list);
275 ev->client_list = NULL;
276 }
277 RET();
278 }
279
280 static void
281 ev_client_list_stacking(FbEv *ev, gpointer p)
282 {
283 ENTER;
284 if (ev->client_list_stacking) {
285 XFree(ev->client_list_stacking);
286 ev->client_list_stacking = NULL;
287 }
288 RET();
289 }
290
291 int
292 fb_ev_current_desktop(FbEv *ev)
293 {
294 ENTER;
295 if (ev->current_desktop == -1) {
296 gulong *data;
297
298 data = get_xaproperty (GDK_ROOT_WINDOW(), a_NET_CURRENT_DESKTOP, XA_CARDINAL, 0);
299 if (data) {
300 ev->current_desktop = *data;
301 XFree (data);
302 } else
303 ev->current_desktop = 0;
304 }
305 RET(ev->current_desktop);
306 }
307
308 int
309 fb_ev_number_of_desktops(FbEv *ev)
310 {
311 ENTER;
312 if (ev->number_of_desktops == -1) {
313 gulong *data;
314
315 data = get_xaproperty (GDK_ROOT_WINDOW(), a_NET_NUMBER_OF_DESKTOPS, XA_CARDINAL, 0);
316 if (data) {
317 ev->number_of_desktops = *data;
318 XFree (data);
319 } else
320 ev->number_of_desktops = 0;
321 }
322 RET(ev->number_of_desktops);
323
324 }
325
326 Window *fb_ev_active_window(FbEv *ev)
327 {
328 return &ev->active_window;
329 }
330
331 Window *fb_ev_client_list(FbEv *ev)
332 {
333 return ev->client_list;
334 }
335
336 Window *fb_ev_client_list_stacking(FbEv *ev)
337 {
338 return ev->client_list_stacking;
339 }
340