]> git.tdb.fi Git - libs/gui.git/blobdiff - source/gbase/window.cpp
Implement video mode changing and fullscreen on win32
[libs/gui.git] / source / gbase / window.cpp
index da877e966679b8ffd8f66b362a9f8feec2b6e695..3ba8d767a90e9edf5b9392bd2ef5d3d5b4f62e2d 100644 (file)
@@ -19,8 +19,6 @@ Distributed under the LGPL
 
 using namespace std;
 
-#include <iostream>
-
 namespace Msp {
 namespace Graphics {
 
@@ -87,15 +85,32 @@ void Window::reconfigure(const WindowOptions &opts)
        options=opts;
 
 #ifdef WIN32
-       // XXX Preserve position
-       MoveWindow(window, 0, 0, options.width, options.height, false);
+       RECT rect;
+       SetRect(&rect, 0, 0, options.width, options.height);
+
+       int style=(options.fullscreen ? WS_POPUP : WS_OVERLAPPEDWINDOW);
+       if(!options.resizable)
+               style&=~WS_THICKFRAME;
+       int exstyle=(options.fullscreen ? WS_EX_APPWINDOW : WS_EX_OVERLAPPEDWINDOW);
+       AdjustWindowRectEx(&rect, style, false, exstyle);
+
+       if(fullscreen_changed)
+       {
+               hide();
+               SetWindowLong(window, GWL_EXSTYLE, exstyle);
+               SetWindowLong(window, GWL_STYLE, style);
+               show();
+       }
+
+       if(options.fullscreen)
+               SetWindowPos(window, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOZORDER);
+       else
+               SetWindowPos(window, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOMOVE|SWP_NOZORDER);
 
        (void)fullscreen_changed;
 #else
        ::Display *dpy=display.get_display();
 
-       XMoveResizeWindow(dpy, window, 0, 0, options.width, options.height);
-
        if(fullscreen_changed)
        {
                hide();
@@ -105,11 +120,27 @@ void Window::reconfigure(const WindowOptions &opts)
                show();
        }
 
+       XSizeHints hints;
+       if(options.resizable)
+               hints.flags=0;
+       else
+       {
+               hints.flags=PMinSize|PMaxSize;
+               hints.min_width=hints.max_width=options.width;
+               hints.min_height=hints.max_height=options.height;
+       }
+       XSetWMNormalHints(dpy, window, &hints);
+
+       if(options.fullscreen)
+               XMoveResizeWindow(dpy, window, 0, 0, options.width, options.height);
+       else
+               XResizeWindow(dpy, window, options.width, options.height);
+#endif
+
        if(options.fullscreen)
                display.set_mode(VideoMode(options.width, options.height));
        else if(fullscreen_changed)
                display.restore_mode();
-#endif
 }
 
 void Window::show()
@@ -161,16 +192,18 @@ void Window::init()
        }
 
        RECT rect;
-       rect.left=0;
-       rect.top=0;
-       rect.right=options.width;
-       rect.bottom=options.height;
-       AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, false, WS_EX_OVERLAPPEDWINDOW);
+       SetRect(&rect, 0, 0, options.width, options.height);
 
-       window=CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
+       int style=(options.fullscreen ? WS_POPUP : WS_OVERLAPPEDWINDOW);
+       if(!options.resizable)
+               style&=~WS_THICKFRAME;
+       int exstyle=(options.fullscreen ? WS_EX_APPWINDOW : WS_EX_OVERLAPPEDWINDOW);
+       AdjustWindowRectEx(&rect, style, false, exstyle);
+
+       window=CreateWindowEx(exstyle,
                "mspgbase",
                "Window",
-               WS_OVERLAPPEDWINDOW,
+               style,
                CW_USEDEFAULT, CW_USEDEFAULT,
                rect.right-rect.left, rect.bottom-rect.top,
                0,
@@ -180,6 +213,9 @@ void Window::init()
        if(!window)
                throw Exception("CreateWindowEx failed");
 
+       if(options.fullscreen)
+               display.set_mode(VideoMode(options.width, options.height));
+
 #else
        ::Display *dpy=display.get_display();
 
@@ -201,6 +237,15 @@ void Window::init()
 
        XSetWMProtocols(dpy, window, &wm_delete_window, 1);
 
+       if(!options.resizable)
+       {
+               XSizeHints hints;
+               hints.flags=PMinSize|PMaxSize;
+               hints.min_width=hints.max_width=options.width;
+               hints.min_height=hints.max_height=options.height;
+               XSetWMNormalHints(dpy, window, &hints);
+       }
+
        if(options.fullscreen)
        {
                display.set_mode(VideoMode(options.width, options.height));
@@ -231,11 +276,11 @@ void Window::event(const XEvent &ev)
                        char buf[16];
                        XLookupString(const_cast<XKeyEvent *>(&ev.xkey), buf, sizeof(buf), 0, 0);
                        // XXX Handle the result according to locale
-                       signal_key_press.emit(ev.xkey.keycode, ev.xkey.state, buf[0]);
+                       signal_key_press.emit(XKeycodeToKeysym(display.get_display(), ev.xkey.keycode, 0), ev.xkey.state, buf[0]);
                }
                break;
        case KeyRelease:
-               signal_key_release.emit(ev.xkey.keycode, ev.xkey.state);
+               signal_key_release.emit(XKeycodeToKeysym(display.get_display(), ev.xkey.keycode, 0), ev.xkey.state);
                break;
        case ConfigureNotify:
                options.width=ev.xconfigure.width;
@@ -264,10 +309,10 @@ int Window::wndproc(UINT msg, WPARAM wp, LPARAM lp)
        switch(msg)
        {
        case WM_KEYDOWN:
-               signal_key_press.emit((lp>>16)&0x1FF, 0, wp);
+               signal_key_press.emit(wp, 0, wp);
                break;
        case WM_KEYUP:
-               signal_key_release.emit((lp>>16)&0x1FF, 0);
+               signal_key_release.emit(wp, 0);
                break;
        case WM_LBUTTONDOWN:
                signal_button_press.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 1, 0);
@@ -290,6 +335,11 @@ int Window::wndproc(UINT msg, WPARAM wp, LPARAM lp)
        case WM_MOUSEMOVE:
                signal_pointer_motion.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp));
                break;
+       case WM_SIZE:
+               options.width=LOWORD(lp);
+               options.height=HIWORD(lp);
+               signal_resize.emit(options.width, options.height);
+               break;
        case WM_CLOSE:
                signal_close.emit();
                break;