X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgbase%2Fwindow.cpp;h=08cb74db081807edd765c6a0115a40684c913696;hb=a8e642edcf466cf92313cbf1f467a2d10de03fb4;hp=7d58fe40b9abfceeacf699edf2081b372c220f63;hpb=746e5da7730baee990fb1e307d416e0593b3f083;p=libs%2Fgui.git diff --git a/source/gbase/window.cpp b/source/gbase/window.cpp index 7d58fe4..08cb74d 100644 --- a/source/gbase/window.cpp +++ b/source/gbase/window.cpp @@ -80,6 +80,97 @@ Window::Window(Display &dpy, const WindowOptions &opts): init(); } +void Window::init() +{ + visible=false; + kbd_autorepeat=true; + 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="mspgbase"; + wndcl.hIconSm=0; + + if(!RegisterClassEx(&wndcl)) + throw Exception("Couldn't register window class"); + + 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, + "mspgbase", + "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 Exception("CreateWindowEx failed"); + +#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 + + display.add_window(*this); + display.check_error(); +} + Window::~Window() { if(priv->window) @@ -149,16 +240,23 @@ void Window::reconfigure(const WindowOptions &opts) if(fullscreen_changed) { - hide(); + bool was_visible=visible; + + if(was_visible) + { + hide(); - // Wait for the window to be unmapped. This makes window managers happy. - XEvent ev; - XPeekIfEvent(dpy, &ev, match_event_type, reinterpret_cast(UnmapNotify)); + // Wait for the window to be unmapped. This makes window managers happy. + XEvent ev; + XPeekIfEvent(dpy, &ev, match_event_type, reinterpret_cast(UnmapNotify)); + } XSetWindowAttributes attr; attr.override_redirect=options.fullscreen; XChangeWindowAttributes(dpy, priv->window, CWOverrideRedirect, &attr); - show(); + + if(was_visible) + show(); } XSizeHints hints; @@ -178,10 +276,18 @@ void Window::reconfigure(const WindowOptions &opts) XResizeWindow(dpy, priv->window, options.width, options.height); #endif - if(options.fullscreen) - display.set_mode(VideoMode(options.width, options.height)); - else if(fullscreen_changed) - display.restore_mode(); + if(visible) + { + if(options.fullscreen) + display.set_mode(VideoMode(options.width, options.height)); + else if(fullscreen_changed) + display.restore_mode(); + } +} + +void Window::set_keyboard_autorepeat(bool r) +{ + kbd_autorepeat=r; } void Window::show_cursor(bool s) @@ -222,6 +328,9 @@ 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 } @@ -232,6 +341,15 @@ void Window::show() #else XMapRaised(display.get_private().display, priv->window); #endif + 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 + } } void Window::hide() @@ -241,103 +359,10 @@ void Window::hide() #else XUnmapWindow(display.get_private().display, priv->window); #endif -} - -void Window::init() -{ - 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="mspgbase"; - wndcl.hIconSm=0; - - if(!RegisterClassEx(&wndcl)) - throw Exception("Couldn't register window class"); - - 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, - "mspgbase", - "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 Exception("CreateWindowEx failed"); - - if(options.fullscreen) - display.set_mode(VideoMode(options.width, options.height)); - -#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); - } + visible=false; if(options.fullscreen) - { - display.set_mode(VideoMode(options.width, options.height)); - XWarpPointer(dpy, None, priv->window, 0, 0, 0, 0, options.width/2, options.height/2); - } -#endif - - display.add_window(*this); - display.check_error(); + display.restore_mode(); } bool Window::event(const Event &evnt) @@ -371,6 +396,13 @@ bool Window::event(const Event &evnt) case WM_RBUTTONUP: signal_button_release.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 3, 0); break; + case WM_MOUSEWHEEL: + { + unsigned btn = (HIWORD(wp)&0x8000) ? 5 : 4; + signal_button_press.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), btn, 0); + signal_button_release.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), btn, 0); + } + break; case WM_MOUSEMOVE: signal_pointer_motion.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp)); break;