1 /* Sticky Notes
2 * Copyright (C) 2002-2003 Loban A Rahman
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 */
19
20 #include <config.h>
21 #include "util.h"
22
23 #include <X11/Xlib.h>
24 #include <X11/Xatom.h>
25 #include <gdk/gdk.h>
26 #include <gdk/gdkx.h>
27 #include <gtk/gtk.h>
28
29 static Atom
xstuff_atom_get(const char * atom_name)30 xstuff_atom_get (const char *atom_name)
31 {
32 static GHashTable *atom_hash;
33 Display *xdisplay;
34 Atom retval;
35
36 g_return_val_if_fail (atom_name != NULL, None);
37
38 xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
39
40 if (!atom_hash)
41 atom_hash = g_hash_table_new_full (g_str_hash,
42 g_str_equal,
43 g_free, NULL);
44
45 retval = GPOINTER_TO_UINT (g_hash_table_lookup (atom_hash, atom_name));
46 if (!retval) {
47 retval = XInternAtom (xdisplay, atom_name, FALSE);
48
49 if (retval != None)
50 g_hash_table_insert (atom_hash, g_strdup (atom_name),
51 GUINT_TO_POINTER (retval));
52 }
53
54 return retval;
55 }
56
57 int
xstuff_get_current_workspace(GtkWindow * window)58 xstuff_get_current_workspace (GtkWindow *window)
59 {
60 Window root_window;
61 Atom type = None;
62 gulong nitems;
63 gulong bytes_after;
64 gulong *num;
65 int format;
66 int result;
67 int retval;
68 GdkDisplay *gdk_display;
69 Display *xdisplay;
70
71 root_window = GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (window)));
72 gdk_display = gdk_display_get_default ();
73 xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display);
74
75 gdk_x11_display_error_trap_push (gdk_display);
76 result = XGetWindowProperty (xdisplay,
77 root_window,
78 xstuff_atom_get ("_NET_CURRENT_DESKTOP"),
79 0, G_MAXLONG,
80 False, XA_CARDINAL,
81 &type, &format, &nitems,
82 &bytes_after, (gpointer) &num);
83 if (gdk_x11_display_error_trap_pop (gdk_display) || result != Success)
84 return -1;
85
86 if (type != XA_CARDINAL) {
87 XFree (num);
88 return -1;
89 }
90
91 retval = *num;
92
93 XFree (num);
94
95 return retval;
96 }
97 void
xstuff_change_workspace(GtkWindow * window,int new_space)98 xstuff_change_workspace (GtkWindow *window,
99 int new_space)
100 {
101 XEvent xev;
102 Window xwindow;
103 Display *gdk_display;
104 Screen *screen;
105
106 gdk_display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
107 xwindow = GDK_WINDOW_XID (GDK_WINDOW (gtk_widget_get_window (GTK_WIDGET (window))));
108 screen = GDK_SCREEN_XSCREEN (gtk_widget_get_screen (GTK_WIDGET (window)));
109
110 xev.xclient.type = ClientMessage;
111 xev.xclient.serial = 0;
112 xev.xclient.send_event = True;
113 xev.xclient.display = gdk_display;
114 xev.xclient.window = xwindow;
115 xev.xclient.message_type = xstuff_atom_get ("_NET_WM_DESKTOP");
116 xev.xclient.format = 32;
117 xev.xclient.data.l[0] = new_space;
118 xev.xclient.data.l[1] = 0;
119 xev.xclient.data.l[2] = 0;
120
121 XSendEvent (gdk_display,
122 RootWindowOfScreen (screen),
123 False,
124 SubstructureRedirectMask | SubstructureNotifyMask,
125 &xev);
126 }
127