event.c
changeset 76 4bd49f404f10
parent 75 f08271b7cb20
child 77 38c8f7f7d401
equal deleted inserted replaced
75:f08271b7cb20 76:4bd49f404f10
     1 /*
     1 /*
     2  * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
     2  * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
     3  * See LICENSE file for license details.
     3  * See LICENSE file for license details.
     4  */
     4  */
     5 
     5 #include "dwm.h"
     6 #include <fcntl.h>
     6 
     7 #include <stdio.h>
       
     8 #include <stdlib.h>
     7 #include <stdlib.h>
     9 #include <string.h>
       
    10 #include <unistd.h>
       
    11 #include <X11/keysym.h>
     8 #include <X11/keysym.h>
    12 #include <X11/Xatom.h>
     9 #include <X11/Xatom.h>
    13 
       
    14 #include "dwm.h"
       
    15 
    10 
    16 #define ButtonMask      (ButtonPressMask | ButtonReleaseMask)
    11 #define ButtonMask      (ButtonPressMask | ButtonReleaseMask)
    17 #define MouseMask       (ButtonMask | PointerMotionMask)
    12 #define MouseMask       (ButtonMask | PointerMotionMask)
    18 
    13 
    19 /********** CUSTOMIZE **********/
    14 /********** CUSTOMIZE **********/
    52 	{ ControlMask,			XK_3,		appendtag,	{ .i = Twork } }, 
    47 	{ ControlMask,			XK_3,		appendtag,	{ .i = Twork } }, 
    53 };
    48 };
    54 
    49 
    55 /********** CUSTOMIZE **********/
    50 /********** CUSTOMIZE **********/
    56 
    51 
    57 /* local functions */
    52 /* static functions */
    58 static void buttonpress(XEvent *e);
    53 
    59 static void configurerequest(XEvent *e);
    54 static void movemouse(Client *c);
    60 static void destroynotify(XEvent *e);
    55 static void resizemouse(Client *c);
    61 static void enternotify(XEvent *e);
       
    62 static void leavenotify(XEvent *e);
       
    63 static void expose(XEvent *e);
       
    64 static void keypress(XEvent *e);
       
    65 static void maprequest(XEvent *e);
       
    66 static void propertynotify(XEvent *e);
       
    67 static void unmapnotify(XEvent *e);
       
    68 
       
    69 void (*handler[LASTEvent]) (XEvent *) = {
       
    70 	[ButtonPress] = buttonpress,
       
    71 	[ConfigureRequest] = configurerequest,
       
    72 	[DestroyNotify] = destroynotify,
       
    73 	[EnterNotify] = enternotify,
       
    74 	[LeaveNotify] = leavenotify,
       
    75 	[Expose] = expose,
       
    76 	[KeyPress] = keypress,
       
    77 	[MapRequest] = maprequest,
       
    78 	[PropertyNotify] = propertynotify,
       
    79 	[UnmapNotify] = unmapnotify
       
    80 };
       
    81 
       
    82 void
       
    83 grabkeys()
       
    84 {
       
    85 	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
       
    86 	unsigned int i;
       
    87 	KeyCode code;
       
    88 
       
    89 	for(i = 0; i < len; i++) {
       
    90 		code = XKeysymToKeycode(dpy, key[i].keysym);
       
    91 		XUngrabKey(dpy, code, key[i].mod, root);
       
    92 		XGrabKey(dpy, code, key[i].mod, root, True,
       
    93 				GrabModeAsync, GrabModeAsync);
       
    94 	}
       
    95 }
       
    96 
       
    97 static void
       
    98 keypress(XEvent *e)
       
    99 {
       
   100 	XKeyEvent *ev = &e->xkey;
       
   101 	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
       
   102 	unsigned int i;
       
   103 	KeySym keysym;
       
   104 
       
   105 	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
       
   106 	for(i = 0; i < len; i++)
       
   107 		if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
       
   108 			if(key[i].func)
       
   109 				key[i].func(&key[i].arg);
       
   110 			return;
       
   111 		}
       
   112 }
       
   113 
       
   114 static void
       
   115 resizemouse(Client *c)
       
   116 {
       
   117 	XEvent ev;
       
   118 	int ocx, ocy;
       
   119 
       
   120 	ocx = c->x;
       
   121 	ocy = c->y;
       
   122 	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
       
   123 				None, cursor[CurResize], CurrentTime) != GrabSuccess)
       
   124 		return;
       
   125 	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
       
   126 	for(;;) {
       
   127 		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
       
   128 		switch(ev.type) {
       
   129 		default: break;
       
   130 		case Expose:
       
   131 			handler[Expose](&ev);
       
   132 			break;
       
   133 		case MotionNotify:
       
   134 			XFlush(dpy);
       
   135 			c->w = abs(ocx - ev.xmotion.x);
       
   136 			c->h = abs(ocy - ev.xmotion.y);
       
   137 			c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w;
       
   138 			c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h;
       
   139 			resize(c, True);
       
   140 			break;
       
   141 		case ButtonRelease:
       
   142 			XUngrabPointer(dpy, CurrentTime);
       
   143 			return;
       
   144 		}
       
   145 	}
       
   146 }
       
   147 
       
   148 static void
       
   149 movemouse(Client *c)
       
   150 {
       
   151 	XEvent ev;
       
   152 	int x1, y1, ocx, ocy, di;
       
   153 	unsigned int dui;
       
   154 	Window dummy;
       
   155 
       
   156 	ocx = c->x;
       
   157 	ocy = c->y;
       
   158 	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
       
   159 				None, cursor[CurMove], CurrentTime) != GrabSuccess)
       
   160 		return;
       
   161 	XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
       
   162 	for(;;) {
       
   163 		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
       
   164 		switch (ev.type) {
       
   165 		default: break;
       
   166 		case Expose:
       
   167 			handler[Expose](&ev);
       
   168 			break;
       
   169 		case MotionNotify:
       
   170 			XFlush(dpy);
       
   171 			c->x = ocx + (ev.xmotion.x - x1);
       
   172 			c->y = ocy + (ev.xmotion.y - y1);
       
   173 			resize(c, False);
       
   174 			break;
       
   175 		case ButtonRelease:
       
   176 			XUngrabPointer(dpy, CurrentTime);
       
   177 			return;
       
   178 		}
       
   179 	}
       
   180 }
       
   181 
    56 
   182 static void
    57 static void
   183 buttonpress(XEvent *e)
    58 buttonpress(XEvent *e)
   184 {
    59 {
   185 	int x;
    60 	int x;
   278 	else if(ev->window == root)
   153 	else if(ev->window == root)
   279 		issel = True;
   154 		issel = True;
   280 }
   155 }
   281 
   156 
   282 static void
   157 static void
   283 leavenotify(XEvent *e)
       
   284 {
       
   285 	XCrossingEvent *ev = &e->xcrossing;
       
   286 
       
   287 	if((ev->window == root) && !ev->same_screen)
       
   288 		issel = True;
       
   289 }
       
   290 
       
   291 static void
       
   292 expose(XEvent *e)
   158 expose(XEvent *e)
   293 {
   159 {
   294 	XExposeEvent *ev = &e->xexpose;
   160 	XExposeEvent *ev = &e->xexpose;
   295 	Client *c;
   161 	Client *c;
   296 
   162 
   301 			drawtitle(c);
   167 			drawtitle(c);
   302 	}
   168 	}
   303 }
   169 }
   304 
   170 
   305 static void
   171 static void
       
   172 keypress(XEvent *e)
       
   173 {
       
   174 	XKeyEvent *ev = &e->xkey;
       
   175 	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
       
   176 	unsigned int i;
       
   177 	KeySym keysym;
       
   178 
       
   179 	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
       
   180 	for(i = 0; i < len; i++)
       
   181 		if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
       
   182 			if(key[i].func)
       
   183 				key[i].func(&key[i].arg);
       
   184 			return;
       
   185 		}
       
   186 }
       
   187 
       
   188 static void
       
   189 leavenotify(XEvent *e)
       
   190 {
       
   191 	XCrossingEvent *ev = &e->xcrossing;
       
   192 
       
   193 	if((ev->window == root) && !ev->same_screen)
       
   194 		issel = True;
       
   195 }
       
   196 
       
   197 static void
   306 maprequest(XEvent *e)
   198 maprequest(XEvent *e)
   307 {
   199 {
   308 	XMapRequestEvent *ev = &e->xmaprequest;
   200 	XMapRequestEvent *ev = &e->xmaprequest;
   309 	static XWindowAttributes wa;
   201 	static XWindowAttributes wa;
   310 
   202 
   317 		return;
   209 		return;
   318 	}
   210 	}
   319 
   211 
   320 	if(!getclient(ev->window))
   212 	if(!getclient(ev->window))
   321 		manage(ev->window, &wa);
   213 		manage(ev->window, &wa);
       
   214 }
       
   215 
       
   216 static void
       
   217 movemouse(Client *c)
       
   218 {
       
   219 	XEvent ev;
       
   220 	int x1, y1, ocx, ocy, di;
       
   221 	unsigned int dui;
       
   222 	Window dummy;
       
   223 
       
   224 	ocx = c->x;
       
   225 	ocy = c->y;
       
   226 	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
       
   227 				None, cursor[CurMove], CurrentTime) != GrabSuccess)
       
   228 		return;
       
   229 	XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
       
   230 	for(;;) {
       
   231 		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
       
   232 		switch (ev.type) {
       
   233 		default: break;
       
   234 		case Expose:
       
   235 			handler[Expose](&ev);
       
   236 			break;
       
   237 		case MotionNotify:
       
   238 			XFlush(dpy);
       
   239 			c->x = ocx + (ev.xmotion.x - x1);
       
   240 			c->y = ocy + (ev.xmotion.y - y1);
       
   241 			resize(c, False);
       
   242 			break;
       
   243 		case ButtonRelease:
       
   244 			XUngrabPointer(dpy, CurrentTime);
       
   245 			return;
       
   246 		}
       
   247 	}
   322 }
   248 }
   323 
   249 
   324 static void
   250 static void
   325 propertynotify(XEvent *e)
   251 propertynotify(XEvent *e)
   326 {
   252 {
   353 		}
   279 		}
   354 	}
   280 	}
   355 }
   281 }
   356 
   282 
   357 static void
   283 static void
       
   284 resizemouse(Client *c)
       
   285 {
       
   286 	XEvent ev;
       
   287 	int ocx, ocy;
       
   288 
       
   289 	ocx = c->x;
       
   290 	ocy = c->y;
       
   291 	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
       
   292 				None, cursor[CurResize], CurrentTime) != GrabSuccess)
       
   293 		return;
       
   294 	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
       
   295 	for(;;) {
       
   296 		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
       
   297 		switch(ev.type) {
       
   298 		default: break;
       
   299 		case Expose:
       
   300 			handler[Expose](&ev);
       
   301 			break;
       
   302 		case MotionNotify:
       
   303 			XFlush(dpy);
       
   304 			c->w = abs(ocx - ev.xmotion.x);
       
   305 			c->h = abs(ocy - ev.xmotion.y);
       
   306 			c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w;
       
   307 			c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h;
       
   308 			resize(c, True);
       
   309 			break;
       
   310 		case ButtonRelease:
       
   311 			XUngrabPointer(dpy, CurrentTime);
       
   312 			return;
       
   313 		}
       
   314 	}
       
   315 }
       
   316 
       
   317 static void
   358 unmapnotify(XEvent *e)
   318 unmapnotify(XEvent *e)
   359 {
   319 {
   360 	Client *c;
   320 	Client *c;
   361 	XUnmapEvent *ev = &e->xunmap;
   321 	XUnmapEvent *ev = &e->xunmap;
   362 
   322 
   363 	if((c = getclient(ev->window)))
   323 	if((c = getclient(ev->window)))
   364 		unmanage(c);
   324 		unmanage(c);
   365 }
   325 }
       
   326 
       
   327 /* extern functions */
       
   328 
       
   329 void (*handler[LASTEvent]) (XEvent *) = {
       
   330 	[ButtonPress] = buttonpress,
       
   331 	[ConfigureRequest] = configurerequest,
       
   332 	[DestroyNotify] = destroynotify,
       
   333 	[EnterNotify] = enternotify,
       
   334 	[LeaveNotify] = leavenotify,
       
   335 	[Expose] = expose,
       
   336 	[KeyPress] = keypress,
       
   337 	[MapRequest] = maprequest,
       
   338 	[PropertyNotify] = propertynotify,
       
   339 	[UnmapNotify] = unmapnotify
       
   340 };
       
   341 
       
   342 void
       
   343 grabkeys()
       
   344 {
       
   345 	static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
       
   346 	unsigned int i;
       
   347 	KeyCode code;
       
   348 
       
   349 	for(i = 0; i < len; i++) {
       
   350 		code = XKeysymToKeycode(dpy, key[i].keysym);
       
   351 		XUngrabKey(dpy, code, key[i].mod, root);
       
   352 		XGrabKey(dpy, code, key[i].mod, root, True,
       
   353 				GrabModeAsync, GrabModeAsync);
       
   354 	}
       
   355 }