14 #include "wm.h" |
14 #include "wm.h" |
15 |
15 |
16 /* X structs */ |
16 /* X structs */ |
17 Display *dpy; |
17 Display *dpy; |
18 Window root, barwin; |
18 Window root, barwin; |
19 Atom net_atom[NetLast]; |
19 Atom wm_atom[WMLast], net_atom[NetLast]; |
20 Cursor cursor[CurLast]; |
20 Cursor cursor[CurLast]; |
21 XRectangle rect, barrect; |
21 XRectangle rect, barrect; |
22 Bool running = True; |
22 Bool running = True; |
|
23 Bool sel_screen; |
23 |
24 |
24 char *bartext, tag[256]; |
25 char *bartext, tag[256]; |
25 int screen, sel_screen; |
26 int screen; |
26 |
27 |
27 Brush brush = {0}; |
28 Brush brush = {0}; |
28 Client *clients = NULL; |
29 Client *clients = NULL; |
29 |
30 Client *stack = NULL; |
30 enum { WM_PROTOCOL_DELWIN = 1 }; |
|
31 |
31 |
32 static Bool other_wm_running; |
32 static Bool other_wm_running; |
33 static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; |
33 static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; |
34 static int (*x_error_handler) (Display *, XErrorEvent *); |
34 static int (*x_error_handler) (Display *, XErrorEvent *); |
35 |
35 |
58 manage(wins[i], &wa); |
58 manage(wins[i], &wa); |
59 } |
59 } |
60 } |
60 } |
61 if(wins) |
61 if(wins) |
62 XFree(wins); |
62 XFree(wins); |
|
63 } |
|
64 |
|
65 static int |
|
66 win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) |
|
67 { |
|
68 Atom real; |
|
69 int format; |
|
70 unsigned long res, extra; |
|
71 int status; |
|
72 |
|
73 status = XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format, |
|
74 &res, &extra, prop); |
|
75 |
|
76 if(status != Success || *prop == 0) { |
|
77 return 0; |
|
78 } |
|
79 if(res == 0) { |
|
80 free((void *) *prop); |
|
81 } |
|
82 return res; |
|
83 } |
|
84 |
|
85 int |
|
86 win_proto(Window w) |
|
87 { |
|
88 Atom *protocols; |
|
89 long res; |
|
90 int protos = 0; |
|
91 int i; |
|
92 |
|
93 res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L, |
|
94 ((unsigned char **) &protocols)); |
|
95 if(res <= 0) { |
|
96 return protos; |
|
97 } |
|
98 for(i = 0; i < res; i++) { |
|
99 if(protocols[i] == wm_atom[WMDelete]) |
|
100 protos |= WM_PROTOCOL_DELWIN; |
|
101 } |
|
102 free((char *) protocols); |
|
103 return protos; |
|
104 } |
|
105 |
|
106 void |
|
107 send_message(Window w, Atom a, long value) |
|
108 { |
|
109 XEvent e; |
|
110 |
|
111 e.type = ClientMessage; |
|
112 e.xclient.window = w; |
|
113 e.xclient.message_type = a; |
|
114 e.xclient.format = 32; |
|
115 e.xclient.data.l[0] = value; |
|
116 e.xclient.data.l[1] = CurrentTime; |
|
117 XSendEvent(dpy, w, False, NoEventMask, &e); |
|
118 XFlush(dpy); |
63 } |
119 } |
64 |
120 |
65 /* |
121 /* |
66 * There's no way to check accesses to destroyed windows, thus |
122 * There's no way to check accesses to destroyed windows, thus |
67 * those cases are ignored (especially on UnmapNotify's). |
123 * those cases are ignored (especially on UnmapNotify's). |
158 |
214 |
159 XSetErrorHandler(0); |
215 XSetErrorHandler(0); |
160 x_error_handler = XSetErrorHandler(error_handler); |
216 x_error_handler = XSetErrorHandler(error_handler); |
161 |
217 |
162 /* init atoms */ |
218 /* init atoms */ |
|
219 wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); |
|
220 wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); |
163 net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); |
221 net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); |
164 net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); |
222 net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); |
165 |
223 |
166 XChangeProperty(dpy, root, net_atom[NetSupported], XA_ATOM, 32, |
224 XChangeProperty(dpy, root, net_atom[NetSupported], XA_ATOM, 32, |
167 PropModeReplace, (unsigned char *) net_atom, NetLast); |
225 PropModeReplace, (unsigned char *) net_atom, NetLast); |