All pastes #985909 Raw Edit

Stuff

public text v1 · immutable
·published 2008-04-15 12:11 UTC
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);
    }
}