diff --git a/include/IrrlichtDevice.h b/include/IrrlichtDevice.h index 9d4031e2..a548f511 100644 --- a/include/IrrlichtDevice.h +++ b/include/IrrlichtDevice.h @@ -236,6 +236,9 @@ namespace irr //! Restore the window to normal size if possible. virtual void restoreWindow() =0; + //! Get the position of the frame on-screen + virtual core::position2di getWindowPosition() = 0; + //! Activate any joysticks, and generate events for them. /** Irrlicht contains support for joysticks, but does not generate joystick events by default, as this would consume joystick info that 3rd party libraries might rely on. Call this method to diff --git a/include/SIrrCreationParameters.h b/include/SIrrCreationParameters.h index cbf558dd..d6762283 100644 --- a/include/SIrrCreationParameters.h +++ b/include/SIrrCreationParameters.h @@ -9,6 +9,7 @@ #include "EDeviceTypes.h" #include "dimension2d.h" #include "ILogger.h" +#include "position2d.h" namespace irr { @@ -23,6 +24,7 @@ namespace irr DeviceType(EIDT_BEST), DriverType(video::EDT_BURNINGSVIDEO), WindowSize(core::dimension2d(800, 600)), + WindowPosition(core::position2di(-1,-1)), Bits(16), ZBufferBits(16), Fullscreen(false), @@ -58,6 +60,7 @@ namespace irr DeviceType = other.DeviceType; DriverType = other.DriverType; WindowSize = other.WindowSize; + WindowPosition = other.WindowPosition; Bits = other.Bits; ZBufferBits = other.ZBufferBits; Fullscreen = other.Fullscreen; @@ -102,6 +105,9 @@ namespace irr //! Size of the window or the video mode in fullscreen mode. Default: 800x600 core::dimension2d WindowSize; + //! Position of the window on-screen. Default: (-1, -1) or centered. + core::position2di WindowPosition; + //! Minimum Bits per pixel of the color buffer in fullscreen mode. Ignored if windowed mode. Default: 16. u8 Bits; diff --git a/source/Irrlicht/CIrrDeviceConsole.h b/source/Irrlicht/CIrrDeviceConsole.h index 8052182b..b2cd1b78 100644 --- a/source/Irrlicht/CIrrDeviceConsole.h +++ b/source/Irrlicht/CIrrDeviceConsole.h @@ -68,6 +68,12 @@ namespace irr //! returns if window is minimized virtual bool isWindowMinimized() const; + //! returns current window position (not supported for this device) + virtual core::position2di getWindowPosition() + { + return core::position2di(-1, -1); + } + //! presents a surface in the client area virtual bool present(video::IImage* surface, void* windowId=0, core::rect* src=0); diff --git a/source/Irrlicht/CIrrDeviceFB.h b/source/Irrlicht/CIrrDeviceFB.h index 07a9aca1..0108fa8a 100644 --- a/source/Irrlicht/CIrrDeviceFB.h +++ b/source/Irrlicht/CIrrDeviceFB.h @@ -63,6 +63,12 @@ namespace irr //! Restores original window size virtual void restoreWindow(); + //! returns current window position (not supported for this device) + virtual core::position2di getWindowPosition() + { + return core::position2di(-1, -1); + } + //! presents a surface in the client area virtual bool present(video::IImage* surface, void* windowId = 0, core::rect* src=0 ); diff --git a/source/Irrlicht/CIrrDeviceLinux.cpp b/source/Irrlicht/CIrrDeviceLinux.cpp index 80ce17e8..8d0d665d 100644 --- a/source/Irrlicht/CIrrDeviceLinux.cpp +++ b/source/Irrlicht/CIrrDeviceLinux.cpp @@ -662,15 +662,25 @@ bool CIrrDeviceLinux::createWindow() if (!CreationParams.WindowId) { + int x = 0; + int y = 0; + + if (!CreationParams.Fullscreen) + { + if (CreationParams.WindowPosition.X > 0) x = CreationParams.WindowPosition.X; + if (CreationParams.WindowPosition.Y > 0) y = CreationParams.WindowPosition.Y; + } + // create new Window // Remove window manager decoration in fullscreen attributes.override_redirect = CreationParams.Fullscreen; window = XCreateWindow(display, RootWindow(display, visual->screen), - 0, 0, Width, Height, 0, visual->depth, + x, y, Width, Height, 0, visual->depth, InputOutput, visual->visual, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &attributes); + XMapRaised(display, window); CreationParams.WindowId = (void*)window; Atom wmDelete; @@ -1435,6 +1445,13 @@ void CIrrDeviceLinux::restoreWindow() #endif } +core::position2di CIrrDeviceLinux::getWindowPosition() +{ + int wx = 0, wy = 0; + Window child; + XTranslateCoordinates(display, window, DefaultRootWindow(display), 0, 0, &wx, &wy, &child); + return core::position2di(wx, wy); +} void CIrrDeviceLinux::createKeyMap() { diff --git a/source/Irrlicht/CIrrDeviceLinux.h b/source/Irrlicht/CIrrDeviceLinux.h index 4d2a2c65..a95c65c0 100644 --- a/source/Irrlicht/CIrrDeviceLinux.h +++ b/source/Irrlicht/CIrrDeviceLinux.h @@ -101,6 +101,9 @@ namespace irr //! Restores the window size. virtual void restoreWindow(); + //! Get the position of this window on screen + virtual core::position2di getWindowPosition(); + //! Activate any joysticks, and generate events for them. virtual bool activateJoysticks(core::array & joystickInfo); diff --git a/source/Irrlicht/CIrrDeviceSDL.cpp b/source/Irrlicht/CIrrDeviceSDL.cpp index 00422ca8..e64d28aa 100644 --- a/source/Irrlicht/CIrrDeviceSDL.cpp +++ b/source/Irrlicht/CIrrDeviceSDL.cpp @@ -753,6 +753,12 @@ void CIrrDeviceSDL::maximizeWindow() // do nothing } +//! Get the position of this window on screen +core::position2di getWindowPosition() +{ + return core::position2di(-1, -1); +} + //! Restore original window size void CIrrDeviceSDL::restoreWindow() diff --git a/source/Irrlicht/CIrrDeviceSDL.h b/source/Irrlicht/CIrrDeviceSDL.h index c151f1d8..e1e1e0a3 100644 --- a/source/Irrlicht/CIrrDeviceSDL.h +++ b/source/Irrlicht/CIrrDeviceSDL.h @@ -77,6 +77,9 @@ namespace irr //! Restores the window size. virtual void restoreWindow(); + //! Get the position of this window on screen + virtual core::position2di getWindowPosition(); + //! Activate any joysticks, and generate events for them. virtual bool activateJoysticks(core::array & joystickInfo); diff --git a/source/Irrlicht/CIrrDeviceWin32.cpp b/source/Irrlicht/CIrrDeviceWin32.cpp index 93af8026..87cb715f 100644 --- a/source/Irrlicht/CIrrDeviceWin32.cpp +++ b/source/Irrlicht/CIrrDeviceWin32.cpp @@ -976,8 +976,12 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params) const s32 realWidth = clientSize.right - clientSize.left; const s32 realHeight = clientSize.bottom - clientSize.top; - s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2; - s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2; + s32 windowLeft = (CreationParams.WindowPosition.X == -1 ? + (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2 : + CreationParams.WindowPosition.X); + s32 windowTop = (CreationParams.WindowPosition.Y == -1 ? + (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2 : + CreationParams.WindowPosition.Y); if ( windowLeft < 0 ) windowLeft = 0; @@ -1735,6 +1739,22 @@ void CIrrDeviceWin32::restoreWindow() SetWindowPlacement(HWnd, &wndpl); } +core::position2di CIrrDeviceWin32::getWindowPosition() +{ + WINDOWPLACEMENT wndpl; + wndpl.length = sizeof(WINDOWPLACEMENT); + if (GetWindowPlacement(HWnd, &wndpl)) + { + return core::position2di((int)wndpl.rcNormalPosition.left, + (int)wndpl.rcNormalPosition.top); + } + else + { + // No reason for this to happen + os::Printer::log("Failed to retrieve window location", ELL_ERROR); + return core::position2di(-1, -1); + } +} bool CIrrDeviceWin32::activateJoysticks(core::array & joystickInfo) { diff --git a/source/Irrlicht/CIrrDeviceWin32.h b/source/Irrlicht/CIrrDeviceWin32.h index 16c5d542..b80b6434 100644 --- a/source/Irrlicht/CIrrDeviceWin32.h +++ b/source/Irrlicht/CIrrDeviceWin32.h @@ -85,6 +85,9 @@ namespace irr //! Restores the window size. virtual void restoreWindow(); + //! Get the position of the window on screen + virtual core::position2di getWindowPosition(); + //! Activate any joysticks, and generate events for them. virtual bool activateJoysticks(core::array & joystickInfo); diff --git a/source/Irrlicht/CIrrDeviceWinCE.h b/source/Irrlicht/CIrrDeviceWinCE.h index 7fe10630..2212d4ca 100644 --- a/source/Irrlicht/CIrrDeviceWinCE.h +++ b/source/Irrlicht/CIrrDeviceWinCE.h @@ -53,6 +53,12 @@ namespace irr //! returns if window is minimized virtual bool isWindowMinimized() const; + //! returns current window position (not supported for this device) + virtual core::position2di getWindowPosition() + { + return core::position2di(-1, -1); + } + //! presents a surface in the client area virtual bool present(video::IImage* surface, void* windowId = 0, core::rect* src=0 ); diff --git a/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h b/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h index da1cba2a..24a6e8b7 100644 --- a/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h +++ b/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.h @@ -84,6 +84,9 @@ namespace irr //! Restore the window to normal size if possible. virtual void restoreWindow(); + //! Get the position of this window on screen + virtual core::position2di getWindowPosition(); + //! Activate any joysticks, and generate events for them. virtual bool activateJoysticks(core::array & joystickInfo); diff --git a/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm b/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm index 7dba8f89..c24dfc6a 100644 --- a/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm +++ b/source/Irrlicht/MacOSX/CIrrDeviceMacOSX.mm @@ -26,7 +26,7 @@ #include "COSOperator.h" #include "CColorConverter.h" #include "irrlicht.h" - +#include #import #import @@ -623,9 +623,18 @@ bool CIrrDeviceMacOSX::createWindow() { if(!CreationParams.WindowId) //create another window when WindowId is null { - NSBackingStoreType type = (CreationParams.DriverType == video::EDT_OPENGL) ? NSBackingStoreBuffered : NSBackingStoreNonretained; + const NSBackingStoreType type = (CreationParams.DriverType == video::EDT_OPENGL) ? NSBackingStoreBuffered : NSBackingStoreNonretained; - Window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,CreationParams.WindowSize.Width,CreationParams.WindowSize.Height) styleMask:NSTitledWindowMask+NSClosableWindowMask+NSResizableWindowMask backing:type defer:FALSE]; + int x = std::max(0, CreationParams.WindowPosition.X); + int y = std::max(0, CreationParams.WindowPosition.Y); + + if (CreationParams.WindowPosition.Y > -1) + { + int screenHeight = [[[NSScreen screens] objectAtIndex:0] frame].size.height; + y = screenHeight - y - CreationParams.WindowSize.Height; + } + + Window = [[NSWindow alloc] initWithContentRect:NSMakeRect(x,y,CreationParams.WindowSize.Width,CreationParams.WindowSize.Height) styleMask:NSTitledWindowMask+NSClosableWindowMask+NSResizableWindowMask backing:type defer:FALSE]; } if (Window != NULL || CreationParams.WindowId) @@ -718,7 +727,10 @@ bool CIrrDeviceMacOSX::createWindow() { if (!CreationParams.WindowId) { - [Window center]; + if (CreationParams.WindowPosition.X == -1 && CreationParams.WindowPosition.Y == -1) + { + [Window center]; + } [Window setDelegate:[NSApp delegate]]; if(CreationParams.DriverType == video::EDT_OPENGL) @@ -1497,11 +1509,20 @@ void CIrrDeviceMacOSX::maximizeWindow() } -//! Restore the window to normal size if possible. +//! get the window to normal size if possible. void CIrrDeviceMacOSX::restoreWindow() { [Window deminiaturize:[NSApp self]]; } + +//! Get the position of this window on screen +core::position2di CIrrDeviceMacOSX::getWindowPosition() +{ + NSRect rect = [Window frame]; + int screenHeight = [[[NSScreen screens] objectAtIndex:0] frame].size.height; + return core::position2di(rect.origin.x, screenHeight - rect.origin.y - rect.size.height); +} + bool CIrrDeviceMacOSX::present(video::IImage* surface, void* windowId, core::rect* src )