Beispiel #1
0
static void
winFreeFBPrimaryDD(ScreenPtr pScreen)
{
    winScreenPriv(pScreen);
    winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;

    /* Free the offscreen surface, if there is one */
    if (pScreenPriv->pddsOffscreen) {
        IDirectDrawSurface2_Unlock(pScreenPriv->pddsOffscreen, NULL);
        IDirectDrawSurface2_Release(pScreenPriv->pddsOffscreen);
        pScreenPriv->pddsOffscreen = NULL;
    }

    /* Release the primary surface, if there is one */
    if (pScreenPriv->pddsPrimary) {
        IDirectDrawSurface2_Unlock(pScreenPriv->pddsPrimary, NULL);
        IDirectDrawSurface2_Release(pScreenPriv->pddsPrimary);
        pScreenPriv->pddsPrimary = NULL;
    }

    /* Free the DirectDraw object, if there is one */
    if (pScreenPriv->pdd) {
        IDirectDraw2_RestoreDisplayMode(pScreenPriv->pdd);
        IDirectDraw2_Release(pScreenPriv->pdd);
        pScreenPriv->pdd = NULL;
    }

    /* Invalidate the ScreenInfo's fb pointer */
    pScreenInfo->pfb = NULL;
}
Beispiel #2
0
/**
 * It finds out the 32bits RGB pixel value of the colorkey.
 */
static uint32_t DirectXFindColorkey(vout_display_t *vd, uint32_t *color)
{
    vout_display_sys_t *sys = vd->sys;
    HRESULT hr;

    /* */
    DDSURFACEDESC ddsd;
    ddsd.dwSize = sizeof(ddsd);
    hr = IDirectDrawSurface2_Lock(sys->display, NULL, &ddsd, DDLOCK_WAIT, NULL);
    if (hr != DD_OK)
        return 0;

    uint32_t backup = *(uint32_t *)ddsd.lpSurface;

    switch (ddsd.ddpfPixelFormat.dwRGBBitCount) {
    case 4:
        *(uint8_t *)ddsd.lpSurface = *color | (*color << 4);
        break;
    case 8:
        *(uint8_t *)ddsd.lpSurface = *color;
        break;
    case 15:
    case 16:
        *(uint16_t *)ddsd.lpSurface = *color;
        break;
    case 24:
        /* Seems to be problematic so we'll just put black as the colorkey */
        *color = 0;
    default:
        *(uint32_t *)ddsd.lpSurface = *color;
        break;
    }
    IDirectDrawSurface2_Unlock(sys->display, NULL);

    /* */
    HDC hdc;
    COLORREF rgb;
    if (IDirectDrawSurface2_GetDC(sys->display, &hdc) == DD_OK) {
        rgb = GetPixel(hdc, 0, 0);
        IDirectDrawSurface2_ReleaseDC(sys->display, hdc);
    } else {
        rgb = 0;
    }

    /* Restore the pixel value */
    ddsd.dwSize = sizeof(ddsd);
    if (IDirectDrawSurface2_Lock(sys->display, NULL, &ddsd, DDLOCK_WAIT, NULL) == DD_OK) {
        *(uint32_t *)ddsd.lpSurface = backup;
        IDirectDrawSurface2_Unlock(sys->display, NULL);
    }

    return rgb;
}
void DDUnlockSurface( LPDIRECTDRAWSURFACE2 pSurface, PTR pSurfaceData )
{
	Assert( pSurface != NULL );

	ATTEMPT( IDirectDrawSurface2_Unlock( pSurface, pSurfaceData ) );

}
Beispiel #4
0
/* gfx_directx_unlock:
 *  Unlocks the surface.
 */
void gfx_directx_unlock(BITMAP *bmp)
{
   DDRAW_SURFACE *surf;
   BITMAP *parent;
   HRESULT hr;

   if (bmp->id & BMP_ID_SUB) {
      /* recurse when unlocking sub-bitmaps */
      parent = (BITMAP *)bmp->extra;
      gfx_directx_unlock(parent);
      if (!(parent->id & BMP_ID_LOCKED))
         bmp->id &= ~BMP_ID_LOCKED;
   }
   else {
      /* regular bitmaps can be unlocked directly */
      surf = DDRAW_SURFACE_OF(bmp);

      if (surf->lock_nesting > 0) {
         surf->lock_nesting--;

         if ((!surf->lock_nesting) && (bmp->id & BMP_ID_LOCKED)) {
            if (!(surf->flags & DDRAW_SURFACE_LOST)) {
               /* only unlock if it doesn't use pseudo video memory */
               hr = IDirectDrawSurface2_Unlock(surf->id, NULL);

               /* If the surface has been lost, try to restore all surfaces
                * and, on success, try again to unlock the surface.
                */
               if (hr == DDERR_SURFACELOST) {
                  if (restore_all_ddraw_surfaces() == 0)
                     hr = IDirectDrawSurface2_Unlock(surf->id, NULL);
               }

               if (FAILED(hr))
                  _TRACE(PREFIX_E "Can't unlock surface (%x)\n", hr);
            }

            bmp->id &= ~BMP_ID_LOCKED;
         }

         /* release bitmap for other threads */
         _exit_gfx_critical();
      }
   }
}
Beispiel #5
0
/* gfx_directx_release_lock:
 *  Releases the surface lock, for hardware accelerated drawing.
 */
void gfx_directx_release_lock(BITMAP *bmp)
{
   DDRAW_SURFACE *surf;
   HRESULT hr;

   /* handle display switch */
   if (!_win_app_foreground)
      gfx_directx_switch_out();

   /* find parent */
   while (bmp->id & BMP_ID_SUB) {
      bmp->id &= ~BMP_ID_LOCKED;
      bmp = (BITMAP *)bmp->extra;
   }

   if (bmp->id & BMP_ID_LOCKED) {
      surf = DDRAW_SURFACE_OF(bmp);

      if (!(surf->flags & DDRAW_SURFACE_LOST)) {
         /* only unlock if it doesn't use pseudo video memory */
         hr = IDirectDrawSurface2_Unlock(surf->id, NULL);

         /* If the surface has been lost, try to restore all surfaces
          * and, on success, try again to unlock the surface.
          */
         if (hr == DDERR_SURFACELOST) {
            if (restore_all_ddraw_surfaces() == 0)
               hr = IDirectDrawSurface2_Unlock(surf->id, NULL);
         }

         if (FAILED(hr))
            _TRACE(PREFIX_E "Can't release lock (%x)\n", hr);
      }

      bmp->id &= ~BMP_ID_LOCKED;
   }
}
Beispiel #6
0
static void
winFreeFBShadowDD (ScreenPtr pScreen)
{
  winScreenPriv(pScreen);
  winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;

  /* Free the shadow surface, if there is one */
  if (pScreenPriv->pddsShadow)
    {
      IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
      IDirectDrawSurface2_Release (pScreenPriv->pddsShadow);
      pScreenPriv->pddsShadow = NULL;
    }

  /* Detach the clipper from the primary surface and release the primary surface, if there is one */
  winReleasePrimarySurfaceShadowDD(pScreen);

  /* Release the clipper object */
  if (pScreenPriv->pddcPrimary)
    {
      IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
      pScreenPriv->pddcPrimary = NULL;
    }

  /* Free the DirectDraw2 object, if there is one */
  if (pScreenPriv->pdd2)
    {
      IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd2);
      IDirectDraw2_Release (pScreenPriv->pdd2);
      pScreenPriv->pdd2 = NULL;
    }

  /* Free the DirectDraw object, if there is one */
  if (pScreenPriv->pdd)
    {
      IDirectDraw_Release (pScreenPriv->pdd);
      pScreenPriv->pdd = NULL;
    }

  /* Invalidate the ScreenInfo's fb pointer */
  pScreenInfo->pfb = NULL;
}
Beispiel #7
0
static Bool
winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
  Bool			fReturn;
  
#if CYGDEBUG
  winDebug ("winCloseScreenShadowDD - Freeing screen resources\n");
#endif

  /* Flag that the screen is closed */
  pScreenPriv->fClosed = TRUE;
  pScreenPriv->fActive = FALSE;

  /* Call the wrapped CloseScreen procedure */
  WIN_UNWRAP(CloseScreen);
  fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);

  /* Free the screen DC */
  ReleaseDC (pScreenPriv->hwndScreen, pScreenPriv->hdcScreen);

  /* Delete the window property */
  RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);

  /* Free the shadow surface, if there is one */
  if (pScreenPriv->pddsShadow)
    {
      IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL);
      IDirectDrawSurface2_Release (pScreenPriv->pddsShadow);
      pScreenPriv->pddsShadow = NULL;
    }

  /* Detach the clipper from the primary surface and release the clipper. */
  if (pScreenPriv->pddcPrimary)
    {
      /* Detach the clipper */
      IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary,
				      NULL);

      /* Release the clipper object */
      IDirectDrawClipper_Release (pScreenPriv->pddcPrimary);
      pScreenPriv->pddcPrimary = NULL;
    }

  /* Release the primary surface, if there is one */
  if (pScreenPriv->pddsPrimary)
    {
      IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
      pScreenPriv->pddsPrimary = NULL;
    }

  /* Free the DirectDraw2 object, if there is one */
  if (pScreenPriv->pdd2)
    {
      IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd2);
      IDirectDraw2_Release (pScreenPriv->pdd2);
      pScreenPriv->pdd2 = NULL;
    }

  /* Free the DirectDraw object, if there is one */
  if (pScreenPriv->pdd)
    {
      IDirectDraw_Release (pScreenPriv->pdd);
      pScreenPriv->pdd = NULL;
    }

  /* Delete tray icon, if we have one */
  if (!pScreenInfo->fNoTrayIcon)
    winDeleteNotifyIcon (pScreenPriv);
  
  /* Free the exit confirmation dialog box, if it exists */
  if (g_hDlgExit != NULL)
    {
      DestroyWindow (g_hDlgExit);
      g_hDlgExit = NULL;
    }

  /* Kill our window */
  if (pScreenPriv->hwndScreen)
    {
      DestroyWindow (pScreenPriv->hwndScreen);
      pScreenPriv->hwndScreen = NULL;
    }

#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
  /* Destroy the thread startup mutex */
  pthread_mutex_destroy (&pScreenPriv->pmServerStarted);
#endif

  /* Kill our screeninfo's pointer to the screen */
  pScreenInfo->pScreen = NULL;

  /* Invalidate the ScreenInfo's fb pointer */
  pScreenInfo->pfb = NULL;

  /* Free the screen privates for this screen */
  free ((pointer) pScreenPriv);

  return fReturn;
}
Beispiel #8
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 = REGION_NUM_RECTS (damage);
  BoxPtr		pBox = REGION_RECTS (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;

  /* 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 = REGION_EXTENTS (pScreen, 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, g_pszLogFile);

      /* Location of shadow framebuffer has changed */
      pScreenInfo->pfb = pScreenPriv->pddsdShadow->lpSurface;
      
      /* Update the screen pixmap */
      if (!(*pScreen->ModifyPixmapHeader)(pScreen->devPrivate,
					  pScreen->width,
					  pScreen->height,
					  pScreen->rootDepth,
					  BitsPerPixel (pScreen->rootDepth),
					  PixmapBytePad (pScreenInfo->dwStride,
							 pScreenInfo->dwBPP),
					  pScreenInfo->pfb))
	{
	  ErrorF ("winShadowUpdateDD - Bits changed, could not "
		  "notify fb.\n");
	  return;
	}
    }
}
Beispiel #9
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;
}
Beispiel #10
0
static void DirectXUnlockSurface(LPDIRECTDRAWSURFACE2 front_surface,
                                 LPDIRECTDRAWSURFACE2 surface)
{
    VLC_UNUSED(front_surface);
    IDirectDrawSurface2_Unlock(surface, NULL);
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
0
Bool
winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
  Bool			fReturn;
  
  ErrorF ("winCloseScreenPrimaryDD - Freeing screen resources\n");

  /* Flag that the screen is closed */
  pScreenPriv->fClosed = TRUE;
  pScreenPriv->fActive = FALSE;

  /* Call the wrapped CloseScreen procedure */
  pScreen->CloseScreen = pScreenPriv->CloseScreen;
  fReturn = (*pScreen->CloseScreen) (nIndex, pScreen);

  /* Delete the window property */
  RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP);

  /* Free the offscreen surface, if there is one */
  if (pScreenPriv->pddsOffscreen)
    {
      IDirectDrawSurface2_Unlock (pScreenPriv->pddsOffscreen, NULL);
      IDirectDrawSurface2_Release (pScreenPriv->pddsOffscreen);
      pScreenPriv->pddsOffscreen = NULL;
    }

  /* Release the primary surface, if there is one */
  if (pScreenPriv->pddsPrimary)
    {
      IDirectDrawSurface2_Unlock (pScreenPriv->pddsPrimary, NULL);
      IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary);
      pScreenPriv->pddsPrimary = NULL;
    }

  /* Free the DirectDraw object, if there is one */
  if (pScreenPriv->pdd)
    {
      IDirectDraw2_RestoreDisplayMode (pScreenPriv->pdd);
      IDirectDraw2_Release (pScreenPriv->pdd);
      pScreenPriv->pdd = NULL;
    }

  /* Kill our window */
  if (pScreenPriv->hwndScreen)
    {
      DestroyWindow (pScreenPriv->hwndScreen);
      pScreenPriv->hwndScreen = NULL;
    }

  /* Kill our screeninfo's pointer to the screen */
  pScreenInfo->pScreen = NULL;

  /* Invalidate the ScreenInfo's fb pointer */
  pScreenInfo->pfb = NULL;

  /* Free the screen privates for this screen */
  free ((pointer) pScreenPriv);

  return fReturn;
}
Beispiel #14
0
int directdraw_draw(void *pic, int w, int h)
{
	DDSURFACEDESC  descriptor;
	RECT           rct;
	HWND           hwndp;

#define fourcc(a,b,c,d) (( ((uint32_t)a) | ( ((uint32_t)b) << 8 ) | ( ((uint32_t)c) << 16 ) | ( ((uint32_t)d) << 24 ) ))

	int bh = h, bw = w;
	//w = default_sw;
	//h = default_sh;

	vdata.getdata(get_window_video, 0, &hwndp, 0);

	if(!hwndp) return 0;
	if(video_window_parent != hwndp)
	{
		video_uninit();
		video_init(hwndp);
		video_window_parent = hwndp;
	}

	if(w != d_width || h != d_height)
	{

		if(size_in_list(w, h))size_is_ok = 1;
		else size_is_ok = 0;

		if(w && h)
		{
			d_width  = w;
			d_height = h;

			if(lpDDS_secondary)
				IDirectDrawSurface2_Release(lpDDS_secondary);

			memset(&descriptor, 0, sizeof(descriptor));
			
			descriptor.dwSize         = sizeof(descriptor);
			descriptor.dwFlags        = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
			descriptor.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
			descriptor.dwWidth        = d_width;
			descriptor.dwHeight       = d_height;

		
			if(FAILED(IDirectDraw2_CreateSurface(lpDD, &descriptor, &lpDDS_secondary, 0))) return 0;
	    	
			lpDDS_back    = lpDDS_secondary;
		}
	}

	if(use_osd_surface)
	{
		GetClientRect(video_window, &rct);

		if(rct.right != window_w || rct.bottom != window_h || osd_created == 0)
		{
			window_w = rct.right;
			window_h = rct.bottom;

			if(surface_osd)
				IDirectDrawSurface2_Release(surface_osd);

			memset( &descriptor, 0, sizeof(descriptor));

			descriptor.dwSize         = sizeof(descriptor);
			descriptor.dwFlags        = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
			descriptor.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
			descriptor.dwWidth        = window_w;
			descriptor.dwHeight       = window_h;

			if(FAILED(IDirectDraw2_CreateSurface(lpDD, &descriptor, &surface_osd, 0))) return 0;

			osd_created = 1;
		}
	}

    IDirectDrawSurface2_Restore(lpDDS);
    if(pic)
		IDirectDrawSurface2_Restore(lpDDS_secondary);

	memset(&descriptor, 0, sizeof(descriptor));
    descriptor.dwSize = sizeof(descriptor);

	if(pic)
	{
		HRESULT res;
		

		if(size_is_ok)
		{
			res = IDirectDrawSurface2_Lock(lpDDS_back, 0, &descriptor, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0);
			if(FAILED(res)) return 0;

			memcpy(descriptor.lpSurface, pic, w * h * 4);

			IDirectDrawSurface2_Unlock(lpDDS_back, descriptor.lpSurface);

		}else{

			HBITMAP bmp;
			HDC     hdc, cdc;
						
			bmp = CreateBitmap(w, h, 1, 32, pic);

			if(!FAILED(IDirectDrawSurface2_GetDC(lpDDS_back, &hdc)))
			{
				cdc = CreateCompatibleDC(0);
				
				SelectObject(cdc, bmp);
				BitBlt(hdc, 0, 0, w, h, cdc, 0, 0, SRCCOPY);
				IDirectDrawSurface2_ReleaseDC(lpDDS_back, hdc);

				DeleteDC(cdc);
			}

			DeleteObject(bmp);
		}

		IDirectDrawSurface2_Flip(lpDDS, 0, DDFLIP_WAIT);
	}



	return 1;
}
Beispiel #15
0
static int
DDCreateSurface(directx_priv *priv, ggi_mode *mode)
{
	HRESULT hr;
	LPDIRECTDRAWCLIPPER pClipper;
	DDSURFACEDESC pddsd, bddsd;
	int i;

	if (!priv->fullscreen)
		IDirectDraw2_SetCooperativeLevel(priv->lpddext, priv->hWnd,
						DDSCL_NORMAL);
	else {
		/* Only the thread that has excluse access (Cooperative level)
		 * may restore the surfaces when they are lost. Therefore
		 * let the helper thread get exclusive access so that it can
		 * later do restores.
		 */
		directx_fullscreen dxfull;
		dxfull.priv = priv;
		dxfull.mode = mode;
		dxfull.event = CreateEvent(NULL, FALSE, FALSE, NULL);
		PostThreadMessage(priv->nThreadID,
			WM_DDFULLSCREEN, 0, (long)&dxfull);
		WaitForSingleObject(dxfull.event, INFINITE);
		CloseHandle(dxfull.event);
	}

	/* create the primary surface */
	memset(&pddsd, 0, sizeof(pddsd));
	pddsd.dwSize = sizeof(pddsd);
	pddsd.dwFlags = DDSD_CAPS;
	pddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
	if (priv->fullscreen)
		pddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
	hr = IDirectDraw2_CreateSurface(priv->lpddext, &pddsd,
				       &priv->lppdds, NULL);
	if (hr != 0) {
		fprintf(stderr,
			"Init Primary Surface Failed RC = %lx. Exiting\n",
			hr);
		exit(-1);
	}
	IDirectDraw2_CreateClipper(priv->lpddext, 0, &pClipper, NULL);
	IDirectDrawClipper_SetHWnd(pClipper, 0, priv->hWnd);
	IDirectDrawSurface_SetClipper(priv->lppdds, pClipper);
	IDirectDrawClipper_Release(pClipper);
	pddsd.dwSize = sizeof(pddsd);
	IDirectDrawSurface_GetSurfaceDesc(priv->lppdds, &pddsd);

	DPRINT_MISC("DDraw pixel format:\n");
	DPRINT_MISC("  Size %u\n", pddsd.ddpfPixelFormat.dwSize);
	DPRINT_MISC("  Flags %08x\n", pddsd.ddpfPixelFormat.dwFlags);
	DPRINT_MISC("  FourCC %08x\n", pddsd.ddpfPixelFormat.dwFourCC);
	DPRINT_MISC("  Count %u\n", pddsd.ddpfPixelFormat.dwRGBBitCount);
	DPRINT_MISC("  R-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwRBitMask);
	DPRINT_MISC("  G-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwGBitMask);
	DPRINT_MISC("  B-Mask(etc) %08x\n", pddsd.ddpfPixelFormat.dwBBitMask);
	DPRINT_MISC("  Z-Mask(etc) %08x\n",
		pddsd.ddpfPixelFormat.dwRGBZBitMask);

	/* create the back storages */
	for (i = 0; i < mode->frames; ++i) {
		memset(&bddsd, 0, sizeof(bddsd));
		bddsd.dwSize = sizeof(bddsd);
		bddsd.dwFlags =
		    DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
		bddsd.ddsCaps.dwCaps =
		    DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
		bddsd.dwWidth = mode->virt.x;
		bddsd.dwHeight = mode->virt.y;

		/* set up the pixel format */
		ZeroMemory(&bddsd.ddpfPixelFormat, sizeof(DDPIXELFORMAT));
		bddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
		bddsd.ddpfPixelFormat.dwFlags =
		    pddsd.ddpfPixelFormat.dwFlags;
		bddsd.ddpfPixelFormat.dwFourCC =
		    pddsd.ddpfPixelFormat.dwFourCC;
		bddsd.ddpfPixelFormat.dwRGBBitCount =
		    pddsd.ddpfPixelFormat.dwRGBBitCount;
		bddsd.ddpfPixelFormat.dwRBitMask =
		    pddsd.ddpfPixelFormat.dwRBitMask;
		bddsd.ddpfPixelFormat.dwGBitMask =
		    pddsd.ddpfPixelFormat.dwGBitMask;
		bddsd.ddpfPixelFormat.dwBBitMask =
		    pddsd.ddpfPixelFormat.dwBBitMask;
		bddsd.ddpfPixelFormat.dwRGBAlphaBitMask =
		    pddsd.ddpfPixelFormat.dwRGBAlphaBitMask;

		hr = IDirectDraw2_CreateSurface(priv->lpddext,
					       &bddsd, &priv->lpbdds[i],
					       NULL);
		if (hr) {
			fprintf(stderr,
				"Init Backup Failed RC = %lx. Exiting\n", hr);
			exit(-1);
		}
		IDirectDrawSurface2_Lock(priv->lpbdds[i], NULL, &bddsd,
					 DDLOCK_SURFACEMEMORYPTR, NULL);
		priv->lpSurfaceAdd[i] = (char *) bddsd.lpSurface;
		IDirectDrawSurface2_Unlock(priv->lpbdds[i],
					   bddsd.lpSurface);
	}

	/* set private mode parameters */
	priv->maxX = mode->virt.x;
	priv->maxY = mode->virt.y;
	priv->ColorDepth = pddsd.ddpfPixelFormat.dwRGBBitCount;
	priv->pitch = bddsd.lPitch;

	if (pddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
		static PALETTEENTRY pal[256];
		/* todo fill in pal */
		hr = IDirectDraw_CreatePalette(priv->lpddext,
			DDPCAPS_8BIT|DDPCAPS_ALLOW256,
			pal, &priv->lpddp, NULL);
		if (hr) {
			fprintf(stderr,
				"Init Palette failed RC = %lx. Exiting\n",
				hr);
			exit(-1);
		}
		hr = IDirectDrawSurface_SetPalette(priv->lppdds, priv->lpddp);
		if (hr) {
			fprintf(stderr,
				 "Install Palette failed RC = %lx. Exiting\n",
				hr);
			exit(-1);
		}
	}

	return 1;
}