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); }
/* 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); } }
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; }
/* 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); }
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; } } }
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; }
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; }
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; }
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); } } }
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 ); }
/* 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); }