Merging upstream version 0.8.0 (Closes: #639729, #761971).
[debian/lxpanel.git] / src / ev.c
CommitLineData
6cc5e1a6
DB
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
41struct _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
52struct _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;
00916e98 61
6cc5e1a6
DB
62 Window xroot;
63 Atom id;
64 GC gc;
65 Display *dpy;
66 Pixmap pixmap;
67};
68
89173f95
AG
69/* it is created in main.c */
70FbEv *fbev = NULL;
71
6cc5e1a6
DB
72static void fb_ev_class_init (FbEvClass *klass);
73static void fb_ev_init (FbEv *monitor);
74static void fb_ev_finalize (GObject *object);
75
76static void ev_current_desktop(FbEv *ev, gpointer p);
77static void ev_active_window(FbEv *ev, gpointer p);
78static void ev_number_of_desktops(FbEv *ev, gpointer p);
79static void ev_desktop_names(FbEv *ev, gpointer p);
80static void ev_client_list(FbEv *ev, gpointer p);
81static void ev_client_list_stacking(FbEv *ev, gpointer p);
82
83static guint signals [LAST_SIGNAL] = { 0 };
84
85
86GType
87fb_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
113static void
114fb_ev_class_init (FbEvClass *klass)
115{
116 GObjectClass *object_class = G_OBJECT_CLASS (klass);
117
00916e98 118 signals [EV_CURRENT_DESKTOP] =
6cc5e1a6
DB
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);
00916e98 126 signals [EV_NUMBER_OF_DESKTOPS] =
6cc5e1a6
DB
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);
00916e98 134 signals [EV_DESKTOP_NAMES] =
6cc5e1a6
DB
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);
00916e98 142 signals [EV_ACTIVE_WINDOW] =
6cc5e1a6
DB
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);
00916e98 150 signals [EV_DESTROY_WINDOW] =
6cc5e1a6
DB
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);
00916e98 158 signals [EV_CLIENT_LIST_STACKING] =
6cc5e1a6
DB
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);
00916e98 166 signals [EV_CLIENT_LIST] =
6cc5e1a6
DB
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
184static void
185fb_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
195FbEv *
196fb_ev_new()
197{
198 return g_object_new (FB_TYPE_EV, NULL);
199}
200
201static void
202fb_ev_finalize (GObject *object)
203{
00916e98 204 //FbEv *ev;
6cc5e1a6 205
00916e98 206 //ev = FB_EV (object);
6cc5e1a6
DB
207 //XFreeGC(ev->dpy, ev->gc);
208}
209
210void
211fb_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 {
00916e98
AG
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 }
6cc5e1a6
DB
226 }
227 g_signal_emit(ev, signals [signal], 0);
228}
229
230void fb_ev_emit_destroy(FbEv *ev, Window win)
231{
00916e98 232 g_signal_emit(ev, signals [EV_DESTROY_WINDOW], 0, win );
6cc5e1a6
DB
233}
234
235static void
236ev_current_desktop(FbEv *ev, gpointer p)
237{
238 ENTER;
239 ev->current_desktop = -1;
240 RET();
241}
242
243static void
244ev_active_window(FbEv *ev, gpointer p)
245{
246 ENTER;
1ea75322 247// ev->active_window = None; // Wrecks fb_ev_active window
6cc5e1a6
DB
248 RET();
249}
250
251static void
252ev_number_of_desktops(FbEv *ev, gpointer p)
253{
254 ENTER;
255 ev->number_of_desktops = -1;
256 RET();
257}
258
259static void
260ev_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}
269static void
270ev_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
280static void
281ev_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
291int
292fb_ev_current_desktop(FbEv *ev)
293{
294 ENTER;
295 if (ev->current_desktop == -1) {
dcd17043 296 gulong *data;
6cc5e1a6
DB
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
00916e98 303 ev->current_desktop = 0;
6cc5e1a6
DB
304 }
305 RET(ev->current_desktop);
306}
00916e98 307
6cc5e1a6
DB
308int
309fb_ev_number_of_desktops(FbEv *ev)
310{
311 ENTER;
312 if (ev->number_of_desktops == -1) {
dcd17043 313 gulong *data;
6cc5e1a6
DB
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
00916e98 320 ev->number_of_desktops = 0;
6cc5e1a6
DB
321 }
322 RET(ev->number_of_desktops);
323
324}
325
326Window *fb_ev_active_window(FbEv *ev)
327{
00916e98 328 return &ev->active_window;
6cc5e1a6
DB
329}
330
331Window *fb_ev_client_list(FbEv *ev)
332{
00916e98 333 return ev->client_list;
6cc5e1a6
DB
334}
335
336Window *fb_ev_client_list_stacking(FbEv *ev)
337{
00916e98 338 return ev->client_list_stacking;
6cc5e1a6
DB
339}
340