Move patform specific code from irr_driver to irrlicht devices

This commit is contained in:
Deve 2017-09-27 17:37:56 +02:00
parent e655c5e971
commit e2c0f83fb0
18 changed files with 271 additions and 139 deletions

View File

@ -240,6 +240,15 @@ namespace irr
//! Restore the window to normal size if possible. //! Restore the window to normal size if possible.
virtual void restoreWindow() =0; virtual void restoreWindow() =0;
//! Move window to requested position
/** \return true if success */
virtual bool moveWindow(int x, int y) = 0;
//! Get current window position.
/** \return true if success */
virtual bool getWindowPosition(int* x, int* y) = 0;
//! Activate any joysticks, and generate events for them. //! Activate any joysticks, and generate events for them.
/** Irrlicht contains support for joysticks, but does not generate joystick events by default, /** 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 as this would consume joystick info that 3rd party libraries might rely on. Call this method to

View File

@ -276,6 +276,18 @@ void CIrrDeviceAndroid::restoreWindow()
{ {
} }
bool CIrrDeviceAndroid::moveWindow(int x, int y)
{
return true;
}
bool CIrrDeviceAndroid::getWindowPosition(int* x, int* y)
{
*x = 0;
*y = 0;
return true;
}
E_DEVICE_TYPE CIrrDeviceAndroid::getType() const E_DEVICE_TYPE CIrrDeviceAndroid::getType() const
{ {
return EIDT_ANDROID; return EIDT_ANDROID;

View File

@ -47,6 +47,8 @@ namespace irr
virtual void minimizeWindow(); virtual void minimizeWindow();
virtual void maximizeWindow(); virtual void maximizeWindow();
virtual void restoreWindow(); virtual void restoreWindow();
virtual bool moveWindow(int x, int y);
virtual bool getWindowPosition(int* x, int* y);
virtual E_DEVICE_TYPE getType() const; virtual E_DEVICE_TYPE getType() const;
virtual bool activateAccelerometer(float updateInterval); virtual bool activateAccelerometer(float updateInterval);
virtual bool deactivateAccelerometer(); virtual bool deactivateAccelerometer();

View File

@ -446,6 +446,17 @@ void CIrrDeviceConsole::restoreWindow()
// do nothing // do nothing
} }
//! Move window to requested position
bool CIrrDeviceConsole::moveWindow(int x, int y)
{
return false;
}
//! Get current window position.
bool CIrrDeviceConsole::getWindowPosition(int* x, int* y)
{
return false;
}
void CIrrDeviceConsole::setTextCursorPos(s16 x, s16 y) void CIrrDeviceConsole::setTextCursorPos(s16 x, s16 y)
{ {

View File

@ -89,6 +89,12 @@ namespace irr
//! Restores the window size. //! Restores the window size.
virtual void restoreWindow(); virtual void restoreWindow();
//! Move window to requested position
virtual bool moveWindow(int x, int y);
//! Get current window position.
virtual bool getWindowPosition(int* x, int* y);
//! Get the device type //! Get the device type
virtual E_DEVICE_TYPE getType() const virtual E_DEVICE_TYPE getType() const
{ {

View File

@ -391,6 +391,18 @@ void CIrrDeviceFB::restoreWindow()
{ {
} }
//! Move window to requested position
bool CIrrDeviceFB::moveWindow(int x, int y)
{
return false;
}
//! Get current window position.
bool CIrrDeviceFB::getWindowPosition(int* x, int* y)
{
return false;
}
//! Returns the type of this device //! Returns the type of this device
E_DEVICE_TYPE CIrrDeviceFB::getType() const E_DEVICE_TYPE CIrrDeviceFB::getType() const

View File

@ -66,6 +66,12 @@ namespace irr
//! Restores original window size //! Restores original window size
virtual void restoreWindow(); virtual void restoreWindow();
//! Move window to requested position
virtual bool moveWindow(int x, int y);
//! Get current window position.
virtual bool getWindowPosition(int* x, int* y);
//! presents a surface in the client area //! presents a surface in the client area
virtual bool present(video::IImage* surface, void* windowId = 0, core::rect<s32>* src=0 ); virtual bool present(video::IImage* surface, void* windowId = 0, core::rect<s32>* src=0 );

View File

@ -2194,6 +2194,101 @@ void CIrrDeviceLinux::restoreWindow()
#endif #endif
} }
/*
Returns the parent window of "window" (i.e. the ancestor of window
that is a direct child of the root, or window itself if it is a direct child).
If window is the root window, returns window.
*/
bool get_toplevel_parent(Display* display, Window window, Window* tp_window)
{
#ifdef _IRR_COMPILE_WITH_X11_
Window current_window = window;
Window parent;
Window root;
Window* children;
unsigned int num_children;
while (true)
{
bool success = XQueryTree(display, current_window, &root,
&parent, &children, &num_children);
if (!success)
{
os::Printer::log("XQueryTree error", ELL_ERROR);
return false;
}
if (children)
{
XFree(children);
}
if (current_window == root || parent == root)
{
*tp_window = current_window;
return true;
}
else
{
current_window = parent;
}
}
#endif
return false;
}
//! Move window to requested position
bool CIrrDeviceLinux::moveWindow(int x, int y)
{
#ifdef _IRR_COMPILE_WITH_X11_
if (CreationParams.DriverType == video::EDT_NULL || CreationParams.Fullscreen)
return false;
int display_width = XDisplayWidth(display, screennr);
int display_height = XDisplayHeight(display, screennr);
core::min_(x, display_width - (int)Width);
core::min_(y, display_height - (int)Height);
XMoveWindow(display, window, x, y);
return true;
#endif
return false;
}
//! Get current window position.
bool CIrrDeviceLinux::getWindowPosition(int* x, int* y)
{
#ifdef _IRR_COMPILE_WITH_X11_
if (CreationParams.DriverType == video::EDT_NULL || CreationParams.Fullscreen)
return false;
Window tp_window;
bool success = get_toplevel_parent(display, window, &tp_window);
if (!success)
return false;
XWindowAttributes xwa;
success = XGetWindowAttributes(display, tp_window, &xwa);
if (!success)
return false;
*x = xwa.x;
*y = xwa.y;
return true;
#endif
return false;
}
void CIrrDeviceLinux::createKeyMap() void CIrrDeviceLinux::createKeyMap()
{ {

View File

@ -100,6 +100,12 @@ namespace irr
//! Restores the window size. //! Restores the window size.
virtual void restoreWindow(); virtual void restoreWindow();
//! Move window to requested position
virtual bool moveWindow(int x, int y);
//! Get current window position.
virtual bool getWindowPosition(int* x, int* y);
//! Activate any joysticks, and generate events for them. //! Activate any joysticks, and generate events for them.
virtual bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo); virtual bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo);

View File

@ -761,6 +761,18 @@ void CIrrDeviceSDL::restoreWindow()
// do nothing // do nothing
} }
//! Move window to requested position
bool CIrrDeviceSDL::moveWindow(int x, int y)
{
return false;
}
//! Get current window position.
bool CIrrDeviceSDL::getWindowPosition(int* x, int* y)
{
return false;
}
//! returns if window is active. if not, nothing need to be drawn //! returns if window is active. if not, nothing need to be drawn
bool CIrrDeviceSDL::isWindowActive() const bool CIrrDeviceSDL::isWindowActive() const

View File

@ -80,6 +80,12 @@ namespace irr
//! Restores the window size. //! Restores the window size.
virtual void restoreWindow(); virtual void restoreWindow();
//! Move window to requested position
virtual bool moveWindow(int x, int y);
//! Get current window position.
virtual bool getWindowPosition(int* x, int* y);
//! Activate any joysticks, and generate events for them. //! Activate any joysticks, and generate events for them.
virtual bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo); virtual bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo);

View File

@ -1073,6 +1073,18 @@ void CIrrDeviceWayland::restoreWindow()
{ {
} }
//! Move window to requested position
bool CIrrDeviceWayland::moveWindow(int x, int y)
{
return false;
}
//! Get current window position.
bool CIrrDeviceWayland::getWindowPosition(int* x, int* y)
{
return false;
}
//! Set the current Gamma Value for the Display //! Set the current Gamma Value for the Display
bool CIrrDeviceWayland::setGammaRamp(f32 red, f32 green, f32 blue, bool CIrrDeviceWayland::setGammaRamp(f32 red, f32 green, f32 blue,
f32 brightness, f32 contrast) f32 brightness, f32 contrast)

View File

@ -105,6 +105,12 @@ namespace irr
//! Restores the window size. //! Restores the window size.
virtual void restoreWindow(); virtual void restoreWindow();
//! Move window to requested position
virtual bool moveWindow(int x, int y);
//! Get current window position.
virtual bool getWindowPosition(int* x, int* y);
//! Activate any joysticks, and generate events for them. //! Activate any joysticks, and generate events for them.
virtual bool activateJoysticks(core::array<SJoystickInfo>& joystickInfo); virtual bool activateJoysticks(core::array<SJoystickInfo>& joystickInfo);

View File

@ -2131,6 +2131,38 @@ void CIrrDeviceWin32::restoreWindow()
SetWindowPlacement(HWnd, &wndpl); SetWindowPlacement(HWnd, &wndpl);
} }
//! Move window to requested position
bool CIrrDeviceWin32::moveWindow(int x, int y)
{
if (CreationParams.DriverType == video::EDT_NULL || CreationParams.Fullscreen)
return false;
bool success = SetWindowPos(HWnd, HWND_TOP, x, y, -1, -1,
SWP_NOOWNERZORDER | SWP_NOSIZE);
return success;
}
//! Get current window position.
bool CIrrDeviceWin32::getWindowPosition(int* x, int* y)
{
if (CreationParams.DriverType == video::EDT_NULL || CreationParams.Fullscreen)
return false;
WINDOWPLACEMENT placement;
placement.length = sizeof(WINDOWPLACEMENT);
bool success = GetWindowPlacement(HWnd, &placement);
if (!success)
return false;
*x = (int)placement.rcNormalPosition.left;
*y = (int)placement.rcNormalPosition.top;
return true;
}
bool CIrrDeviceWin32::activateJoysticks(core::array<SJoystickInfo> & joystickInfo) bool CIrrDeviceWin32::activateJoysticks(core::array<SJoystickInfo> & joystickInfo)
{ {

View File

@ -88,6 +88,12 @@ namespace irr
//! Restores the window size. //! Restores the window size.
virtual void restoreWindow(); virtual void restoreWindow();
//! Move window to requested position
virtual bool moveWindow(int x, int y);
//! Get current window position.
virtual bool getWindowPosition(int* x, int* y);
//! Activate any joysticks, and generate events for them. //! Activate any joysticks, and generate events for them.
virtual bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo); virtual bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo);

View File

@ -83,6 +83,12 @@ namespace irr
//! Restore the window to normal size if possible. //! Restore the window to normal size if possible.
virtual void restoreWindow(); virtual void restoreWindow();
//! Move window to requested position
virtual bool moveWindow(int x, int y);
//! Get current window position.
virtual bool getWindowPosition(int* x, int* y);
//! Activate any joysticks, and generate events for them. //! Activate any joysticks, and generate events for them.
virtual bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo); virtual bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo);

View File

@ -1528,6 +1528,18 @@ void CIrrDeviceMacOSX::restoreWindow()
[Window deminiaturize:[NSApp self]]; [Window deminiaturize:[NSApp self]];
} }
//! Move window to requested position
bool CIrrDeviceMacOSX::moveWindow(int x, int y)
{
return false;
}
//! Get current window position.
bool CIrrDeviceMacOSX::getWindowPosition(int* x, int* y)
{
return false;
}
bool CIrrDeviceMacOSX::present(video::IImage* surface, void* windowId, core::rect<s32>* src ) bool CIrrDeviceMacOSX::present(video::IImage* surface, void* windowId, core::rect<s32>* src )
{ {

View File

@ -91,15 +91,6 @@ please use the included version."
using namespace irr; using namespace irr;
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#if defined(__linux__) && !defined(ANDROID)
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif
/** singleton */ /** singleton */
IrrDriver *irr_driver = NULL; IrrDriver *irr_driver = NULL;
@ -228,45 +219,6 @@ std::unique_ptr<RenderTarget> IrrDriver::createRenderTarget(const irr::core::dim
} // createRenderTarget } // createRenderTarget
#endif // ~SERVER_ONLY #endif // ~SERVER_ONLY
// ----------------------------------------------------------------------------
#if defined(__linux__) && !defined(ANDROID)
/*
Returns the parent window of "window" (i.e. the ancestor of window
that is a direct child of the root, or window itself if it is a direct child).
If window is the root window, returns window.
*/
Window get_toplevel_parent(Display* display, Window window)
{
#ifndef SERVER_ONLY
Window parent;
Window root;
Window * children;
unsigned int num_children;
while (true)
{
if (0 == XQueryTree(display, window, &root,
&parent, &children, &num_children))
{
Log::fatal("irr_driver", "XQueryTree error\n");
}
if (children) { //must test for null
XFree(children);
}
if (window == root || parent == root) {
return window;
}
else {
window = parent;
}
}
#else
return NULL;
#endif
}
#endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** If the position of the window should be remembered, store it in the config /** If the position of the window should be remembered, store it in the config
* file. * file.
@ -278,61 +230,26 @@ void IrrDriver::updateConfigIfRelevant()
if (!UserConfigParams::m_fullscreen && if (!UserConfigParams::m_fullscreen &&
UserConfigParams::m_remember_window_location) UserConfigParams::m_remember_window_location)
{ {
#ifdef WIN32 int x = 0;
const video::SExposedVideoData& videoData = m_device->getVideoDriver() int y = 0;
->getExposedVideoData();
// this should work even if using DirectX in theory because the HWnd is bool success = m_device->getWindowPosition(&x, &y);
// always third pointer in the struct, no matter which union is used
HWND window = (HWND)videoData.OpenGLWin32.HWnd; if (!success)
WINDOWPLACEMENT placement;
placement.length = sizeof(WINDOWPLACEMENT);
if (GetWindowPlacement(window, &placement))
{ {
int x = (int)placement.rcNormalPosition.left; Log::warn("irr_driver", "Could not retrieve window location");
int y = (int)placement.rcNormalPosition.top; return;
}
Log::verbose("irr_driver", "Retrieved window location for config: "
"%i %i", x, y);
// If the windows position is saved, it must be a non-negative // If the windows position is saved, it must be a non-negative
// number. So if the window is partly off screen, move it to the // number. So if the window is partly off screen, move it to the
// corresponding edge. // corresponding edge.
if(x<0) x = 0; UserConfigParams::m_window_x = std::max(0, x);
if(y<0) y = 0; UserConfigParams::m_window_y = std::max(0, y);
Log::verbose("irr_driver",
"Retrieved window location for config : %i %i\n", x, y);
if (UserConfigParams::m_window_x != x || UserConfigParams::m_window_y != y)
{
UserConfigParams::m_window_x = x;
UserConfigParams::m_window_y = y;
} }
}
else
{
Log::warn("irr_driver", "Could not retrieve window location\n");
}
#elif defined(__linux__) && !defined(ANDROID)
if (m_device->getType() == EIDT_X11)
{
const video::SExposedVideoData& videoData =
m_device->getVideoDriver()->getExposedVideoData();
Display* display = (Display*)videoData.OpenGLLinux.X11Display;
XWindowAttributes xwa;
XGetWindowAttributes(display, get_toplevel_parent(display,
videoData.OpenGLLinux.X11Window), &xwa);
int wx = xwa.x;
int wy = xwa.y;
Log::verbose("irr_driver",
"Retrieved window location for config : %i %i\n", wx, wy);
if (UserConfigParams::m_window_x != wx ||
UserConfigParams::m_window_y != wy)
{
UserConfigParams::m_window_x = wx;
UserConfigParams::m_window_y = wy;
}
}
#endif
}
#endif // !SERVER_ONLY #endif // !SERVER_ONLY
} // updateConfigIfRelevant } // updateConfigIfRelevant
@ -867,49 +784,13 @@ core::position2di IrrDriver::getMouseLocation()
bool IrrDriver::moveWindow(int x, int y) bool IrrDriver::moveWindow(int x, int y)
{ {
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
#ifdef WIN32 bool success = m_device->moveWindow(x, y);
const video::SExposedVideoData& videoData =
m_video_driver->getExposedVideoData(); if (!success)
// this should work even if using DirectX in theory,
// because the HWnd is always third pointer in the struct,
// no matter which union is used
HWND window = (HWND)videoData.OpenGLWin32.HWnd;
if (SetWindowPos(window, HWND_TOP, x, y, -1, -1,
SWP_NOOWNERZORDER | SWP_NOSIZE))
{
// everything OK
return true;
}
else
{ {
Log::warn("irr_driver", "Could not set window location\n"); Log::warn("irr_driver", "Could not set window location\n");
return false; return false;
} }
#elif defined(__linux__) && !defined(ANDROID)
if (m_device->getType() == EIDT_X11)
{
const video::SExposedVideoData& videoData =
m_video_driver->getExposedVideoData();
Display* display = (Display*)videoData.OpenGLLinux.X11Display;
int screen = DefaultScreen(display);
int screen_w = DisplayWidth(display, screen);
int screen_h = DisplayHeight(display, screen);
if (x + UserConfigParams::m_width > screen_w)
{
x = screen_w - UserConfigParams::m_width;
}
if (y + UserConfigParams::m_height > screen_h)
{
y = screen_h - UserConfigParams::m_height;
}
// TODO: Actually handle possible failure
XMoveWindow(display, videoData.OpenGLLinux.X11Window, x, y);
}
#endif
#endif #endif
return true; return true;
} }