wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

xdnd.c (1767B)


      1 /* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
      2  * See LICENSE file for license details.
      3  */
      4 #include "dat.h"
      5 #include "fns.h"
      6 
      7 static Handlers	handlers;
      8 
      9 void
     10 xdnd_initwindow(Window *w) {
     11 	long l;
     12 
     13 	l = 3; /* They are insane. Why is this an ATOM?! */
     14 	changeprop_long(w, "XdndAware", "ATOM", &l, 1);
     15 	pushhandler(w, &handlers, nil);
     16 }
     17 
     18 typedef struct Dnd Dnd;
     19 struct Dnd {
     20 	XWindow		source;
     21 	Rectangle	r;
     22 };
     23 
     24 static bool
     25 clientmessage_event(Window *w, void *aux, XClientMessageEvent *e) {
     26 	Dnd *dnd;
     27 	long *l;
     28 	Rectangle r;
     29 	Point p;
     30 	long pos, siz;
     31 	ulong msg;
     32 
     33 	dnd = nil;
     34 	msg = e->message_type;
     35 	l = e->data.l;
     36 	Dprint(DDnd, "ClientMessage: %A\n", msg);
     37 
     38 	if(msg == xatom("XdndEnter")) {
     39 		if(e->format != 32)
     40 			return false;
     41 		if(w->dnd == nil)
     42 			w->dnd = emallocz(sizeof *dnd);
     43 		dnd = w->dnd;
     44 		dnd->source = l[0];
     45 		dnd->r = ZR;
     46 		return false;
     47 	}else
     48 	if(msg == xatom("XdndLeave")) {
     49 		if(e->format != 32)
     50 			return false;
     51 		if(w->dnd) {
     52 			free(w->dnd);
     53 			w->dnd = nil;
     54 		}
     55 		return false;
     56 	}else
     57 	if(msg == xatom("XdndPosition")) {
     58 		if(e->format != 32)
     59 			return false;
     60 		r = ZR;
     61 		dnd = w->dnd;
     62 		if(dnd) {
     63 			p.x = (ulong)l[2] >> 16;
     64 			p.y = (ulong)l[2] & 0xffff;
     65 			p = subpt(p, w->r.min);
     66 			Dprint(DDnd, "\tw: %W\n", w);
     67 			Dprint(DDnd, "\tp: %P\n", p);
     68 			if(eqrect(dnd->r, ZR) || !rect_haspoint_p(dnd->r, p))
     69 				if(w->handler->dndmotion)
     70 					dnd->r = w->handler->dndmotion(w, w->aux, p);
     71 			r = dnd->r;
     72 			if(!eqrect(r, ZR))
     73 				r = rectaddpt(r, w->r.min);
     74 			Dprint(DDnd, "\tr: %R\n", r);
     75 		}
     76 		pos = (r.min.x<<16) | r.min.y;
     77 		siz = (Dx(r)<<16) | Dy(r);
     78 		sendmessage(window(l[0]), "XdndStatus", e->window, 0, pos, siz, 0);
     79 		return false;
     80 	}
     81 
     82 	return true;
     83 }
     84 
     85 static Handlers handlers = {
     86 	.message = clientmessage_event
     87 };
     88