| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807 |
- /*
- -----------------------------------------------------------------------------
- This source file is part of OGRE
- (Object-oriented Graphics Rendering Engine)
- For the latest info, see http://www.ogre3d.org/
- Copyright (c) 2000-2011 Torus Knot Software Ltd
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- -----------------------------------------------------------------------------
- */
- #ifndef _WIN32_WINNT
- #define _WIN32_WINNT 0x0500
- #endif
- #include "CmWin32Window.h"
- #include "CmRenderSystem.h"
- #include "CmException.h"
- #include "CmWin32GLSupport.h"
- #include "CmWin32Context.h"
- #include "CmWindowEventUtilities.h"
- #include "CmGLPixelFormat.h"
- namespace CamelotEngine {
- #define _MAX_CLASS_NAME_ 128
- Win32Window::Win32Window(Win32GLSupport &glsupport):
- mGLSupport(glsupport),
- mContext(0)
- {
- mIsFullScreen = false;
- mHWnd = 0;
- mGlrc = 0;
- mIsExternal = false;
- mIsExternalGLControl = false;
- mIsExternalGLContext = false;
- mSizing = false;
- mClosed = false;
- mDisplayFrequency = 0;
- mActive = false;
- mDeviceName = NULL;
- }
- Win32Window::~Win32Window()
- {
- destroy();
- }
- void Win32Window::initialize(const String& name, unsigned int width, unsigned int height,
- bool fullScreen, const NameValuePairList *miscParams)
- {
- // destroy current window, if any
- if (mHWnd)
- destroy();
- #ifdef CM_STATIC_LIB
- HINSTANCE hInst = GetModuleHandle( NULL );
- #else
- HINSTANCE hInst = GetModuleHandle("CamelotGLRenderSystem.dll");
- #endif
- mHWnd = 0;
- mName = name;
- mIsFullScreen = fullScreen;
- mClosed = false;
- mDisplayFrequency = 0;
- mColorDepth = mIsFullScreen? 32 : GetDeviceCaps(GetDC(0), BITSPIXEL);
- int left = -1; // Defaults to screen center
- int top = -1; // Defaults to screen center
- HWND parent = 0;
- String title = name;
- bool vsync = false;
- unsigned int vsyncInterval = 1;
- String border;
- bool outerSize = false;
- bool hwGamma = false;
- int monitorIndex = -1;
- HMONITOR hMonitor = NULL;
- if(miscParams)
- {
- // Get variable-length params
- NameValuePairList::const_iterator opt;
- NameValuePairList::const_iterator end = miscParams->end();
- if ((opt = miscParams->find("title")) != end)
- title = opt->second;
- if ((opt = miscParams->find("left")) != end)
- left = parseInt(opt->second);
- if ((opt = miscParams->find("top")) != end)
- top = parseInt(opt->second);
- if ((opt = miscParams->find("vsync")) != end)
- vsync = parseBool(opt->second);
- if ((opt = miscParams->find("vsyncInterval")) != end)
- vsyncInterval = parseUnsignedInt(opt->second);
- if ((opt = miscParams->find("FSAA")) != end)
- mFSAA = parseUnsignedInt(opt->second);
- if ((opt = miscParams->find("FSAAHint")) != end)
- mFSAAHint = opt->second;
- if ((opt = miscParams->find("gamma")) != end)
- hwGamma = parseBool(opt->second);
- if ((opt = miscParams->find("externalWindowHandle")) != end)
- {
- mHWnd = (HWND)parseUnsignedInt(opt->second);
- if (mHWnd)
- {
- mIsExternal = true;
- mIsFullScreen = false;
- }
- if ((opt = miscParams->find("externalGLControl")) != end) {
- mIsExternalGLControl = parseBool(opt->second);
- }
- }
- if ((opt = miscParams->find("externalGLContext")) != end)
- {
- mGlrc = (HGLRC)parseUnsignedLong(opt->second);
- if( mGlrc )
- mIsExternalGLContext = true;
- }
- // window border style
- opt = miscParams->find("border");
- if(opt != miscParams->end())
- border = opt->second;
- // set outer dimensions?
- opt = miscParams->find("outerDimensions");
- if(opt != miscParams->end())
- outerSize = parseBool(opt->second);
- // only available with fullscreen
- if ((opt = miscParams->find("displayFrequency")) != end)
- mDisplayFrequency = parseUnsignedInt(opt->second);
- if ((opt = miscParams->find("colourDepth")) != end)
- {
- mColorDepth = parseUnsignedInt(opt->second);
- if (!mIsFullScreen)
- {
- // make sure we don't exceed desktop colour depth
- if ((int)mColorDepth > GetDeviceCaps(GetDC(0), BITSPIXEL))
- mColorDepth = GetDeviceCaps(GetDC(0), BITSPIXEL);
- }
- }
- // incompatible with fullscreen
- if ((opt = miscParams->find("parentWindowHandle")) != end)
- parent = (HWND)parseUnsignedInt(opt->second);
- // monitor index
- if ((opt = miscParams->find("monitorIndex")) != end)
- monitorIndex = parseInt(opt->second);
-
- // monitor handle
- if ((opt = miscParams->find("monitorHandle")) != end)
- hMonitor = (HMONITOR)parseInt(opt->second);
- }
- if (!mIsExternal)
- {
- DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN;
- DWORD dwStyleEx = 0;
- MONITORINFOEX monitorInfoEx;
- RECT rc;
-
- // If we didn't specified the adapter index, or if it didn't find it
- if (hMonitor == NULL)
- {
- POINT windowAnchorPoint;
- // Fill in anchor point.
- windowAnchorPoint.x = left;
- windowAnchorPoint.y = top;
- // Get the nearest monitor to this window.
- hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTONEAREST);
- }
- // Get the target monitor info
- memset(&monitorInfoEx, 0, sizeof(MONITORINFOEX));
- monitorInfoEx.cbSize = sizeof(MONITORINFOEX);
- GetMonitorInfo(hMonitor, &monitorInfoEx);
- size_t devNameLen = strlen(monitorInfoEx.szDevice);
- mDeviceName = new char[devNameLen + 1];
-
- strcpy_s(mDeviceName, devNameLen + 1, monitorInfoEx.szDevice);
- // No specified top left -> Center the window in the middle of the monitor
- if (left == -1 || top == -1)
- {
- int screenw = monitorInfoEx.rcWork.right - monitorInfoEx.rcWork.left;
- int screenh = monitorInfoEx.rcWork.bottom - monitorInfoEx.rcWork.top;
- unsigned int winWidth, winHeight;
- adjustWindow(width, height, &winWidth, &winHeight);
- // clamp window dimensions to screen size
- int outerw = (int(winWidth) < screenw)? int(winWidth) : screenw;
- int outerh = (int(winHeight) < screenh)? int(winHeight) : screenh;
- if (left == -1)
- left = monitorInfoEx.rcWork.left + (screenw - outerw) / 2;
- else if (monitorIndex != -1)
- left += monitorInfoEx.rcWork.left;
- if (top == -1)
- top = monitorInfoEx.rcWork.top + (screenh - outerh) / 2;
- else if (monitorIndex != -1)
- top += monitorInfoEx.rcWork.top;
- }
- else if (monitorIndex != -1)
- {
- left += monitorInfoEx.rcWork.left;
- top += monitorInfoEx.rcWork.top;
- }
- mWidth = width;
- mHeight = height;
- mTop = top;
- mLeft = left;
- if (mIsFullScreen)
- {
- dwStyle |= WS_POPUP;
- dwStyleEx |= WS_EX_TOPMOST;
- mTop = monitorInfoEx.rcMonitor.top;
- mLeft = monitorInfoEx.rcMonitor.left;
- }
- else
- {
- if (parent)
- {
- dwStyle |= WS_CHILD;
- }
- else
- {
- if (border == "none")
- dwStyle |= WS_POPUP;
- else if (border == "fixed")
- dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION |
- WS_SYSMENU | WS_MINIMIZEBOX;
- else
- dwStyle |= WS_OVERLAPPEDWINDOW;
- }
- int screenw = GetSystemMetrics(SM_CXSCREEN);
- int screenh = GetSystemMetrics(SM_CYSCREEN);
- if (!outerSize)
- {
- // Calculate window dimensions required
- // to get the requested client area
- SetRect(&rc, 0, 0, mWidth, mHeight);
- AdjustWindowRect(&rc, dwStyle, false);
- mWidth = rc.right - rc.left;
- mHeight = rc.bottom - rc.top;
- // Clamp window rect to the nearest display monitor.
- if (mLeft < monitorInfoEx.rcWork.left)
- mLeft = monitorInfoEx.rcWork.left;
- if (mTop < monitorInfoEx.rcWork.top)
- mTop = monitorInfoEx.rcWork.top;
- if ((int)mWidth > monitorInfoEx.rcWork.right - mLeft)
- mWidth = monitorInfoEx.rcWork.right - mLeft;
- if ((int)mHeight > monitorInfoEx.rcWork.bottom - mTop)
- mHeight = monitorInfoEx.rcWork.bottom - mTop;
- }
- }
- // register class and create window
- WNDCLASS wc = { CS_OWNDC, WindowEventUtilities::_WndProc, 0, 0, hInst,
- LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW),
- (HBRUSH)GetStockObject(BLACK_BRUSH), NULL, "GLWindow" };
- RegisterClass(&wc);
- if (mIsFullScreen)
- {
- DEVMODE displayDeviceMode;
- memset(&displayDeviceMode, 0, sizeof(displayDeviceMode));
- displayDeviceMode.dmSize = sizeof(DEVMODE);
- displayDeviceMode.dmBitsPerPel = mColorDepth;
- displayDeviceMode.dmPelsWidth = mWidth;
- displayDeviceMode.dmPelsHeight = mHeight;
- displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
- if (mDisplayFrequency)
- {
- displayDeviceMode.dmDisplayFrequency = mDisplayFrequency;
- displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY;
- if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL)
- {
- // TODO LOG PORT - Log this somewhere
- //LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed");
- //displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY;
- }
- }
- if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL)
- {
- // TODO LOG PORT - Log this somewhere
- //LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed");
- }
- }
- // Pass pointer to self as WM_CREATE parameter
- mHWnd = CreateWindowEx(dwStyleEx, "GLWindow", title.c_str(),
- dwStyle, mLeft, mTop, mWidth, mHeight, parent, 0, hInst, this);
- WindowEventUtilities::_addRenderWindow(this);
- }
- HDC old_hdc = wglGetCurrentDC();
- HGLRC old_context = wglGetCurrentContext();
- RECT rc;
- // top and left represent outer window position
- GetWindowRect(mHWnd, &rc);
- mTop = rc.top;
- mLeft = rc.left;
- // width and height represent drawable area only
- GetClientRect(mHWnd, &rc);
- mWidth = rc.right;
- mHeight = rc.bottom;
- mHDC = GetDC(mHWnd);
- if (!mIsExternalGLControl)
- {
- int testFsaa = mFSAA;
- bool testHwGamma = hwGamma;
- bool formatOk = mGLSupport.selectPixelFormat(mHDC, mColorDepth, testFsaa, testHwGamma);
- if (!formatOk)
- {
- if (mFSAA > 0)
- {
- // try without FSAA
- testFsaa = 0;
- formatOk = mGLSupport.selectPixelFormat(mHDC, mColorDepth, testFsaa, testHwGamma);
- }
- if (!formatOk && hwGamma)
- {
- // try without sRGB
- testHwGamma = false;
- testFsaa = mFSAA;
- formatOk = mGLSupport.selectPixelFormat(mHDC, mColorDepth, testFsaa, testHwGamma);
- }
- if (!formatOk && hwGamma && (mFSAA > 0))
- {
- // try without both
- testHwGamma = false;
- testFsaa = 0;
- formatOk = mGLSupport.selectPixelFormat(mHDC, mColorDepth, testFsaa, testHwGamma);
- }
- if (!formatOk)
- CM_EXCEPT(RenderingAPIException, "selectPixelFormat failed");
- }
- // record what gamma option we used in the end
- // this will control enabling of sRGB state flags when used
- mHwGamma = testHwGamma;
- mFSAA = testFsaa;
- }
- if (!mIsExternalGLContext)
- {
- mGlrc = wglCreateContext(mHDC);
- if (!mGlrc)
- {
- CM_EXCEPT(RenderingAPIException,
- "wglCreateContext failed: " + translateWGLError());
- }
- }
- if (!wglMakeCurrent(mHDC, mGlrc))
- {
- CM_EXCEPT(RenderingAPIException, "wglMakeCurrent");
- }
- // Do not change vsync if the external window has the OpenGL control
- if (!mIsExternalGLControl) {
- // Don't use wglew as if this is the first window, we won't have initialised yet
- PFNWGLSWAPINTERVALEXTPROC _wglSwapIntervalEXT =
- (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
- if (_wglSwapIntervalEXT)
- _wglSwapIntervalEXT(vsync? vsyncInterval : 0);
- }
- if (old_context && old_context != mGlrc)
- {
- // Restore old context
- if (!wglMakeCurrent(old_hdc, old_context))
- CM_EXCEPT(RenderingAPIException, "wglMakeCurrent() failed");
- // Share lists with old context
- if (!wglShareLists(old_context, mGlrc))
- CM_EXCEPT(RenderingAPIException, "wglShareLists() failed");
- }
- // Create RenderSystem context
- mContext = new Win32Context(mHDC, mGlrc);
- mActive = true;
- }
- void Win32Window::adjustWindow(unsigned int clientWidth, unsigned int clientHeight,
- unsigned int* winWidth, unsigned int* winHeight)
- {
- // NB only call this for non full screen
- RECT rc;
- SetRect(&rc, 0, 0, clientWidth, clientHeight);
- AdjustWindowRect(&rc, WS_VISIBLE | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW, false);
- *winWidth = rc.right - rc.left;
- *winHeight = rc.bottom - rc.top;
- // adjust to monitor
- HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
- // Get monitor info
- MONITORINFO monitorInfo;
- memset(&monitorInfo, 0, sizeof(MONITORINFO));
- monitorInfo.cbSize = sizeof(MONITORINFO);
- GetMonitorInfo(hMonitor, &monitorInfo);
- LONG maxW = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
- LONG maxH = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
- if (*winWidth > (unsigned int)maxW)
- *winWidth = maxW;
- if (*winHeight > (unsigned int)maxH)
- *winHeight = maxH;
- }
- void Win32Window::setFullscreen(bool fullScreen, unsigned int width, unsigned int height)
- {
- if (mIsFullScreen != fullScreen || width != mWidth || height != mHeight)
- {
- mIsFullScreen = fullScreen;
- DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN;
- if (mIsFullScreen)
- {
- dwStyle |= WS_POPUP;
- DEVMODE displayDeviceMode;
- memset(&displayDeviceMode, 0, sizeof(displayDeviceMode));
- displayDeviceMode.dmSize = sizeof(DEVMODE);
- displayDeviceMode.dmBitsPerPel = mColorDepth;
- displayDeviceMode.dmPelsWidth = width;
- displayDeviceMode.dmPelsHeight = height;
- displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
- if (mDisplayFrequency)
- {
- displayDeviceMode.dmDisplayFrequency = mDisplayFrequency;
- displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY;
- if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL,
- CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL)
- {
- // TODO LOG PORT - Log this somewhere
- //LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed");
- displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY;
- }
- }
- else
- {
- // try a few
- displayDeviceMode.dmDisplayFrequency = 100;
- displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY;
- if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL,
- CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL)
- {
- displayDeviceMode.dmDisplayFrequency = 75;
- if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL,
- CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL)
- {
- displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY;
- }
- }
- }
- // move window to 0,0 before display switch
- SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, mWidth, mHeight, SWP_NOACTIVATE);
- if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL)
- {
- // TODO LOG PORT - Log this somewhere
- //LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed");
- }
- // Get the nearest monitor to this window.
- HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
- // Get monitor info
- MONITORINFO monitorInfo;
- memset(&monitorInfo, 0, sizeof(MONITORINFO));
- monitorInfo.cbSize = sizeof(MONITORINFO);
- GetMonitorInfo(hMonitor, &monitorInfo);
- mTop = monitorInfo.rcMonitor.top;
- mLeft = monitorInfo.rcMonitor.left;
- SetWindowLong(mHWnd, GWL_STYLE, dwStyle);
- SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, width, height,
- SWP_NOACTIVATE);
- mWidth = width;
- mHeight = height;
- }
- else
- {
- dwStyle |= WS_OVERLAPPEDWINDOW;
- // drop out of fullscreen
- ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL);
- // calculate overall dimensions for requested client area
- unsigned int winWidth, winHeight;
- adjustWindow(width, height, &winWidth, &winHeight);
- // deal with centreing when switching down to smaller resolution
- HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST);
- MONITORINFO monitorInfo;
- memset(&monitorInfo, 0, sizeof(MONITORINFO));
- monitorInfo.cbSize = sizeof(MONITORINFO);
- GetMonitorInfo(hMonitor, &monitorInfo);
- LONG screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
- LONG screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
- int left = screenw > int(winWidth) ? ((screenw - int(winWidth)) / 2) : 0;
- int top = screenh > int(winHeight) ? ((screenh - int(winHeight)) / 2) : 0;
- SetWindowLong(mHWnd, GWL_STYLE, dwStyle);
- SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight,
- SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE);
- mWidth = width;
- mHeight = height;
- windowMovedOrResized();
- }
- }
- }
- void Win32Window::destroy(void)
- {
- if (!mHWnd)
- return;
- // Unregister and destroy OGRE GLContext
- delete mContext;
- if (!mIsExternalGLContext && mGlrc)
- {
- wglDeleteContext(mGlrc);
- mGlrc = 0;
- }
- if (!mIsExternal)
- {
- WindowEventUtilities::_removeRenderWindow(this);
- if (mIsFullScreen)
- ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL);
- DestroyWindow(mHWnd);
- }
- else
- {
- // just release the DC
- ReleaseDC(mHWnd, mHDC);
- }
- mActive = false;
- mClosed = true;
- mHDC = 0; // no release thanks to CS_OWNDC wndclass style
- mHWnd = 0;
- if (mDeviceName != NULL)
- {
- delete[] mDeviceName;
- mDeviceName = NULL;
- }
-
- }
- bool Win32Window::isActive(void) const
- {
- if (isFullScreen())
- return isVisible();
- return mActive && isVisible();
- }
- bool Win32Window::isVisible() const
- {
- return (mHWnd && !IsIconic(mHWnd));
- }
- bool Win32Window::isClosed() const
- {
- return mClosed;
- }
- void Win32Window::reposition(int left, int top)
- {
- if (mHWnd && !mIsFullScreen)
- {
- SetWindowPos(mHWnd, 0, left, top, 0, 0,
- SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
- }
- }
- void Win32Window::resize(unsigned int width, unsigned int height)
- {
- if (mHWnd && !mIsFullScreen)
- {
- RECT rc = { 0, 0, width, height };
- AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false);
- width = rc.right - rc.left;
- height = rc.bottom - rc.top;
- SetWindowPos(mHWnd, 0, 0, 0, width, height,
- SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
- }
- }
- void Win32Window::windowMovedOrResized()
- {
- if (!mHWnd || IsIconic(mHWnd))
- return;
- RECT rc;
- // top and left represent outer window position
- GetWindowRect(mHWnd, &rc);
- mTop = rc.top;
- mLeft = rc.left;
- // width and height represent drawable area only
- GetClientRect(mHWnd, &rc);
- if (mWidth == rc.right && mHeight == rc.bottom)
- return;
- mWidth = rc.right - rc.left;
- mHeight = rc.bottom - rc.top;
- // TODO - Notify viewports of resize
- }
- void Win32Window::swapBuffers(bool waitForVSync)
- {
- if (!mIsExternalGLControl) {
- SwapBuffers(mHDC);
- }
- }
- void Win32Window::copyContentsToMemory(const PixelData &dst, FrameBuffer buffer)
- {
- if ((dst.left < 0) || (dst.right > mWidth) ||
- (dst.top < 0) || (dst.bottom > mHeight) ||
- (dst.front != 0) || (dst.back != 1))
- {
- CM_EXCEPT(InvalidParametersException, "Invalid box.");
- }
- if (buffer == FB_AUTO)
- {
- buffer = mIsFullScreen? FB_FRONT : FB_BACK;
- }
- GLenum format = CamelotEngine::GLPixelUtil::getGLOriginFormat(dst.format);
- GLenum type = CamelotEngine::GLPixelUtil::getGLOriginDataType(dst.format);
- if ((format == GL_NONE) || (type == 0))
- {
- CM_EXCEPT(InvalidParametersException, "Unsupported format.");
- }
- // Must change the packing to ensure no overruns!
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK);
- glReadPixels((GLint)dst.left, (GLint)dst.top,
- (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(),
- format, type, dst.data);
- // restore default alignment
- glPixelStorei(GL_PACK_ALIGNMENT, 4);
- //vertical flip
- {
- size_t rowSpan = dst.getWidth() * PixelUtil::getNumElemBytes(dst.format);
- size_t height = dst.getHeight();
- UINT8 *tmpData = new UINT8[rowSpan * height];
- UINT8 *srcRow = (UINT8 *)dst.data, *tmpRow = tmpData + (height - 1) * rowSpan;
- while (tmpRow >= tmpData)
- {
- memcpy(tmpRow, srcRow, rowSpan);
- srcRow += rowSpan;
- tmpRow -= rowSpan;
- }
- memcpy(dst.data, tmpData, rowSpan * height);
- delete [] tmpData;
- }
- }
- void Win32Window::getCustomAttribute( const String& name, void* pData )
- {
- if( name == "GLCONTEXT" ) {
- *static_cast<GLContext**>(pData) = mContext;
- return;
- } else if( name == "WINDOW" )
- {
- HWND *pHwnd = (HWND*)pData;
- *pHwnd = getWindowHandle();
- return;
- }
- }
- void Win32Window::setActive( bool state )
- {
- if (mDeviceName != NULL && state == false)
- {
- HWND hActiveWindow = GetActiveWindow();
- char classNameSrc[_MAX_CLASS_NAME_ + 1];
- char classNameDst[_MAX_CLASS_NAME_ + 1];
- GetClassName(mHWnd, classNameSrc, _MAX_CLASS_NAME_);
- GetClassName(hActiveWindow, classNameDst, _MAX_CLASS_NAME_);
- if (strcmp(classNameDst, classNameSrc) == 0)
- {
- state = true;
- }
- }
-
- mActive = state;
- if( mIsFullScreen )
- {
- if( state == false )
- { //Restore Desktop
- ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL);
- ShowWindow(mHWnd, SW_SHOWMINNOACTIVE);
- }
- else
- { //Restore App
- ShowWindow(mHWnd, SW_SHOWNORMAL);
- DEVMODE displayDeviceMode;
- memset(&displayDeviceMode, 0, sizeof(displayDeviceMode));
- displayDeviceMode.dmSize = sizeof(DEVMODE);
- displayDeviceMode.dmBitsPerPel = mColorDepth;
- displayDeviceMode.dmPelsWidth = mWidth;
- displayDeviceMode.dmPelsHeight = mHeight;
- displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
- if (mDisplayFrequency)
- {
- displayDeviceMode.dmDisplayFrequency = mDisplayFrequency;
- displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY;
- }
- ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL);
- }
- }
- }
- }
|