X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fwindow.cpp;fp=source%2Fwindow.cpp;h=7f6f6d8fa0e6c77463df993397d01b9dc10ff777;hb=61eeb96535d1575ca0cf698d833c0ddfc7ae0f50;hp=f916d1c9e5312e4290d40224e076b0e9e776b5e1;hpb=f347e2259f66ca2d43deaf8da7bd718622b90f9e;p=libs%2Fgui.git diff --git a/source/window.cpp b/source/window.cpp index f916d1c..7f6f6d8 100644 --- a/source/window.cpp +++ b/source/window.cpp @@ -6,14 +6,21 @@ Distributed under the LGPL */ #include +#ifndef WIN32 #include #include +#else +#include +#endif +#include #include #include "display.h" #include "window.h" using namespace std; +#include + namespace Msp { namespace Graphics { @@ -45,7 +52,11 @@ Window::Window(Display &dpy, const WindowOptions &opts): Window::~Window() { if(window) +#ifdef WIN32 + CloseWindow(window); +#else XDestroyWindow(display.get_display(), window); +#endif display.remove_window(this); @@ -55,6 +66,9 @@ Window::~Window() void Window::set_title(const string &title) { +#ifdef WIN32 + SetWindowText(window, title.c_str()); +#else vector buf(title.begin(), title.end()); XTextProperty prop; prop.value=&buf[0]; @@ -63,6 +77,7 @@ void Window::set_title(const string &title) prop.nitems=title.size(); XSetWMName(display.get_display(), window, &prop); display.check_error(); +#endif } void Window::reconfigure(const WindowOptions &opts) @@ -71,6 +86,12 @@ void Window::reconfigure(const WindowOptions &opts) options=opts; +#ifdef WIN32 + // XXX Preserve position + MoveWindow(window, 0, 0, options.width, options.height, false); + + (void)fullscreen_changed; +#else ::Display *dpy=display.get_display(); XMoveResizeWindow(dpy, window, 0, 0, options.width, options.height); @@ -88,22 +109,78 @@ void Window::reconfigure(const WindowOptions &opts) display.set_mode(VideoMode(options.width, options.height)); else if(fullscreen_changed) display.restore_mode(); +#endif } void Window::show() { +#ifdef WIN32 + ShowWindow(window, SW_SHOWNORMAL); +#else XMapRaised(display.get_display(), window); display.check_error(); +#endif } void Window::hide() { +#ifdef WIN32 + ShowWindow(window, SW_HIDE); +#else XUnmapWindow(display.get_display(), window); display.check_error(); +#endif } void Window::init() { +#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=0; + 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; + rect.left=0; + rect.top=0; + rect.right=options.width; + rect.bottom=options.height; + AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, false, WS_EX_OVERLAPPEDWINDOW); + + window=CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, + "mspgbase", + "Window", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + rect.right-rect.left, rect.bottom-rect.top, + 0, + 0, + reinterpret_cast(Application::get_data()), + this); + if(!window) + throw Exception("CreateWindowEx failed"); + +#else ::Display *dpy=display.get_display(); wm_delete_window=XInternAtom(dpy, "WM_DELETE_WINDOW", true); @@ -112,7 +189,15 @@ void Window::init() attr.override_redirect=options.fullscreen; attr.event_mask=ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask|EnterWindowMask; - window=XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, options.width, options.height, 0, CopyFromParent, InputOutput, CopyFromParent, CWOverrideRedirect|CWEventMask, &attr); + window=XCreateWindow(dpy, + DefaultRootWindow(dpy), + 0, 0, + options.width, options.height, + 0, + CopyFromParent, + InputOutput, + CopyFromParent, + CWOverrideRedirect|CWEventMask, &attr); XSetWMProtocols(dpy, window, &wm_delete_window, 1); @@ -121,11 +206,13 @@ void Window::init() display.set_mode(VideoMode(options.width, options.height)); XWarpPointer(dpy, None, window, 0, 0, 0, 0, options.width/2, options.height/2); } +#endif display.add_window(this); display.check_error(); } +#ifndef WIN32 void Window::event(const XEvent &ev) { switch(ev.type) @@ -169,6 +256,67 @@ void Window::event(const XEvent &ev) default:; } } +#endif + +#ifdef WIN32 +int Window::wndproc(UINT msg, WPARAM wp, LPARAM lp) +{ + switch(msg) + { + case WM_KEYDOWN: + signal_key_press.emit(wp, 0, wp); + break; + case WM_KEYUP: + signal_key_release.emit(wp, 0); + break; + case WM_LBUTTONDOWN: + signal_button_press.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 1, 0); + break; + case WM_LBUTTONUP: + signal_button_release.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 1, 0); + break; + case WM_MBUTTONDOWN: + signal_button_press.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 2, 0); + break; + case WM_MBUTTONUP: + signal_button_release.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 2, 0); + break; + case WM_RBUTTONDOWN: + signal_button_press.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 3, 0); + break; + case WM_RBUTTONUP: + signal_button_release.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp), 3, 0); + break; + case WM_MOUSEMOVE: + signal_pointer_motion.emit(GET_X_LPARAM(lp), GET_Y_LPARAM(lp)); + break; + case WM_CLOSE: + signal_close.emit(); + break; + default: + return 0; + } + + return 1; +} + +LRESULT CALLBACK Window::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 + { + Window *wnd=reinterpret_cast(GetWindowLong(hwnd, 0)); + if(wnd && wnd->wndproc(msg, wparam, lparam)) + return 0; + } + + return DefWindowProc(hwnd, msg, wparam, lparam); +} +#endif } // namespace Graphics } // namespace Msp