X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgraphics%2Fwindow.cpp;h=658eb26f5aab722c2b1515a4c64c4f6f9334ec73;hb=e5dd55567618c0a0789d25882d2e0eab69437d63;hp=a1353acf8fe4000f6b5a35cce9624cd6b2d43399;hpb=5d688fbf457b1f4d3bebde431a7f58c898be584c;p=libs%2Fgui.git diff --git a/source/graphics/window.cpp b/source/graphics/window.cpp index a1353ac..658eb26 100644 --- a/source/graphics/window.cpp +++ b/source/graphics/window.cpp @@ -1,53 +1,9 @@ -#include -#ifndef WIN32 -#include -#include -#ifdef WITH_XF86VIDMODE -#include -#endif -#else -#include -#endif -#include -#include #include "display.h" #include "window.h" -#include "display_priv.h" +#include "window_private.h" using namespace std; -namespace { - -#ifdef WIN32 -LRESULT CALLBACK wndproc_(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -{ - if(msg==WM_CREATE) - { - CREATESTRUCT *cs = reinterpret_cast(lparam); - SetWindowLong(hwnd, 0, reinterpret_cast(cs->lpCreateParams)); - } - else - { - Msp::Graphics::Window *wnd = reinterpret_cast(GetWindowLong(hwnd, 0)); - Msp::Graphics::Window::Event ev; - ev.msg = msg; - ev.wparam = wparam; - ev.lparam = lparam; - if(wnd && wnd->event(ev)) - return 0; - } - - return DefWindowProc(hwnd, msg, wparam, lparam); -} -#else -Bool match_event_type(Display *, XEvent *event, XPointer arg) -{ - return event->type==*reinterpret_cast(arg); -} -#endif - -} - namespace Msp { namespace Graphics { @@ -83,86 +39,7 @@ void Window::init() resizing = false; priv = new Private; -#ifdef WIN32 - static bool wndclass_created = false; - - if(!wndclass_created) - { - WNDCLASSEX wndcl; - - wndcl.cbSize = sizeof(WNDCLASSEX); - wndcl.style = 0; - wndcl.lpfnWndProc = &wndproc_; - wndcl.cbClsExtra = 0; - wndcl.cbWndExtra = sizeof(Window *); - wndcl.hInstance = reinterpret_cast(Application::get_data()); - wndcl.hIcon = 0; - wndcl.hCursor = LoadCursor(0, IDC_ARROW); - wndcl.hbrBackground = 0; - wndcl.lpszMenuName = 0; - wndcl.lpszClassName = "mspgui"; - wndcl.hIconSm = 0; - - if(!RegisterClassEx(&wndcl)) - throw system_error("RegisterClassEx"); - - wndclass_created = true; - } - - 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); - - priv->window = CreateWindowEx(exstyle, - "mspgui", - "Window", - style, - CW_USEDEFAULT, CW_USEDEFAULT, - rect.right-rect.left, rect.bottom-rect.top, - 0, - 0, - reinterpret_cast(Application::get_data()), - this); - if(!priv->window) - throw system_error("CreateWindowEx"); - -#else - ::Display *dpy = display.get_private().display; - - priv->wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", true); - priv->invisible_cursor = 0; - - XSetWindowAttributes attr; - attr.override_redirect = options.fullscreen; - attr.event_mask = ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask|EnterWindowMask; - - priv->window = XCreateWindow(dpy, - DefaultRootWindow(dpy), - 0, 0, - options.width, options.height, - 0, - CopyFromParent, - InputOutput, - CopyFromParent, - CWOverrideRedirect|CWEventMask, &attr); - - XSetWMProtocols(dpy, priv->window, &priv->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, priv->window, &hints); - } - -#endif + platform_init(); display.add_window(*this); display.check_error(); @@ -170,120 +47,32 @@ void Window::init() Window::~Window() { - if(priv->window) -#ifdef WIN32 - CloseWindow(priv->window); -#else - XDestroyWindow(display.get_private().display, priv->window); - - if(priv->invisible_cursor) - XFreeCursor(display.get_private().display, priv->invisible_cursor); -#endif + platform_cleanup(); display.remove_window(*this); - if(options.fullscreen) + if(options.fullscreen && visible) display.restore_mode(); delete priv; } -void Window::set_title(const string &title) -{ -#ifdef WIN32 - SetWindowText(priv->window, title.c_str()); -#else - vector buf(title.begin(), title.end()); - XTextProperty prop; - prop.value = &buf[0]; - prop.encoding = XA_STRING; - prop.format = 8; - prop.nitems = title.size(); - XSetWMName(display.get_private().display, priv->window, &prop); - display.check_error(); -#endif -} - void Window::reconfigure(const WindowOptions &opts) { bool fullscreen_changed = (opts.fullscreen!=options.fullscreen); - resizing = (opts.width!=options.width || opts.height!=options.height); - - options = opts; - -#ifdef WIN32 - 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(priv->window, GWL_EXSTYLE, exstyle); - SetWindowLong(priv->window, GWL_STYLE, style); - show(); - } - - if(options.fullscreen) - SetWindowPos(priv->window, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOZORDER); - else - SetWindowPos(priv->window, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOMOVE|SWP_NOZORDER); -#else - ::Display *dpy = display.get_private().display; - - bool was_visible = visible; - if(fullscreen_changed) - { - if(was_visible) - { - hide(); - - // Wait for the window to be unmapped. This makes window managers happy. - XEvent ev; - int ev_type = UnmapNotify; - XPeekIfEvent(dpy, &ev, match_event_type, reinterpret_cast(&ev_type)); - } - - XSetWindowAttributes attr; - attr.override_redirect = options.fullscreen; - XChangeWindowAttributes(dpy, priv->window, CWOverrideRedirect, &attr); - } - - 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, priv->window, &hints); - - if(options.fullscreen) - XMoveResizeWindow(dpy, priv->window, 0, 0, options.width, options.height); - else - XResizeWindow(dpy, priv->window, options.width, options.height); - - if(fullscreen_changed) - { - if(was_visible) - show(); - } -#endif + if(opts.width!=options.width || opts.height!=options.height) + resizing = true; if(visible) { - if(options.fullscreen) - display.set_mode(VideoMode(options.width, options.height)); + if(opts.fullscreen) + display.set_mode(VideoMode(opts.width, opts.height)); else if(fullscreen_changed) display.restore_mode(); } + + options = opts; + platform_reconfigure(fullscreen_changed); } void Window::set_keyboard_autorepeat(bool r) @@ -291,155 +80,26 @@ void Window::set_keyboard_autorepeat(bool r) kbd_autorepeat = r; } -void Window::show_cursor(bool s) -{ -#ifdef WIN32 - ShowCursor(s); -#else - ::Display *dpy = display.get_private().display; - - if(s) - XUndefineCursor(dpy, priv->window); - else - { - if(!priv->invisible_cursor) - { - int screen = DefaultScreen(dpy); - - Pixmap pm = XCreatePixmap(dpy, priv->window, 1, 1, 1); - GC gc = XCreateGC(dpy, pm, 0, 0); - XSetFunction(dpy, gc, GXclear); - XDrawPoint(dpy, pm, gc, 0, 0); - XFreeGC(dpy, gc); - - XColor black; - black.pixel = BlackPixel(dpy, screen); - XQueryColor(dpy, DefaultColormap(dpy, screen), &black); - - priv->invisible_cursor = XCreatePixmapCursor(dpy, pm, pm, &black, &black, 0, 0); - - XFreePixmap(dpy, pm); - } - XDefineCursor(dpy, priv->window, priv->invisible_cursor); - } -#endif -} - -void Window::warp_pointer(int x, int y) -{ -#ifndef WIN32 - XWarpPointer(display.get_private().display, None, priv->window, 0, 0, 0, 0, x, y); -#else - (void)x; - (void)y; -#endif -} - void Window::show() { -#ifdef WIN32 - ShowWindow(priv->window, SW_SHOWNORMAL); -#else - XMapRaised(display.get_private().display, priv->window); -#endif + platform_show(); visible = true; if(options.fullscreen) { - display.set_mode(VideoMode(options.width, options.height)); -#ifndef WIN32 - XWarpPointer(display.get_private().display, None, priv->window, 0, 0, 0, 0, options.width/2, options.height/2); -#endif + display.set_mode(VideoMode(options.width, options.height), true); + warp_pointer(options.width/2, options.height/2); } } void Window::hide() { -#ifdef WIN32 - ShowWindow(priv->window, SW_HIDE); -#else - XUnmapWindow(display.get_private().display, priv->window); -#endif + platform_hide(); visible = false; if(options.fullscreen) display.restore_mode(); } -bool Window::event(const Event &evnt) -{ -#ifdef WIN32 - switch(evnt.msg) - { - case WM_KEYDOWN: - case WM_KEYUP: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_MOUSEWHEEL: - case WM_MOUSEMOVE: - signal_input_event.emit(evnt); - break; - case WM_SIZE: - options.width = LOWORD(evnt.lparam); - options.height = HIWORD(evnt.lparam); - signal_resize.emit(options.width, options.height); - break; - case WM_CLOSE: - signal_close.emit(); - break; - default: - return false; - } -#else - const XEvent &ev = evnt.xevent; - switch(ev.type) - { - case ButtonPress: - case ButtonRelease: - case MotionNotify: - case KeyPress: - case KeyRelease: - signal_input_event.emit(evnt); - break; - case ConfigureNotify: - if((ev.xconfigure.width==static_cast(options.width) && ev.xconfigure.height==static_cast(options.height)) == resizing) - { - options.width = ev.xconfigure.width; - options.height = ev.xconfigure.height; - resizing = false; - signal_resize.emit(options.width, options.height); - } -#ifdef WITH_XF86VIDMODE - if(options.fullscreen) - { - ::Display *dpy = display.get_private().display; - int screen = DefaultScreen(dpy); - XF86VidModeSetViewPort(dpy, screen, ev.xconfigure.x, ev.xconfigure.y); - } -#endif - break; - case ClientMessage: - if(ev.xclient.data.l[0]==static_cast(priv->wm_delete_window)) - signal_close.emit(); - break; - case EnterNotify: - if(options.fullscreen) - XSetInputFocus(display.get_private().display, priv->window, RevertToParent, CurrentTime); - break; - case MapNotify: - if(options.fullscreen) - XGrabPointer(display.get_private().display, priv->window, true, None, GrabModeAsync, GrabModeAsync, priv->window, None, CurrentTime); - break; - default: - return false; - } -#endif - return true; -} - } // namespace Graphics } // namespace Msp