from my engine, I used this function from several year and work well on my Slackware/xfce, Xp & seven
Code: Select all
#if defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(WIN64)
#include <windows.h>
#elif __linux
#include <X11/Xlib.h>
#include <X11/extensions/xf86vmode.h>
#endif
void IEntityManager::moveWindow(const irr::core::dimension2du &pos) noexcept
{
irr::video::SExposedVideoData evd = getVideoDriver()->getExposedVideoData();
#if defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(WIN64)
if(dev->getType() != irr::EIDT_WIN32) return;
HWND handle;
switch(getDevice()->getType())
{
EDT_DIRECT3D8: handle = (HWND)evd.D3D8.HWnd; break;
EDT_DIRECT3D9: handle = (HWND)evd.D3D9.HWnd; break;
default: handle = (HWND)evd.OpenGLWin32.HWnd; break;
}
MoveWindow(handle, pos.Width, pos.Height, getVideoDriver()->getScreenSize().Width, getVideoDriver()->getScreenSize().Height, false);
ShowWindow(handle, SW_SHOW);
UpdateWindow(handle);
#elif defined __linux
if(dev->getType() != irr::EIDT_X11) return;
if(evd.OpenGLLinux.X11Display && evd.OpenGLLinux.X11Window)
XMoveWindow((Display*)evd.OpenGLLinux.X11Display, (Window)evd.OpenGLLinux.X11Window, pos.Width, pos.Height);
#endif
}
void IEntityManager::centerWindow() noexcept
{
irr::core::dimension2du pos = dev->getVideoModeList()->getDesktopResolution();
pos -= getVideoDriver()->getScreenSize(); pos /= 2;
moveWindow(pos);
}
void IEntityManager::resizeWindow(const irr::core::dimension2du &s) noexcept
{
if(size == s) return;
irr::video::SExposedVideoData evd = getVideoDriver()->getExposedVideoData();
#if defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(WIN64)
if(dev->getType() != irr::EIDT_WIN32) return;
RECT r;
HWND handle;
switch(getDevice()->getType())
{
EDT_DIRECT3D8: handle = (HWND)evd.D3D8.HWnd; break;
EDT_DIRECT3D9: handle = (HWND)evd.D3D9.HWnd; break;
default: handle = (HWND)evd.OpenGLWin32.HWnd; break;
}
GetClientRect(handle, &r);
MoveWindow(handle, r.left, r.top, s.Width, s.Height, FALSE);
ShowWindow(handle, SW_SHOW);
UpdateWindow(handle);
#elif defined __linux
if(dev->getType() != irr::EIDT_X11) return;
if(evd.OpenGLLinux.X11Display && evd.OpenGLLinux.X11Window)
{
XResizeWindow((Display*)evd.OpenGLLinux.X11Display, (Window)evd.OpenGLLinux.X11Window, s.Width, s.Height);
XRaiseWindow((Display*)evd.OpenGLLinux.X11Display, (Window)evd.OpenGLLinux.X11Window);
XFlush((Display*)evd.OpenGLLinux.X11Display);
}
#endif
getVideoDriver()->OnResize({s.Width, s.Height});
getVideoDriver()->setViewPort({0,0, irr::s32(s.Width), irr::s32(s.Height)});
size = s;
irr::SEvent ev;
ev.UserEvent.UserData1 = 1;
ev.UserEvent.UserData2 = 1;
dev->postEventFromUser(ev);
}
irr::core::dimension2du IEntityManager::getScreenSize() noexcept
{
return size;
}
void IEntityManager::fullscreenWindow(const bool fs) noexcept
{
if(fullscreen == fs) return;
irr::video::SExposedVideoData evd = getVideoDriver()->getExposedVideoData();
#if defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(WIN64)
if(fs)
{
DEVMODE dm;
memset(&dm, 0, sizeof(dm));
dm.dmSize = sizeof(dm);
// use default values from current setting
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
dm.dmPelsWidth = getVideoDriver()->getScreenSize().Width;
dm.dmPelsHeight = getVideoDriver()->getScreenSize().Height;
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
LONG res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
if(res != DISP_CHANGE_SUCCESSFUL)
{
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
}
}
else ChangeDisplaySettings(NULL,0);
#elif defined __linux
if(dev->getType() != irr::EIDT_X11) return;
if(evd.OpenGLLinux.X11Display && evd.OpenGLLinux.X11Window)
{
Display *display = (Display*)evd.OpenGLLinux.X11Display;
Window window = (Window)evd.OpenGLLinux.X11Window;
Hints hints;
hints.flags = 2; // Specify that we're changing the window decorations.
hints.decorations = !fs;
Atom property;
property = XInternAtom(display,"_MOTIF_WM_HINTS",true);
XChangeProperty(display, window,property,property,32,PropModeReplace,(irr::u8 *)&hints,5);
irr::s32 modeCount;
XF86VidModeModeInfo** modes;
XF86VidModeGetAllModeLines(display, DefaultScreen(display), &modeCount, &modes);
irr::s32 bestMode = -1;
if(fs)
{
XMoveWindow(display, window, 0, 0);
for (irr::s32 i = 0; i<modeCount; ++i)
{
if (bestMode==-1 && modes[i]->hdisplay >= getVideoDriver()->getScreenSize().Width && modes[i]->vdisplay >= getVideoDriver()->getScreenSize().Height)
bestMode = i;
else if (bestMode!=-1 &&
modes[i]->hdisplay >= getVideoDriver()->getScreenSize().Width &&
modes[i]->vdisplay >= getVideoDriver()->getScreenSize().Height &&
modes[i]->hdisplay <= modes[bestMode]->hdisplay &&
modes[i]->vdisplay <= modes[bestMode]->vdisplay)
bestMode = i;
}
}
else
{
Screen *scr = XDefaultScreenOfDisplay(display);
for(irr::s32 i = 0; i<modeCount; ++i)
{
if (bestMode==-1 && modes[i]->hdisplay >= WidthOfScreen(scr) && modes[i]->vdisplay >= HeightOfScreen(scr))
bestMode = i;
else if(bestMode!=-1 &&
modes[i]->hdisplay >= WidthOfScreen(scr) &&
modes[i]->vdisplay >= HeightOfScreen(scr) &&
modes[i]->hdisplay <= modes[bestMode]->hdisplay &&
modes[i]->vdisplay <= modes[bestMode]->vdisplay)
bestMode = i;
}
irr::core::dimension2du pos(WidthOfScreen(scr), HeightOfScreen(scr));
pos -= getVideoDriver()->getScreenSize(); pos /= 2;
XMoveWindow(display, window, pos.Width, pos.Height);
}
//XGrabPointer(display,window,false,0,GrabModeAsync,GrabModeAsync,window,0L,CurrentTime);
//XGrabKeyboard(display,window,false,GrabModeAsync,GrabModeAsync,CurrentTime);
XF86VidModeSwitchToMode(display, DefaultScreen(display), modes[bestMode]);
XF86VidModeSetViewPort(display,DefaultScreen(display), 0, 0);
XRaiseWindow((Display*)evd.OpenGLLinux.X11Display, (Window)evd.OpenGLLinux.X11Window);
XFlush((Display*)evd.OpenGLLinux.X11Display);
XFree(modes);
}
#endif
fullscreen = fs;
}
Code: Select all
irr::core::dimension2du size;
bool fullscreen;
irr::IrrlichtDevice *dev;
sorry if I don't have the time to make a patch
