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.
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.
/** 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

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
{
return EIDT_ANDROID;

View File

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

View File

@ -446,6 +446,17 @@ void CIrrDeviceConsole::restoreWindow()
// 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)
{

View File

@ -88,6 +88,12 @@ namespace irr
//! Restores the window size.
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
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
E_DEVICE_TYPE CIrrDeviceFB::getType() const

View File

@ -65,6 +65,12 @@ namespace irr
//! Restores original window size
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
virtual bool present(video::IImage* surface, void* windowId = 0, core::rect<s32>* src=0 );

View File

@ -2194,6 +2194,101 @@ void CIrrDeviceLinux::restoreWindow()
#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()
{

View File

@ -99,6 +99,12 @@ namespace irr
//! Restores the window size.
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.
virtual bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo);

View File

@ -761,6 +761,18 @@ void CIrrDeviceSDL::restoreWindow()
// 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
bool CIrrDeviceSDL::isWindowActive() const

View File

@ -79,6 +79,12 @@ namespace irr
//! Restores the window size.
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.
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
bool CIrrDeviceWayland::setGammaRamp(f32 red, f32 green, f32 blue,
f32 brightness, f32 contrast)

View File

@ -104,6 +104,12 @@ namespace irr
//! Restores the window size.
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.
virtual bool activateJoysticks(core::array<SJoystickInfo>& joystickInfo);

View File

@ -2131,6 +2131,38 @@ void CIrrDeviceWin32::restoreWindow()
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)
{

View File

@ -87,6 +87,12 @@ namespace irr
//! Restores the window size.
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.
virtual bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo);

View File

@ -83,6 +83,12 @@ namespace irr
//! Restore the window to normal size if possible.
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.
virtual bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo);

View File

@ -1528,6 +1528,18 @@ void CIrrDeviceMacOSX::restoreWindow()
[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 )
{

View File

@ -91,15 +91,6 @@ please use the included version."
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 */
IrrDriver *irr_driver = NULL;
@ -228,45 +219,6 @@ std::unique_ptr<RenderTarget> IrrDriver::createRenderTarget(const irr::core::dim
} // createRenderTarget
#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
* file.
@ -278,61 +230,26 @@ void IrrDriver::updateConfigIfRelevant()
if (!UserConfigParams::m_fullscreen &&
UserConfigParams::m_remember_window_location)
{
#ifdef WIN32
const video::SExposedVideoData& videoData = m_device->getVideoDriver()
->getExposedVideoData();
// 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;
WINDOWPLACEMENT placement;
placement.length = sizeof(WINDOWPLACEMENT);
if (GetWindowPlacement(window, &placement))
int x = 0;
int y = 0;
bool success = m_device->getWindowPosition(&x, &y);
if (!success)
{
int x = (int)placement.rcNormalPosition.left;
int y = (int)placement.rcNormalPosition.top;
// 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
// corresponding edge.
if(x<0) x = 0;
if(y<0) y = 0;
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;
}
Log::warn("irr_driver", "Could not retrieve window location");
return;
}
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
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
// number. So if the window is partly off screen, move it to the
// corresponding edge.
UserConfigParams::m_window_x = std::max(0, x);
UserConfigParams::m_window_y = std::max(0, y);
}
#endif // !SERVER_ONLY
} // updateConfigIfRelevant
@ -867,49 +784,13 @@ core::position2di IrrDriver::getMouseLocation()
bool IrrDriver::moveWindow(int x, int y)
{
#ifndef SERVER_ONLY
#ifdef WIN32
const video::SExposedVideoData& videoData =
m_video_driver->getExposedVideoData();
// 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
bool success = m_device->moveWindow(x, y);
if (!success)
{
Log::warn("irr_driver", "Could not set window location\n");
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
return true;
}