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