Exemple #1
0
RegionPtr
CreateBoundingShape(WindowPtr pWin)
{
    BoxRec extents;

    extents.x1 = -wBorderWidth(pWin);
    extents.y1 = -wBorderWidth(pWin);
    extents.x2 = pWin->drawable.width + wBorderWidth(pWin);
    extents.y2 = pWin->drawable.height + wBorderWidth(pWin);
    return RegionCreate(&extents, 1);
}
Exemple #2
0
static
int
winAddRgn (WindowPtr pWin, pointer data)
{
  int		iX, iY, iWidth, iHeight, iBorder;
  HRGN		hRgn = *(HRGN*)data;
  HRGN		hRgnWin;
  winWindowPriv(pWin);
  
  /* If pWin is not Root */
  if (pWin->parent != NULL) 
    {
#if CYGDEBUG
      ErrorF ("winAddRgn ()\n");
#endif
      if (pWin->mapped)
	{
	  iBorder = wBorderWidth (pWin);
	  
	  iX = pWin->drawable.x - iBorder;
	  iY = pWin->drawable.y - iBorder;
	  
	  iWidth = pWin->drawable.width + iBorder * 2;
	  iHeight = pWin->drawable.height + iBorder * 2;
	  
	  hRgnWin = CreateRectRgn (0, 0, iWidth, iHeight);
	  
	  if (hRgnWin == NULL)
	    {
	      ErrorF ("winAddRgn - CreateRectRgn () failed\n");
	      ErrorF ("  Rect %d %d %d %d\n",
		      iX, iY, iX + iWidth, iY + iHeight);
	    }
	  
	  if (pWinPriv->hRgn)
	    {
	      if (CombineRgn (hRgnWin, hRgnWin, pWinPriv->hRgn, RGN_AND)
		  == ERROR)
		{
		  ErrorF ("winAddRgn - CombineRgn () failed\n");
		}
	    }
	  
	  OffsetRgn (hRgnWin, iX, iY);

	  if (CombineRgn (hRgn, hRgn, hRgnWin, RGN_OR) == ERROR)
	    {
	      ErrorF ("winAddRgn - CombineRgn () failed\n");
	    }
	  
	  DeleteObject (hRgnWin);
	}
      return WT_DONTWALKCHILDREN;
    }
  else
    {
      return WT_WALKCHILDREN;
    }
}
Exemple #3
0
WindowPtr
miSpriteTrace(SpritePtr pSprite, int x, int y)
{
    WindowPtr pWin;
    BoxRec box;

    pWin = DeepestSpriteWin(pSprite)->firstChild;
    while (pWin) {
        if ((pWin->mapped) &&
            (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
            (x < pWin->drawable.x + (int) pWin->drawable.width +
             wBorderWidth(pWin)) &&
            (y >= pWin->drawable.y - wBorderWidth(pWin)) &&
            (y < pWin->drawable.y + (int) pWin->drawable.height +
             wBorderWidth(pWin))
            /* When a window is shaped, a further check
             * is made to see if the point is inside
             * borderSize
             */
            && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
            && (!wInputShape(pWin) ||
                RegionContainsPoint(wInputShape(pWin),
                                    x - pWin->drawable.x,
                                    y - pWin->drawable.y, &box))
#ifdef ROOTLESS
            /* In rootless mode windows may be offscreen, even when
             * they're in X's stack. (E.g. if the native window system
             * implements some form of virtual desktop system).
             */
            && !pWin->rootlessUnhittable
#endif
            ) {
            if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize) {
                pSprite->spriteTraceSize += 10;
                pSprite->spriteTrace = realloc(pSprite->spriteTrace,
                                               pSprite->spriteTraceSize *
                                               sizeof(WindowPtr));
            }
            pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
            pWin = pWin->firstChild;
        }
        else
            pWin = pWin->nextSib;
    }
    return DeepestSpriteWin(pSprite);
}
Exemple #4
0
/** Get an image from the back-end server associated with \a pDrawable's
 *  screen.  If \a pDrawable is a window, it must be viewable to get an
 *  image from it.  If it is not viewable, then get the image from the
 *  first ancestor of \a pDrawable that is viewable.  If no viewable
 *  ancestor is found, then simply return without getting an image.  */
void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
		 unsigned int format, unsigned long planeMask, char *pdstLine)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
    XImage        *img;
    Drawable       draw;

    /* Cannot get image from unviewable window */
    if (pDrawable->type == DRAWABLE_WINDOW) {
	WindowPtr pWindow = (WindowPtr)pDrawable;
	if (!pWindow->viewable) {
	    while (!pWindow->viewable && pWindow->parent) {
		sx += pWindow->origin.x - wBorderWidth(pWindow);
		sx += pWindow->origin.y - wBorderWidth(pWindow);
		pWindow = pWindow->parent;
	    }
	    if (!pWindow->viewable) {
		return;
	    }
	}
	DMX_GCOPS_SET_DRAWABLE(&pWindow->drawable, draw);
	if (DMX_GCOPS_OFFSCREEN(&pWindow->drawable))
	    return;
    } else {
	DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
	if (DMX_GCOPS_OFFSCREEN(pDrawable)) {
            /* Try to find the pixmap on a non-detached Xinerama screen */
            dmxScreen = dmxFindAlternatePixmap(pDrawable, &draw);
            if (!dmxScreen) return;
        }
    }

    img = XGetImage(dmxScreen->beDisplay, draw,
		    sx, sy, w, h, planeMask, format);
    if (img) {
	int len = img->bytes_per_line * img->height;
	memmove(pdstLine, img->data, len);
	XDestroyImage(img);
    }

    dmxSync(dmxScreen, FALSE);
}
Exemple #5
0
void
miChangeBorderWidth(WindowPtr pWin, unsigned int width)
{
    int oldwidth;
    Bool anyMarked = FALSE;
    ScreenPtr pScreen;
    Bool WasViewable = (Bool)(pWin->viewable);
    Bool HadBorder;
    WindowPtr  pLayerWin;

    oldwidth = wBorderWidth (pWin);
    if (oldwidth == width)
	return;
    HadBorder = HasBorder(pWin);
    pScreen = pWin->drawable.pScreen;
    if (WasViewable && width < oldwidth)
	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);

    pWin->borderWidth = width;
    SetBorderSize (pWin);

    if (WasViewable)
    {
	if (width > oldwidth)
	{
	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
							  &pLayerWin);
	    /*
	     * save the old border visible region to correctly compute
	     * borderExposed.
	     */
	    if (pWin->valdata && HadBorder)
	    {
		RegionPtr   borderVisible;
		borderVisible = REGION_CREATE(pScreen, NULL, 1);
		REGION_SUBTRACT(pScreen, borderVisible,
				      &pWin->borderClip, &pWin->winSize);
		pWin->valdata->before.borderVisible = borderVisible;
	    }
	}

	if (anyMarked)
	{
	    (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
	    (*pScreen->HandleExposures)(pLayerWin->parent);
	}
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
					  VTOther);
    }
    if (pWin->realized)
	WindowsRestructured ();
}
Exemple #6
0
void
xnestCollectExposures(void)
{
    XEvent X;
    WindowPtr pWin;
    RegionRec Rgn;
    BoxRec Box;

    while (XCheckIfEvent(xnestDisplay, &X, xnestExposurePredicate, NULL)) {
        pWin = xnestWindowPtr(X.xexpose.window);

        if (pWin && X.xexpose.width && X.xexpose.height) {
            Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + X.xexpose.x;
            Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + X.xexpose.y;
            Box.x2 = Box.x1 + X.xexpose.width;
            Box.y2 = Box.y1 + X.xexpose.height;

            RegionInit(&Rgn, &Box, 1);

            miSendExposures(pWin, &Rgn, Box.x2, Box.y2);
        }
    }
}
Exemple #7
0
void
miSlideAndSizeWindow(WindowPtr pWin,
                     int x, int y,
                     unsigned int w, unsigned int h,
                     WindowPtr pSib)
{
    WindowPtr pParent;
    Bool WasViewable = (Bool)(pWin->viewable);
    unsigned short width = pWin->drawable.width,
		   height = pWin->drawable.height;
    short oldx = pWin->drawable.x,
	  oldy = pWin->drawable.y;
    int bw = wBorderWidth (pWin);
    short dw, dh;
    DDXPointRec oldpt;
    RegionPtr oldRegion = NULL;
    Bool anyMarked = FALSE;
    ScreenPtr pScreen;
    WindowPtr pFirstChange;
    WindowPtr pChild;
    RegionPtr	gravitate[StaticGravity + 1];
    unsigned g;
    int		nx, ny;		/* destination x,y */
    int		newx, newy;	/* new inner window position */
    RegionPtr	pRegion = NULL;
    RegionPtr	destClip;	/* portions of destination already written */
    RegionPtr	oldWinClip = NULL;	/* old clip list for window */
    RegionPtr	borderVisible = NullRegion; /* visible area of the border */
    Bool	shrunk = FALSE; /* shrunk in an inner dimension */
    Bool	moved = FALSE;	/* window position changed */
    WindowPtr  pLayerWin;

    /* if this is a root window, can't be resized */
    if (!(pParent = pWin->parent))
	return ;

    pScreen = pWin->drawable.pScreen;
    newx = pParent->drawable.x + x + bw;
    newy = pParent->drawable.y + y + bw;
    if (WasViewable)
    {
	anyMarked = FALSE;
	/*
	 * save the visible region of the window
	 */
	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
	REGION_COPY(pScreen, oldRegion, &pWin->winSize);

	/*
	 * categorize child windows into regions to be moved
	 */
	for (g = 0; g <= StaticGravity; g++)
	    gravitate[g] = (RegionPtr) NULL;
	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
	{
	    g = pChild->winGravity;
	    if (g != UnmapGravity)
	    {
		if (!gravitate[g])
		    gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
		REGION_UNION(pScreen, gravitate[g],
				   gravitate[g], &pChild->borderClip);
	    }
	    else
	    {
		UnmapWindow(pChild, TRUE);
		anyMarked = TRUE;
	    }
	}
	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 
						       &pLayerWin);

	oldWinClip = NULL;
	if (pWin->bitGravity != ForgetGravity)
	{
	    oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
	    REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
	}
	/*
	 * if the window is changing size, borderExposed
	 * can't be computed correctly without some help.
	 */
	if (pWin->drawable.height > h || pWin->drawable.width > w)
	    shrunk = TRUE;

	if (newx != oldx || newy != oldy)
	    moved = TRUE;

	if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
	    HasBorder (pWin))
	{
	    borderVisible = REGION_CREATE(pScreen, NullBox, 1);
	    /* for tiled borders, we punt and draw the whole thing */
	    if (pWin->borderIsPixel || !moved)
	    {
		if (shrunk || moved)
		    REGION_SUBTRACT(pScreen, borderVisible,
					  &pWin->borderClip,
					  &pWin->winSize);
		else
		    REGION_COPY(pScreen, borderVisible,
					    &pWin->borderClip);
	    }
	}
    }
    pWin->origin.x = x + bw;
    pWin->origin.y = y + bw;
    pWin->drawable.height = h;
    pWin->drawable.width = w;

    x = pWin->drawable.x = newx;
    y = pWin->drawable.y = newy;

    SetWinSize (pWin);
    SetBorderSize (pWin);

    dw = (int)w - (int)width;
    dh = (int)h - (int)height;
    ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);

    /* let the hardware adjust background and border pixmaps, if any */
    (*pScreen->PositionWindow)(pWin, x, y);

    pFirstChange = MoveWindowInStack(pWin, pSib);

    if (WasViewable)
    {
	pRegion = REGION_CREATE(pScreen, NullBox, 1);

	if (pLayerWin == pWin)
	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
						NULL);
	else
	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
						NULL);

	if (pWin->valdata)
	{
	    pWin->valdata->before.resized = TRUE;
	    pWin->valdata->before.borderVisible = borderVisible;
	}


	if (anyMarked)
	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
	/*
	 * the entire window is trashed unless bitGravity
	 * recovers portions of it
	 */
	REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
    }

    GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);

    if (WasViewable)
    {
	/* avoid the border */
	if (HasBorder (pWin))
	{
	    int	offx, offy, dx, dy;

	    /* kruft to avoid double translates for each gravity */
	    offx = 0;
	    offy = 0;
	    for (g = 0; g <= StaticGravity; g++)
	    {
		if (!gravitate[g])
		    continue;

		/* align winSize to gravitate[g].
		 * winSize is in new coordinates,
		 * gravitate[g] is still in old coordinates */
		GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
		
		dx = (oldx - nx) - offx;
		dy = (oldy - ny) - offy;
		if (dx || dy)
		{
		    REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
		    offx += dx;
		    offy += dy;
		}
		REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
				 &pWin->winSize);
	    }
	    /* get winSize back where it belongs */
	    if (offx || offy)
		REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
	}
	/*
	 * add screen bits to the appropriate bucket
	 */

	if (oldWinClip)
	{
	    /*
	     * clip to new clipList
	     */
	    REGION_COPY(pScreen, pRegion, oldWinClip);
	    REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
	    REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
	    /*
	     * don't step on any gravity bits which will be copied after this
	     * region.	Note -- this assumes that the regions will be copied
	     * in gravity order.
	     */
	    for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
	    {
		if (gravitate[g])
		    REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
					gravitate[g]);
	    }
	    REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
	    g = pWin->bitGravity;
	    if (!gravitate[g])
		gravitate[g] = oldWinClip;
	    else
	    {
		REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
		REGION_DESTROY(pScreen, oldWinClip);
	    }
	}

	/*
	 * move the bits on the screen
	 */

	destClip = NULL;

	for (g = 0; g <= StaticGravity; g++)
	{
	    if (!gravitate[g])
		continue;

	    GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);

	    oldpt.x = oldx + (x - nx);
	    oldpt.y = oldy + (y - ny);

	    /* Note that gravitate[g] is *translated* by CopyWindow */

	    /* only copy the remaining useful bits */

	    REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);

	    /* clip to not overwrite already copied areas */

	    if (destClip) {
		REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
		REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
		REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
	    }

	    /* and move those bits */

	    if (oldpt.x != x || oldpt.y != y
#ifdef COMPOSITE
		|| pWin->redirectDraw
#endif
		)
	    {
		(*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
	    }

	    /* remove any overwritten bits from the remaining useful bits */

	    REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);

	    /*
	     * recompute exposed regions of child windows
	     */
	
	    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
	    {
		if (pChild->winGravity != g)
		    continue;
		REGION_INTERSECT(pScreen, pRegion,
				       &pChild->borderClip, gravitate[g]);
		TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
	    }

	    /*
	     * remove the successfully copied regions of the
	     * window from its exposed region
	     */

	    if (g == pWin->bitGravity)
		REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
				     &pWin->valdata->after.exposed, gravitate[g]);
	    if (!destClip)
		destClip = gravitate[g];
	    else
	    {
		REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
		REGION_DESTROY(pScreen, gravitate[g]);
	    }
	}

	REGION_DESTROY(pScreen, oldRegion);
	REGION_DESTROY(pScreen, pRegion);
	if (destClip)
	    REGION_DESTROY(pScreen, destClip);
	if (anyMarked)
	    (*pScreen->HandleExposures)(pLayerWin->parent);
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
					  VTOther);
    }
    if (pWin->realized)
	WindowsRestructured ();
}
Exemple #8
0
void
miMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pNextSib, VTKind kind)
{
    WindowPtr pParent;
    Bool WasViewable = (Bool)(pWin->viewable);
    short bw;
    RegionPtr oldRegion = NULL;
    DDXPointRec oldpt;
    Bool anyMarked = FALSE;
    ScreenPtr pScreen;
    WindowPtr windowToValidate;
    WindowPtr pLayerWin;

    /* if this is a root window, can't be moved */
    if (!(pParent = pWin->parent))
       return ;
    pScreen = pWin->drawable.pScreen;
    bw = wBorderWidth (pWin);

    oldpt.x = pWin->drawable.x;
    oldpt.y = pWin->drawable.y;
    if (WasViewable)
    {
	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
	REGION_COPY(pScreen, oldRegion, &pWin->borderClip);
	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
    }
    pWin->origin.x = x + (int)bw;
    pWin->origin.y = y + (int)bw;
    x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
    y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;

    SetWinSize (pWin);
    SetBorderSize (pWin);

    (*pScreen->PositionWindow)(pWin, x, y);

    windowToValidate = MoveWindowInStack(pWin, pNextSib);

    ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);

    if (WasViewable)
    {
	if (pLayerWin == pWin)
	    anyMarked |= (*pScreen->MarkOverlappedWindows)
				(pWin, windowToValidate, NULL);
	else
	    anyMarked |= (*pScreen->MarkOverlappedWindows)
				(pWin, pLayerWin, NULL);


	if (anyMarked)
	{
	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
	    (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
	    REGION_DESTROY(pScreen, oldRegion);
	    /* XXX need to retile border if ParentRelative origin */
	    (*pScreen->HandleExposures)(pLayerWin->parent);
	}
	if (anyMarked && pScreen->PostValidateTree)
	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
    }
    if (pWin->realized)
	WindowsRestructured ();
}
LRESULT CALLBACK
winMWExtWMWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    WindowPtr pWin = NULL;
    win32RootlessWindowPtr pRLWinPriv = NULL;
    ScreenPtr pScreen = NULL;
    winPrivScreenPtr pScreenPriv = NULL;
    winScreenInfo *pScreenInfo = NULL;
    HWND hwndScreen = NULL;
    POINT ptMouse;
    static Bool s_fTracking = FALSE;
    HDC hdcUpdate;
    PAINTSTRUCT ps;
    LPWINDOWPOS pWinPos = NULL;
    RECT rcClient;
    winWMMessageRec wmMsg;
    Bool fWMMsgInitialized = FALSE;

    /* Check if the Windows window property for our X window pointer is valid */
    if ((pRLWinPriv =
         (win32RootlessWindowPtr) GetProp(hwnd, WIN_WINDOW_PROP)) != NULL) {
        pWin = pRLWinPriv->pFrame->win;
        pScreen = pWin->drawable.pScreen;
        if (pScreen)
            pScreenPriv = winGetScreenPriv(pScreen);
        if (pScreenPriv)
            pScreenInfo = pScreenPriv->pScreenInfo;
        if (pScreenPriv)
            hwndScreen = pScreenPriv->hwndScreen;

        wmMsg.msg = 0;
        wmMsg.hwndWindow = hwnd;
        wmMsg.iWindow = (Window) pWin->drawable.id;

        wmMsg.iX = pRLWinPriv->pFrame->x;
        wmMsg.iY = pRLWinPriv->pFrame->y;
        wmMsg.iWidth = pRLWinPriv->pFrame->width;
        wmMsg.iHeight = pRLWinPriv->pFrame->height;

        fWMMsgInitialized = TRUE;
#if CYGDEBUG
        winDebugWin32Message("winMWExtWMWindowProc", hwnd, message, wParam,
                             lParam);

        winDebug("\thWnd %08X\n", hwnd);
        winDebug("\tpScreenPriv %08X\n", pScreenPriv);
        winDebug("\tpScreenInfo %08X\n", pScreenInfo);
        winDebug("\thwndScreen %08X\n", hwndScreen);
        winDebug("winMWExtWMWindowProc (%08x) %08x %08x %08x\n",
                 pRLWinPriv, message, wParam, lParam);
#endif
    }
    /* Branch on message type */
    switch (message) {
    case WM_CREATE:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_CREATE\n");
#endif
        /* */
        SetProp(hwnd,
                WIN_WINDOW_PROP,
                (HANDLE) ((LPCREATESTRUCT) lParam)->lpCreateParams);
        return 0;

    case WM_CLOSE:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_CLOSE %d\n", pRLWinPriv->fClose);
#endif
        /* Tell window-manager to close window */
        if (pRLWinPriv->fClose) {
            DestroyWindow(hwnd);
        }
        else {
            if (winIsInternalWMRunning(pScreenInfo)) {
                /* Tell our Window Manager thread to kill the window */
                wmMsg.msg = WM_WM_KILL;
                if (fWMMsgInitialized)
                    winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
            }
            winWindowsWMSendEvent(WindowsWMControllerNotify,
                                  WindowsWMControllerNotifyMask,
                                  1,
                                  WindowsWMCloseWindow,
                                  pWin->drawable.id, 0, 0, 0, 0);
        }
        return 0;

    case WM_DESTROY:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_DESTROY\n");
#endif
        /* Free the shaodw DC; which allows the bitmap to be freed */
        DeleteDC(pRLWinPriv->hdcShadow);
        pRLWinPriv->hdcShadow = NULL;

        /* Free the shadow bitmap */
        DeleteObject(pRLWinPriv->hbmpShadow);
        pRLWinPriv->hbmpShadow = NULL;

        /* Free the screen DC */
        ReleaseDC(pRLWinPriv->hWnd, pRLWinPriv->hdcScreen);
        pRLWinPriv->hdcScreen = NULL;

        /* Free shadow buffer info header */
        free(pRLWinPriv->pbmihShadow);
        pRLWinPriv->pbmihShadow = NULL;

        pRLWinPriv->fResized = FALSE;
        pRLWinPriv->pfb = NULL;
        free(pRLWinPriv);
        RemoveProp(hwnd, WIN_WINDOW_PROP);
        break;

    case WM_MOUSEMOVE:
#if CYGMULTIWINDOW_DEBUG && 0
        winDebug("winMWExtWMWindowProc - WM_MOUSEMOVE\n");
#endif
        /* Unpack the client area mouse coordinates */
        ptMouse.x = GET_X_LPARAM(lParam);
        ptMouse.y = GET_Y_LPARAM(lParam);

        /* Translate the client area mouse coordinates to screen coordinates */
        ClientToScreen(hwnd, &ptMouse);

        /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
        ptMouse.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
        ptMouse.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);

        /* We can't do anything without privates */
        if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
            break;

        /* Has the mouse pointer crossed screens? */
        if (pScreen != miPointerGetScreen(inputInfo.pointer))
             miPointerSetScreen(inputInfo.pointer, pScreenInfo->dwScreen,
                                ptMouse.x - pScreenInfo->dwXOffset,
                                ptMouse.y - pScreenInfo->dwYOffset);

        /* Are we tracking yet? */
        if (!s_fTracking) {
            TRACKMOUSEEVENT tme;

            /* Setup data structure */
            ZeroMemory(&tme, sizeof(tme));
            tme.cbSize = sizeof(tme);
            tme.dwFlags = TME_LEAVE;
            tme.hwndTrack = hwnd;

            /* Call the tracking function */
            if (!TrackMouseEvent(&tme))
                ErrorF("winMWExtWMWindowProc - TrackMouseEvent failed\n");

            /* Flag that we are tracking now */
            s_fTracking = TRUE;
        }

        /* Kill the timer used to poll mouse events */
        if (g_uipMousePollingTimerID != 0) {
            KillTimer(pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID);
            g_uipMousePollingTimerID = 0;
        }

        /* Deliver absolute cursor position to X Server */
        winEnqueueMotion(ptMouse.x - pScreenInfo->dwXOffset,
                         ptMouse.y - pScreenInfo->dwYOffset);

        return 0;

    case WM_NCMOUSEMOVE:
#if CYGMULTIWINDOW_DEBUG && 0
        winDebug("winMWExtWMWindowProc - WM_NCMOUSEMOVE\n");
#endif
        /*
         * We break instead of returning 0 since we need to call
         * DefWindowProc to get the mouse cursor changes
         * and min/max/close button highlighting in Windows XP.
         * The Platform SDK says that you should return 0 if you
         * process this message, but it fails to mention that you
         * will give up any default functionality if you do return 0.
         */

        /* We can't do anything without privates */
        if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
            break;

        /*
         * Timer to poll mouse events.  This is needed to make
         * programs like xeyes follow the mouse properly.
         */
        if (g_uipMousePollingTimerID == 0)
            g_uipMousePollingTimerID = SetTimer(pScreenPriv->hwndScreen,
                                                WIN_POLLING_MOUSE_TIMER_ID,
                                                MOUSE_POLLING_INTERVAL, NULL);
        break;

    case WM_MOUSELEAVE:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_MOUSELEAVE\n");
#endif
        /* Mouse has left our client area */

        /* Flag that we are no longer tracking */
        s_fTracking = FALSE;

        /*
         * Timer to poll mouse events.  This is needed to make
         * programs like xeyes follow the mouse properly.
         */
        if (g_uipMousePollingTimerID == 0)
            g_uipMousePollingTimerID = SetTimer(pScreenPriv->hwndScreen,
                                                WIN_POLLING_MOUSE_TIMER_ID,
                                                MOUSE_POLLING_INTERVAL, NULL);
        return 0;

    case WM_LBUTTONDBLCLK:
    case WM_LBUTTONDOWN:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_LBUTTONDBLCLK\n");
#endif
        if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
            break;
        SetCapture(hwnd);
        return winMouseButtonsHandle(pScreen, ButtonPress, Button1, wParam);

    case WM_LBUTTONUP:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_LBUTTONUP\n");
#endif
        if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
            break;
        ReleaseCapture();
        return winMouseButtonsHandle(pScreen, ButtonRelease, Button1, wParam);

    case WM_MBUTTONDBLCLK:
    case WM_MBUTTONDOWN:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_MBUTTONDBLCLK\n");
#endif
        if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
            break;
        SetCapture(hwnd);
        return winMouseButtonsHandle(pScreen, ButtonPress, Button2, wParam);

    case WM_MBUTTONUP:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_MBUTTONUP\n");
#endif
        if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
            break;
        ReleaseCapture();
        return winMouseButtonsHandle(pScreen, ButtonRelease, Button2, wParam);

    case WM_RBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_RBUTTONDBLCLK\n");
#endif
        if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
            break;
        SetCapture(hwnd);
        return winMouseButtonsHandle(pScreen, ButtonPress, Button3, wParam);

    case WM_RBUTTONUP:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_RBUTTONUP\n");
#endif
        if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
            break;
        ReleaseCapture();
        return winMouseButtonsHandle(pScreen, ButtonRelease, Button3, wParam);

    case WM_XBUTTONDBLCLK:
    case WM_XBUTTONDOWN:
        if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
            break;
        SetCapture(hwnd);
        return winMouseButtonsHandle(pScreen, ButtonPress, HIWORD(wParam) + 5,
                                     wParam);
    case WM_XBUTTONUP:
        if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
            break;
        ReleaseCapture();
        return winMouseButtonsHandle(pScreen, ButtonRelease, HIWORD(wParam) + 5,
                                     wParam);

    case WM_MOUSEWHEEL:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_MOUSEWHEEL\n");
#endif

        /* Pass the message to the root window */
        SendMessage(hwndScreen, message, wParam, lParam);
        return 0;

    case WM_MOUSEACTIVATE:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_MOUSEACTIVATE\n");
#endif
#if 1
        /* Check if this window needs to be made active when clicked */
        if (winIsInternalWMRunning(pScreenInfo) && pWin->overrideRedirect) {
#if CYGMULTIWINDOW_DEBUG
            winDebug("winMWExtWMWindowProc - WM_MOUSEACTIVATE - "
                     "MA_NOACTIVATE\n");
#endif

            /* */
            return MA_NOACTIVATE;
        }
#endif
        if (!winIsInternalWMRunning(pScreenInfo) && !IsMouseActive(pWin))
            return MA_NOACTIVATE;

        break;

    case WM_KILLFOCUS:
        /* Pop any pressed keys since we are losing keyboard focus */
        winKeybdReleaseKeys();
        return 0;

    case WM_SYSDEADCHAR:
    case WM_DEADCHAR:
        /*
         * NOTE: We do nothing with WM_*CHAR messages,
         * nor does the root window, so we can just toss these messages.
         */
        return 0;

    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_*KEYDOWN\n");
#endif

        /*
         * Don't pass Alt-F4 key combo to root window,
         * let Windows translate to WM_CLOSE and close this top-level window.
         *
         * NOTE: We purposely don't check the fUseWinKillKey setting because
         * it should only apply to the key handling for the root window,
         * not for top-level window-manager windows.
         *
         * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
         * because that is a key combo that no X app should be expecting to
         * receive, since it has historically been used to shutdown the X server.
         * Passing Ctrl-Alt-Backspace to the root window preserves that
         * behavior, assuming that -unixkill has been passed as a parameter.
         */
        if (wParam == VK_F4 && (GetKeyState(VK_MENU) & 0x8000))
            break;

        /* Pass the message to the root window */
        SendMessage(hwndScreen, message, wParam, lParam);
        return 0;

    case WM_SYSKEYUP:
    case WM_KEYUP:

#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_*KEYUP\n");
#endif

        /* Pass the message to the root window */
        SendMessage(hwndScreen, message, wParam, lParam);
        return 0;

    case WM_HOTKEY:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_HOTKEY\n");
#endif

        /* Pass the message to the root window */
        SendMessage(hwndScreen, message, wParam, lParam);
        return 0;

    case WM_ERASEBKGND:
#if CYGDEBUG
        winDebug("winMWExtWMWindowProc - WM_ERASEBKGND\n");
#endif
        /*
         * Pretend that we did erase the background but we don't care,
         * since we repaint the entire region anyhow
         * This avoids some flickering when resizing.
         */
        return TRUE;

    case WM_PAINT:

        /* BeginPaint gives us an hdc that clips to the invalidated region */
        hdcUpdate = BeginPaint(hwnd, &ps);

        /* Try to copy from the shadow buffer */
        if (!BitBlt(hdcUpdate,
                    ps.rcPaint.left, ps.rcPaint.top,
                    ps.rcPaint.right - ps.rcPaint.left,
                    ps.rcPaint.bottom - ps.rcPaint.top,
                    pRLWinPriv->hdcShadow,
                    ps.rcPaint.left, ps.rcPaint.top, SRCCOPY)) {
            LPVOID lpMsgBuf;

            /* Display a fancy error message */
            FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                          FORMAT_MESSAGE_FROM_SYSTEM |
                          FORMAT_MESSAGE_IGNORE_INSERTS,
                          NULL,
                          GetLastError(),
                          MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                          (LPTSTR) &lpMsgBuf, 0, NULL);

            ErrorF("winMWExtWMWindowProc - BitBlt failed: %s\n",
                   (LPSTR) lpMsgBuf);
            LocalFree(lpMsgBuf);
        }

        /* EndPaint frees the DC */
        EndPaint(hwnd, &ps);
        break;

    case WM_ACTIVATE:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_ACTIVATE\n");
#endif
        if (LOWORD(wParam) != WA_INACTIVE) {
            if (winIsInternalWMRunning(pScreenInfo)) {
#if 0
                /* Raise the window to the top in Z order */
                wmMsg.msg = WM_WM_RAISE;
                if (fWMMsgInitialized)
                    winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
#endif
                /* Tell our Window Manager thread to activate the window */
                wmMsg.msg = WM_WM_ACTIVATE;
                if (fWMMsgInitialized)
                    if (!pWin || !pWin->overrideRedirect)       /* for OOo menus */
                        winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
            }
            winWindowsWMSendEvent(WindowsWMControllerNotify,
                                  WindowsWMControllerNotifyMask,
                                  1,
                                  WindowsWMActivateWindow,
                                  pWin->drawable.id, 0, 0, 0, 0);
        }
        return 0;

#if 1
    case WM_WINDOWPOSCHANGING:
        pWinPos = (LPWINDOWPOS) lParam;
        if (!(pWinPos->flags & SWP_NOZORDER)) {
            if (pRLWinPriv->fRestackingNow || pScreenPriv->fRestacking) {
#if CYGMULTIWINDOW_DEBUG
                winDebug("Win %08x is now restacking.\n",
                         (unsigned int) pRLWinPriv);
#endif
                break;
            }

            if (winIsInternalWMRunning(pScreenInfo) || IsRaiseOnClick(pWin)) {
#if CYGMULTIWINDOW_DEBUG
                winDebug("Win %08x has WINDOWSWM_RAISE_ON_CLICK.\n",
                         (unsigned int) pRLWinPriv);
#endif
                break;
            }

#if CYGMULTIWINDOW_DEBUG
            winDebug("Win %08x forbid to change z order (%08x).\n",
                     (unsigned int) pRLWinPriv,
                     (unsigned int) pWinPos->hwndInsertAfter);
#endif
            pWinPos->flags |= SWP_NOZORDER;
        }
        break;
#endif

    case WM_MOVE:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_MOVE - %d ms\n",
                 (unsigned int) GetTickCount());
#endif
        if (g_fNoConfigureWindow)
            break;
#if 0
        /* Bail if Windows window is not actually moving */
        if (pRLWinPriv->dwX == (short) LOWORD(lParam)
            && pRLWinPriv->dwY == (short) HIWORD(lParam))
            break;

        /* Also bail if we're maximizing, we'll do the whole thing in WM_SIZE */
        {
            WINDOWPLACEMENT windPlace;

            windPlace.length = sizeof(WINDOWPLACEMENT);

            /* Get current window placement */
            GetWindowPlacement(hwnd, &windPlace);

            /* Bail if maximizing */
            if (windPlace.showCmd == SW_MAXIMIZE
                || windPlace.showCmd == SW_SHOWMAXIMIZED)
                break;
        }
#endif

#if CYGMULTIWINDOW_DEBUG
        winDebug("\t(%d, %d)\n", (short) LOWORD(lParam),
                 (short) HIWORD(lParam));
#endif
        if (!pRLWinPriv->fMovingOrSizing) {
            if (winIsInternalWMRunning(pScreenInfo))
                winAdjustXWindow(pWin, hwnd);

            winMWExtWMMoveXWindow(pWin, (LOWORD(lParam) - wBorderWidth(pWin)
                                         - GetSystemMetrics(SM_XVIRTUALSCREEN)),
                                  (HIWORD(lParam) - wBorderWidth(pWin)
                                   - GetSystemMetrics(SM_YVIRTUALSCREEN)));
        }
        return 0;

    case WM_SHOWWINDOW:
#if CYGMULTIWINDOW_DEBUG || TRUE
        winDebug("winMWExtWMWindowProc - WM_SHOWWINDOW - %d ms\n",
                 (unsigned int) GetTickCount());
#endif
        /* Bail out if the window is being hidden */
        if (!wParam)
            return 0;

        if (!pScreenInfo->fInternalWM)  //XXXX
            return 0;

        winMWExtWMUpdateWindowDecoration(pRLWinPriv, pScreenInfo);

        if (winIsInternalWMRunning(pScreenInfo)) {
#if CYGMULTIWINDOW_DEBUG || TRUE
            winDebug("\tMapWindow\n");
#endif
            /* Tell X to map the window */
            MapWindow(pWin, wClient(pWin));

            if (!pRLWinPriv->pFrame->win->overrideRedirect)
                /* Bring the Windows window to the foreground */
                SetForegroundWindow(hwnd);

            /* Setup the Window Manager message */
            wmMsg.msg = WM_WM_MAP;
            wmMsg.iWidth = pRLWinPriv->pFrame->width;
            wmMsg.iHeight = pRLWinPriv->pFrame->height;

            /* Tell our Window Manager thread to map the window */
            if (fWMMsgInitialized)
                winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
        }
        break;

    case WM_SIZING:
        /* Need to legalize the size according to WM_NORMAL_HINTS */
        /* for applications like xterm */
        return ValidateSizing(hwnd, pWin, wParam, lParam);

    case WM_WINDOWPOSCHANGED:
    {
        pWinPos = (LPWINDOWPOS) lParam;
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED\n");
        winDebug("\tflags: %s%s%s%s%s%s%s%s%s%s%s%s\n",
                 (pWinPos->flags & SWP_DRAWFRAME) ? "SWP_DRAWFRAME " : "",
                 (pWinPos->flags & SWP_FRAMECHANGED) ? "SWP_FRAMECHANGED " : "",
                 (pWinPos->flags & SWP_HIDEWINDOW) ? "SWP_HIDEWINDOW " : "",
                 (pWinPos->flags & SWP_NOACTIVATE) ? "SWP_NOACTIVATE " : "",
                 (pWinPos->flags & SWP_NOCOPYBITS) ? "SWP_NOCOPYBITS " : "",
                 (pWinPos->flags & SWP_NOMOVE) ? "SWP_NOMOVE " : "",
                 (pWinPos->
                  flags & SWP_NOOWNERZORDER) ? "SWP_NOOWNERZORDER " : "",
                 (pWinPos->flags & SWP_NOSIZE) ? "SWP_NOSIZE " : "",
                 (pWinPos->flags & SWP_NOREDRAW) ? "SWP_NOREDRAW " : "",
                 (pWinPos->
                  flags & SWP_NOSENDCHANGING) ? "SWP_NOSENDCHANGING " : "",
                 (pWinPos->flags & SWP_NOZORDER) ? "SWP_NOZORDER " : "",
                 (pWinPos->flags & SWP_SHOWWINDOW) ? "SWP_SHOWWINDOW " : "");
        winDebug("\tno_configure: %s\n", (g_fNoConfigureWindow ? "Yes" : "No"));
        winDebug("\textend: (%d, %d, %d, %d)\n",
                 pWinPos->x, pWinPos->y, pWinPos->cx, pWinPos->cy);

#endif
        if (pWinPos->flags & SWP_HIDEWINDOW)
            break;

        /* Reorder if window z order was changed */
        if ((pScreenPriv != NULL)
            && !(pWinPos->flags & SWP_NOZORDER)
            && !(pWinPos->flags & SWP_SHOWWINDOW)
            && winIsInternalWMRunning(pScreenInfo)) {
#if CYGMULTIWINDOW_DEBUG
            winDebug("\twindow z order was changed\n");
#endif
            if (pWinPos->hwndInsertAfter == HWND_TOP
                || pWinPos->hwndInsertAfter == HWND_TOPMOST
                || pWinPos->hwndInsertAfter == HWND_NOTOPMOST) {
#if CYGMULTIWINDOW_DEBUG
                winDebug("\traise to top\n");
#endif
                /* Raise the window to the top in Z order */
                wmMsg.msg = WM_WM_RAISE;
                if (fWMMsgInitialized)
                    winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
            }
#if 1
            else if (pWinPos->hwndInsertAfter == HWND_BOTTOM) {
            }
            else {
                /* Check if this window is top of X windows. */
                HWND hWndAbove = NULL;
                DWORD dwCurrentProcessID = GetCurrentProcessId();
                DWORD dwWindowProcessID = 0;

                for (hWndAbove = pWinPos->hwndInsertAfter;
                     hWndAbove != NULL;
                     hWndAbove = GetNextWindow(hWndAbove, GW_HWNDPREV)) {
                    /* Ignore other XWin process's window */
                    GetWindowThreadProcessId(hWndAbove, &dwWindowProcessID);

                    if ((dwWindowProcessID == dwCurrentProcessID)
                        && GetProp(hWndAbove, WIN_WINDOW_PROP)
                        && !IsWindowVisible(hWndAbove)
                        && !IsIconic(hWndAbove))        /* ignore minimized windows */
                        break;
                }
                /* If this is top of X windows in Windows stack,
                   raise it in X stack. */
                if (hWndAbove == NULL) {
#if CYGMULTIWINDOW_DEBUG
                    winDebug("\traise to top\n");
#endif
                    /* Raise the window to the top in Z order */
                    wmMsg.msg = WM_WM_RAISE;
                    if (fWMMsgInitialized)
                        winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
                }
            }
#endif
        }

        if (!(pWinPos->flags & SWP_NOSIZE)) {
            if (IsIconic(hwnd)) {
#if CYGMULTIWINDOW_DEBUG
                winDebug("\tIconic -> MINIMIZED\n");
#endif
                if (winIsInternalWMRunning(pScreenInfo)) {
                    /* Raise the window to the top in Z order */
                    wmMsg.msg = WM_WM_LOWER;
                    if (fWMMsgInitialized)
                        winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
                }
                winWindowsWMSendEvent(WindowsWMControllerNotify,
                                      WindowsWMControllerNotifyMask,
                                      1,
                                      WindowsWMMinimizeWindow,
                                      pWin->drawable.id, 0, 0, 0, 0);
            }
            else if (IsZoomed(hwnd)) {
#if CYGMULTIWINDOW_DEBUG
                winDebug("\tZoomed -> MAXIMIZED\n");
#endif
                winWindowsWMSendEvent(WindowsWMControllerNotify,
                                      WindowsWMControllerNotifyMask,
                                      1,
                                      WindowsWMMaximizeWindow,
                                      pWin->drawable.id, 0, 0, 0, 0);
            }
            else {
#if CYGMULTIWINDOW_DEBUG
                winDebug("\tnone -> RESTORED\n");
#endif
                winWindowsWMSendEvent(WindowsWMControllerNotify,
                                      WindowsWMControllerNotifyMask,
                                      1,
                                      WindowsWMRestoreWindow,
                                      pWin->drawable.id, 0, 0, 0, 0);
            }
        }
        if (!g_fNoConfigureWindow) {

            if (!pRLWinPriv->fMovingOrSizing
                /*&& (pWinPos->flags & SWP_SHOWWINDOW) */ ) {
                GetClientRect(hwnd, &rcClient);
                MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT) &rcClient, 2);

                if (!(pWinPos->flags & SWP_NOMOVE)
                    && !(pWinPos->flags & SWP_NOSIZE)) {
#if CYGMULTIWINDOW_DEBUG
                    winDebug("\tmove & resize\n");
#endif
                    if (winIsInternalWMRunning(pScreenInfo))
                        winAdjustXWindow(pWin, hwnd);

                    winMWExtWMMoveResizeXWindow(pWin,
                                                rcClient.left -
                                                wBorderWidth(pWin)
                                                -
                                                GetSystemMetrics
                                                (SM_XVIRTUALSCREEN),
                                                rcClient.top -
                                                wBorderWidth(pWin)
                                                -
                                                GetSystemMetrics
                                                (SM_YVIRTUALSCREEN),
                                                rcClient.right - rcClient.left -
                                                wBorderWidth(pWin) * 2,
                                                rcClient.bottom - rcClient.top -
                                                wBorderWidth(pWin) * 2);
                }
                else if (!(pWinPos->flags & SWP_NOMOVE)) {
#if CYGMULTIWINDOW_DEBUG
                    winDebug("\tmove\n");
#endif
                    if (winIsInternalWMRunning(pScreenInfo))
                        winAdjustXWindow(pWin, hwnd);

                    winMWExtWMMoveResizeXWindow(pWin,
                                                rcClient.left -
                                                wBorderWidth(pWin)
                                                -
                                                GetSystemMetrics
                                                (SM_XVIRTUALSCREEN),
                                                rcClient.top -
                                                wBorderWidth(pWin)
                                                -
                                                GetSystemMetrics
                                                (SM_YVIRTUALSCREEN),
                                                rcClient.right - rcClient.left -
                                                wBorderWidth(pWin) * 2,
                                                rcClient.bottom - rcClient.top -
                                                wBorderWidth(pWin) * 2);
                }
                else if (!(pWinPos->flags & SWP_NOMOVE)) {
#if CYGMULTIWINDOW_DEBUG
                    winDebug("\tmove\n");
#endif
                    if (winIsInternalWMRunning(pScreenInfo))
                        winAdjustXWindow(pWin, hwnd);

                    winMWExtWMMoveXWindow(pWin,
                                          rcClient.left - wBorderWidth(pWin)
                                          - GetSystemMetrics(SM_XVIRTUALSCREEN),
                                          rcClient.top - wBorderWidth(pWin)
                                          -
                                          GetSystemMetrics(SM_YVIRTUALSCREEN));
                }
                else if (!(pWinPos->flags & SWP_NOSIZE)) {
#if CYGMULTIWINDOW_DEBUG
                    winDebug("\tresize\n");
#endif
                    if (winIsInternalWMRunning(pScreenInfo))
                        winAdjustXWindow(pWin, hwnd);

                    winMWExtWMResizeXWindow(pWin,
                                            rcClient.right - rcClient.left
                                            - wBorderWidth(pWin) * 2,
                                            rcClient.bottom - rcClient.top
                                            - wBorderWidth(pWin) * 2);
                }
            }
        }
    }
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED - done.\n");
#endif
        return 0;

    case WM_SIZE:
        /* see dix/window.c */
        /* FIXME: Maximize/Restore? */
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_SIZE - %d ms\n",
                 (unsigned int) GetTickCount());
#endif
#if CYGMULTIWINDOW_DEBUG
        winDebug("\t(%d, %d) %d\n", (short) LOWORD(lParam),
                 (short) HIWORD(lParam), g_fNoConfigureWindow);
#endif
        if (g_fNoConfigureWindow)
            break;

        /* Branch on type of resizing occurring */
        switch (wParam) {
        case SIZE_MINIMIZED:
#if CYGMULTIWINDOW_DEBUG
            winDebug("\tSIZE_MINIMIZED\n");
#endif
            if (winIsInternalWMRunning(pScreenInfo)) {
                /* Raise the window to the top in Z order */
                wmMsg.msg = WM_WM_LOWER;
                if (fWMMsgInitialized)
                    winSendMessageToWM(pScreenPriv->pWMInfo, &wmMsg);
            }
            winWindowsWMSendEvent(WindowsWMControllerNotify,
                                  WindowsWMControllerNotifyMask,
                                  1,
                                  WindowsWMMinimizeWindow,
                                  pWin->drawable.id,
                                  0, 0, LOWORD(lParam), HIWORD(lParam));
            break;

        case SIZE_RESTORED:
#if CYGMULTIWINDOW_DEBUG
            winDebug("\tSIZE_RESTORED\n");
#endif
            winWindowsWMSendEvent(WindowsWMControllerNotify,
                                  WindowsWMControllerNotifyMask,
                                  1,
                                  WindowsWMRestoreWindow,
                                  pWin->drawable.id,
                                  0, 0, LOWORD(lParam), HIWORD(lParam));
            break;

        case SIZE_MAXIMIZED:
#if CYGMULTIWINDOW_DEBUG
            winDebug("\tSIZE_MAXIMIZED\n");
#endif
            winWindowsWMSendEvent(WindowsWMControllerNotify,
                                  WindowsWMControllerNotifyMask,
                                  1,
                                  WindowsWMMaximizeWindow,
                                  pWin->drawable.id,
                                  0, 0, LOWORD(lParam), HIWORD(lParam));
            break;
        }

        /* Perform the resize and notify the X client */
        if (!pRLWinPriv->fMovingOrSizing) {
            if (winIsInternalWMRunning(pScreenInfo))
                winAdjustXWindow(pWin, hwnd);

            winMWExtWMResizeXWindow(pWin, (short) LOWORD(lParam)
                                    - wBorderWidth(pWin) * 2,
                                    (short) HIWORD(lParam)
                                    - wBorderWidth(pWin) * 2);
        }
        break;

    case WM_ACTIVATEAPP:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_ACTIVATEAPP - %d ms\n",
                 (unsigned int) GetTickCount());
#endif
        if (wParam) {
            if (winIsInternalWMRunning(pScreenInfo)) {
            }
            else {
            }
            winWindowsWMSendEvent(WindowsWMActivationNotify,
                                  WindowsWMActivationNotifyMask,
                                  1,
                                  WindowsWMIsActive,
                                  pWin->drawable.id, 0, 0, 0, 0);
        }
        else {
            winWindowsWMSendEvent(WindowsWMActivationNotify,
                                  WindowsWMActivationNotifyMask,
                                  1,
                                  WindowsWMIsInactive,
                                  pWin->drawable.id, 0, 0, 0, 0);
        }
        break;

    case WM_SETCURSOR:
        if (LOWORD(lParam) == HTCLIENT) {
            if (!g_fSoftwareCursor)
                SetCursor(pScreenPriv->cursor.handle);
            return TRUE;
        }
        break;

    case WM_ENTERSIZEMOVE:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_ENTERSIZEMOVE - %d ms\n",
                 (unsigned int) GetTickCount());
#endif
        pRLWinPriv->fMovingOrSizing = TRUE;
        break;

    case WM_EXITSIZEMOVE:
#if CYGMULTIWINDOW_DEBUG
        winDebug("winMWExtWMWindowProc - WM_EXITSIZEMOVE - %d ms\n",
                 (unsigned int) GetTickCount());
#endif
        pRLWinPriv->fMovingOrSizing = FALSE;

        GetClientRect(hwnd, &rcClient);

        MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT) &rcClient, 2);

        if (winIsInternalWMRunning(pScreenInfo))
            winAdjustXWindow(pWin, hwnd);

        winMWExtWMMoveResizeXWindow(pWin, rcClient.left - wBorderWidth(pWin)
                                    - GetSystemMetrics(SM_XVIRTUALSCREEN),
                                    rcClient.top - wBorderWidth(pWin)
                                    - GetSystemMetrics(SM_YVIRTUALSCREEN),
                                    rcClient.right - rcClient.left
                                    - wBorderWidth(pWin) * 2,
                                    rcClient.bottom - rcClient.top
                                    - wBorderWidth(pWin) * 2);
        break;

    case WM_MANAGE:
        ErrorF("winMWExtWMWindowProc - WM_MANAGE\n");
        break;

    case WM_UNMANAGE:
        ErrorF("winMWExtWMWindowProc - WM_UNMANAGE\n");
        break;

    default:
        break;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}
/*
 * winAdjustXWindow
 *
 * Move and resize X window with respect to corresponding Windows window.
 * This is called from WM_MOVE/WM_SIZE handlers when the user performs
 * any windowing operation (move, resize, minimize, maximize, restore).
 *
 * The functionality is the inverse of winPositionWindowMultiWindow, which
 * adjusts Windows window with respect to X window.
 */
int
winAdjustXWindow (WindowPtr pWin, HWND hwnd)
{
  RECT rcDraw; /* Rect made from pWin->drawable to be adjusted */
  RECT rcWin;  /* The source: WindowRect from hwnd */
  DrawablePtr pDraw;
  XID vlist[4];
  LONG dX, dY, dW, dH, x, y;
  DWORD dwStyle, dwExStyle;

#define WIDTH(rc) (rc.right - rc.left)
#define HEIGHT(rc) (rc.bottom - rc.top)
  
#if CYGWINDOWING_DEBUG
  ErrorF ("winAdjustXWindow\n");
#endif

  if (IsIconic (hwnd))
    {
#if CYGWINDOWING_DEBUG
      ErrorF ("\timmediately return because the window is iconized\n");
#endif
      /*
       * If the Windows window is minimized, its WindowRect has
       * meaningless values so we don't adjust X window to it.
       */
      vlist[0] = 0;
      vlist[1] = 0;
      return ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin));
    }
  
  pDraw = &pWin->drawable;

  /* Calculate the window rect from the drawable */
  x = pDraw->x + GetSystemMetrics (SM_XVIRTUALSCREEN);
  y = pDraw->y + GetSystemMetrics (SM_YVIRTUALSCREEN);
  SetRect (&rcDraw, x, y, x + pDraw->width, y + pDraw->height);
#ifdef CYGMULTIWINDOW_DEBUG
          winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n", 
              rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
              rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
#endif
  dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE);
  dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE);
#ifdef CYGMULTIWINDOW_DEBUG
          winDebug("\tWindowStyle: %08x %08x\n", dwStyle, dwExStyle);
#endif
  AdjustWindowRectEx (&rcDraw, dwStyle, FALSE, dwExStyle);

  /* The source of adjust */
  GetWindowRect (hwnd, &rcWin);
#ifdef CYGMULTIWINDOW_DEBUG
          winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n", 
              rcWin.left, rcWin.top, rcWin.right, rcWin.bottom,
              rcWin.right - rcWin.left, rcWin.bottom - rcWin.top);
          winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n", 
              rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
              rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
#endif

  if (EqualRect (&rcDraw, &rcWin)) {
    /* Bail if no adjust is needed */
#if CYGWINDOWING_DEBUG
    ErrorF ("\treturn because already adjusted\n");
#endif
    return 0;
  }
  
  /* Calculate delta values */
  dX = rcWin.left - rcDraw.left;
  dY = rcWin.top - rcDraw.top;
  dW = WIDTH(rcWin) - WIDTH(rcDraw);
  dH = HEIGHT(rcWin) - HEIGHT(rcDraw);

  /*
   * Adjust.
   * We may only need to move (vlist[0] and [1]), or only resize
   * ([2] and [3]) but currently we set all the parameters and leave
   * the decision to ConfigureWindow.  The reason is code simplicity.
  */
  vlist[0] = pDraw->x + dX - wBorderWidth(pWin);
  vlist[1] = pDraw->y + dY - wBorderWidth(pWin);
  vlist[2] = pDraw->width + dW;
  vlist[3] = pDraw->height + dH;
#if CYGWINDOWING_DEBUG
  ErrorF ("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist[0], vlist[1],
	  vlist[2], vlist[3]);
#endif
  return ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight,
			  vlist, wClient(pWin));
  
#undef WIDTH
#undef HEIGHT
}
Exemple #11
0
static int
ProcShapeGetRectangles(ClientPtr client)
{
    REQUEST(xShapeGetRectanglesReq);
    WindowPtr pWin;
    xShapeGetRectanglesReply rep;
    xRectangle *rects;
    int nrects, i, rc;
    RegionPtr region;

    REQUEST_SIZE_MATCH(xShapeGetRectanglesReq);
    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
    if (rc != Success)
        return rc;
    switch (stuff->kind) {
    case ShapeBounding:
        region = wBoundingShape(pWin);
        break;
    case ShapeClip:
        region = wClipShape(pWin);
        break;
    case ShapeInput:
        region = wInputShape(pWin);
        break;
    default:
        client->errorValue = stuff->kind;
        return BadValue;
    }
    if (!region) {
        nrects = 1;
        rects = malloc(sizeof(xRectangle));
        if (!rects)
            return BadAlloc;
        switch (stuff->kind) {
        case ShapeBounding:
            rects->x = -(int) wBorderWidth(pWin);
            rects->y = -(int) wBorderWidth(pWin);
            rects->width = pWin->drawable.width + wBorderWidth(pWin);
            rects->height = pWin->drawable.height + wBorderWidth(pWin);
            break;
        case ShapeClip:
            rects->x = 0;
            rects->y = 0;
            rects->width = pWin->drawable.width;
            rects->height = pWin->drawable.height;
            break;
        case ShapeInput:
            rects->x = -(int) wBorderWidth(pWin);
            rects->y = -(int) wBorderWidth(pWin);
            rects->width = pWin->drawable.width + wBorderWidth(pWin);
            rects->height = pWin->drawable.height + wBorderWidth(pWin);
            break;
        }
    }
    else {
        BoxPtr box;

        nrects = RegionNumRects(region);
        box = RegionRects(region);
        rects = malloc(nrects * sizeof(xRectangle));
        if (!rects && nrects)
            return BadAlloc;
        for (i = 0; i < nrects; i++, box++) {
            rects[i].x = box->x1;
            rects[i].y = box->y1;
            rects[i].width = box->x2 - box->x1;
            rects[i].height = box->y2 - box->y1;
        }
    }
    rep.type = X_Reply;
    rep.sequenceNumber = client->sequence;
    rep.length = bytes_to_int32(nrects * sizeof(xRectangle));
    rep.ordering = YXBanded;
    rep.nrects = nrects;
    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swapl(&rep.nrects);
        SwapShorts((short *) rects, (unsigned long) nrects * 4);
    }
    WriteToClient(client, sizeof(rep), (char *) &rep);
    WriteToClient(client, nrects * sizeof(xRectangle), (char *) rects);
    free(rects);
    return Success;
}
Exemple #12
0
void
SendShapeNotify(WindowPtr pWin, int which)
{
    ShapeEventPtr *pHead, pShapeEvent;
    xShapeNotifyEvent se;
    BoxRec extents;
    RegionPtr region;
    BYTE shaped;
    int rc;

    rc = dixLookupResourceByType((pointer *) &pHead, pWin->drawable.id,
                                 ShapeEventType, serverClient, DixReadAccess);
    if (rc != Success)
        return;
    switch (which) {
    case ShapeBounding:
        region = wBoundingShape(pWin);
        if (region) {
            extents = *RegionExtents(region);
            shaped = xTrue;
        }
        else {
            extents.x1 = -wBorderWidth(pWin);
            extents.y1 = -wBorderWidth(pWin);
            extents.x2 = pWin->drawable.width + wBorderWidth(pWin);
            extents.y2 = pWin->drawable.height + wBorderWidth(pWin);
            shaped = xFalse;
        }
        break;
    case ShapeClip:
        region = wClipShape(pWin);
        if (region) {
            extents = *RegionExtents(region);
            shaped = xTrue;
        }
        else {
            extents.x1 = 0;
            extents.y1 = 0;
            extents.x2 = pWin->drawable.width;
            extents.y2 = pWin->drawable.height;
            shaped = xFalse;
        }
        break;
    case ShapeInput:
        region = wInputShape(pWin);
        if (region) {
            extents = *RegionExtents(region);
            shaped = xTrue;
        }
        else {
            extents.x1 = -wBorderWidth(pWin);
            extents.y1 = -wBorderWidth(pWin);
            extents.x2 = pWin->drawable.width + wBorderWidth(pWin);
            extents.y2 = pWin->drawable.height + wBorderWidth(pWin);
            shaped = xFalse;
        }
        break;
    default:
        return;
    }
    for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
        se.type = ShapeNotify + ShapeEventBase;
        se.kind = which;
        se.window = pWin->drawable.id;
        se.x = extents.x1;
        se.y = extents.y1;
        se.width = extents.x2 - extents.x1;
        se.height = extents.y2 - extents.y1;
        se.time = currentTime.milliseconds;
        se.shaped = shaped;
        WriteEventsToClient(pShapeEvent->client, 1, (xEvent *) &se);
    }
}
Exemple #13
0
static int
ProcShapeQueryExtents(ClientPtr client)
{
    REQUEST(xShapeQueryExtentsReq);
    WindowPtr pWin;
    xShapeQueryExtentsReply rep;
    BoxRec extents, *pExtents;
    int rc;
    RegionPtr region;

    REQUEST_SIZE_MATCH(xShapeQueryExtentsReq);
    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
    if (rc != Success)
        return rc;
    memset(&rep, 0, sizeof(xShapeQueryExtentsReply));
    rep.type = X_Reply;
    rep.length = 0;
    rep.sequenceNumber = client->sequence;
    rep.boundingShaped = (wBoundingShape(pWin) != 0);
    rep.clipShaped = (wClipShape(pWin) != 0);
    if ((region = wBoundingShape(pWin))) {
        /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
        pExtents = RegionExtents(region);
        extents = *pExtents;
    }
    else {
        extents.x1 = -wBorderWidth(pWin);
        extents.y1 = -wBorderWidth(pWin);
        extents.x2 = pWin->drawable.width + wBorderWidth(pWin);
        extents.y2 = pWin->drawable.height + wBorderWidth(pWin);
    }
    rep.xBoundingShape = extents.x1;
    rep.yBoundingShape = extents.y1;
    rep.widthBoundingShape = extents.x2 - extents.x1;
    rep.heightBoundingShape = extents.y2 - extents.y1;
    if ((region = wClipShape(pWin))) {
        /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
        pExtents = RegionExtents(region);
        extents = *pExtents;
    }
    else {
        extents.x1 = 0;
        extents.y1 = 0;
        extents.x2 = pWin->drawable.width;
        extents.y2 = pWin->drawable.height;
    }
    rep.xClipShape = extents.x1;
    rep.yClipShape = extents.y1;
    rep.widthClipShape = extents.x2 - extents.x1;
    rep.heightClipShape = extents.y2 - extents.y1;
    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swaps(&rep.xBoundingShape);
        swaps(&rep.yBoundingShape);
        swaps(&rep.widthBoundingShape);
        swaps(&rep.heightBoundingShape);
        swaps(&rep.xClipShape);
        swaps(&rep.yClipShape);
        swaps(&rep.widthClipShape);
        swaps(&rep.heightClipShape);
    }
    WriteToClient(client, sizeof(xShapeQueryExtentsReply), (char *) &rep);
    return Success;
}
LRESULT CALLBACK
winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    POINT ptMouse;
    HDC hdcUpdate;
    PAINTSTRUCT ps;
    WindowPtr pWin = NULL;
    winPrivWinPtr pWinPriv = NULL;
    ScreenPtr s_pScreen = NULL;
    winPrivScreenPtr s_pScreenPriv = NULL;
    winScreenInfo *s_pScreenInfo = NULL;
    HWND hwndScreen = NULL;
    DrawablePtr pDraw = NULL;
    winWMMessageRec wmMsg;
    Bool fWMMsgInitialized = FALSE;
    static Bool s_fTracking = FALSE;
    Bool needRestack = FALSE;
    LRESULT ret;
    static Bool	hasEnteredSizeMove = FALSE;

    winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam,
                         lParam);

    /* Check if the Windows window property for our X window pointer is valid */
    if ((pWin = GetProp(hwnd, WIN_WINDOW_PROP)) != NULL) {
        /* Our X window pointer is valid */

        /* Get pointers to the drawable and the screen */
        pDraw = &pWin->drawable;
        s_pScreen = pWin->drawable.pScreen;

        /* Get a pointer to our window privates */
        pWinPriv = winGetWindowPriv(pWin);

        /* Get pointers to our screen privates and screen info */
        s_pScreenPriv = pWinPriv->pScreenPriv;
        s_pScreenInfo = s_pScreenPriv->pScreenInfo;

        /* Get the handle for our screen-sized window */
        hwndScreen = s_pScreenPriv->hwndScreen;

        /* */
        wmMsg.msg = 0;
        wmMsg.hwndWindow = hwnd;
        wmMsg.iWindow = (Window) GetProp(hwnd, WIN_WID_PROP);

        wmMsg.iX = pDraw->x;
        wmMsg.iY = pDraw->y;
        wmMsg.iWidth = pDraw->width;
        wmMsg.iHeight = pDraw->height;

        fWMMsgInitialized = TRUE;

    }
#ifdef _DEBUG
    else if (message!=WM_CREATE)
    {
        winDebug("Warning: message 0x%x received when WIN_WINDOW_PROP NULL\n",message);
    }
#endif

    /* Branch on message type */
    switch (message) {
    case WM_CREATE:

        /* */
        SetProp(hwnd,
                WIN_WINDOW_PROP,
                (HANDLE) ((LPCREATESTRUCT) lParam)->lpCreateParams);

        /* */
        SetProp(hwnd,
                WIN_WID_PROP,
                (HANDLE) winGetWindowID(((LPCREATESTRUCT) lParam)->
                                        lpCreateParams));

        /*
         * Make X windows' Z orders sync with Windows windows because
         * there can be AlwaysOnTop windows overlapped on the window
         * currently being created.
         */
        winReorderWindowsMultiWindow();

        /* Fix a 'round title bar corner background should be transparent not black' problem when first painted */
        {
            RECT rWindow;
            HRGN hRgnWindow;

            GetWindowRect(hwnd, &rWindow);
            hRgnWindow = CreateRectRgnIndirect(&rWindow);
            SetWindowRgn(hwnd, hRgnWindow, TRUE);
        }

        SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)VCXSRV_SIGNATURE);

        return 0;

    case WM_INIT_SYS_MENU:
        /*
         * Add whatever the setup file wants to for this window
         */
        SetupSysMenu((unsigned long) hwnd);
        return 0;

    case WM_SYSCOMMAND:
        /*
         * Any window menu items go through here
         */
        if (HandleCustomWM_COMMAND((unsigned long) hwnd, LOWORD(wParam))) {
            /* Don't pass customized menus to DefWindowProc */
            return 0;
        }
        if (wParam == SC_RESTORE || wParam == SC_MAXIMIZE) {
            WINDOWPLACEMENT wndpl;

            wndpl.length = sizeof(wndpl);
            if (GetWindowPlacement(hwnd, &wndpl) &&
                    wndpl.showCmd == SW_SHOWMINIMIZED)
                needRestack = TRUE;
        }
        break;

    case WM_INITMENU:
        /* Checks/Unchecks any menu items before they are displayed */
        HandleCustomWM_INITMENU((unsigned long) hwnd, wParam);
        break;

    case WM_ERASEBKGND:
        /*
         * Pretend that we did erase the background but we don't care,
         * since we repaint the entire region anyhow
         * This avoids some flickering when resizing.
         */
        return TRUE;

    case WM_PAINT:
        /* Only paint if our window handle is valid */
        if (hwndScreen == NULL)
            break;

        /* BeginPaint gives us an hdc that clips to the invalidated region */
        hdcUpdate = BeginPaint(hwnd, &ps);
        /* Avoid the BitBlt's if the PAINTSTRUCT is bogus */
        if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 &&
                ps.rcPaint.left == 0 && ps.rcPaint.top == 0) {
            EndPaint(hwnd, &ps);
            return 0;
        }

#ifdef XWIN_GLX_WINDOWS
        if (pWinPriv->fWglUsed) {
            /*
               For regions which are being drawn by GL, the shadow framebuffer doesn't have the
               correct bits, so don't bitblt from the shadow framebuffer

               XXX: For now, just leave it alone, but ideally we want to send an expose event to
               the window so it really redraws the affected region...
             */
            ValidateRect(hwnd, &(ps.rcPaint));
        }
        else
#endif
            /* Try to copy from the shadow buffer */
            if (!BitBlt(hdcUpdate,
                        ps.rcPaint.left, ps.rcPaint.top,
                        ps.rcPaint.right - ps.rcPaint.left,
                        ps.rcPaint.bottom - ps.rcPaint.top,
                        s_pScreenPriv->hdcShadow,
                        ps.rcPaint.left + pWin->drawable.x,
                        ps.rcPaint.top + pWin->drawable.y, SRCCOPY)) {
                LPVOID lpMsgBuf;

                /* Display a fancy error message */
                FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                              FORMAT_MESSAGE_FROM_SYSTEM |
                              FORMAT_MESSAGE_IGNORE_INSERTS,
                              NULL,
                              GetLastError(),
                              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                              (LPTSTR) &lpMsgBuf, 0, NULL);

                ErrorF("winTopLevelWindowProc - BitBlt failed: %s\n",
                       (LPSTR) lpMsgBuf);
                LocalFree(lpMsgBuf);
            }

        /* EndPaint frees the DC */
        EndPaint(hwnd, &ps);
        return 0;

    case WM_MOUSEMOVE:
        /* Unpack the client area mouse coordinates */
        ptMouse.x = GET_X_LPARAM(lParam);
        ptMouse.y = GET_Y_LPARAM(lParam);

        /* Translate the client area mouse coordinates to screen coordinates */
        ClientToScreen(hwnd, &ptMouse);

        /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
        ptMouse.x -= GetSystemMetrics(SM_XVIRTUALSCREEN);
        ptMouse.y -= GetSystemMetrics(SM_YVIRTUALSCREEN);

        /* We can't do anything without privates */
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;

        /* Has the mouse pointer crossed screens? */
        if (s_pScreen != miPointerGetScreen(g_pwinPointer))
            miPointerSetScreen(g_pwinPointer, s_pScreenInfo->dwScreen,
                               ptMouse.x - s_pScreenInfo->dwXOffset,
                               ptMouse.y - s_pScreenInfo->dwYOffset);

        /* Are we tracking yet? */
        if (!s_fTracking) {
            TRACKMOUSEEVENT tme;

            /* Setup data structure */
            ZeroMemory(&tme, sizeof(tme));
            tme.cbSize = sizeof(tme);
            tme.dwFlags = TME_LEAVE;
            tme.hwndTrack = hwnd;

            /* Call the tracking function */
            if (!TrackMouseEvent(&tme))
                ErrorF("winTopLevelWindowProc - TrackMouseEvent failed\n");

            /* Flag that we are tracking now */
            s_fTracking = TRUE;
        }

        /* Hide or show the Windows mouse cursor */
        if (g_fSoftwareCursor && g_fCursor) {
            /* Hide Windows cursor */
            g_fCursor = FALSE;
            ShowCursor(FALSE);
        }

        /* Kill the timer used to poll mouse events */
        if (g_uipMousePollingTimerID != 0) {
            KillTimer(s_pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID);
            g_uipMousePollingTimerID = 0;
        }

        /* Deliver absolute cursor position to X Server */
        winEnqueueMotion(ptMouse.x - s_pScreenInfo->dwXOffset,
                         ptMouse.y - s_pScreenInfo->dwYOffset);

        return 0;

    case WM_NCMOUSEMOVE:
        /*
         * We break instead of returning 0 since we need to call
         * DefWindowProc to get the mouse cursor changes
         * and min/max/close button highlighting in Windows XP.
         * The Platform SDK says that you should return 0 if you
         * process this message, but it fails to mention that you
         * will give up any default functionality if you do return 0.
         */

        /* We can't do anything without privates */
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;

        /* Non-client mouse movement, show Windows cursor */
        if (g_fSoftwareCursor && !g_fCursor) {
            g_fCursor = TRUE;
            ShowCursor(TRUE);
        }

        winStartMousePolling(s_pScreenPriv);

        break;

    case WM_MOUSELEAVE:
        /* We can't do anything without privates */
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        /* Mouse has left our client area */

        /* Flag that we are no longer tracking */
        s_fTracking = FALSE;

        /* Show the mouse cursor, if necessary */
        if (g_fSoftwareCursor && !g_fCursor) {
            g_fCursor = TRUE;
            ShowCursor(TRUE);
        }

        winStartMousePolling(s_pScreenPriv);

        return 0;

    case WM_LBUTTONDBLCLK:
    case WM_LBUTTONDOWN:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        g_fButton[0] = TRUE;
        SetCapture(hwnd);
        return winMouseButtonsHandle(s_pScreen, ButtonPress, Button1, wParam);

    case WM_LBUTTONUP:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        g_fButton[0] = FALSE;
        ReleaseCapture();
        winStartMousePolling(s_pScreenPriv);
        return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button1, wParam);

    case WM_MBUTTONDBLCLK:
    case WM_MBUTTONDOWN:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        g_fButton[1] = TRUE;
        SetCapture(hwnd);
        return winMouseButtonsHandle(s_pScreen, ButtonPress, Button2, wParam);

    case WM_MBUTTONUP:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        g_fButton[1] = FALSE;
        ReleaseCapture();
        winStartMousePolling(s_pScreenPriv);
        return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button2, wParam);

    case WM_RBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        g_fButton[2] = TRUE;
        SetCapture(hwnd);
        return winMouseButtonsHandle(s_pScreen, ButtonPress, Button3, wParam);

    case WM_RBUTTONUP:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        g_fButton[2] = FALSE;
        ReleaseCapture();
        winStartMousePolling(s_pScreenPriv);
        return winMouseButtonsHandle(s_pScreen, ButtonRelease, Button3, wParam);

    case WM_XBUTTONDBLCLK:
    case WM_XBUTTONDOWN:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        SetCapture(hwnd);
        return winMouseButtonsHandle(s_pScreen, ButtonPress, HIWORD(wParam) + 5,
                                     wParam);

    case WM_XBUTTONUP:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;
        ReleaseCapture();
        winStartMousePolling(s_pScreenPriv);
        return winMouseButtonsHandle(s_pScreen, ButtonRelease,
                                     HIWORD(wParam) + 5, wParam);

    case WM_MOUSEWHEEL:
        if (SendMessage
                (hwnd, WM_NCHITTEST, 0,
                 MAKELONG(GET_X_LPARAM(lParam),
                          GET_Y_LPARAM(lParam))) == HTCLIENT) {
            /* Pass the message to the root window */
            SendMessage(hwndScreen, message, wParam, lParam);
            return 0;
        }
        else
            break;

    case WM_SETFOCUS:
        if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput)
            break;

        {
            /* Get the parent window for transient handling */
            HWND hParent = GetParent(hwnd);

            if (hParent && IsIconic(hParent))
                ShowWindow(hParent, SW_RESTORE);
        }

        winRestoreModeKeyStates();

        /* Add the keyboard hook if possible */
        if (g_fKeyboardHookLL)
            g_fKeyboardHookLL = winInstallKeyboardHookLL();
        return 0;

    case WM_KILLFOCUS:
        /* Pop any pressed keys since we are losing keyboard focus */
        winKeybdReleaseKeys();

        /* Remove our keyboard hook if it is installed */
        winRemoveKeyboardHookLL();

        /* Revert the X focus as well, but only if the Windows focus is going to another window */
        if (!wParam && pWin)
            DeleteWindowFromAnyEvents(pWin, FALSE);

        return 0;

    case WM_SYSDEADCHAR:
    case WM_DEADCHAR:
        /*
         * NOTE: We do nothing with WM_*CHAR messages,
         * nor does the root window, so we can just toss these messages.
         */
        return 0;

    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:

        /*
         * Don't pass Alt-F4 key combo to root window,
         * let Windows translate to WM_CLOSE and close this top-level window.
         *
         * NOTE: We purposely don't check the fUseWinKillKey setting because
         * it should only apply to the key handling for the root window,
         * not for top-level window-manager windows.
         *
         * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
         * because that is a key combo that no X app should be expecting to
         * receive, since it has historically been used to shutdown the X server.
         * Passing Ctrl-Alt-Backspace to the root window preserves that
         * behavior, assuming that -unixkill has been passed as a parameter.
         */
        if (wParam == VK_F4 && (GetKeyState(VK_MENU) & 0x8000))
            break;

#ifdef WINDBG
        if (wParam == VK_ESCAPE) {
            /* Place for debug: put any tests and dumps here */
            WINDOWPLACEMENT windPlace;
            RECT rc;
            LPRECT pRect;

            windPlace.length = sizeof(WINDOWPLACEMENT);
            GetWindowPlacement(hwnd, &windPlace);
            pRect = &windPlace.rcNormalPosition;
            winDebug ("\nCYGWINDOWING Dump:\n"
                      "\tdrawable: (%hd, %hd) - %hdx%hd\n", pDraw->x,
                      pDraw->y, pDraw->width, pDraw->height);
            winDebug ("\twindPlace: (%ld, %ld) - %ldx%ld\n", pRect->left,
                      pRect->top, pRect->right - pRect->left,
                      pRect->bottom - pRect->top);
            if (GetClientRect(hwnd, &rc)) {
                pRect = &rc;
                winDebug ("\tClientRect: (%ld, %ld) - %ldx%ld\n", pRect->left,
                          pRect->top, pRect->right - pRect->left,
                          pRect->bottom - pRect->top);
            }
            if (GetWindowRect(hwnd, &rc)) {
                pRect = &rc;
                winDebug ("\tWindowRect: (%ld, %ld) - %ldx%ld\n", pRect->left,
                          pRect->top, pRect->right - pRect->left,
                          pRect->bottom - pRect->top);
            }
            winDebug ("\n");
        }
#endif

        /* Pass the message to the root window */
        return winWindowProc(hwndScreen, message, wParam, lParam);

    case WM_SYSKEYUP:
    case WM_KEYUP:

        /* Pass the message to the root window */
        return winWindowProc(hwndScreen, message, wParam, lParam);

    case WM_HOTKEY:

        /* Pass the message to the root window */
        SendMessage(hwndScreen, message, wParam, lParam);
        return 0;

    case WM_ACTIVATE:

        /* Pass the message to the root window */
        SendMessage(hwndScreen, message, wParam, lParam);

        if (LOWORD(wParam) != WA_INACTIVE) {
            /* Raise the window to the top in Z order */
            /* ago: Activate does not mean putting it to front! */
            /*
               wmMsg.msg = WM_WM_RAISE;
               if (fWMMsgInitialized)
               winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
             */

            /* Tell our Window Manager thread to activate the window */
            wmMsg.msg = WM_WM_ACTIVATE;
            if (fWMMsgInitialized && pWin->realized && !pWin->overrideRedirect /* for OOo menus */)
                winSendMessageToWM (s_pScreenPriv->pWMInfo, &wmMsg);
        }
        /* Prevent the mouse wheel from stalling when another window is minimized */
        if (HIWORD(wParam) == 0 && LOWORD(wParam) == WA_ACTIVE &&
                (HWND) lParam != NULL && (HWND) lParam != (HWND) GetParent(hwnd))
            SetFocus(hwnd);
        return 0;

    case WM_ACTIVATEAPP:
        /*
         * This message is also sent to the root window
         * so we do nothing for individual multiwindow windows
         */
        break;

    case WM_CLOSE:
        /* Removep AppUserModelID property */
        winSetAppUserModelID(hwnd, NULL);
        /* Branch on if the window was killed in X already */
        if (pWinPriv->fXKilled) {
            /* Window was killed, go ahead and destroy the window */
            DestroyWindow(hwnd);
        }
        else {
            /* Tell our Window Manager thread to kill the window */
            wmMsg.msg = WM_WM_KILL;
            if (fWMMsgInitialized)
                winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg);
        }
        return 0;

    case WM_DESTROY:

        /* Branch on if the window was killed in X already */
        if (pWinPriv && !pWinPriv->fXKilled) {
            winDebug ("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n");

            /* Tell our Window Manager thread to kill the window */
            wmMsg.msg = WM_WM_KILL;
            if (fWMMsgInitialized)
                winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg);
        }

        RemoveProp(hwnd, WIN_WINDOW_PROP);
        RemoveProp(hwnd, WIN_WID_PROP);
        RemoveProp(hwnd, WIN_NEEDMANAGE_PROP);

        break;

    case WM_MOVE:
        /* Adjust the X Window to the moved Windows window */
        if (!hasEnteredSizeMove) winAdjustXWindow (pWin, hwnd);
        /* else: Wait for WM_EXITSIZEMOVE */
        return 0;

    case WM_SHOWWINDOW:
        /* Bail out if the window is being hidden */
        if (!wParam)
            return 0;

        /* */
        if (!pWin->overrideRedirect) {
            HWND zstyle = HWND_NOTOPMOST;

            /* Flag that this window needs to be made active when clicked */
            SetProp(hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1);

            /* Set the transient style flags */
            if (GetParent(hwnd))
                SetWindowLongPtr(hwnd, GWL_STYLE,
                                 WS_POPUP | WS_OVERLAPPED | WS_SYSMENU |
                                 WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
            /* Set the window standard style flags */
            else
                SetWindowLongPtr(hwnd, GWL_STYLE,
                                 (WS_POPUP | WS_OVERLAPPEDWINDOW |
                                  WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
                                 & ~WS_CAPTION & ~WS_SIZEBOX);

            winUpdateWindowPosition(hwnd, &zstyle);

            {
                WinXWMHints hints;

                if (winMultiWindowGetWMHints(pWin, &hints)) {
                    /*
                       Give the window focus, unless it has an InputHint
                       which is FALSE (this is used by e.g. glean to
                       avoid every test window grabbing the focus)
                     */
                    if (!((hints.flags & InputHint) && (!hints.input))) {
                        SetForegroundWindow(hwnd);
                    }
                }
            }
            wmMsg.msg = WM_WM_MAP3;
        }
        else {                  /* It is an overridden window so make it top of Z stack */

            HWND forHwnd = GetForegroundWindow();
            winDebug ("overridden window is shown\n");
            if (forHwnd != NULL) {
                if (GetWindowLongPtr(forHwnd, GWLP_USERDATA) & (LONG_PTR)
                        VCXSRV_SIGNATURE) {
                    if (GetWindowLongPtr(forHwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)
                        SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
                                     SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
                    else
                        SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
                                     SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
                }
            }
            wmMsg.msg = WM_WM_MAP2;
        }

        /* Tell our Window Manager thread to map the window */
        if (fWMMsgInitialized)
            winSendMessageToWM(s_pScreenPriv->pWMInfo, &wmMsg);

        winStartMousePolling(s_pScreenPriv);

        return 0;

    case WM_SIZING:
        /* Need to legalize the size according to WM_NORMAL_HINTS */
        /* for applications like xterm */
        return ValidateSizing(hwnd, pWin, wParam, lParam);

    case WM_WINDOWPOSCHANGING:
    {
        /*
          When window is moved or resized, force it to be redrawn, so that
          any OpenGL content is re-drawn correctly, rather than copying bits
          (which seem to be wrong, either because we are copying the wrong
          window in the window heirarchy, or because we don't have the bits
          drawn by OpenGL at all)

          XXX: really this should check if any child has fWglUsed set, but
          that might be expensive to check....
         */
        if (g_fNativeGl)
        {
            LPWINDOWPOS pWinPos = (LPWINDOWPOS)lParam;
            pWinPos->flags |= SWP_NOCOPYBITS;
        }
    }
    break;

    case WM_WINDOWPOSCHANGED:
    {
        LPWINDOWPOS pWinPos = (LPWINDOWPOS) lParam;

        if (!(pWinPos->flags & SWP_NOZORDER)) {
#if CYGWINDOWING_DEBUG
            winDebug("\twindow z order was changed\n");
#endif
            if (pWinPos->hwndInsertAfter == HWND_TOP
                    || pWinPos->hwndInsertAfter == HWND_TOPMOST
                    || pWinPos->hwndInsertAfter == HWND_NOTOPMOST) {
#if CYGWINDOWING_DEBUG
                winDebug("\traise to top\n");
#endif
                /* Raise the window to the top in Z order */
                winRaiseWindow(pWin);
            }
            else if (pWinPos->hwndInsertAfter == HWND_BOTTOM) {
            }
            else {
                /* Check if this window is top of X windows. */
                HWND hWndAbove = NULL;
                DWORD dwCurrentProcessID = GetCurrentProcessId();
                DWORD dwWindowProcessID = 0;

                for (hWndAbove = pWinPos->hwndInsertAfter;
                        hWndAbove != NULL;
                        hWndAbove = GetNextWindow(hWndAbove, GW_HWNDPREV)) {
                    /* Ignore other XWin process's window */
                    GetWindowThreadProcessId(hWndAbove, &dwWindowProcessID);

                    if ((dwWindowProcessID == dwCurrentProcessID)
                            && GetProp(hWndAbove, WIN_WINDOW_PROP)
                            && !IsWindowVisible(hWndAbove)
                            && !IsIconic(hWndAbove))        /* ignore minimized windows */
                        break;
                }
                /* If this is top of X windows in Windows stack,
                   raise it in X stack. */
                if (hWndAbove == NULL) {
#if CYGWINDOWING_DEBUG
                    winDebug("\traise to top\n");
#endif
                    winRaiseWindow(pWin);
                }
            }
        }
    }
        /*
         * Pass the message to DefWindowProc to let the function
         * break down WM_WINDOWPOSCHANGED to WM_MOVE and WM_SIZE.
         */
    break;

    case WM_ENTERSIZEMOVE:
        hasEnteredSizeMove = TRUE;
        return 0;

    case WM_EXITSIZEMOVE:
        /* Adjust the X Window to the moved Windows window */
        hasEnteredSizeMove = FALSE;
        winAdjustXWindow (pWin, hwnd);
        return 0;

    case WM_SIZE:
        /* see dix/window.c */
#ifdef WINDBG
    {
        char buf[64];

        switch (wParam) {
        case SIZE_MINIMIZED:
            strcpy(buf, "SIZE_MINIMIZED");
            break;
        case SIZE_MAXIMIZED:
            strcpy(buf, "SIZE_MAXIMIZED");
            break;
        case SIZE_RESTORED:
            strcpy(buf, "SIZE_RESTORED");
            break;
        default:
            strcpy(buf, "UNKNOWN_FLAG");
        }
        winDebug ("winTopLevelWindowProc - WM_SIZE to %dx%d (%s) - %d ms\n",
                  (int) LOWORD(lParam), (int) HIWORD(lParam), buf,
                  (int) (GetTickCount()));
    }
#endif
    if (!hasEnteredSizeMove)
    {
        /* Adjust the X Window to the moved Windows window */
        winAdjustXWindow (pWin, hwnd);
        if (wParam == SIZE_MINIMIZED) winReorderWindowsMultiWindow();
    }
        /* else: wait for WM_EXITSIZEMOVE */
        return 0; /* end of WM_SIZE handler */

    case WM_STYLECHANGED:
        /* when the style changes, adjust the window size so the client area remains the same */
    {
        LONG x,y;
        DrawablePtr pDraw = &pWin->drawable;
        x =  pDraw->x - wBorderWidth(pWin);
        y = pDraw->y - wBorderWidth(pWin);
        winPositionWindowMultiWindow(pWin, x, y);
    }
    return 0;

    case WM_MOUSEACTIVATE:

        /* Check if this window needs to be made active when clicked */
        if (!GetProp(pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) {
            winDebug ("winTopLevelWindowProc - WM_MOUSEACTIVATE - "
                      "MA_NOACTIVATE\n");

            /* */
            return MA_NOACTIVATE;
        }
        break;

    case WM_SETCURSOR:
        if (LOWORD(lParam) == HTCLIENT) {
            if (!g_fSoftwareCursor)
                SetCursor(s_pScreenPriv->cursor.handle);
            return TRUE;
        }
        break;

    default:
        break;
    }

    ret = DefWindowProc(hwnd, message, wParam, lParam);
    /*
     * If the window was minized we get the stack change before the window is restored
     * and so it gets lost. Ensure there stacking order is correct.
     */
    if (needRestack)
        winReorderWindowsMultiWindow();
    return ret;
}
Exemple #15
0
static int
ProcShmGetImage(ClientPtr client)
{
    DrawablePtr		pDraw;
    long		lenPer = 0, length;
    Mask		plane = 0;
    xShmGetImageReply	xgi;
    ShmDescPtr		shmdesc;
    int			n, rc;

    REQUEST(xShmGetImageReq);

    REQUEST_SIZE_MATCH(xShmGetImageReq);
    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
    {
	client->errorValue = stuff->format;
        return BadValue;
    }
    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
			   DixReadAccess);
    if (rc != Success)
	return rc;
    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
    if (pDraw->type == DRAWABLE_WINDOW)
    {
      if( /* check for being viewable */
	 !((WindowPtr) pDraw)->realized ||
	  /* check for being on screen */
         pDraw->x + stuff->x < 0 ||
         pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
         pDraw->y + stuff->y < 0 ||
         pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
          /* check for being inside of border */
         stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
         stuff->x + (int)stuff->width >
		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
         stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
         stuff->y + (int)stuff->height >
		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
        )
	    return BadMatch;
	xgi.visual = wVisual(((WindowPtr)pDraw));
    }
    else
    {
	if (stuff->x < 0 ||
	    stuff->x+(int)stuff->width > pDraw->width ||
	    stuff->y < 0 ||
	    stuff->y+(int)stuff->height > pDraw->height
	    )
	    return BadMatch;
	xgi.visual = None;
    }
    xgi.type = X_Reply;
    xgi.length = 0;
    xgi.sequenceNumber = client->sequence;
    xgi.depth = pDraw->depth;
    if(stuff->format == ZPixmap)
    {
	length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
    }
    else
    {
	lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
	plane = ((Mask)1) << (pDraw->depth - 1);
	/* only planes asked for */
	length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
    }

    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
    xgi.size = length;

    if (length == 0)
    {
	/* nothing to do */
    }
    else if (stuff->format == ZPixmap)
    {
	(*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
				    stuff->width, stuff->height,
				    stuff->format, stuff->planeMask,
				    shmdesc->addr + stuff->offset);
    }
    else
    {

	length = stuff->offset;
        for (; plane; plane >>= 1)
	{
	    if (stuff->planeMask & plane)
	    {
		(*pDraw->pScreen->GetImage)(pDraw,
					    stuff->x, stuff->y,
					    stuff->width, stuff->height,
					    stuff->format, plane,
					    shmdesc->addr + length);
		length += lenPer;
	    }
	}
    }

    if (client->swapped) {
	swaps(&xgi.sequenceNumber, n);
	swapl(&xgi.length, n);
	swapl(&xgi.visual, n);
	swapl(&xgi.size, n);
    }
    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);

    return Success;
}
Exemple #16
0
static int 
ProcPanoramiXShmGetImage(ClientPtr client)
{
    PanoramiXRes	*draw;
    DrawablePtr 	*drawables;
    DrawablePtr 	pDraw;
    xShmGetImageReply	xgi;
    ShmDescPtr		shmdesc;
    int         	i, x, y, w, h, format, rc;
    Mask		plane = 0, planemask;
    long		lenPer = 0, length, widthBytesLine;
    Bool		isRoot;

    REQUEST(xShmGetImageReq);

    REQUEST_SIZE_MATCH(xShmGetImageReq);

    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
	client->errorValue = stuff->format;
        return BadValue;
    }

    rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
				  XRC_DRAWABLE, client, DixWriteAccess);
    if (rc != Success)
	return (rc == BadValue) ? BadDrawable : rc;

    if (draw->type == XRT_PIXMAP)
	return ProcShmGetImage(client);

    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
			   DixReadAccess);
    if (rc != Success)
	return rc;

    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);

    x = stuff->x;
    y = stuff->y;
    w = stuff->width;
    h = stuff->height;
    format = stuff->format;
    planemask = stuff->planeMask;

    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;

    if(isRoot) {
      if( /* check for being onscreen */
	x < 0 || x + w > PanoramiXPixWidth ||
	y < 0 || y + h > PanoramiXPixHeight )
	    return BadMatch;
    } else {
      if( /* check for being onscreen */
	screenInfo.screens[0]->x + pDraw->x + x < 0 ||
	screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth ||
	screenInfo.screens[0]->y + pDraw->y + y < 0 ||
	screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight ||
	 /* check for being inside of border */
       	x < - wBorderWidth((WindowPtr)pDraw) ||
	x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
	y < -wBorderWidth((WindowPtr)pDraw) ||
	y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
	    return BadMatch;
    }

    drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr));
    if(!drawables)
	return BadAlloc;

    drawables[0] = pDraw;
    for(i = 1; i < PanoramiXNumScreens; i++) {
	rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0, 
			       DixReadAccess);
	if (rc != Success)
	{
	    free(drawables);
	    return rc;
	}
    }

    xgi.visual = wVisual(((WindowPtr)pDraw));
    xgi.type = X_Reply;
    xgi.length = 0;
    xgi.sequenceNumber = client->sequence;
    xgi.depth = pDraw->depth;

    if(format == ZPixmap) {
	widthBytesLine = PixmapBytePad(w, pDraw->depth);
	length = widthBytesLine * h;
    } else {
	widthBytesLine = PixmapBytePad(w, 1);
	lenPer = widthBytesLine * h;
	plane = ((Mask)1) << (pDraw->depth - 1);
	length = lenPer * Ones(planemask & (plane | (plane - 1)));
    }

    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
    xgi.size = length;

    if (length == 0) {/* nothing to do */ }
    else if (format == ZPixmap) {
	    XineramaGetImageData(drawables, x, y, w, h, format, planemask,
					shmdesc->addr + stuff->offset,
					widthBytesLine, isRoot);
    } else {

	length = stuff->offset;
        for (; plane; plane >>= 1) {
	    if (planemask & plane) {
		XineramaGetImageData(drawables, x, y, w, h, 
				     format, plane, shmdesc->addr + length,
				     widthBytesLine, isRoot);
		length += lenPer;
	    }
	}
    }
    free(drawables);
    
    if (client->swapped) {
	int n;
    	swaps(&xgi.sequenceNumber, n);
    	swapl(&xgi.length, n);
	swapl(&xgi.visual, n);
	swapl(&xgi.size, n);
    }
    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);

    return Success;
}
Exemple #17
0
/*
 *-----------------------------------------------------------------------
 * miComputeClips --
 *	Recompute the clipList, borderClip, exposed and borderExposed
 *	regions for pParent and its children. Only viewable windows are
 *	taken into account.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	clipList, borderClip, exposed and borderExposed are altered.
 *	A VisibilityNotify event may be generated on the parent window.
 *
 *-----------------------------------------------------------------------
 */
static void
miComputeClips (
    WindowPtr	pParent,
    ScreenPtr	pScreen,
    RegionPtr	universe,
    VTKind		kind,
    RegionPtr		exposed ) /* for intermediate calculations */
{
    int			dx,
			dy;
    RegionRec		childUniverse;
    WindowPtr		pChild;
    int     	  	oldVis, newVis;
    BoxRec		borderSize;
    RegionRec		childUnion;
    Bool		overlap;
    RegionPtr		borderVisible;
    /*
     * Figure out the new visibility of this window.
     * The extent of the universe should be the same as the extent of
     * the borderSize region. If the window is unobscured, this rectangle
     * will be completely inside the universe (the universe will cover it
     * completely). If the window is completely obscured, none of the
     * universe will cover the rectangle.
     */
    borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
    borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
    dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent);
    if (dx > 32767)
	dx = 32767;
    borderSize.x2 = dx;
    dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent);
    if (dy > 32767)
	dy = 32767;
    borderSize.y2 = dy;

#ifdef COMPOSITE
    /*
     * In redirected drawing case, reset universe to borderSize
     */
    if (pParent->redirectDraw != RedirectDrawNone)
    {
	if (miSetRedirectBorderClipProc)
	{
	    if (TreatAsTransparent (pParent))
		RegionEmpty(universe);
	    (*miSetRedirectBorderClipProc) (pParent, universe);
	}
	RegionCopy(universe, &pParent->borderSize);
    }
#endif

    oldVis = pParent->visibility;
    switch (RegionContainsRect(universe, &borderSize))
    {
	case rgnIN:
	    newVis = VisibilityUnobscured;
	    break;
	case rgnPART:
	    newVis = VisibilityPartiallyObscured;
	    {
		RegionPtr   pBounding;

		if ((pBounding = wBoundingShape (pParent)))
		{
		    switch (miShapedWindowIn (universe, pBounding,
					      &borderSize,
					      pParent->drawable.x,
 					      pParent->drawable.y))
		    {
		    case rgnIN:
			newVis = VisibilityUnobscured;
			break;
		    case rgnOUT:
			newVis = VisibilityFullyObscured;
			break;
		    }
		}
	    }
	    break;
	default:
	    newVis = VisibilityFullyObscured;
	    break;
    }
    pParent->visibility = newVis;
    if (oldVis != newVis &&
	((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
	SendVisibilityNotify(pParent);

    dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
    dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;

    /*
     * avoid computations when dealing with simple operations
     */

    switch (kind) {
    case VTMap:
    case VTStack:
    case VTUnmap:
	break;
    case VTMove:
	if ((oldVis == newVis) &&
	    ((oldVis == VisibilityFullyObscured) ||
	     (oldVis == VisibilityUnobscured)))
	{
	    pChild = pParent;
	    while (1)
	    {
		if (pChild->viewable)
		{
		    if (pChild->visibility != VisibilityFullyObscured)
		    {
			RegionTranslate(&pChild->borderClip,
						      dx, dy);
			RegionTranslate(&pChild->clipList,
						      dx, dy);
			pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
			if (pScreen->ClipNotify)
			    (* pScreen->ClipNotify) (pChild, dx, dy);

		    }
		    if (pChild->valdata)
		    {
			RegionNull(&pChild->valdata->after.borderExposed);
			if (HasParentRelativeBorder(pChild))
			{
			    RegionSubtract(&pChild->valdata->after.borderExposed,
					   &pChild->borderClip,
					   &pChild->winSize);
			}
			RegionNull(&pChild->valdata->after.exposed);
		    }
		    if (pChild->firstChild)
		    {
			pChild = pChild->firstChild;
			continue;
		    }
		}
		while (!pChild->nextSib && (pChild != pParent))
		    pChild = pChild->parent;
		if (pChild == pParent)
		    break;
		pChild = pChild->nextSib;
	    }
	    return;
	}
	/* fall through */
    default:
    	/*
     	 * To calculate exposures correctly, we have to translate the old
     	 * borderClip and clipList regions to the window's new location so there
     	 * is a correspondence between pieces of the new and old clipping regions.
     	 */
    	if (dx || dy) 
    	{
	    /*
	     * We translate the old clipList because that will be exposed or copied
	     * if gravity is right.
	     */
	    RegionTranslate(&pParent->borderClip, dx, dy);
	    RegionTranslate(&pParent->clipList, dx, dy);
    	} 
	break;
    case VTBroken:
	RegionEmpty(&pParent->borderClip);
	RegionEmpty(&pParent->clipList);
	break;
    }

    borderVisible = pParent->valdata->before.borderVisible;
    RegionNull(&pParent->valdata->after.borderExposed);
    RegionNull(&pParent->valdata->after.exposed);

    /*
     * Since the borderClip must not be clipped by the children, we do
     * the border exposure first...
     *
     * 'universe' is the window's borderClip. To figure the exposures, remove
     * the area that used to be exposed from the new.
     * This leaves a region of pieces that weren't exposed before.
     */

    if (HasBorder (pParent))
    {
    	if (borderVisible)
    	{
	    /*
	     * when the border changes shape, the old visible portions
	     * of the border will be saved by DIX in borderVisible --
	     * use that region and destroy it
	     */
	    RegionSubtract(exposed, universe, borderVisible);
	    RegionDestroy(borderVisible);
    	}
    	else
    	{
	    RegionSubtract(exposed, universe, &pParent->borderClip);
    	}
	if (HasParentRelativeBorder(pParent) && (dx || dy))
	    RegionSubtract(&pParent->valdata->after.borderExposed,
				  universe,
				  &pParent->winSize);
	else
	    RegionSubtract(&pParent->valdata->after.borderExposed,
			       exposed, &pParent->winSize);

	RegionCopy(&pParent->borderClip, universe);
    
    	/*
     	 * To get the right clipList for the parent, and to make doubly sure
     	 * that no child overlaps the parent's border, we remove the parent's
     	 * border from the universe before proceeding.
     	 */
    
	RegionIntersect(universe, universe, &pParent->winSize);
    }
    else
	RegionCopy(&pParent->borderClip, universe);
    
    if ((pChild = pParent->firstChild) && pParent->mapped)
    {
	RegionNull(&childUniverse);
	RegionNull(&childUnion);
	if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
	    ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
	     (pChild->drawable.x < pParent->lastChild->drawable.x)))
	{
	    for (; pChild; pChild = pChild->nextSib)
	    {
		if (pChild->viewable && !TreatAsTransparent(pChild))
		    RegionAppend(&childUnion, &pChild->borderSize);
	    }
	}
	else
	{
	    for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
	    {
		if (pChild->viewable && !TreatAsTransparent(pChild))
		    RegionAppend(&childUnion, &pChild->borderSize);
	    }
	}
	RegionValidate(&childUnion, &overlap);

	for (pChild = pParent->firstChild;
	     pChild;
	     pChild = pChild->nextSib)
 	{
	    if (pChild->viewable) {
		/*
		 * If the child is viewable, we want to remove its extents
		 * from the current universe, but we only re-clip it if
		 * it's been marked.
		 */
		if (pChild->valdata) {
		    /*
		     * Figure out the new universe from the child's
		     * perspective and recurse.
		     */
		    RegionIntersect(&childUniverse,
					    universe,
					    &pChild->borderSize);
		    miComputeClips (pChild, pScreen, &childUniverse, kind,
				    exposed);
		}
		/*
		 * Once the child has been processed, we remove its extents
		 * from the current universe, thus denying its space to any
		 * other sibling.
		 */
		if (overlap && !TreatAsTransparent (pChild))
		    RegionSubtract(universe, universe,
					  &pChild->borderSize);
	    }
	}
	if (!overlap)
	    RegionSubtract(universe, universe, &childUnion);
	RegionUninit(&childUnion);
	RegionUninit(&childUniverse);
    } /* if any children */

    /*
     * 'universe' now contains the new clipList for the parent window.
     *
     * To figure the exposure of the window we subtract the old clip from the
     * new, just as for the border.
     */

    if (oldVis == VisibilityFullyObscured ||
	oldVis == VisibilityNotViewable)
    {
	RegionCopy(&pParent->valdata->after.exposed, universe);
    }
    else if (newVis != VisibilityFullyObscured &&
	     newVis != VisibilityNotViewable)
    {
	RegionSubtract(&pParent->valdata->after.exposed,
			       universe, &pParent->clipList);
    }

    /* HACK ALERT - copying contents of regions, instead of regions */
    {
	RegionRec   tmp;

	tmp = pParent->clipList;
	pParent->clipList = *universe;
	*universe = tmp;
    }

#ifdef NOTDEF
    RegionCopy(&pParent->clipList, universe);
#endif

    pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;

    if (pScreen->ClipNotify)
	(* pScreen->ClipNotify) (pParent, dx, dy);
}