📄 user.c
字号:
return S_OK;}HRESULT User_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp){ if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { POINT offset; HWND hDisplayWnd; HDC hDisplayDC; HRESULT hr; hDisplayWnd = get_display_window(This, &offset); hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE); hr = GetDeviceGammaRamp(hDisplayDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED; ReleaseDC(hDisplayWnd, hDisplayDC); return hr; } return Main_DirectDrawSurface_get_gamma_ramp(This, dwFlags, lpGammaRamp);}HRESULT User_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp){ if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { POINT offset; HWND hDisplayWnd; HDC hDisplayDC; HRESULT hr; hDisplayWnd = get_display_window(This, &offset); hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE); hr = SetDeviceGammaRamp(hDisplayDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED; ReleaseDC(hDisplayWnd, hDisplayDC); return hr; } return Main_DirectDrawSurface_set_gamma_ramp(This, dwFlags, lpGammaRamp);}/* Returns the window that hosts the display. * *pt is set to the upper left position of the window relative to the * upper left corner of the surface. */static HWND get_display_window(IDirectDrawSurfaceImpl* This, LPPOINT pt){ memset(pt, 0, sizeof(*pt)); if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN) {#ifdef OWN_WINDOW USER_PRIV_VAR(priv, This);#if 1 SetWindowPos(priv->user.window, HWND_TOP, 0, 0, 0, 0, SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE| SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE);#endif return priv->user.window;#else return This->ddraw_owner->window;#endif } else { if (This->clipper != NULL) { /* looks silly, but since we don't have the clipper locked */ HWND hWnd = This->clipper->hWnd; if (hWnd != 0) { ClientToScreen(hWnd, pt); return hWnd; } else { static BOOL warn = 0; if (!warn++) FIXME("clipper clip lists not supported\n"); return GetDesktopWindow(); } } else { static BOOL warn = 0; if (!warn++) WARN("hosting on root\n"); return GetDesktopWindow(); } }}HWND User_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This){ POINT offset; return get_display_window(This, &offset);}#ifdef OWN_WINDOWstatic void User_create_own_window(IDirectDrawSurfaceImpl* This){ USER_PRIV_VAR(priv, This); if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN) { priv->user.window = CreateWindowExA(WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TRANSPARENT, "WINE_DDRAW", "DirectDraw", WS_POPUP, 0, 0, This->surface_desc.dwWidth, This->surface_desc.dwHeight, GetDesktopWindow(), 0, 0, This); This->more.lpDDRAWReserved = (LPVOID)priv->user.window; SetWindowPos(priv->user.window, HWND_TOP, 0, 0, 0, 0, SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE| SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_SHOWWINDOW); UpdateWindow(priv->user.window); }}static void User_destroy_own_window(IDirectDrawSurfaceImpl* This){ USER_PRIV_VAR(priv, This); if (priv->user.window) { SetWindowPos(priv->user.window, 0, 0, 0, 0, 0, SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOZORDER| SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_HIDEWINDOW); This->more.lpDDRAWReserved = NULL; DestroyWindow(priv->user.window); priv->user.window = 0; }}#endif#ifndef SYNC_UPDATEstatic DWORD CALLBACK User_update_thread(LPVOID arg){ IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)arg; USER_PRIV_VAR(priv, This); volatile HANDLE *pActive = (volatile HANDLE *)&priv->user.update_event; HANDLE event = *pActive;#ifdef OWN_WINDOW User_create_own_window(This);#endif /* the point of this is that many games lock the primary surface * multiple times per frame; this thread will then simply copy as * often as it can without keeping the main thread waiting for * each unlock, thus keeping the frame rate high */ do {#ifdef OWN_WINDOW DWORD ret = MsgWaitForMultipleObjects(1, &event, FALSE, INFINITE, QS_ALLINPUT); MSG msg; while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) { switch (msg.message) { case WM_PAINT: DispatchMessageA(&msg); break; default: /* since we risk getting keyboard messages posted to us, * repost posted messages to cooperative window */ PostMessageA(This->ddraw_owner->window, msg.message, msg.wParam, msg.lParam); } }#else DWORD ret = WaitForSingleObject(event, INFINITE);#endif if (ret == WAIT_OBJECT_0) { if (*pActive) { priv->user.in_refresh = TRUE; User_copy_to_screen(This, NULL); EnterCriticalSection(&priv->user.crit); priv->user.in_refresh = FALSE; if (priv->user.wait_count) SetEvent(priv->user.refresh_event); LeaveCriticalSection(&priv->user.crit); } else break; } else if (ret != WAIT_OBJECT_0+1) break; } while (TRUE); SetEvent(priv->user.refresh_event);#ifdef OWN_WINDOW User_destroy_own_window(This);#endif return 0;}#endifstatic void User_copy_to_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc){ if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { POINT offset; HWND hDisplayWnd; HDC hDisplayDC; HDC hSurfaceDC; RECT drawrect; if (FAILED(This->get_dc(This, &hSurfaceDC))) return; hDisplayWnd = get_display_window(This, &offset); hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE);#if 0 /* FIXME: this doesn't work... if users really want to run * X in 8bpp, then we need to call directly into display.drv * (or Wine's equivalent), and force a private colormap * without default entries. */ if (This->palette) { SelectPalette(hDisplayDC, This->palette->hpal, FALSE); RealizePalette(hDisplayDC); /* sends messages => deadlocks */ }#endif drawrect.left = 0; drawrect.right = This->surface_desc.dwWidth; drawrect.top = 0; drawrect.bottom = This->surface_desc.dwHeight; if (This->clipper) { RECT xrc; HWND hwnd = This->clipper->hWnd; if (hwnd && GetClientRect(hwnd,&xrc)) { OffsetRect(&xrc,offset.x,offset.y); IntersectRect(&drawrect,&drawrect,&xrc); } } if (rc) IntersectRect(&drawrect,&drawrect,rc); else { /* Only use this if the caller did not pass a rectangle, since * due to double locking this could be the wrong one ... */ if (This->lastlockrect.left != This->lastlockrect.right) IntersectRect(&drawrect,&drawrect,&This->lastlockrect); } BitBlt(hDisplayDC, drawrect.left-offset.x, drawrect.top-offset.y, drawrect.right-drawrect.left, drawrect.bottom-drawrect.top, hSurfaceDC, drawrect.left, drawrect.top, SRCCOPY ); ReleaseDC(hDisplayWnd, hDisplayDC); }}#if 0static void User_copy_from_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc){ if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { POINT offset; HWND hDisplayWnd = get_display_window(This, &offset); HDC hDisplayDC = GetDC(hDisplayWnd); RECT drawrect; drawrect.left = 0; drawrect.right = This->surface_desc.dwWidth; drawrect.top = 0; drawrect.bottom = This->surface_desc.dwHeight; if (rc) IntersectRect(&drawrect,&drawrect,rc); BitBlt(This->hDC, drawrect.left, drawrect.top, drawrect.right-drawrect.left, drawrect.bottom-drawrect.top, hDisplayDC, drawrect.left+offset.x, drawrect.top+offset.y, SRCCOPY ); ReleaseDC(hDisplayWnd, hDisplayDC); }}#endifstatic ICOM_VTABLE(IDirectDrawSurface7) User_IDirectDrawSurface7_VTable ={ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE Main_DirectDrawSurface_QueryInterface, Main_DirectDrawSurface_AddRef, Main_DirectDrawSurface_Release, Main_DirectDrawSurface_AddAttachedSurface, Main_DirectDrawSurface_AddOverlayDirtyRect, DIB_DirectDrawSurface_Blt, Main_DirectDrawSurface_BltBatch, DIB_DirectDrawSurface_BltFast, Main_DirectDrawSurface_DeleteAttachedSurface, Main_DirectDrawSurface_EnumAttachedSurfaces, Main_DirectDrawSurface_EnumOverlayZOrders, Main_DirectDrawSurface_Flip, Main_DirectDrawSurface_GetAttachedSurface, Main_DirectDrawSurface_GetBltStatus, Main_DirectDrawSurface_GetCaps, Main_DirectDrawSurface_GetClipper, Main_DirectDrawSurface_GetColorKey, Main_DirectDrawSurface_GetDC, Main_DirectDrawSurface_GetFlipStatus, Main_DirectDrawSurface_GetOverlayPosition, Main_DirectDrawSurface_GetPalette, Main_DirectDrawSurface_GetPixelFormat, Main_DirectDrawSurface_GetSurfaceDesc, Main_DirectDrawSurface_Initialize, Main_DirectDrawSurface_IsLost, Main_DirectDrawSurface_Lock, Main_DirectDrawSurface_ReleaseDC, DIB_DirectDrawSurface_Restore, Main_DirectDrawSurface_SetClipper, Main_DirectDrawSurface_SetColorKey, Main_DirectDrawSurface_SetOverlayPosition, Main_DirectDrawSurface_SetPalette, Main_DirectDrawSurface_Unlock, Main_DirectDrawSurface_UpdateOverlay, Main_DirectDrawSurface_UpdateOverlayDisplay, Main_DirectDrawSurface_UpdateOverlayZOrder, Main_DirectDrawSurface_GetDDInterface, Main_DirectDrawSurface_PageLock, Main_DirectDrawSurface_PageUnlock, DIB_DirectDrawSurface_SetSurfaceDesc, Main_DirectDrawSurface_SetPrivateData, Main_DirectDrawSurface_GetPrivateData, Main_DirectDrawSurface_FreePrivateData, Main_DirectDrawSurface_GetUniquenessValue, Main_DirectDrawSurface_ChangeUniquenessValue, Main_DirectDrawSurface_SetPriority, Main_DirectDrawSurface_GetPriority, Main_DirectDrawSurface_SetLOD, Main_DirectDrawSurface_GetLOD};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -