move/resize/fullscreen window for x11&win

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
Ovan
Posts: 70
Joined: Thu Dec 18, 2008 12:41 am
Contact:

move/resize/fullscreen window for x11&win

Post by Ovan »

Plop community I don't know why irrlicht doesn't provide this function by default but I share you some function to do this
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;
        }
 
using

Code: Select all

 
irr::core::dimension2du size;
bool fullscreen;
irr::IrrlichtDevice *dev;
 
as storage

sorry if I don't have the time to make a patch :?
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Re: move/resize/fullscreen window for x11&win

Post by christianclavet »

Thanks! This look interesting (Particularly the CENTER windows code for Linux, could save me a problem I have on Ubuntu)
Post Reply