Esempio n. 1
0
static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
{
    vout_display_sys_t *sys = vd->sys;

    assert(sys->display);

    /* Our surface can be lost so be sure to check this
     * and restore it if need be */
    if (IDirectDrawSurface2_IsLost(sys->display) == DDERR_SURFACELOST) {
        if (IDirectDrawSurface2_Restore(sys->display) == DD_OK) {
            if (sys->use_overlay)
                DirectXUpdateOverlay(vd, NULL);
        }
    }
    if (sys->restore_overlay)
        DirectXUpdateOverlay(vd, NULL);

    /* */
    DirectXUnlock(picture);

    if (sys->use_overlay) {
        /* Flip the overlay buffers if we are using back buffers */
        if (picture->p_sys->surface != picture->p_sys->front_surface) {
            HRESULT hr = IDirectDrawSurface2_Flip(picture->p_sys->front_surface,
                                                  NULL, DDFLIP_WAIT);
            if (hr != DD_OK)
                msg_Warn(vd, "could not flip overlay (error %li)", hr);
        }
    } else {
        /* Blit video surface to display with the NOTEARING option */
        DDBLTFX  ddbltfx;
        ZeroMemory(&ddbltfx, sizeof(ddbltfx));
        ddbltfx.dwSize = sizeof(ddbltfx);
        ddbltfx.dwDDFX = DDBLTFX_NOTEARING;

        HRESULT hr = IDirectDrawSurface2_Blt(sys->display,
                                             &sys->rect_dest_clipped,
                                             picture->p_sys->surface,
                                             &sys->rect_src_clipped,
                                             DDBLT_ASYNC, &ddbltfx);
        if (hr != DD_OK)
            msg_Warn(vd, "could not blit surface (error %li)", hr);
    }
    DirectXLock(picture);

    if (sys->is_first_display) {
        IDirectDraw_WaitForVerticalBlank(sys->ddobject,
                                         DDWAITVB_BLOCKBEGIN, NULL);
        if (sys->use_overlay) {
            HBRUSH brush = CreateSolidBrush(sys->i_rgb_colorkey);
            /* set the colorkey as the backgound brush for the video window */
            SetClassLongPtr(sys->hvideownd, GCLP_HBRBACKGROUND, (LONG_PTR)brush);
        }
    }
    CommonDisplay(vd);

    picture_Release(picture);
    VLC_UNUSED(subpicture);
}
Esempio n. 2
0
/* ddraw_do_stretch_blit:
 *   Accelerated stretch_blit, stretch_sprite, stretch_masked_blit
 */
static void ddraw_do_stretch_blit(struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int source_width, int source_height, int dest_x, int dest_y, int dest_width, int dest_height, int masked)
{
   RECT dest_rect, source_rect;
   DDCOLORKEY src_key;
   HRESULT hr;
   BITMAP *dest_parent;
   BITMAP *source_parent;

   dest_rect.left = dest_x + dest->x_ofs;
   dest_rect.top = dest_y + dest->y_ofs;
   dest_rect.right = dest_x + dest->x_ofs + dest_width;
   dest_rect.bottom = dest_y + dest->y_ofs + dest_height;

   source_rect.left = source_x + source->x_ofs;
   source_rect.top = source_y + source->y_ofs;
   source_rect.right = source_x + source->x_ofs + source_width;
   source_rect.bottom = source_y + source->y_ofs + source_height;

   src_key.dwColorSpaceLowValue = source->vtable->mask_color;
   src_key.dwColorSpaceHighValue = source->vtable->mask_color;

   if ( ( (masked && (gfx_capabilities & GFX_HW_VRAM_STRETCH_BLIT_MASKED)) ||
          (!masked && (gfx_capabilities & GFX_HW_VRAM_STRETCH_BLIT)) 
        ) && ( is_video_bitmap(source) || is_system_bitmap(source) ) ) {

      /* find parents */
      dest_parent = dest;
      while (dest_parent->id & BMP_ID_SUB)
         dest_parent = (BITMAP *)dest_parent->extra;

      source_parent = source;
      while (source_parent->id & BMP_ID_SUB)
         source_parent = (BITMAP *)source_parent->extra;

      _enter_gfx_critical();
      gfx_directx_release_lock(dest);
      gfx_directx_release_lock(source);

      IDirectDrawSurface2_SetColorKey(DDRAW_SURFACE_OF(source_parent)->id,
                                      DDCKEY_SRCBLT, &src_key);

      hr = IDirectDrawSurface2_Blt(DDRAW_SURFACE_OF(dest_parent)->id, &dest_rect,
                                   DDRAW_SURFACE_OF(source_parent)->id, &source_rect,
                                   (masked ? DDBLT_KEYSRC : 0) | DDBLT_WAIT, NULL);
      _exit_gfx_critical();

      if (FAILED(hr))
	 _TRACE(PREFIX_E "Blt failed (%x)\n", hr);

      /* only for windowed mode */
      if ((gfx_driver->id == GFX_DIRECTX_WIN) && (dest_parent == gfx_directx_forefront_bitmap))
         win_gfx_driver->paint(&dest_rect);
   }
   else {
      /* have to use the original software version */
      _orig_stretch_blit(source, dest, source_x, source_y, source_width, source_height, dest_x, dest_y, dest_width, dest_height, masked);
   }
}
Esempio n. 3
0
static Bool
winRedrawScreenShadowDD (ScreenPtr pScreen)
{
  winScreenPriv(pScreen);
  winScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
  HRESULT		ddrval = DD_OK;
  RECT			rcSrc, rcDest;
  POINT			ptOrigin;

  /* 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 entire shadow surface, as Blt should clip for us */
  rcSrc.left = 0;
  rcSrc.top = 0;
  rcSrc.right = pScreenInfo->dwWidth;
  rcSrc.bottom = pScreenInfo->dwHeight;

  /* Redraw the whole window, to take account for the new colors */
  ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary,
				    &rcDest,
				    pScreenPriv->pddsShadow,
				    &rcSrc,
				    DDBLT_WAIT,
				    NULL);
  if (FAILED (ddrval))
    {
      ErrorF ("winRedrawScreenShadowDD - IDirectDrawSurface_Blt () "
	      "failed: %08x\n",
	      (unsigned int) ddrval);
    }

  return TRUE;
}
Esempio n. 4
0
/* ddraw_clear_to_color:
 *  Accelerated screen clear routine.
 */
static void ddraw_clear_to_color(BITMAP * bitmap, int color)
{
   RECT dest_rect;
   HRESULT hr;
   DDBLTFX blt_fx;
   BITMAP *parent;

   dest_rect.left = bitmap->cl + bitmap->x_ofs;
   dest_rect.top = bitmap->ct + bitmap->y_ofs;
   dest_rect.right = bitmap->x_ofs + bitmap->cr;
   dest_rect.bottom = bitmap->y_ofs + bitmap->cb;

   /* find parent */
   parent = bitmap;
   while (parent->id & BMP_ID_SUB)
      parent = (BITMAP *)parent->extra;

   /* set fill color */
   blt_fx.dwSize = sizeof(blt_fx);
   blt_fx.dwDDFX = 0;
   blt_fx.dwFillColor = color;

   _enter_gfx_critical();
   gfx_directx_release_lock(bitmap);

   hr = IDirectDrawSurface2_Blt(DDRAW_SURFACE_OF(parent)->id, &dest_rect,
                                NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blt_fx);
   _exit_gfx_critical();

   if (FAILED(hr))
      _TRACE(PREFIX_E "Blt failed (%x)\n", hr);

   /* only for windowed mode */
   if ((gfx_driver->id == GFX_DIRECTX_WIN) && (parent == gfx_directx_forefront_bitmap))
      win_gfx_driver->paint(&dest_rect);
}
Esempio 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 = 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;
	}
    }
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}
Esempio n. 9
0
void directdraw_update(int mode)
{
    RECT   source;
    RECT   destination;
	RECT   rectosd, rct, rectwindow;
    POINT  point;
	int    rw, rh, rx = 0, ry = 0; /* relative sizes */
	int    tmprw, tmprh, tmprx = 0, tmpry = 0; /* temporary relative sizes */
	int    ww, wh;                 /* video window sizes */
	float  sc;                     /* scale */
	int    r_frame_w, r_frame_h;   /* resized values of frame size (aspect ratio based) */
	

	if(!video_window) return;
	if(!lpDDS)return;
	if(use_osd_surface && !surface_osd)return;
	if(!lpDDS_secondary)return;

	//frame_w = default_sw;
	//frame_h = default_sh;

	if(lpDDS)
	{
		r_frame_w = frame_w;
		r_frame_h = frame_h;
		
		if(aspect_ratio > 0.0)
			r_frame_h = (int)((double)r_frame_h / aspect_ratio);

		source.left   = 0;
		source.top    = 0;
		source.right  = d_width;
		source.bottom = d_height;

		rectwindow.left   = 0;
		rectwindow.top    = 0;
		rectwindow.right  = window_w;
		rectwindow.bottom = window_h;


		point.x = 0;
		point.y = 0;
		ClientToScreen(video_window, &point);

		GetClientRect(video_window, &destination);
		GetClientRect(video_window, &rct);


		destination.left   += point.x;
		destination.top    += point.y;
		destination.right  += point.x;
		destination.bottom += point.y;

		//vdata.getdata(get_window_video_rect, 0, &rct, 0);
		//vdata.getdata(get_window_video_dc, 0, &hdc, 0);

		//if(w <= 0)w = 256;
		//if(h <= 0)h = 256;

		ww = rw = rct.right - rct.left;
		wh = rh = rct.bottom - rct.top;

		if(frame_w > frame_h)
		{
			sc = (float)rw / (float)r_frame_w;
		}else{
			sc = (float)rh / (float)r_frame_h;
		}

		/* to keep aspect ratio, both width and height should be scaled equally */
		
		rw = (int)((float)r_frame_w * sc);
		rh = (int)((float)r_frame_h * sc);

		/* we gotta handle video's corners vertically and check if it's gonna surpass the parent window's borders */

		if(rh > wh)
			sc = (float)wh / (float)r_frame_h;

		if(rw > ww)
			sc = (float)ww / (float)r_frame_w;

		/* any changes? calculate'em again */

		rw = (int)((float)r_frame_w * sc);
		rh = (int)((float)r_frame_h * sc);

		/* calculate video position */

		rx = (ww - rw) / 2;
		ry = (wh - rh) / 2;


		if(use_osd_surface)
		{

			
			if(video_zoom_x <= 1.0)
			{
				video_zoom_x = 1.0;
				crop_pos_x = 0;
			}
			if(video_zoom_y <= 1.0)
			{
				video_zoom_y = 1.0;
				crop_pos_y = 0;
			}


			
			//tmprw = (rx + rw) * video_zoom;
			//tmprh = (ry + rh) * video_zoom;

			/*if(tmprw < destination.right && tmprh < destination.bottom)
			{
				rw *= video_zoom;
				rh *= video_zoom;
			}else{
				source.right /= video_zoom;
				source.bottom /= video_zoom;
			}	*/

			//if(source.left + crop_pos_x > source.right)crop_pos_x = source.right - source.left;
			//if(source.top + crop_pos_y > source.bottom)crop_pos_y = source.bottom - source.top;

			source.left = crop_pos_x;
			source.top = crop_pos_y;
			source.right = crop_pos_x + (d_width / video_zoom_x);
			source.bottom = crop_pos_y + (d_height / video_zoom_y);

			if(source.left < 0)
			{
				source.left = 0;
				source.right = (d_width / video_zoom_x);
			}
			if(source.top < 0)
			{
				source.top = 0;
				source.bottom = (d_height / video_zoom_y);
			}

			if(source.right > d_width)
			{
				source.left = d_width - (d_width / video_zoom_x);
				source.right = d_width;
			}
			if(source.bottom > d_height)
			{
				source.top = d_height - (d_height / video_zoom_y);
				source.bottom = d_height;
			}

			rectosd.left   = rx;
			rectosd.top    = ry;
			rectosd.right  = rw + rx;
			rectosd.bottom = rh + ry;

			if(video_zoom_y > 1.0 || video_zoom_x > 1.0)
			{
				rectosd.left   = 0;
				rectosd.top    = 0;
				rectosd.right  = window_w;
				rectosd.bottom = window_h;
			}
			
		}


		if(!use_osd_surface)
		{
			IDirectDrawSurface2_Blt(lpDDS, &destination, lpDDS_secondary, &source, DDBLT_WAIT, 0);
		}else{
			HDC  hdc;
			DDBLTFX bfx;
			memset(&bfx, 0, sizeof(bfx));
			bfx.dwFillColor = 0x000000;
			bfx.dwSize      = sizeof(bfx);

			IDirectDrawSurface2_Blt(surface_osd, 0, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bfx);
			
			if(mode)
			{
				
				HRESULT res = IDirectDrawSurface2_Blt(surface_osd, &rectosd, lpDDS_secondary, &source, DDBLT_WAIT | DDBLT_ZBUFFER, 0);
				
				if(show_crop_rect)
				{
					RECT rcr;
					float ar;
					int   vsize = 100, vw;

					ar = d_width / d_height;
					vw = (vsize * ar);

					rcr.top = 5;
					rcr.left = 5;
					rcr.bottom = 5 + vsize;
					rcr.right = 5 + vw;
					
					IDirectDrawSurface2_Blt(surface_osd, &rcr, lpDDS_secondary, &source, DDBLT_WAIT | DDBLT_ZBUFFER, 0);

				}

			}

			if(!FAILED(IDirectDrawSurface2_GetDC(surface_osd, &hdc)))
			{
				float ar;
				int   vsize = 100, vw;
				HPEN    hold_pen;
				HBRUSH  hold_brush;

				if(subtitle_text && show_subtitles)
				{
					RECT   rct, nrct;
					HFONT  nfont, ofont;
					int    subs_fontsize, soffset;
					string subtitle_font_face = uni("Arial");
					static letter subtitle_str[4096];
					static int    sub_italic = 0, sub_bold = 0, sub_underlined = 0;
					static string last_substr;

					if(subtitle_text != last_substr)
					{
						last_substr = subtitle_text;
						str_cpy(subtitle_str, subtitle_text);
						if(replace_i_str(subtitle_str, uni("<i>"), uni("")))
						{
							sub_italic = 1;
							replace_i_str(subtitle_str, uni("</i>"), uni(""));
						}
						if(replace_i_str(subtitle_str, uni("<b>"), uni("")))
						{
							sub_bold = 1;
							replace_i_str(subtitle_str, uni("</b>"), uni(""));
						}
						if(replace_i_str(subtitle_str, uni("<u>"), uni("")))
						{
							sub_underlined = 1;
							replace_i_str(subtitle_str, uni("</u>"), uni(""));
						}
					}

					rct.top     = window_h;
					rct.bottom  = window_h;
					rct.left    = 0;
					rct.right   = window_w;

					subs_fontsize = min(max((min(window_h, window_w) * 15) / 250, 10), 22);
					soffset = min(subs_fontsize / 10, 2);

					nfont = CreateFont(-MulDiv(subs_fontsize, GetDeviceCaps(hdc, LOGPIXELSY), 72),
						0, 0, 0, sub_bold ? FW_BOLD : FW_NORMAL, sub_italic, sub_underlined, 0, DEFAULT_CHARSET,
										OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
										DEFAULT_PITCH, subtitle_font_face);

					ofont = (HFONT) SelectObject(hdc, nfont);

					SetBkMode(hdc, TRANSPARENT);

					nrct.left  = 0;
					nrct.right = window_w;

					DrawText(hdc, subtitle_str, str_len(subtitle_str), &nrct, DT_CENTER | DT_WORDBREAK | DT_CALCRECT);

					rct.top -= nrct.bottom - nrct.top;
					rct.top -= window_h / 12;

					SetTextColor(hdc, 0x000000);

					rct.top   -= soffset; rct.left  -= soffset; rct.right -= soffset;
					DrawText(hdc, subtitle_str, str_len(subtitle_str), &rct, DT_CENTER | DT_WORDBREAK);
					rct.top   += soffset; rct.left  += soffset; rct.right += soffset;

					rct.top   += soffset; rct.left  += soffset; rct.right += soffset;
					DrawText(hdc, subtitle_str, str_len(subtitle_str), &rct, DT_CENTER | DT_WORDBREAK);
					rct.top   -= soffset; rct.left  -= soffset; rct.right -= soffset;

					SetTextColor(hdc, 0xffffff);
					DrawText(hdc, subtitle_str, str_len(subtitle_str), &rct, DT_CENTER | DT_WORDBREAK);

					SelectObject(hdc, ofont);
					DeleteObject(nfont);	
				} /* </if - subtitles_text> */

				if(subtitle_text_sec)
				{
					RECT   rct, nrct;
					HFONT  nfont, ofont;
					int    subs_fontsize, soffset;
					string subtitle_font_face = uni("Arial");
					static letter subtitle_str[4096];
					static int    sub_italic = 0, sub_bold = 0, sub_underlined = 0;
					static string last_substr;

					if(subtitle_text_sec != last_substr)
					{
						last_substr = subtitle_text_sec;
						str_cpy(subtitle_str, subtitle_text_sec);
						if(replace_i_str(subtitle_str, uni("<i>"), uni("")))
						{
							sub_italic = 1;
							replace_i_str(subtitle_str, uni("</i>"), uni(""));
						}
						if(replace_i_str(subtitle_str, uni("<b>"), uni("")))
						{
							sub_bold = 1;
							replace_i_str(subtitle_str, uni("</b>"), uni(""));
						}
						if(replace_i_str(subtitle_str, uni("<u>"), uni("")))
						{
							sub_underlined = 1;
							replace_i_str(subtitle_str, uni("</u>"), uni(""));
						}
					}

					rct.top     = window_h;
					rct.bottom  = window_h;
					rct.left    = 0;
					rct.right   = window_w;

					subs_fontsize = min(max((min(window_h, window_w) * 15) / 250, 10), 22);
					soffset = min(subs_fontsize / 10, 2);

					nfont = CreateFont(-MulDiv(subs_fontsize, GetDeviceCaps(hdc, LOGPIXELSY), 72),
										0, 0, 0, sub_bold ? FW_BOLD : FW_NORMAL, sub_italic, sub_underlined, 0, DEFAULT_CHARSET,
										OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
										DEFAULT_PITCH, subtitle_font_face);

					ofont = (HFONT) SelectObject(hdc, nfont);

					SetBkMode(hdc, TRANSPARENT);

					nrct.left  = 0;
					nrct.right = window_w;

					DrawText(hdc, subtitle_str, str_len(subtitle_str), &nrct, DT_CENTER | DT_WORDBREAK | DT_CALCRECT);

					rct.top = window_h / 16;

					SetTextColor(hdc, 0x000000);

					rct.top   -= soffset; rct.left  -= soffset; rct.right -= soffset;
					DrawText(hdc, subtitle_str, str_len(subtitle_str), &rct, DT_CENTER | DT_WORDBREAK);
					rct.top   += soffset; rct.left  += soffset; rct.right += soffset;

					rct.top   += soffset; rct.left  += soffset; rct.right += soffset;
					DrawText(hdc, subtitle_str, str_len(subtitle_str), &rct, DT_CENTER | DT_WORDBREAK);
					rct.top   -= soffset; rct.left  -= soffset; rct.right -= soffset;

					SetTextColor(hdc, 0xffffff);
					DrawText(hdc, subtitle_str, str_len(subtitle_str), &rct, DT_CENTER | DT_WORDBREAK);

					SelectObject(hdc, ofont);
					DeleteObject(nfont);	
				} /* </if - subtitles_text> */


				/* draw osd controls */
				
				osd_display(hdc, rectosd.right, rectosd.bottom);
				
	
				
				if(show_crop_rect)
				{
					ar = d_width / d_height;
					vw = (vsize * ar);

					hold_pen = (HPEN)SelectObject(hdc, crop_rect_pen);
					hold_brush = (HBRUSH)SelectObject(hdc, crop_rect_brush);

					Rectangle(hdc, 5, 5, 5 + vw, 5 + vsize);
					Rectangle(hdc, 5 + ((source.left * vw) / d_width), 5 + ((source.top * vsize) / d_height), 5 + ((source.right * vw) / d_width), 5 + ((source.bottom * vsize) / d_height));

					SelectObject(hdc, hold_pen);
					SelectObject(hdc, hold_brush);
				}
				
				IDirectDrawSurface2_ReleaseDC(surface_osd, hdc);
			}

			IDirectDrawSurface2_Blt(lpDDS, &destination, surface_osd, &rectwindow, DDBLT_WAIT, 0);
		}
	}
}
Esempio n. 10
0
HRESULT BltDDSurfaceUsingSoftware( LPDIRECTDRAWSURFACE2 pDestSurface, LPRECT pDestRect, LPDIRECTDRAWSURFACE2 pSrcSurface, LPRECT pSrcRect, UINT32 uiFlags, LPDDBLTFX pDDBltFx )
{
	DDSURFACEDESC SurfaceDescription;
	UINT32 uiDestPitchBYTES, uiSrcPitchBYTES;
	UINT8	 *pDestBuf, *pSrcBuf;
  HRESULT       ReturnCode;
  DDCOLORKEY    ColorKey;
	UINT16				us16BPPColorKey;


	// Lock surfaces
	DDLockSurface( (LPDIRECTDRAWSURFACE2)pDestSurface, NULL, &SurfaceDescription, 0, NULL);
	uiDestPitchBYTES = SurfaceDescription.lPitch;
	pDestBuf				 = SurfaceDescription.lpSurface;


	if ( pSrcSurface != NULL )
	{
		// Lock surfaces
		DDLockSurface( (LPDIRECTDRAWSURFACE2)pSrcSurface, NULL, &SurfaceDescription, 0, NULL);
		uiSrcPitchBYTES = SurfaceDescription.lPitch;
		pSrcBuf				 = SurfaceDescription.lpSurface;
	}

	if ( pSrcRect != NULL && 
			 ( ( pSrcRect->right - pSrcRect->left ) != ( pDestRect->right - pDestRect->left ) ||
			 ( pSrcRect->bottom - pSrcRect->top ) != ( pDestRect->bottom - pDestRect->top ) ) )
	{
		DDUnlockSurface( (LPDIRECTDRAWSURFACE2)pDestSurface, NULL );

		if ( pSrcSurface != NULL )
		{
			DDUnlockSurface( (LPDIRECTDRAWSURFACE2)pSrcSurface, NULL );
		}

		// Fall back to DD
		IDirectDrawSurface2_Blt( pDestSurface, pDestRect, pSrcSurface, pSrcRect, uiFlags, pDDBltFx );

		return( DD_OK );
	}
	else if ( uiFlags == DDBLT_WAIT )
	{
		// Lock surfaces
		DDLockSurface( (LPDIRECTDRAWSURFACE2)pSrcSurface, NULL, &SurfaceDescription, 0, NULL);
		uiSrcPitchBYTES = SurfaceDescription.lPitch;
		pSrcBuf				 = SurfaceDescription.lpSurface;

		Blt16BPPTo16BPP( (UINT16 *)pDestBuf, uiDestPitchBYTES, 
					(UINT16 *)pSrcBuf, uiSrcPitchBYTES,  
					pDestRect->left , pDestRect->top, 
					pSrcRect->left , pSrcRect->top, 
					( pSrcRect->right - pSrcRect->left ), 
					( pSrcRect->bottom - pSrcRect->top ) );
	}
	else if ( uiFlags & DDBLT_KEYSRC )
	{
		// Get 16 bpp color key.....
		ReturnCode = IDirectDrawSurface2_GetColorKey( pSrcSurface, DDCKEY_SRCBLT, &ColorKey);

	  if (ReturnCode == DD_OK)
		{
			us16BPPColorKey = (UINT16)ColorKey.dwColorSpaceLowValue;

			Blt16BPPTo16BPPTrans( (UINT16 *)pDestBuf, uiDestPitchBYTES, 
						(UINT16 *)pSrcBuf, uiSrcPitchBYTES,  
						pDestRect->left , pDestRect->top, 
						pSrcRect->left , pSrcRect->top, 
						( pSrcRect->right - pSrcRect->left ), 
						( pSrcRect->bottom - pSrcRect->top ), us16BPPColorKey );

		}
	}
	else if ( uiFlags & DDBLT_COLORFILL )
	{
		// do color fill here...
		FillRect16BPP( (UINT16 *)pDestBuf, uiDestPitchBYTES, pDestRect->left, pDestRect->top, pDestRect->right, pDestRect->bottom, (UINT16)pDDBltFx->dwFillColor );
	}
	else
	{
		// Not supported.....
	}


	DDUnlockSurface( (LPDIRECTDRAWSURFACE2)pDestSurface, NULL );

	if ( pSrcSurface != NULL )
	{
		DDUnlockSurface( (LPDIRECTDRAWSURFACE2)pSrcSurface, NULL );
	}

	return( DD_OK );
}
Esempio n. 11
0
/* ddraw_vline:
 *  Accelerated vline routine.
 */
static void ddraw_vline(BITMAP *bitmap, int x, int y1, int y2, int color)
{
   RECT dest_rect;
   HRESULT hr;
   DDBLTFX blt_fx;
   BITMAP *parent;

   if (_drawing_mode != DRAW_MODE_SOLID) {
      _orig_vline(bitmap, x, y1, y2, color);
      return;
   }

   if (y1 > y2) {
      int tmp = y1;
      y1 = y2;
      y2 = tmp;
   }

   if (bitmap->clip) {
      if ((x < bitmap->cl) || (x >= bitmap->cr))
	 return;

      if (y1 < bitmap->ct)
	 y1 = bitmap->ct;

      if (y2 >= bitmap->cb)
	 y2 = bitmap->cb-1;

      if (y2 < y1)
	 return;
   }

   dest_rect.top = y1 + bitmap->y_ofs;
   dest_rect.left = x + bitmap->x_ofs;
   dest_rect.bottom = y2 + bitmap->y_ofs + 1;
   dest_rect.right = x + bitmap->x_ofs + 1;

   /* find parent */
   parent = bitmap;
   while (parent->id & BMP_ID_SUB)
      parent = (BITMAP *)parent->extra;

   /* set fill color */
   blt_fx.dwSize = sizeof(blt_fx);
   blt_fx.dwDDFX = 0;
   blt_fx.dwFillColor = color;

   _enter_gfx_critical();
   gfx_directx_release_lock(bitmap);

   hr = IDirectDrawSurface2_Blt(DDRAW_SURFACE_OF(parent)->id, &dest_rect,
                                NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blt_fx);
   _exit_gfx_critical();

   if (FAILED(hr))
      _TRACE(PREFIX_E "Blt failed (%x)\n", hr);

   /* only for windowed mode */
   if ((gfx_driver->id == GFX_DIRECTX_WIN) && (parent == gfx_directx_forefront_bitmap))
      win_gfx_driver->paint(&dest_rect);
}