Exemplo n.º 1
0
void
winDoRandRScreenSetSize (ScreenPtr  pScreen,
                         CARD16	    width,
                         CARD16	    height,
                         CARD32	    mmWidth,
                         CARD32	    mmHeight)
{
  winScreenPriv(pScreen);
  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
  WindowPtr pRoot = pScreen->root;

  // Prevent screen updates while we change things around
  SetRootClip(pScreen, FALSE);

  /* Update the screen size as requested */
  pScreenInfo->dwWidth = width;
  pScreenInfo->dwHeight = height;

  /* Reallocate the framebuffer used by the drawing engine */
  (*pScreenPriv->pwinFreeFB)(pScreen);
  if (!(*pScreenPriv->pwinAllocateFB)(pScreen))
    {
      ErrorF ("winDoRandRScreenSetSize - Could not reallocate framebuffer\n");
    }

  pScreen->width = width;
  pScreen->height = height;
  pScreen->mmWidth = mmWidth;
  pScreen->mmHeight = mmHeight;

  /* Update the screen pixmap to point to the new framebuffer */
  winUpdateFBPointer(pScreen, pScreenInfo->pfb);

  // pScreen->devPrivate == pScreen->GetScreenPixmap(screen) ?
  // resize the root window
  //pScreen->ResizeWindow(pRoot, 0, 0, width, height, NULL);
  // does this emit a ConfigureNotify??

  // Restore the ability to update screen, now with new dimensions
  SetRootClip(pScreen, TRUE);

  // and arrange for it to be repainted
  miPaintWindow(pRoot, &pRoot->borderClip,  PW_BACKGROUND);

  /* Indicate that a screen size change took place */
  RRScreenSizeNotify(pScreen);
}
Exemplo n.º 2
0
static Bool
winBltExposedRegionsShadowDD (ScreenPtr pScreen)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
  RECT			rcSrc, rcDest;
  POINT			ptOrigin;
  HDC			hdcUpdate = NULL;
  PAINTSTRUCT		ps;
  HRESULT		ddrval = DD_OK;
  Bool			fReturn = TRUE;
  Bool			fLocked = TRUE;
  int			i;

  /* BeginPaint gives us an hdc that clips to the invalidated region */
  hdcUpdate = BeginPaint (pScreenPriv->hwndScreen, &ps);
  if (hdcUpdate == NULL)
    {
      ErrorF ("winBltExposedRegionsShadowDD - BeginPaint () returned "
	      "a NULL device context handle.  Aborting blit attempt.\n");
      return FALSE;
    }
  
  /* Unlock the shadow surface, so we can blit */
  ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
  if (FAILED (ddrval))
    {
      fReturn = FALSE;
      goto winBltExposedRegionsShadowDD_Exit;
    }
  else
    {
      /* Flag that we have unlocked the shadow surface */
      fLocked = FALSE;
    }

  /* Get the origin of the window in the screen coords */
  ptOrigin.x = pScreenInfo->dwXOffset;
  ptOrigin.y = pScreenInfo->dwYOffset;

  MapWindowPoints (pScreenPriv->hwndScreen,
		   HWND_DESKTOP,
		   (LPPOINT)&ptOrigin, 1);
  rcDest.left = ptOrigin.x;
  rcDest.right = ptOrigin.x + pScreenInfo->dwWidth;
  rcDest.top = ptOrigin.y;
  rcDest.bottom = ptOrigin.y + pScreenInfo->dwHeight;

  /* Source can be enter shadow surface, as Blt should clip */
  rcSrc.left = 0;
  rcSrc.top = 0;
  rcSrc.right = pScreenInfo->dwWidth;
  rcSrc.bottom = pScreenInfo->dwHeight;

  /* Try to regain the primary surface and blit again if we've lost it */
  for (i = 0; i <= WIN_REGAIN_SURFACE_RETRIES; ++i)
    {
      /* Our Blt should be clipped to the invalidated region */
      ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
					&rcDest,
					pScreenPriv->pddsShadow,
					&rcSrc,
					DDBLT_WAIT,
					NULL);
      if (ddrval == DDERR_SURFACELOST)
	{
	  /* Surface was lost */
	  ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt "
		  "reported that the primary surface was lost, "
		  "trying to restore, retry: %d\n", i + 1);

	  /* Try to restore the surface, once */
	  ddrval = IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary);
	  ErrorF ("winBltExposedRegionsShadowDD - "
		  "IDirectDrawSurface2_Restore returned: ");
	  if (ddrval == DD_OK)
	    ErrorF ("DD_OK\n");
	  else if (ddrval == DDERR_WRONGMODE)
	    ErrorF ("DDERR_WRONGMODE\n");
	  else if (ddrval == DDERR_INCOMPATIBLEPRIMARY)
	    ErrorF ("DDERR_INCOMPATIBLEPRIMARY\n");
	  else if (ddrval == DDERR_UNSUPPORTED)
	    ErrorF ("DDERR_UNSUPPORTED\n");
	  else if (ddrval == DDERR_INVALIDPARAMS)
	    ErrorF ("DDERR_INVALIDPARAMS\n");
	  else if (ddrval == DDERR_INVALIDOBJECT)
	    ErrorF ("DDERR_INVALIDOBJECT\n");
	  else
	    ErrorF ("unknown error: %08x\n", (unsigned int) ddrval);

	  /* Loop around to try the blit one more time */
	  continue;
	}
      else if (FAILED (ddrval))
	{
	  fReturn = FALSE;
	  ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Blt "
		  "failed, but surface not lost: %08x %d\n",
		  (unsigned int) ddrval, (int) ddrval);
	  goto winBltExposedRegionsShadowDD_Exit;
	}
      else
	{
	  /* Success, stop looping */
	  break;
	}
    }

  /* Relock the shadow surface */
  ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow,
				     NULL,
				     pScreenPriv->pddsdShadow,
				     DDLOCK_WAIT,
				     NULL);
  if (FAILED (ddrval))
    {
      fReturn = FALSE;
      ErrorF ("winBltExposedRegionsShadowDD - IDirectDrawSurface2_Lock "
	      "failed\n");
      goto winBltExposedRegionsShadowDD_Exit;
    }
  else
    {
      /* Indicate that we have relocked the shadow surface */
      fLocked = TRUE;
    }

  /* Has our memory pointer changed? */
  if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
    winUpdateFBPointer (pScreen,
			pScreenPriv->pddsdShadow->lpSurface);

 winBltExposedRegionsShadowDD_Exit:
  /* EndPaint frees the DC */
  if (hdcUpdate != NULL)
    EndPaint (pScreenPriv->hwndScreen, &ps);

  /*
   * Relock the surface if it is not locked.  We don't care if locking fails,
   * as it will cause the server to shutdown within a few more operations.
   */
  if (!fLocked)
    {
      IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow,
				NULL,
				pScreenPriv->pddsdShadow,
				DDLOCK_WAIT,
				NULL);

      /* Has our memory pointer changed? */
      if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
	winUpdateFBPointer (pScreen,
			    pScreenPriv->pddsdShadow->lpSurface);
      
      fLocked = TRUE;
    }
  return fReturn;
}
Exemplo n.º 3
0
Bool
winActivateAppPrimaryDD (ScreenPtr pScreen)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
  RECT			rcSrc, rcClient;
  HRESULT		ddrval = DD_OK;

  /* Check for errors */
  if (pScreenPriv == NULL
      || pScreenPriv->pddsPrimary == NULL
      || pScreenPriv->pddsOffscreen == NULL)
    return FALSE;

  /* Check for do-nothing */
  if (!pScreenPriv->fActive)
    return TRUE;
  
  /* We are activating */
  ddrval = IDirectDrawSurface2_IsLost (pScreenPriv->pddsOffscreen);
  if (ddrval == DD_OK)
    {
      IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen,
				  NULL);
      /*
       * We don't check for an error from Unlock, because it
       * doesn't matter if the Unlock failed.
       */
    }

  /* Restore both surfaces, just cause I like it that way */
  IDirectDrawSurface2_Restore (pScreenPriv->pddsOffscreen);
  IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary);
			      
  /* Get client area in screen coords */
  GetClientRect (pScreenPriv->hwndScreen, &rcClient);
  MapWindowPoints (pScreenPriv->hwndScreen,
		   HWND_DESKTOP,
		   (LPPOINT)&rcClient, 2);

  /* Setup a source rectangle */
  rcSrc.left = 0;
  rcSrc.top = 0;
  rcSrc.right = pScreenInfo->dwWidth;
  rcSrc.bottom = pScreenInfo->dwHeight;

  ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
				    &rcClient,
				    pScreenPriv->pddsOffscreen,
				    &rcSrc,
				    DDBLT_WAIT,
				    NULL);
  if (ddrval != DD_OK)
    FatalError ("winActivateAppPrimaryDD () - Failed blitting offscreen "
		"surface to primary surface %08x\n", ddrval);
  
  /* Lock the primary surface */
  ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsPrimary,
				     &rcClient,
				     pScreenPriv->pddsdPrimary,
				     DDLOCK_WAIT,
				     NULL);
  if (ddrval != DD_OK
      || pScreenPriv->pddsdPrimary->lpSurface == NULL)
    FatalError ("winActivateAppPrimaryDD () - Could not lock "
		"primary surface\n");

  /* Notify FB of the new memory pointer */
  winUpdateFBPointer (pScreen,
		      pScreenPriv->pddsdPrimary->lpSurface);

  /*
   * Register the Alt-Tab combo as a hotkey so we can copy
   * the primary framebuffer before the display mode changes
   */
  RegisterHotKey (pScreenPriv->hwndScreen, 1, MOD_ALT, 9);

  return TRUE;
}
Exemplo n.º 4
0
Bool
winHotKeyAltTabPrimaryDD (ScreenPtr pScreen)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
  RECT			rcClient, rcSrc;
  HRESULT		ddrval = DD_OK;

  ErrorF ("\nwinHotKeyAltTabPrimaryDD\n\n");

  /* Alt+Tab was pressed, we will lose focus very soon */
  pScreenPriv->fActive = FALSE;
  
  /* Check for error conditions */
  if (pScreenPriv->pddsPrimary == NULL
      || pScreenPriv->pddsOffscreen == NULL)
    return FALSE;

  /* Get client area in screen coords */
  GetClientRect (pScreenPriv->hwndScreen, &rcClient);
  MapWindowPoints (pScreenPriv->hwndScreen,
		   HWND_DESKTOP,
		   (LPPOINT)&rcClient, 2);

  /* Did we loose the primary surface? */
  ddrval = IDirectDrawSurface2_IsLost (pScreenPriv->pddsPrimary);
  if (ddrval == DD_OK)
    {
      ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary,
					   NULL);
      if (FAILED (ddrval))
	FatalError ("winHotKeyAltTabPrimaryDD - Failed unlocking primary "
		    "surface\n");
    }

  /* Setup a source rectangle */
  rcSrc.left = 0;
  rcSrc.top = 0;
  rcSrc.right = pScreenInfo->dwWidth;
  rcSrc.bottom = pScreenInfo->dwHeight;

      /* Blit the primary surface to the offscreen surface */
  ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsOffscreen,
				    NULL, /* should be rcDest */
				    pScreenPriv->pddsPrimary,
				    NULL,
				    DDBLT_WAIT,
				    NULL);
  if (ddrval == DDERR_SURFACELOST)
    {
      IDirectDrawSurface2_Restore (pScreenPriv->pddsOffscreen);  
      IDirectDrawSurface2_Restore (pScreenPriv->pddsPrimary);
		  		  
      /* Blit the primary surface to the offscreen surface */
      ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsOffscreen,
					NULL,
					pScreenPriv->pddsPrimary,
					NULL,
					DDBLT_WAIT,
					NULL);
      if (FAILED (ddrval))
	FatalError ("winHotKeyAltTabPrimaryDD - Failed blitting primary "
		    "surface to offscreen surface: %08x\n",
		    ddrval);
    }
  else
    {
      FatalError ("winHotKeyAltTabPrimaryDD - Unknown error from "
		  "Blt: %08dx\n", ddrval);
    }

  /* Lock the offscreen surface */
  ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsOffscreen,
				     NULL,
				     pScreenPriv->pddsdOffscreen,
				     DDLOCK_WAIT,
				     NULL);
  if (ddrval != DD_OK
      || pScreenPriv->pddsdPrimary->lpSurface == NULL)
    FatalError ("winHotKeyAltTabPrimaryDD - Could not lock "
		"offscreen surface\n");

  /* Notify FB of the new memory pointer */
  winUpdateFBPointer (pScreen,
		      pScreenPriv->pddsdOffscreen->lpSurface);

  /* Unregister our hotkey */
  UnregisterHotKey (pScreenPriv->hwndScreen, 1);

  return TRUE;
}
Exemplo n.º 5
0
static void
winShadowUpdateDD (ScreenPtr pScreen, 
		   shadowBufPtr pBuf)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
  RegionPtr		damage = shadowDamage(pBuf);
  HRESULT		ddrval = DD_OK;
  RECT			rcDest, rcSrc;
  POINT			ptOrigin;
  DWORD			dwBox = RegionNumRects (damage);
  BoxPtr		pBox = RegionRects (damage);
  HRGN			hrgnTemp = NULL, hrgnCombined = NULL;

  /*
   * Return immediately if the app is not active
   * and we are fullscreen, or if we have a bad display depth
   */
  if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
      || pScreenPriv->fBadDepth) return;

  /* Return immediately if we didn't get needed surfaces */
  if (!pScreenPriv->pddsPrimary || !pScreenPriv->pddsShadow)
    return;

  /* Get the origin of the window in the screen coords */
  ptOrigin.x = pScreenInfo->dwXOffset;
  ptOrigin.y = pScreenInfo->dwYOffset;
  MapWindowPoints (pScreenPriv->hwndScreen,
		   HWND_DESKTOP,
		   (LPPOINT)&ptOrigin, 1);

  /* Unlock the shadow surface, so we can blit */
  ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
  if (FAILED (ddrval))
    {
      ErrorF ("winShadowUpdateDD - Unlock failed\n");
      return;
    }

  /*
   * Handle small regions with multiple blits,
   * handle large regions by creating a clipping region and 
   * doing a single blit constrained to that clipping region.
   */
  if (pScreenInfo->dwClipUpdatesNBoxes == 0
      || dwBox < pScreenInfo->dwClipUpdatesNBoxes)
    {
      /* Loop through all boxes in the damaged region */
      while (dwBox--)
	{
	  /* Assign damage box to source rectangle */
	  rcSrc.left = pBox->x1;
	  rcSrc.top = pBox->y1;
	  rcSrc.right = pBox->x2;
	  rcSrc.bottom = pBox->y2;
	  
	  /* Calculate destination rectange */
	  rcDest.left = ptOrigin.x + rcSrc.left;
	  rcDest.top = ptOrigin.y + rcSrc.top;
	  rcDest.right = ptOrigin.x + rcSrc.right;
	  rcDest.bottom = ptOrigin.y + rcSrc.bottom;
	  
	  /* Blit the damaged areas */
	  ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
					    &rcDest,
					    pScreenPriv->pddsShadow,
					    &rcSrc,
					    DDBLT_WAIT,
					    NULL);
	  
	  /* Get a pointer to the next box */
	  ++pBox;
	}
    }
  else
    {
      BoxPtr		pBoxExtents = RegionExtents(damage);

      /* Compute a GDI region from the damaged region */
      hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
      dwBox--;
      pBox++;
      while (dwBox--)
	{
	  hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
	  CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR);
	  DeleteObject (hrgnTemp);
	  pBox++;
	}  

      /* Install the GDI region as a clipping region */
      SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined);
      DeleteObject (hrgnCombined);
      hrgnCombined = NULL;

      /* Calculating a bounding box for the source is easy */
      rcSrc.left = pBoxExtents->x1;
      rcSrc.top = pBoxExtents->y1;
      rcSrc.right = pBoxExtents->x2;
      rcSrc.bottom = pBoxExtents->y2;

      /* Calculating a bounding box for the destination is trickier */
      rcDest.left = ptOrigin.x + rcSrc.left;
      rcDest.top = ptOrigin.y + rcSrc.top;
      rcDest.right = ptOrigin.x + rcSrc.right;
      rcDest.bottom = ptOrigin.y + rcSrc.bottom;
      
      /* Our Blt should be clipped to the invalidated region */
      ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
					&rcDest,
					pScreenPriv->pddsShadow,
					&rcSrc,
					DDBLT_WAIT,
					NULL);

      /* Reset the clip region */
      SelectClipRgn (pScreenPriv->hdcScreen, NULL);
    }

  /* Relock the shadow surface */
  ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow,
				     NULL,
				     pScreenPriv->pddsdShadow,
				     DDLOCK_WAIT,
				     NULL);
  if (FAILED (ddrval))
    {
      ErrorF ("winShadowUpdateDD - Lock failed\n");
      return;
    }

  /* Has our memory pointer changed? */
  if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface)
    {
      ErrorF ("winShadowUpdateDD - Memory location of the shadow "
	      "surface has changed, trying to update the root window "
	      "pixmap header to point to the new address.  If you get "
	      "this message and "PROJECT_NAME" freezes or crashes "
	      "after this message then send a problem report and your "
	      "%s file to " BUILDERADDR "\n", g_pszLogFile);

      /* Location of shadow framebuffer has changed */
      winUpdateFBPointer(pScreen, pScreenPriv->pddsdShadow->lpSurface);
    }
}