rendered paste body
/* Checks if w is a ipw and returns the real window */
static CompWindow *
FWGetRealWindow (CompWindow *w)
{
FWWindowInputInfo *info;
int count = 0;
FREEWINS_SCREEN (w->screen);
for (info = fws->transformedWindows; info; info = info->next)
{
count++;
fprintf(stderr, "Counted %i transformed windows\n", count);
if (w->id == info->ipw)
return info->w;
}
return NULL;
}
static CompWindow *
FWGetRealWindowFromID (CompDisplay *d,
Window wid)
{
CompWindow *orig, *w;
CompScreen *s;
orig = findWindowAtDisplay (d, wid);
for (s = d->screens; s; s = s->next)
for (w = s->windows; w; w = w->next)
if (wid == w->id)
orig = w;
if (!orig)
{
fprintf(stderr, "Cannot get a compWindow for this window\n");
return NULL;
}
return FWGetRealWindow (orig);
}
/* ------ Input Prevention -------------------------------------------*/
static void
FWSaveInputShape (CompWindow *w,
XRectangle **retRects,
int *retCount,
int *retOrdering)
{
XRectangle *rects;
int count = 0, ordering;
Display *dpy = w->screen->display->display;
rects = XShapeGetRectangles (dpy, w->id, ShapeInput, &count, &ordering);
/* check if the returned shape exactly matches the window shape -
if that is true, the window currently has no set input shape */
if ((count == 1) &&
(rects[0].x == -w->serverBorderWidth) &&
(rects[0].y == -w->serverBorderWidth) &&
(rects[0].width == (w->serverWidth + w->serverBorderWidth)) &&
(rects[0].height == (w->serverHeight + w->serverBorderWidth)))
{
count = 0;
}
*retRects = rects;
*retCount = count;
*retOrdering = ordering;
}
static void
FWUnshapeInput (CompWindow *w)
{
Display *dpy = w->screen->display->display;
FREEWINS_WINDOW (w);
if (fww->input->nInputRects)
{
XShapeCombineRectangles (dpy, w->id, ShapeInput, 0, 0,
fww->input->inputRects, fww->input->nInputRects,
ShapeSet, fww->input->inputRectOrdering);
}
else
{
XShapeCombineMask (dpy, w->id, ShapeInput, 0, 0, None, ShapeSet);
}
if (fww->input->frameNInputRects >= 0)
{
if (fww->input->frameInputRects)
{
XShapeCombineRectangles (dpy, w->frame, ShapeInput, 0, 0,
fww->input->frameInputRects,
fww->input->frameNInputRects,
ShapeSet,
fww->input->frameInputRectOrdering);
}
else
{
XShapeCombineMask (dpy, w->frame, ShapeInput, 0, 0, None, ShapeSet);
}
}
}
/* Input Shaper. This no longer adjusts the shape of the window
but instead shapes it to 0 as the IPW deals with the input.
Old code is available commented, but will be removed as soon
as input prevention becomes stable enough */
static void FWShapeInput (CompWindow *w)
{
CompWindow *fw;
Display *dpy = w->screen->display->display;
FREEWINS_WINDOW (w);
/* save old shape */
FWSaveInputShape (w, &fww->input->inputRects,
&fww->input->nInputRects, &fww->input->inputRectOrdering);
fw = findWindowAtDisplay (w->screen->display, w->frame);
if (fw)
{
FWSaveInputShape(fw, &fww->input->frameInputRects,
&fww->input->frameNInputRects,
&fww->input->frameInputRectOrdering);
}
else
{
fww->input->frameInputRects = NULL;
fww->input->frameNInputRects = -1;
fww->input->frameInputRectOrdering = 0;
}
/* clear shape */
XShapeSelectInput (dpy, w->id, NoEventMask);
XShapeCombineRectangles (dpy, w->id, ShapeInput, 0, 0,
NULL, 0, ShapeSet, 0);
if (w->frame)
XShapeCombineRectangles (dpy, w->frame, ShapeInput, 0, 0,
NULL, 0, ShapeSet, 0);
XShapeSelectInput (dpy, w->id, ShapeNotify);
}
/* Add the input info to the list of input info */
static void
FWAddWindowToList (FWWindowInputInfo *info)
{
CompScreen *s = info->w->screen;
FWWindowInputInfo *run;
FREEWINS_SCREEN (s);
run = fws->transformedWindows;
if (!run)
fws->transformedWindows = info;
else
{
for (; run->next; run = run->next)
run->next = info;
}
}
/* Remove the input info from the list of input info */
static void
FWRemoveWindowFromList (FWWindowInputInfo *info)
{
CompScreen *s = info->w->screen;
FWWindowInputInfo *run;
FREEWINS_SCREEN (s);
if (!fws->transformedWindows)
return;
if (fws->transformedWindows == info)
fws->transformedWindows = info->next;
else
{
for (run = fws->transformedWindows; run->next; run = run->next)
{
if (run->next == info)
{
run->next = info->next;
break;
}
}
}
}
/* Adjust size and location of the input prevention window
*/
static void
FWAdjustIPW (CompWindow *w)
{
XWindowChanges xwc;
Display *dpy = w->screen->display->display;
float width, height;
FREEWINS_WINDOW (w);
if (!fww->input || !fww->input->ipw)
return;
width = fww->inputRect.x2 - fww->inputRect.x1;
height = fww->inputRect.y2 - fww->inputRect.y1;
fprintf(stderr, "ipw X %i Y %i W %f H %f\n", fww->inputRect.x1, fww->inputRect.y1, width, height);
xwc.x = (fww->inputRect.x1);
xwc.y = (fww->inputRect.y1);
xwc.width = ceil(width);
xwc.height = ceil(height);
xwc.stack_mode = Below;
xwc.sibling = w->id;
XConfigureWindow (dpy, fww->input->ipw,
CWSibling | CWStackMode | CWX | CWY | CWWidth | CWHeight,
&xwc);
XMapWindow (dpy, fww->input->ipw);
}
/* Create an input prevention window */
static void
FWCreateIPW (CompWindow *w)
{
Window ipw;
XSetWindowAttributes attrib;
FREEWINS_WINDOW (w);
if (!fww->input || fww->input->ipw)
return;
attrib.override_redirect = TRUE;
attrib.event_mask = 0;
ipw = XCreateWindow (w->screen->display->display,
w->screen->root,
w->serverX - w->input.left,
w->serverY - w->input.top,
w->serverWidth + w->input.left + w->input.right,
w->serverHeight + w->input.top + w->input.bottom,
0, CopyFromParent, InputOnly, CopyFromParent,
CWEventMask | CWOverrideRedirect,
&attrib);
fww->input->ipw = ipw;
FWAdjustIPW (w);
if (ipw)
fprintf(stderr, "success in creating IPW with ID of %i", ipw);
}
/* Ensure that the input prevention window
* is always on top of the transformed
* window
*/
static void
FWAdjustIPWStacking (CompScreen *s)
{
FWWindowInputInfo *input;
FREEWINS_SCREEN (s);
for (input = fws->transformedWindows; input; input = input->next)
{
if (!input->w->prev || input->w->prev->id != input->ipw)
FWAdjustIPW (input->w);
}
}
static void FWHandleIPWResizeInitiate (CompWindow *w)
{
FREEWINS_SCREEN (w->screen);
FREEWINS_DISPLAY (w->screen->display);
(*w->screen->activateWindow) (w);
fwd->grab = grabResize;
fws->rotateCursor = XCreateFontCursor (w->screen->display->display, XC_plus);
if(!otherScreenGrabExist(w->screen, "freewins", "resize", 0))
if(!fws->grabIndex)
{
unsigned int mods = 0;
mods &= CompNoMask;
fws->grabIndex = pushScreenGrab(w->screen, fws->rotateCursor, "resize");
(w->screen->windowGrabNotify) (w, w->attrib.x + (w->width / 2),
w->attrib.y + (w->height / 2), mods,
CompWindowGrabMoveMask |
CompWindowGrabButtonMask);
fwd->grabWindow = w;
}
}
static void FWHandleIPWMoveInitiate (CompWindow *w)
{
FREEWINS_SCREEN (w->screen);
FREEWINS_DISPLAY (w->screen->display);
(*w->screen->activateWindow) (w);
fwd->grab = grabMove;
fws->rotateCursor = XCreateFontCursor (w->screen->display->display, XC_fleur);
if(!otherScreenGrabExist(w->screen, "freewins", "move", 0))
if(!fws->grabIndex)
{
unsigned int mods = 0;
mods &= CompNoMask;
fws->grabIndex = pushScreenGrab(w->screen, fws->rotateCursor, "move");
(w->screen->windowGrabNotify) (w, w->attrib.x + (w->width / 2),
w->attrib.y + (w->height / 2), mods,
CompWindowGrabMoveMask |
CompWindowGrabButtonMask);
}
fwd->grabWindow = w;
}
static void FWHandleIPWMoveMotionEvent (CompWindow *w, unsigned int x, unsigned int y)
{
FREEWINS_SCREEN (w->screen);
//static int oldPointerX, oldPointerY;
int dx = x - lastPointerX;
int dy = y - lastPointerY;
if (!fws->grabIndex)
return;
moveWindow(w, dx,
dy, TRUE, FALSE);
syncWindowPosition (w);
}
static void FWHandleIPWResizeMotionEvent (CompWindow *w, unsigned int x, unsigned int y)
{
FREEWINS_WINDOW (w);
int dx = (x - lastPointerX) * 10;
int dy = (y - lastPointerY) * 10;
fww->winH += dx;
fww->winW += dy;
/* In order to prevent a window redraw on resize
* on every motion event we have a threshold
*/
if (fww->winH - 10 > w->height || fww->winW - 10 > w->width)
{
XWindowChanges xwc;
unsigned int mask = CWX | CWY | CWWidth | CWHeight;
xwc.x = w->serverX;
xwc.y = w->serverX;
xwc.width = fww->winW;
xwc.height = fww->winH;
if (xwc.width == w->serverWidth)
mask &= ~CWWidth;
if (xwc.height == w->serverHeight)
mask &= ~CWHeight;
if (w->mapNum && (mask & (CWWidth | CWHeight)))
sendSyncRequest (w);
configureXWindow (w, mask, &xwc);
}
}