1 /*
2  * Functions related to captive-mode ctwm.
3  */
4 
5 #include "ctwm.h"
6 
7 #include <stdlib.h>
8 
9 #include "captive.h"
10 #include "cursor.h"
11 #include "events.h"
12 #include "functions_internal.h"
13 #include "screen.h"
14 
15 
16 /*
17  * Pulling a window into the ctwm it was invoked from.
18  */
DFHANDLER(adoptwindow)19 DFHANDLER(adoptwindow)
20 {
21 	AdoptWindow();
22 }
23 
24 
25 /*
26  * Interactively moving a window between ctwm's.
27  */
DFHANDLER(hypermove)28 DFHANDLER(hypermove)
29 {
30 	bool    cont = true;
31 	Window  root = RootWindow(dpy, Scr->screen);
32 	Cursor  cursor;
33 	Window captive_root;
34 
35 	if(tmp_win->iswinbox || tmp_win->iswspmgr) {
36 		XBell(dpy, 0);
37 		return;
38 	}
39 
40 	{
41 		CaptiveCTWM cctwm = GetCaptiveCTWMUnderPointer();
42 		cursor = MakeStringCursor(cctwm.name);
43 		free(cctwm.name);
44 		captive_root = cctwm.root;
45 	}
46 
47 	XGrabPointer(dpy, root, True,
48 	             ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
49 	             GrabModeAsync, GrabModeAsync, root, cursor, CurrentTime);
50 	while(cont) {
51 		XMaskEvent(dpy, ButtonPressMask | ButtonMotionMask |
52 		           ButtonReleaseMask, &Event);
53 		switch(Event.xany.type) {
54 			case ButtonPress:
55 				cont = false;
56 				break;
57 
58 			case ButtonRelease: {
59 				CaptiveCTWM cctwm = GetCaptiveCTWMUnderPointer();
60 				cont = false;
61 				free(cctwm.name);
62 				if(cctwm.root == Scr->Root) {
63 					break;
64 				}
65 				if(cctwm.root == Scr->XineramaRoot) {
66 					break;
67 				}
68 				SetNoRedirect(tmp_win->w);
69 				XUngrabButton(dpy, AnyButton, AnyModifier, tmp_win->w);
70 				XReparentWindow(dpy, tmp_win->w, cctwm.root, 0, 0);
71 				XMapWindow(dpy, tmp_win->w);
72 				break;
73 			}
74 
75 			case MotionNotify: {
76 				CaptiveCTWM cctwm = GetCaptiveCTWMUnderPointer();
77 				if(cctwm.root != captive_root) {
78 					unsigned int chmask;
79 
80 					XFreeCursor(dpy, cursor);
81 					cursor = MakeStringCursor(cctwm.name);
82 					captive_root = cctwm.root;
83 
84 					chmask = (ButtonPressMask | ButtonMotionMask
85 					          | ButtonReleaseMask);
86 					XChangeActivePointerGrab(dpy, chmask,
87 					                         cursor, CurrentTime);
88 				}
89 				free(cctwm.name);
90 				break;
91 			}
92 		}
93 	}
94 
95 	ButtonPressed = -1;
96 	XUngrabPointer(dpy, CurrentTime);
97 	XFreeCursor(dpy, cursor);
98 
99 	return;
100 }
101