📄 device.c
字号:
* That shouldn't happen
*/
TRACE("(%p): Setting up window %p for exclusive mode\n", This, window);
if (This->style || This->exStyle) {
ERR("(%p): Want to change the window parameters of HWND %p, but "
"another style is stored for restoration afterwards\n", This, window);
}
/* Get the parameters and save them */
style = GetWindowLongW(window, GWL_STYLE);
exStyle = GetWindowLongW(window, GWL_EXSTYLE);
This->style = style;
This->exStyle = exStyle;
/* Filter out window decorations */
style &= ~WS_CAPTION;
style &= ~WS_THICKFRAME;
exStyle &= ~WS_EX_WINDOWEDGE;
exStyle &= ~WS_EX_CLIENTEDGE;
/* Make sure the window is managed, otherwise we won't get keyboard input */
style |= WS_POPUP | WS_SYSMENU;
TRACE("Old style was %08x,%08x, setting to %08x,%08x\n",
This->style, This->exStyle, style, exStyle);
SetWindowLongW(window, GWL_STYLE, style);
SetWindowLongW(window, GWL_EXSTYLE, exStyle);
/* Inform the window about the update. */
SetWindowPos(window, HWND_TOP, 0, 0,
This->ddraw_width, This->ddraw_height, SWP_FRAMECHANGED);
ShowWindow(window, SW_NORMAL);
}
/*****************************************************************************
* IWineD3DDeviceImpl_RestoreWindow
*
* Helper function that restores a windows' properties when taking it out
* of fullscreen mode
*
* Params:
* iface: Pointer to the IWineD3DDevice interface
* window: Window to setup
*
*****************************************************************************/
static void WINAPI IWineD3DDeviceImpl_RestoreWindow(IWineD3DDevice *iface, HWND window) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
/* This could be a DDSCL_NORMAL -> DDSCL_NORMAL
* switch, do nothing
*/
if (!This->style && !This->exStyle) return;
TRACE("(%p): Restoring window settings of window %p to %08x, %08x\n",
This, window, This->style, This->exStyle);
SetWindowLongW(window, GWL_STYLE, This->style);
SetWindowLongW(window, GWL_EXSTYLE, This->exStyle);
/* Delete the old values */
This->style = 0;
This->exStyle = 0;
/* Inform the window about the update */
SetWindowPos(window, 0 /* InsertAfter, ignored */,
0, 0, 0, 0, /* Pos, Size, ignored */
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
}
/* example at http://www.fairyengine.com/articles/dxmultiviews.htm */
static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevice* iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters, IWineD3DSwapChain** ppSwapChain,
IUnknown* parent,
D3DCB_CREATERENDERTARGETFN D3DCB_CreateRenderTarget,
D3DCB_CREATEDEPTHSTENCILSURFACEFN D3DCB_CreateDepthStencil) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
HDC hDc;
IWineD3DSwapChainImpl *object; /** NOTE: impl ref allowed since this is a create function **/
HRESULT hr = WINED3D_OK;
IUnknown *bufferParent;
TRACE("(%p) : Created Aditional Swap Chain\n", This);
/** FIXME: Test under windows to find out what the life cycle of a swap chain is,
* does a device hold a reference to a swap chain giving them a lifetime of the device
* or does the swap chain notify the device of its destruction.
*******************************/
/* Check the params */
if(pPresentationParameters->BackBufferCount > WINED3DPRESENT_BACK_BUFFER_MAX) {
ERR("App requested %d back buffers, this is not supported for now\n", pPresentationParameters->BackBufferCount);
return WINED3DERR_INVALIDCALL;
} else if (pPresentationParameters->BackBufferCount > 1) {
FIXME("The app requests more than one back buffer, this can't be supported properly. Please configure the application to use double buffering(=1 back buffer) if possible\n");
}
D3DCREATEOBJECTINSTANCE(object, SwapChain)
/*********************
* Lookup the window Handle and the relating X window handle
********************/
/* Setup hwnd we are using, plus which display this equates to */
object->win_handle = pPresentationParameters->hDeviceWindow;
if (!object->win_handle) {
object->win_handle = This->createParms.hFocusWindow;
}
object->win_handle = GetAncestor(object->win_handle, GA_ROOT);
hDc = GetDC(object->win_handle);
TRACE("Using hDc %p\n", hDc);
if (NULL == hDc) {
WARN("Failed to get a HDc for Window %p\n", object->win_handle);
return WINED3DERR_NOTAVAILABLE;
}
object->orig_width = GetSystemMetrics(SM_CXSCREEN);
object->orig_height = GetSystemMetrics(SM_CYSCREEN);
object->orig_fmt = pixelformat_for_depth(GetDeviceCaps(hDc, BITSPIXEL) * GetDeviceCaps(hDc, PLANES));
ReleaseDC(object->win_handle, hDc);
/** MSDN: If Windowed is TRUE and either of the BackBufferWidth/Height values is zero,
* then the corresponding dimension of the client area of the hDeviceWindow
* (or the focus window, if hDeviceWindow is NULL) is taken.
**********************/
if (pPresentationParameters->Windowed &&
((pPresentationParameters->BackBufferWidth == 0) ||
(pPresentationParameters->BackBufferHeight == 0))) {
RECT Rect;
GetClientRect(object->win_handle, &Rect);
if (pPresentationParameters->BackBufferWidth == 0) {
pPresentationParameters->BackBufferWidth = Rect.right;
TRACE("Updating width to %d\n", pPresentationParameters->BackBufferWidth);
}
if (pPresentationParameters->BackBufferHeight == 0) {
pPresentationParameters->BackBufferHeight = Rect.bottom;
TRACE("Updating height to %d\n", pPresentationParameters->BackBufferHeight);
}
}
/* Put the correct figures in the presentation parameters */
TRACE("Copying across presentation parameters\n");
object->presentParms = *pPresentationParameters;
TRACE("calling rendertarget CB\n");
hr = D3DCB_CreateRenderTarget((IUnknown *) This->parent,
parent,
object->presentParms.BackBufferWidth,
object->presentParms.BackBufferHeight,
object->presentParms.BackBufferFormat,
object->presentParms.MultiSampleType,
object->presentParms.MultiSampleQuality,
TRUE /* Lockable */,
&object->frontBuffer,
NULL /* pShared (always null)*/);
if (object->frontBuffer != NULL) {
IWineD3DSurface_SetContainer(object->frontBuffer, (IWineD3DBase *)object);
} else {
ERR("Failed to create the front buffer\n");
goto error;
}
/**
* Create an opengl context for the display visual
* NOTE: the visual is chosen as the window is created and the glcontext cannot
* use different properties after that point in time. FIXME: How to handle when requested format
* doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
* it chooses is identical to the one already being used!
**********************************/
/** FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat **/
object->context = HeapAlloc(GetProcessHeap(), 0, sizeof(object->context));
if(!object->context)
return E_OUTOFMEMORY;
object->num_contexts = 1;
ENTER_GL();
object->context[0] = CreateContext(This, (IWineD3DSurfaceImpl *) object->frontBuffer, object->win_handle, FALSE /* pbuffer */, pPresentationParameters);
LEAVE_GL();
if (!object->context[0]) {
ERR("Failed to create a new context\n");
hr = WINED3DERR_NOTAVAILABLE;
goto error;
} else {
TRACE("Context created (HWND=%p, glContext=%p)\n",
object->win_handle, object->context[0]->glCtx);
}
/*********************
* Windowed / Fullscreen
*******************/
/**
* TODO: MSDN says that we are only allowed one fullscreen swapchain per device,
* so we should really check to see if there is a fullscreen swapchain already
* I think Windows and X have different ideas about fullscreen, does a single head count as full screen?
**************************************/
if (!pPresentationParameters->Windowed) {
DEVMODEW devmode;
HDC hdc;
int bpp = 0;
RECT clip_rc;
/* Get info on the current display setup */
hdc = GetDC(0);
bpp = GetDeviceCaps(hdc, BITSPIXEL);
ReleaseDC(0, hdc);
/* Change the display settings */
memset(&devmode, 0, sizeof(devmode));
devmode.dmSize = sizeof(devmode);
devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
devmode.dmBitsPerPel = (bpp >= 24) ? 32 : bpp; /* Stupid XVidMode cannot change bpp */
devmode.dmPelsWidth = pPresentationParameters->BackBufferWidth;
devmode.dmPelsHeight = pPresentationParameters->BackBufferHeight;
ChangeDisplaySettingsExW(This->adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL);
/* For GetDisplayMode */
This->ddraw_width = devmode.dmPelsWidth;
This->ddraw_height = devmode.dmPelsHeight;
This->ddraw_format = pPresentationParameters->BackBufferFormat;
IWineD3DDevice_SetFullscreen(iface, TRUE);
/* And finally clip mouse to our screen */
SetRect(&clip_rc, 0, 0, devmode.dmPelsWidth, devmode.dmPelsHeight);
ClipCursor(&clip_rc);
}
/*********************
* Create the back, front and stencil buffers
*******************/
if(object->presentParms.BackBufferCount > 0) {
int i;
object->backBuffer = HeapAlloc(GetProcessHeap(), 0, sizeof(IWineD3DSurface *) * object->presentParms.BackBufferCount);
if(!object->backBuffer) {
ERR("Out of memory\n");
hr = E_OUTOFMEMORY;
goto error;
}
for(i = 0; i < object->presentParms.BackBufferCount; i++) {
TRACE("calling rendertarget CB\n");
hr = D3DCB_CreateRenderTarget((IUnknown *) This->parent,
parent,
object->presentParms.BackBufferWidth,
object->presentParms.BackBufferHeight,
object->presentParms.BackBufferFormat,
object->presentParms.MultiSampleType,
object->presentParms.MultiSampleQuality,
TRUE /* Lockable */,
&object->backBuffer[i],
NULL /* pShared (always null)*/);
if(hr == WINED3D_OK && object->backBuffer[i]) {
IWineD3DSurface_SetContainer(object->backBuffer[i], (IWineD3DBase *)object);
} else {
ERR("Cannot create new back buffer\n");
goto error;
}
ENTER_GL();
glDrawBuffer(GL_BACK);
checkGLcall("glDrawBuffer(GL_BACK)");
LEAVE_GL();
}
} else {
object->backBuffer = NULL;
/* Single buffering - draw to front buffer */
ENTER_GL();
glDrawBuffer(GL_FRONT);
checkGLcall("glDrawBuffer(GL_FRONT)");
LEAVE_GL();
}
/* Under directX swapchains share the depth stencil, so only create one depth-stencil */
if (pPresentationParameters->EnableAutoDepthStencil && hr == WINED3D_OK) {
TRACE("Creating depth stencil buffer\n");
if (This->depthStencilBuffer == NULL ) {
hr = D3DCB_CreateDepthStencil((IUnknown *) This->parent,
parent,
object->presentParms.BackBufferWidth,
object->presentParms.BackBufferHeight,
object->presentParms.AutoDepthStencilFormat,
object->presentParms.MultiSampleType,
object->presentParms.MultiSampleQuality,
FALSE /* FIXME: Discard */,
&This->depthStencilBuffer,
NULL /* pShared (always null)*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -