]> git.tdb.fi Git - libs/gui.git/blobdiff - source/gbase/window.cpp
Move Image from mspgl to here
[libs/gui.git] / source / gbase / window.cpp
index 4a14441e9c3704507520135239ac63ae729ea14d..9f2361e4e3c90ab93243294d0d206cf648e15ffb 100644 (file)
@@ -54,6 +54,9 @@ Window::~Window()
                CloseWindow(window);
 #else
                XDestroyWindow(display.get_display(), window);
+
+       if(invisible_cursor)
+               XFreeCursor(display.get_display(), invisible_cursor);
 #endif
 
        display.remove_window(this);
@@ -85,15 +88,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();
@@ -103,10 +123,63 @@ 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();
+}
+
+void Window::show_cursor(bool s)
+{
+#ifdef WIN32
+       ShowCursor(s);
+#else
+       ::Display *dpy=display.get_display();
+
+       if(s)
+               XUndefineCursor(dpy, window);
+       else
+       {
+               if(!invisible_cursor)
+               {
+                       int screen=DefaultScreen(dpy);
+                       char data=0;
+                       XImage *img=XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap, 0, &data, 1, 1, 8, 1);
+
+                       Pixmap pm=XCreatePixmap(dpy, window, 1, 1, 1);
+                       GC gc=XCreateGC(dpy, pm, 0, 0);
+                       XPutImage(dpy, pm, gc, img, 0, 0, 0, 0, 1, 1);
+
+                       XColor black;
+                       black.pixel=BlackPixel(dpy, screen);
+                       XQueryColor(dpy, DefaultColormap(dpy, screen), &black);
+
+                       invisible_cursor=XCreatePixmapCursor(dpy, pm, pm, &black, &black, 0, 0);
+
+                       XFreeGC(dpy, gc);
+                       XFreePixmap(dpy, pm);
+                       img->data=0;
+                       XDestroyImage(img);
+               }
+               XDefineCursor(dpy, window, invisible_cursor);
+       }
 #endif
 }
 
@@ -159,16 +232,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);
+
+       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(WS_EX_OVERLAPPEDWINDOW,
+       window=CreateWindowEx(exstyle,
                "mspgbase",
                "Window",
-               WS_OVERLAPPEDWINDOW,
+               style,
                CW_USEDEFAULT, CW_USEDEFAULT,
                rect.right-rect.left, rect.bottom-rect.top,
                0,
@@ -178,10 +253,14 @@ 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();
 
        wm_delete_window=XInternAtom(dpy, "WM_DELETE_WINDOW", true);
+       invisible_cursor=0;
 
        XSetWindowAttributes attr;
        attr.override_redirect=options.fullscreen;
@@ -199,6 +278,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));
@@ -288,6 +376,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;