~ubuntu-branches/ubuntu/saucy/stalonetray/saucy

« back to all changes in this revision

Viewing changes to src/wmh.c

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2009-10-10 02:05:20 UTC
  • mfrom: (1.1.7 upstream) (3.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091010020520-adj6s9i1ujpvzapo
Tags: 0.8.0~beta1-1
* New upstream release
* bump Standards-Version to 3.8.3
* Remove Torsten from Uploaders as requested

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
#include "debug.h"
14
14
#include "xutils.h"
15
15
 
16
 
#define _NET_WM_STATE_REMOVE        0   /* remove/unset property */
17
 
#define _NET_WM_STATE_ADD           1   /* add/set property */
18
 
#define _NET_WM_STATE_TOGGLE        2   /* toggle property  */
19
 
 
20
16
/* Structure for Motif WM hints */
21
17
typedef struct {
22
18
    unsigned long flags;
32
28
#define MWM_HINTS_STATUS        (1L << 3)
33
29
/* Number of CARD32 entries in MWM hints data structure */
34
30
#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
35
 
/* List of all EWMH atoms supoorted by WM */
36
 
Atom                    *ewmh_list = NULL;
37
 
/* Length of previously-mentioned list */
38
 
unsigned long   ewmh_list_len = 0;
39
 
/* Atom: _NET_SUPPORTED */
40
 
Atom                    xa_net_supported = None;
41
 
 
42
 
/* Check if WM supports EWMH */
43
 
int ewmh_check_support(Display *dpy)
44
 
{
45
 
        unsigned long i;
46
 
#ifdef DEBUG
47
 
        char *atom_name;
48
 
#endif
49
 
 
50
 
        /* Check for presence of _NET_SUPPORTED atom */
51
 
        if (xa_net_supported == None) 
52
 
                xa_net_supported = XInternAtom(dpy, "_NET_SUPPORTED", True);
53
 
        if (xa_net_supported == None) return FAILURE;
54
 
 
55
 
        /* Retrive the value of _NET_SUPPORTED property of root window */
56
 
        if (!x11_get_win_prop32(dpy, DefaultRootWindow(dpy), xa_net_supported, XA_ATOM, (unsigned char **) &ewmh_list, &ewmh_list_len)) {
57
 
                xa_net_supported = None;
58
 
                return FAILURE;
59
 
        }
60
 
 
61
 
#ifdef DEBUG
62
 
        for (i = 0; i < ewmh_list_len; i++) {
63
 
                atom_name = XGetAtomName(dpy, ewmh_list[i]);
64
 
                DBG(8, ("_NET_WM_SUPPORTED[%d] = 0x%x (%s)\n", i, ewmh_list[i], atom_name));
65
 
                XFree(atom_name);
66
 
                x11_ok();
67
 
        }
68
 
#endif
69
 
        
70
 
        return SUCCESS;
71
 
}
72
 
 
73
 
/* Check if atom is in the list of supported EWMH atoms */
74
 
int ewmh_atom_supported(Atom atom)
75
 
{
76
 
        int i;
77
 
        if (atom == None || xa_net_supported == None) return False;
78
 
        for (i = 0; i < ewmh_list_len; i++) 
79
 
                if (atom == ewmh_list[i])
80
 
                        return True;
81
 
        return False;
 
31
 
 
32
/* Check if WM that supports EWMH hints is present on given display */
 
33
int ewmh_wm_present(Display *dpy)
 
34
{
 
35
        Window *check_win, *check_win_self_ref;
 
36
        unsigned long cw_len = 0, cwsr_len = 0;
 
37
        int rc = False;
 
38
        /* see _NET_SUPPORTING_WM_CHECK in the WM spec. */
 
39
        rc = x11_get_root_winlist_prop(dpy, 
 
40
                        XInternAtom(dpy, _NET_SUPPORTING_WM_CHECK, False), 
 
41
                        (unsigned char **) &check_win, 
 
42
                        &cw_len);
 
43
        if (x11_ok() && rc && cw_len == 1) {
 
44
                LOG_TRACE(("_NET_SUPPORTING_WM_CHECK (root) = 0x%x\n", check_win[0]));
 
45
                x11_get_window_prop32(dpy, 
 
46
                                check_win[0], 
 
47
                                XInternAtom(dpy, _NET_SUPPORTING_WM_CHECK, False), 
 
48
                                XA_WINDOW, 
 
49
                                (unsigned char **) &check_win_self_ref, 
 
50
                                &cwsr_len);
 
51
                rc = (x11_ok() && rc && cwsr_len == 1 && check_win[0] == check_win_self_ref[0]);
 
52
                LOG_TRACE(("_NET_SUPPORTING_WM_CHECK (self reference) = 0x%x\n", check_win[0]));
 
53
        }
 
54
        if (cw_len != 0) XFree(check_win);
 
55
        if (cwsr_len != 0) XFree(check_win_self_ref);
 
56
        LOG_TRACE(("EWMH WM %sdetected\n", rc ? "" : "not "));
 
57
        return rc;
82
58
}
83
59
 
84
60
/* Add EWMH window state for the given window */
88
64
        Atom atom;
89
65
        XWindowAttributes xwa;
90
66
        int rc;
91
 
 
92
 
        /* Check if WM supports EWMH window states */
93
 
        prop = XInternAtom(dpy, "_NET_WM_STATE", True);
94
 
        atom = XInternAtom(dpy, state, True);
95
 
        if (atom == None || prop == None || !ewmh_atom_supported(atom)) return FAILURE;
96
 
 
97
 
        DBG(8, ("adding window state %s (0x%x)\n", state, atom));
98
 
 
 
67
        prop = XInternAtom(dpy, "_NET_WM_STATE", False);
 
68
        atom = XInternAtom(dpy, state, False);
 
69
        LOG_TRACE(("adding state %s to window 0x%x\n", state, atom));
 
70
        /* Ping the window and get its state */
99
71
        rc = XGetWindowAttributes(dpy, wnd, &xwa);
100
72
        if (!x11_ok() || !rc ) return FAILURE;
101
73
 
102
 
        if (xwa.map_state != IsUnmapped) {
103
 
                /* For unmapped windows, ask WM to add the window state */
104
 
                return x11_send_client_msg32(dpy, DefaultRootWindow(dpy), wnd, prop, 
 
74
        if (xwa.map_state != IsUnmapped && ewmh_wm_present(dpy)) {
 
75
                /* For mapped windows, ask WM (if it is here) to add the window state */
 
76
                rc = x11_send_client_msg32(dpy, xwa.root, wnd, prop, 
105
77
                                             _NET_WM_STATE_ADD, atom, 0, 0, 0);
106
78
        } else {
107
 
                /* Else, add the window state ourselves */
108
 
                XChangeProperty(dpy, wnd, prop, XA_ATOM, 32, PropModeAppend, (unsigned char *)&atom, 1);
109
 
                return x11_ok();
 
79
                /* Else, alter the window state atom value ourselves */
 
80
                rc = XChangeProperty(dpy, wnd, prop, XA_ATOM, 32, PropModeAppend, (unsigned char *)&atom, 1);
 
81
                rc = x11_ok() && rc;
110
82
        }
 
83
        return rc;
111
84
}
112
85
 
113
86
/* Add EWMH window type for the given window */
115
88
{
116
89
        Atom prop;
117
90
        Atom atom;
118
 
        /* Check if WM supports supports _NET_WM_WINDOW_TYPE and requested window type */
119
 
        prop = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", True);
120
 
        atom = XInternAtom(dpy, type, True);
121
 
        if (atom == None || prop == None || !ewmh_atom_supported(atom)) return FAILURE;
122
 
        
 
91
        prop = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
 
92
        atom = XInternAtom(dpy, type, False);
 
93
        LOG_TRACE(("adding type %s to window 0x%x\n", type, atom));
123
94
        /* Update property value (append) */
124
95
        XChangeProperty(dpy, wnd, prop, XA_ATOM, 32, PropModeAppend, (unsigned char *)&atom, 1);
125
 
 
126
 
        if (!x11_ok()) {
127
 
                DBG(0, ("could append atom to the _NET_WM_WINDOW_TYPE list property of 0x%x\n", wnd));
128
 
                return FAILURE;
129
 
        }
130
 
 
131
 
        return SUCCESS;
132
 
}
133
 
 
134
 
#ifdef DEBUG
135
 
/* List EWMH states that are set for the given window */
136
 
int ewmh_dump_window_states(Display *dpy, Window wnd)
137
 
{
138
 
        Atom prop, *data;
139
 
        unsigned long prop_len;
140
 
        int j;
141
 
        char *tmp;
142
 
 
143
 
        /* Check if WM supports _NET_WM_STATE */
144
 
        prop = XInternAtom(tray_data.dpy, "_NET_WM_STATE", True);
145
 
        if (prop == None) return FAILURE;
146
 
 
147
 
        /* Retrive the list of states */
148
 
        if (x11_get_win_prop32(dpy, wnd, prop, XA_ATOM, (unsigned char**) &data, &prop_len)) {
149
 
                for (j = 0; j < prop_len; j++) {
150
 
                        tmp = XGetAtomName(tray_data.dpy, data[j]);
151
 
                        if (x11_ok() && tmp != NULL) {
152
 
                                DBG(8, ("0x%x:_NET_WM_STATE[%d] = %s\n", wnd, j, tmp));
153
 
                                XFree(tmp);
154
 
                        }
155
 
                }
156
 
                return SUCCESS;
157
 
        }
158
 
 
159
 
        return FAILURE;
160
 
}
161
 
#endif
 
96
        return x11_ok();
 
97
}
 
98
 
 
99
/* Set data for _NET_WM_STRUT{,_PARTIAL} hints */
 
100
int ewmh_set_window_strut(Display *dpy, Window wnd, wm_strut_t wm_strut)
 
101
{
 
102
        Atom prop_strut;
 
103
        Atom prop_strut_partial;
 
104
        prop_strut = XInternAtom(dpy, _NET_WM_STRUT, False);
 
105
        prop_strut_partial = XInternAtom(dpy, _NET_WM_STRUT_PARTIAL, False);
 
106
        XChangeProperty(dpy, wnd, prop_strut, XA_CARDINAL, 32, PropModeReplace, 
 
107
                        (unsigned char *)wm_strut, _NET_WM_STRUT_SZ);
 
108
        XChangeProperty(dpy, wnd, prop_strut_partial, XA_CARDINAL, 32, PropModeReplace, 
 
109
                        (unsigned char *)wm_strut, _NET_WM_STRUT_PARTIAL_SZ);
 
110
        return x11_ok();
 
111
}
 
112
 
 
113
/* Set CARD32 value of EWMH atom for a given window */
 
114
int ewmh_set_window_atom32(Display *dpy, Window wnd, char *prop_name, CARD32 value)
 
115
{
 
116
        Atom prop; 
 
117
        Atom atom;
 
118
        XWindowAttributes xwa;
 
119
        int rc;
 
120
        prop = XInternAtom(dpy, prop_name, False);
 
121
        LOG_TRACE(("0x%x: setting atom %s to 0x%x\n", wnd, prop_name, value));
 
122
        /* Ping the window and get its state */
 
123
        rc = XGetWindowAttributes(dpy, wnd, &xwa);
 
124
        if (!x11_ok() || !rc ) return FAILURE;
 
125
        if (xwa.map_state != IsUnmapped && ewmh_wm_present(dpy)) {
 
126
                /* For mapped windows, ask WM (if it is here) to add the window state */
 
127
                return x11_send_client_msg32(dpy, DefaultRootWindow(dpy), wnd, prop,
 
128
                                             value, 2 /* source indication */, 0, 0, 0);
 
129
        } else {
 
130
                /* Else, alter the window state atom value ourselves */
 
131
                XChangeProperty(dpy, wnd, prop, XA_ATOM, 32, PropModeAppend, (unsigned char *)&atom, 1);
 
132
                return x11_ok();
 
133
        }
 
134
}
162
135
 
163
136
/* Set MWM hints */
164
137
int mwm_set_hints(Display *dpy, Window wnd, unsigned long decorations, unsigned long functions)
167
140
        int act_fmt, rc; 
168
141
        unsigned long nitems, bytes_after;
169
142
        static Atom atom = None, act_type;
170
 
 
171
143
        /* Check if WM supports Motif WM hints */
172
144
        if (atom == None) atom = XInternAtom(dpy, "_MOTIF_WM_HINTS", False);
173
145
        if (atom == None) return FAILURE;
174
 
 
175
146
        /* Get current hints */
176
147
        rc = XGetWindowProperty(dpy, wnd, atom, 0, 5, False, atom, 
177
148
                                &act_type, &act_fmt, &nitems, &bytes_after, 
178
149
                                (unsigned char**) &prop);
179
 
 
180
150
        if ((act_type == None && act_fmt == 0 && bytes_after == 0) || nitems == 0) {
181
151
                /* Hints are either not set or have some other type.
182
152
                 * Reset all values. */
193
163
                x11_ok(); /* Reset x11 error status */
194
164
                return FAILURE;
195
165
        }
196
 
 
197
166
        /* Update value */
198
167
        prop->flags |= MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS;
199
168
        prop->decorations = decorations;
200
169
        prop->functions = functions;
201
 
 
202
170
        XChangeProperty(dpy, wnd, atom, atom, 32, PropModeReplace, 
203
171
                        (unsigned char*) prop, PROP_MOTIF_WM_HINTS_ELEMENTS);
204
 
 
205
172
        return x11_ok();
206
173
}
207
174
 
 
175
#ifdef DEBUG
 
176
/* Dumps EWMH atoms supported by WM */
 
177
int ewmh_list_supported_atoms(Display *dpy)
 
178
{
 
179
        Atom *atom_list;
 
180
        unsigned long atom_list_len, i;
 
181
        char *atom_name;
 
182
        if (ewmh_wm_present(dpy)) {
 
183
                if (x11_get_window_prop32(dpy, 
 
184
                                        DefaultRootWindow(dpy),
 
185
                                        XInternAtom(dpy, _NET_SUPPORTED, False),
 
186
                                        XA_ATOM,
 
187
                                        (unsigned char **) &atom_list,
 
188
                                        &atom_list_len))
 
189
                if (atom_list_len) {
 
190
                        for (i = 0; i < atom_list_len; i++) {
 
191
                                atom_name = XGetAtomName(dpy, atom_list[i]);
 
192
                                if (atom_name != NULL) {
 
193
                                        LOG_TRACE(("_NET_SUPPORTED[%d]: %s (0x%x)\n", i, atom_name, atom_list[i]));
 
194
                                } else
 
195
                                        LOG_TRACE(("_NET_SUPPORTED[%d]: bogus value (0x%x)\n", i, atom_list[i]));
 
196
                                XFree(atom_name);
 
197
                                x11_ok();
 
198
                        }
 
199
                        free(atom_list);
 
200
                        return SUCCESS;
 
201
                }
 
202
        }
 
203
        return FAILURE;
 
204
}
 
205
 
 
206
/* List EWMH states that are set for the given window */
 
207
int ewmh_dump_window_states(Display *dpy, Window wnd)
 
208
{
 
209
        Atom prop, *data;
 
210
        unsigned long prop_len;
 
211
        int j;
 
212
        char *tmp;
 
213
        /* Check if WM supports _NET_WM_STATE */
 
214
        prop = XInternAtom(tray_data.dpy, "_NET_WM_STATE", True);
 
215
        if (prop == None) return FAILURE;
 
216
        /* Retrive the list of states */
 
217
        if (x11_get_window_prop32(dpy, wnd, prop, XA_ATOM, (unsigned char**) &data, &prop_len)) {
 
218
                for (j = 0; j < prop_len; j++) {
 
219
                        tmp = XGetAtomName(tray_data.dpy, data[j]);
 
220
                        if (x11_ok() && tmp != NULL) {
 
221
                                LOG_TRACE(("0x%x:_NET_WM_STATE[%d] = %s\n", wnd, j, tmp));
 
222
                                XFree(tmp);
 
223
                        }
 
224
                }
 
225
                return SUCCESS;
 
226
        }
 
227
        return FAILURE;
 
228
}
 
229
#endif
 
230