| 1 | #include "Python.h" |
|---|
| 2 | #include <X11/X.h> |
|---|
| 3 | #include <X11/Xatom.h> |
|---|
| 4 | #include <X11/Xlib.h> |
|---|
| 5 | #include <X11/Xmd.h> |
|---|
| 6 | #include <X11/Xutil.h> |
|---|
| 7 | #include <X11/keysym.h> |
|---|
| 8 | #ifdef SHAPE |
|---|
| 9 | #include <X11/extensions/shape.h> |
|---|
| 10 | #endif |
|---|
| 11 | |
|---|
| 12 | #include "keymap.h" |
|---|
| 13 | |
|---|
| 14 | /* Required for interpreting MWM hints: */ |
|---|
| 15 | #define _XA_MWM_HINTS "_MOTIF_WM_HINTS" |
|---|
| 16 | #define PROP_MWM_HINTS_ELEMENTS 3 |
|---|
| 17 | #define MWM_HINTS_DECORATIONS (1L << 1) |
|---|
| 18 | #define MWM_DECOR_ALL (1L << 0) |
|---|
| 19 | #define MWM_DECOR_BORDER (1L << 1) |
|---|
| 20 | typedef struct { |
|---|
| 21 | unsigned long flags; |
|---|
| 22 | unsigned long functions; |
|---|
| 23 | unsigned long decorations; |
|---|
| 24 | } PropMwmHints; |
|---|
| 25 | |
|---|
| 26 | /* sanity on options */ |
|---|
| 27 | #if defined(INFOBANNER_MOVERESIZE) && !defined(INFOBANNER) |
|---|
| 28 | # define INFOBANNER |
|---|
| 29 | #endif |
|---|
| 30 | |
|---|
| 31 | /* default settings */ |
|---|
| 32 | |
|---|
| 33 | #define DEF_FONT "variable" |
|---|
| 34 | #define DEF_FG "goldenrod" |
|---|
| 35 | #define DEF_BG "grey50" |
|---|
| 36 | #define DEF_BW 1 |
|---|
| 37 | #define DEF_FC "blue" |
|---|
| 38 | #define SPACE 3 |
|---|
| 39 | #ifdef DEBIAN |
|---|
| 40 | #define DEF_TERM "x-terminal-emulator" |
|---|
| 41 | #else |
|---|
| 42 | #define DEF_TERM "xterm" |
|---|
| 43 | #endif |
|---|
| 44 | |
|---|
| 45 | /* readability stuff */ |
|---|
| 46 | |
|---|
| 47 | #define KEY_TO_VDESK(key) ((key) - XK_1) |
|---|
| 48 | #define valid_vdesk(v) ((unsigned)(v) < KEY_TO_VDESK(XK_8)) |
|---|
| 49 | |
|---|
| 50 | #define RAISE 1 |
|---|
| 51 | #define NO_RAISE 0 /* for unhide() */ |
|---|
| 52 | |
|---|
| 53 | #define MAXIMISE_HORZ (1<<0) |
|---|
| 54 | #define MAXIMISE_VERT (1<<1) |
|---|
| 55 | |
|---|
| 56 | /* some coding shorthand */ |
|---|
| 57 | |
|---|
| 58 | #define ChildMask (SubstructureRedirectMask|SubstructureNotifyMask) |
|---|
| 59 | #define ButtonMask (ButtonPressMask|ButtonReleaseMask) |
|---|
| 60 | #define MouseMask (ButtonMask|PointerMotionMask) |
|---|
| 61 | |
|---|
| 62 | #define grab_pointer(w, mask, curs) \ |
|---|
| 63 | (XGrabPointer(dpy, w, False, mask, GrabModeAsync, GrabModeAsync, \ |
|---|
| 64 | None, curs, CurrentTime) == GrabSuccess) |
|---|
| 65 | |
|---|
| 66 | #define grab_button(w, mask, button) do { \ |
|---|
| 67 | XGrabButton(dpy, button, (mask), w, False, ButtonMask, \ |
|---|
| 68 | GrabModeAsync, GrabModeSync, None, None); \ |
|---|
| 69 | XGrabButton(dpy, button, LockMask|(mask), w, False, ButtonMask,\ |
|---|
| 70 | GrabModeAsync, GrabModeSync, None, None); \ |
|---|
| 71 | XGrabButton(dpy, button, numlockmask|(mask), w, False, \ |
|---|
| 72 | ButtonMask, GrabModeAsync, GrabModeSync, \ |
|---|
| 73 | None, None); \ |
|---|
| 74 | XGrabButton(dpy, button, numlockmask|LockMask|(mask), w, False,\ |
|---|
| 75 | ButtonMask, GrabModeAsync, GrabModeSync, \ |
|---|
| 76 | None, None); \ |
|---|
| 77 | } while (0) |
|---|
| 78 | #define setmouse(w, x, y) XWarpPointer(dpy, None, w, 0, 0, 0, 0, x, y) |
|---|
| 79 | #define get_mouse_position(xp,yp,root) do { \ |
|---|
| 80 | Window dw; \ |
|---|
| 81 | int di; \ |
|---|
| 82 | unsigned int dui; \ |
|---|
| 83 | XQueryPointer(dpy, root, &dw, &dw, xp, yp, &di, &di, &dui); \ |
|---|
| 84 | } while (0) |
|---|
| 85 | #define gravitate(c) gravitate_client(c, 1) |
|---|
| 86 | #define ungravitate(c) gravitate_client(c, -1) |
|---|
| 87 | |
|---|
| 88 | #define is_sticky(c) (c->sticky) |
|---|
| 89 | #define add_sticky(c) c->sticky = 1 |
|---|
| 90 | #define remove_sticky(c) c->sticky = 0 |
|---|
| 91 | #define toggle_sticky(c) c->sticky = !c->sticky |
|---|
| 92 | |
|---|
| 93 | #define discard_enter_events() do { \ |
|---|
| 94 | XEvent dummy; \ |
|---|
| 95 | XSync(dpy, False); \ |
|---|
| 96 | while (XCheckMaskEvent(dpy, EnterWindowMask, &dummy)); \ |
|---|
| 97 | } while (0) |
|---|
| 98 | |
|---|
| 99 | /* screen structure */ |
|---|
| 100 | |
|---|
| 101 | typedef struct ScreenInfo ScreenInfo; |
|---|
| 102 | struct ScreenInfo { |
|---|
| 103 | int screen; |
|---|
| 104 | Window root; |
|---|
| 105 | GC invert_gc; |
|---|
| 106 | XColor fg, bg; |
|---|
| 107 | #ifdef VWM |
|---|
| 108 | int vdesk; |
|---|
| 109 | XColor fc; |
|---|
| 110 | #endif |
|---|
| 111 | char *display; |
|---|
| 112 | }; |
|---|
| 113 | |
|---|
| 114 | /* client structure */ |
|---|
| 115 | |
|---|
| 116 | typedef struct Client Client; |
|---|
| 117 | struct Client { |
|---|
| 118 | Window window; |
|---|
| 119 | Window parent; |
|---|
| 120 | ScreenInfo *screen; |
|---|
| 121 | #ifdef COLOURMAP |
|---|
| 122 | Colormap cmap; |
|---|
| 123 | #endif |
|---|
| 124 | int ignore_unmap; |
|---|
| 125 | |
|---|
| 126 | int x, y, width, height; |
|---|
| 127 | int border; |
|---|
| 128 | int oldx, oldy, oldw, oldh; /* used when maximising */ |
|---|
| 129 | |
|---|
| 130 | int min_width, min_height; |
|---|
| 131 | int max_width, max_height; |
|---|
| 132 | int width_inc, height_inc; |
|---|
| 133 | int base_width, base_height; |
|---|
| 134 | int win_gravity; |
|---|
| 135 | int old_border; |
|---|
| 136 | #ifdef VWM |
|---|
| 137 | int vdesk; |
|---|
| 138 | int sticky; |
|---|
| 139 | #endif |
|---|
| 140 | int remove; /* set when client needs to be removed */ |
|---|
| 141 | PyObject *dict; |
|---|
| 142 | Client *next; |
|---|
| 143 | }; |
|---|
| 144 | |
|---|
| 145 | typedef struct Application Application; |
|---|
| 146 | struct Application { |
|---|
| 147 | char *res_name; |
|---|
| 148 | char *res_class; |
|---|
| 149 | int geometry_mask; |
|---|
| 150 | int x, y; |
|---|
| 151 | unsigned int width, height; |
|---|
| 152 | #ifdef VWM |
|---|
| 153 | int vdesk; |
|---|
| 154 | int sticky; |
|---|
| 155 | #endif |
|---|
| 156 | Application *next; |
|---|
| 157 | }; |
|---|
| 158 | |
|---|
| 159 | /* Declarations for global variables in main.c */ |
|---|
| 160 | |
|---|
| 161 | /* Commonly used X information */ |
|---|
| 162 | extern Display *dpy; |
|---|
| 163 | extern XFontStruct *font; |
|---|
| 164 | extern Cursor move_curs; |
|---|
| 165 | extern Cursor resize_curs; |
|---|
| 166 | extern int num_screens; |
|---|
| 167 | extern ScreenInfo *screens; |
|---|
| 168 | #ifdef SHAPE |
|---|
| 169 | extern int have_shape, shape_event; |
|---|
| 170 | #endif |
|---|
| 171 | |
|---|
| 172 | /* Standard X protocol atoms */ |
|---|
| 173 | extern Atom xa_wm_state; |
|---|
| 174 | extern Atom xa_wm_protos; |
|---|
| 175 | extern Atom xa_wm_delete; |
|---|
| 176 | extern Atom xa_wm_cmapwins; |
|---|
| 177 | /* Motif atoms */ |
|---|
| 178 | extern Atom mwm_hints; |
|---|
| 179 | /* EWMH atoms */ |
|---|
| 180 | #ifdef VWM |
|---|
| 181 | extern Atom xa_net_wm_desktop; |
|---|
| 182 | extern Atom xa_net_wm_state; |
|---|
| 183 | extern Atom xa_net_wm_state_sticky; |
|---|
| 184 | #endif |
|---|
| 185 | |
|---|
| 186 | /* Things that affect user interaction */ |
|---|
| 187 | extern unsigned int numlockmask; |
|---|
| 188 | extern unsigned int grabmask1; |
|---|
| 189 | extern unsigned int grabmask2; |
|---|
| 190 | extern unsigned int altmask; |
|---|
| 191 | extern const char *opt_term[3]; |
|---|
| 192 | extern int opt_bw; |
|---|
| 193 | #ifdef SNAP |
|---|
| 194 | extern int opt_snap; |
|---|
| 195 | #endif |
|---|
| 196 | #ifdef SOLIDDRAG |
|---|
| 197 | extern int solid_drag; |
|---|
| 198 | #else |
|---|
| 199 | # define solid_drag (0) |
|---|
| 200 | #endif |
|---|
| 201 | extern Application *head_app; |
|---|
| 202 | |
|---|
| 203 | /* Client tracking information */ |
|---|
| 204 | extern Client *head_client; |
|---|
| 205 | extern Client *current; |
|---|
| 206 | extern volatile Window initialising; |
|---|
| 207 | |
|---|
| 208 | /* main.c*/ |
|---|
| 209 | |
|---|
| 210 | int wm_main(int argc, char *argv[]); |
|---|
| 211 | |
|---|
| 212 | /* client.c */ |
|---|
| 213 | |
|---|
| 214 | Client *find_client(Window w); |
|---|
| 215 | void gravitate_client(Client *c, int sign); |
|---|
| 216 | void select_client(Client *c); |
|---|
| 217 | #ifdef VWM |
|---|
| 218 | void fix_client(Client *c); |
|---|
| 219 | #endif |
|---|
| 220 | void remove_client(Client *c); |
|---|
| 221 | void send_config(Client *c); |
|---|
| 222 | void send_wm_delete(Client *c, int kill_client); |
|---|
| 223 | void set_wm_state(Client *c, int state); |
|---|
| 224 | void set_shape(Client *c); |
|---|
| 225 | |
|---|
| 226 | /* events.c */ |
|---|
| 227 | |
|---|
| 228 | void event_main_loop(void); |
|---|
| 229 | |
|---|
| 230 | /* misc.c */ |
|---|
| 231 | |
|---|
| 232 | extern int need_client_tidy; |
|---|
| 233 | extern int ignore_xerror; |
|---|
| 234 | int handle_xerror(Display *dsply, XErrorEvent *e); |
|---|
| 235 | void spawn(const char *const cmd[]); |
|---|
| 236 | void handle_signal(int signo); |
|---|
| 237 | |
|---|
| 238 | /* new.c */ |
|---|
| 239 | |
|---|
| 240 | void make_new_client(Window w, ScreenInfo *s); |
|---|
| 241 | long get_wm_normal_hints(Client *c); |
|---|
| 242 | |
|---|
| 243 | /* screen.c */ |
|---|
| 244 | |
|---|
| 245 | void drag(Client *c); |
|---|
| 246 | void moveresize(Client *c); |
|---|
| 247 | void maximise_client(Client *c, int hv); |
|---|
| 248 | void show_info(Client *c, KeySym key); |
|---|
| 249 | void sweep(Client *c); |
|---|
| 250 | void unhide(Client *c, int raise_win); |
|---|
| 251 | void next(void); |
|---|
| 252 | #ifdef VWM |
|---|
| 253 | void hide(Client *c); |
|---|
| 254 | void switch_vdesk(ScreenInfo *s, int v); |
|---|
| 255 | #endif |
|---|
| 256 | ScreenInfo *find_screen(Window root); |
|---|
| 257 | ScreenInfo *find_current_screen(void); |
|---|
| 258 | void grab_keys_for_screen(ScreenInfo *s); |
|---|
| 259 | |
|---|
| 260 | /* ewmh.c */ |
|---|
| 261 | |
|---|
| 262 | #ifdef VWM |
|---|
| 263 | void update_net_wm_desktop(Client *c); |
|---|
| 264 | void update_net_wm_state(Client *c); |
|---|
| 265 | #endif |
|---|
| 266 | |
|---|
| 267 | /* mwmmodule.c */ |
|---|
| 268 | #include <Python.h> |
|---|
| 269 | |
|---|
| 270 | #define HOOK_DECLARE(name) \ |
|---|
| 271 | PyObject * run_ ## name ## _hook(Client *); |
|---|
| 272 | |
|---|
| 273 | HOOK_DECLARE(geometry); |
|---|
| 274 | HOOK_DECLARE(drag_start); |
|---|
| 275 | HOOK_DECLARE(drag_end); |
|---|
| 276 | HOOK_DECLARE(sweep_start); |
|---|
| 277 | HOOK_DECLARE(sweep_end); |
|---|
| 278 | HOOK_DECLARE(mouse_enter); |
|---|
| 279 | HOOK_DECLARE(mouse_leave); |
|---|
| 280 | HOOK_DECLARE(mouse_button1); |
|---|
| 281 | HOOK_DECLARE(mouse_button2); |
|---|
| 282 | HOOK_DECLARE(mouse_button3); |
|---|
| 283 | |
|---|
| 284 | void upd_check(void*); |
|---|
| 285 | |
|---|
| 286 | typedef struct { |
|---|
| 287 | KeySym key; |
|---|
| 288 | unsigned mask; |
|---|
| 289 | PyObject *cb; |
|---|
| 290 | } KeyBind; |
|---|
| 291 | |
|---|
| 292 | extern KeyBind **kbs; |
|---|
| 293 | extern int kbs_len; |
|---|
| 294 | |
|---|
| 295 | PyObject* grab_keys(PyObject *_, PyObject *pkbs); |
|---|