void DDReleaseDC( LPDIRECTDRAWSURFACE2 pSurface, HDC hDC ) { Assert( pSurface != NULL ); ATTEMPT( IDirectDrawSurface2_ReleaseDC( pSurface, hDC ) ); }
/* win_release_dc: (WinAPI) * Releases device context of a video or system bitmap. */ void win_release_dc(BITMAP *bmp, HDC dc) { LPDIRECTDRAWSURFACE2 ddsurf; HRESULT hr; if (bmp) { if (bmp->id & (BMP_ID_SYSTEM | BMP_ID_VIDEO)) { ddsurf = DDRAW_SURFACE_OF(bmp)->id; hr = IDirectDrawSurface2_ReleaseDC(ddsurf, dc); /* If the surface has been lost, try to restore all surfaces * and, on success, try again to release the DC. */ if (hr == DDERR_SURFACELOST) { if (restore_all_ddraw_surfaces() == 0) hr = IDirectDrawSurface2_ReleaseDC(ddsurf, dc); } } } }
/** * 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 PrintWinFont( UINT32 uiDestBuf, INT32 iFont, INT32 x, INT32 y, STR16 pFontString, ...) { va_list argptr; CHAR16 string[512]; HVSURFACE hVSurface; LPDIRECTDRAWSURFACE2 pDDSurface; HDC hdc; HWINFONT *pWinFont; int len; pWinFont = GetWinFont( iFont ); if ( pWinFont == NULL ) { return; } va_start(argptr, pFontString); // Set up variable argument pointer len = vswprintf(string, pFontString, argptr); // process gprintf string (get output str) va_end(argptr); // Get surface... GetVideoSurface( &hVSurface, uiDestBuf ); pDDSurface = GetVideoSurfaceDDSurface( hVSurface ); IDirectDrawSurface2_GetDC( pDDSurface, &hdc ); SelectObject(hdc, pWinFont->hFont ); SetTextColor( hdc, pWinFont->ForeColor ); SetBkColor(hdc, pWinFont->BackColor ); SetBkMode(hdc, TRANSPARENT); SetTextAlign(hdc, TA_TOP|TA_LEFT); #ifdef DEC_INTERNAL_LEADING if (y - pWinFont->InternalLeading >=0) { y -= pWinFont->InternalLeading; } #endif TextOutW( hdc, x, y, string, len ); IDirectDrawSurface2_ReleaseDC( pDDSurface, hdc ); }
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; }
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); } } }