10bbfda8aSnia/*
20bbfda8aSnia * Functions related to captive-mode ctwm.
30bbfda8aSnia */
40bbfda8aSnia
50bbfda8aSnia#include "ctwm.h"
60bbfda8aSnia
70bbfda8aSnia#include <stdlib.h>
80bbfda8aSnia
90bbfda8aSnia#include "captive.h"
100bbfda8aSnia#include "cursor.h"
110bbfda8aSnia#include "events.h"
120bbfda8aSnia#include "functions_internal.h"
130bbfda8aSnia#include "screen.h"
140bbfda8aSnia
150bbfda8aSnia
160bbfda8aSnia/*
170bbfda8aSnia * Pulling a window into the ctwm it was invoked from.
180bbfda8aSnia */
190bbfda8aSniaDFHANDLER(adoptwindow)
200bbfda8aSnia{
210bbfda8aSnia	AdoptWindow();
220bbfda8aSnia}
230bbfda8aSnia
240bbfda8aSnia
250bbfda8aSnia/*
260bbfda8aSnia * Interactively moving a window between ctwm's.
270bbfda8aSnia */
280bbfda8aSniaDFHANDLER(hypermove)
290bbfda8aSnia{
300bbfda8aSnia	bool    cont = true;
310bbfda8aSnia	Window  root = RootWindow(dpy, Scr->screen);
320bbfda8aSnia	Cursor  cursor;
330bbfda8aSnia	Window captive_root;
340bbfda8aSnia
350bbfda8aSnia	if(tmp_win->iswinbox || tmp_win->iswspmgr) {
360bbfda8aSnia		XBell(dpy, 0);
370bbfda8aSnia		return;
380bbfda8aSnia	}
390bbfda8aSnia
400bbfda8aSnia	{
410bbfda8aSnia		CaptiveCTWM cctwm = GetCaptiveCTWMUnderPointer();
420bbfda8aSnia		cursor = MakeStringCursor(cctwm.name);
430bbfda8aSnia		free(cctwm.name);
440bbfda8aSnia		captive_root = cctwm.root;
450bbfda8aSnia	}
460bbfda8aSnia
470bbfda8aSnia	XGrabPointer(dpy, root, True,
480bbfda8aSnia	             ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
490bbfda8aSnia	             GrabModeAsync, GrabModeAsync, root, cursor, CurrentTime);
500bbfda8aSnia	while(cont) {
510bbfda8aSnia		XMaskEvent(dpy, ButtonPressMask | ButtonMotionMask |
520bbfda8aSnia		           ButtonReleaseMask, &Event);
530bbfda8aSnia		switch(Event.xany.type) {
540bbfda8aSnia			case ButtonPress:
550bbfda8aSnia				cont = false;
560bbfda8aSnia				break;
570bbfda8aSnia
580bbfda8aSnia			case ButtonRelease: {
590bbfda8aSnia				CaptiveCTWM cctwm = GetCaptiveCTWMUnderPointer();
600bbfda8aSnia				cont = false;
610bbfda8aSnia				free(cctwm.name);
620bbfda8aSnia				if(cctwm.root == Scr->Root) {
630bbfda8aSnia					break;
640bbfda8aSnia				}
650bbfda8aSnia				if(cctwm.root == Scr->XineramaRoot) {
660bbfda8aSnia					break;
670bbfda8aSnia				}
680bbfda8aSnia				SetNoRedirect(tmp_win->w);
690bbfda8aSnia				XUngrabButton(dpy, AnyButton, AnyModifier, tmp_win->w);
700bbfda8aSnia				XReparentWindow(dpy, tmp_win->w, cctwm.root, 0, 0);
710bbfda8aSnia				XMapWindow(dpy, tmp_win->w);
720bbfda8aSnia				break;
730bbfda8aSnia			}
740bbfda8aSnia
750bbfda8aSnia			case MotionNotify: {
760bbfda8aSnia				CaptiveCTWM cctwm = GetCaptiveCTWMUnderPointer();
770bbfda8aSnia				if(cctwm.root != captive_root) {
780bbfda8aSnia					unsigned int chmask;
790bbfda8aSnia
800bbfda8aSnia					XFreeCursor(dpy, cursor);
810bbfda8aSnia					cursor = MakeStringCursor(cctwm.name);
820bbfda8aSnia					captive_root = cctwm.root;
830bbfda8aSnia
840bbfda8aSnia					chmask = (ButtonPressMask | ButtonMotionMask
850bbfda8aSnia					          | ButtonReleaseMask);
860bbfda8aSnia					XChangeActivePointerGrab(dpy, chmask,
870bbfda8aSnia					                         cursor, CurrentTime);
880bbfda8aSnia				}
890bbfda8aSnia				free(cctwm.name);
900bbfda8aSnia				break;
910bbfda8aSnia			}
920bbfda8aSnia		}
930bbfda8aSnia	}
940bbfda8aSnia
950bbfda8aSnia	ButtonPressed = -1;
960bbfda8aSnia	XUngrabPointer(dpy, CurrentTime);
970bbfda8aSnia	XFreeCursor(dpy, cursor);
980bbfda8aSnia
990bbfda8aSnia	return;
1000bbfda8aSnia}
101