From fcd5f24311fcfe772825a75678e038749401a9be Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 5 Oct 2008 08:57:50 +0000 Subject: [PATCH] Hide the platform-specific parts of other classes as well --- source/gbase/display.cpp | 50 ++++---- source/gbase/display.h | 19 ++- source/gbase/display_priv.h | 27 +++++ source/gbase/drawcontext.cpp | 73 +++++++----- source/gbase/drawcontext.h | 15 +-- source/gbase/glcontext.cpp | 22 ++-- source/gbase/types.h | 29 ----- source/gbase/window.cpp | 223 ++++++++++++++++++----------------- source/gbase/window.h | 22 ++-- source/gbase/window_priv.h | 49 ++++++++ source/input/keyboard.cpp | 7 +- 11 files changed, 301 insertions(+), 235 deletions(-) create mode 100644 source/gbase/display_priv.h delete mode 100644 source/gbase/types.h create mode 100644 source/gbase/window_priv.h diff --git a/source/gbase/display.cpp b/source/gbase/display.cpp index b39330b..3a75501 100644 --- a/source/gbase/display.cpp +++ b/source/gbase/display.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgbase -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -15,6 +15,7 @@ Distributed under the LGPL #include #include "display.h" #include "window.h" +#include "display_priv.h" using namespace std; @@ -52,7 +53,8 @@ int x_error_handler(Display *display, XErrorEvent *event) namespace Msp { namespace Graphics { -Display::Display(const string &disp_name) +Display::Display(const string &disp_name): + priv(new Private) { #ifdef WIN32 (void)disp_name; @@ -76,19 +78,19 @@ Display::Display(const string &disp_name) } #else if(disp_name.empty()) - display=XOpenDisplay(0); + priv->display=XOpenDisplay(0); else - display=XOpenDisplay(disp_name.c_str()); - if(!display) + priv->display=XOpenDisplay(disp_name.c_str()); + if(!priv->display) throw Exception("Couldn't open X display"); XSetErrorHandler(x_error_handler); - int screen=DefaultScreen(display); + int screen=DefaultScreen(priv->display); int nmodes; XF86VidModeModeInfo **infos; - XF86VidModeGetAllModeLines(display, screen, &nmodes, &infos); + XF86VidModeGetAllModeLines(priv->display, screen, &nmodes, &infos); for(int i=0; idisplay, screen, &dotclock, &modeline); orig_mode=VideoMode(modeline.hdisplay, modeline.vdisplay); if(modeline.htotal && modeline.vtotal) orig_mode.rate=dotclock/(modeline.htotal*modeline.vtotal); @@ -113,19 +115,19 @@ Display::Display(const string &disp_name) Display::~Display() { #ifndef WIN32 - XCloseDisplay(display); - display=0; + XCloseDisplay(priv->display); + delete priv; #endif } -void Display::add_window(Window *wnd) +void Display::add_window(Window &wnd) { - windows[wnd->get_handle()]=wnd; + priv->windows[wnd.get_private().window]=&wnd; } -void Display::remove_window(Window *wnd) +void Display::remove_window(Window &wnd) { - windows.erase(wnd->get_handle()); + priv->windows.erase(wnd.get_private().window); } void Display::set_mode(const VideoMode &mode) @@ -144,11 +146,11 @@ void Display::set_mode(const VideoMode &mode) ChangeDisplaySettings(&info, CDS_FULLSCREEN); #else - int screen=DefaultScreen(display); + int screen=DefaultScreen(priv->display); int nmodes; XF86VidModeModeInfo **infos; - XF86VidModeGetAllModeLines(display, screen, &nmodes, &infos); + XF86VidModeGetAllModeLines(priv->display, screen, &nmodes, &infos); for(int i=0; idisplay, screen, &info); + XF86VidModeSetViewPort(priv->display, screen, 0, 0); return; } } @@ -181,20 +183,22 @@ void Display::tick() else break; #else - int pending=XPending(display); + int pending=XPending(priv->display); if(pending==0) break; for(int i=0; idisplay, &event.xevent); check_error(); - map::iterator j=windows.find(event.xany.window); - if(j!=windows.end()) + map::iterator j=priv->windows.find(event.xevent.xany.window); + if(j!=priv->windows.end()) + { j->second->event(event); + } } #endif } diff --git a/source/gbase/display.h b/source/gbase/display.h index 70efd20..a827f50 100644 --- a/source/gbase/display.h +++ b/source/gbase/display.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgbase -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -11,7 +11,6 @@ Distributed under the LGPL #include #include #include -#include "types.h" namespace Msp { namespace Graphics { @@ -30,24 +29,22 @@ struct VideoMode class Display { +public: + struct Private; + private: -#ifndef WIN32 - ::Display *display; -#endif std::list modes; VideoMode orig_mode; - std::map windows; + Private *priv; public: Display(const std::string &disp_name=std::string()); ~Display(); -#ifndef WIN32 - ::Display *get_display() const { return display; } -#endif + const Private &get_private() const { return *priv; } - void add_window(Window *); - void remove_window(Window *); + void add_window(Window &); + void remove_window(Window &); const std::list &get_modes() const { return modes; } void set_mode(const VideoMode &); diff --git a/source/gbase/display_priv.h b/source/gbase/display_priv.h new file mode 100644 index 0000000..1c4f6c5 --- /dev/null +++ b/source/gbase/display_priv.h @@ -0,0 +1,27 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2008 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GBASE_DISPLAY_PRIV_H_ +#define MSP_GBASE_DISPLAY_PRIV_H_ + +#include "window_priv.h" + +namespace Msp { +namespace Graphics { + +struct Display::Private +{ +#ifndef WIN32 + ::Display *display; +#endif + std::map windows; +}; + +} // namespace Graphics +} // namespace Msp + +#endif diff --git a/source/gbase/drawcontext.cpp b/source/gbase/drawcontext.cpp index 86edf56..b3eaf9e 100644 --- a/source/gbase/drawcontext.cpp +++ b/source/gbase/drawcontext.cpp @@ -1,56 +1,72 @@ /* $Id$ This file is part of libmspgbase -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ #ifndef WIN32 #include #include +#include +#include #include #endif #include #include "display.h" #include "drawcontext.h" #include "window.h" +#include "display_priv.h" namespace Msp { namespace Graphics { +struct DrawContext::Private +{ +#ifndef WIN32 + XImage *image; + bool use_shm; + XShmSegmentInfo shminfo; +#endif +}; + DrawContext::DrawContext(Window &w): display(w.get_display()), window(w) { -#ifndef WIN32 - ::Display *dpy=display.get_display(); +#ifdef WIN32 + throw Exception("DrawContext not supported on win32 yet"); +#else + priv=new Private; - use_shm=XShmQueryExtension(dpy); + ::Display *dpy=display.get_private().display; + + priv->use_shm=XShmQueryExtension(dpy); XWindowAttributes wa; - XGetWindowAttributes(dpy, window.get_handle(), &wa); + XGetWindowAttributes(dpy, window.get_private().window, &wa); - if(use_shm) + if(priv->use_shm) { - image=XShmCreateImage(dpy, wa.visual, wa.depth, ZPixmap, 0, &shminfo, wa.width, wa.height); - if(!image) + priv->image=XShmCreateImage(dpy, wa.visual, wa.depth, ZPixmap, 0, &priv->shminfo, wa.width, wa.height); + if(!priv->image) throw Exception("Could not create shared memory XImage"); - shminfo.shmid=shmget(IPC_PRIVATE, image->bytes_per_line*image->height, IPC_CREAT|0666); - shminfo.shmaddr=image->data=reinterpret_cast(shmat(shminfo.shmid, 0, 0)); - shminfo.readOnly=false; + priv->shminfo.shmid=shmget(IPC_PRIVATE, priv->image->bytes_per_line*priv->image->height, IPC_CREAT|0666); + priv->shminfo.shmaddr=priv->image->data=reinterpret_cast(shmat(priv->shminfo.shmid, 0, 0)); + priv->shminfo.readOnly=false; - XShmAttach(dpy, &shminfo); + XShmAttach(dpy, &priv->shminfo); XSync(dpy, false); display.check_error(); } else { - image=XCreateImage(dpy, wa.visual, wa.depth, ZPixmap, 0, 0, wa.width, wa.height, 8, 0); - if(!image) + priv->image=XCreateImage(dpy, wa.visual, wa.depth, ZPixmap, 0, 0, wa.width, wa.height, 8, 0); + if(!priv->image) throw Exception("Could not create XImage"); - image->data=new char[image->bytes_per_line*image->height]; + priv->image->data=new char[priv->image->bytes_per_line*priv->image->height]; } #endif } @@ -58,15 +74,17 @@ DrawContext::DrawContext(Window &w): DrawContext::~DrawContext() { #ifndef WIN32 - if(use_shm) + if(priv->use_shm) { - XShmDetach(display.get_display(), &shminfo); - shmdt(shminfo.shmaddr); - shmctl(shminfo.shmid, IPC_RMID, 0); + XShmDetach(display.get_private().display, &priv->shminfo); + shmdt(priv->shminfo.shmaddr); + shmctl(priv->shminfo.shmid, IPC_RMID, 0); } - XDestroyImage(image); + XDestroyImage(priv->image); #endif + + delete priv; } unsigned DrawContext::get_depth() const @@ -74,7 +92,7 @@ unsigned DrawContext::get_depth() const #ifdef WIN32 return 0; #else - return image->bits_per_pixel; + return priv->image->bits_per_pixel; #endif } @@ -83,21 +101,22 @@ unsigned char *DrawContext::get_data() #ifdef WIN32 return 0; #else - return reinterpret_cast(image->data); + return reinterpret_cast(priv->image->data); #endif } void DrawContext::update() { #ifndef WIN32 - ::Display *dpy=display.get_display(); + ::Display *dpy=display.get_private().display; + WindowHandle wnd=window.get_private().window; - GC gc=XCreateGC(dpy, window.get_handle(), 0, 0); + GC gc=XCreateGC(dpy, wnd, 0, 0); - if(use_shm) - XShmPutImage(dpy, window.get_handle(), gc, image, 0, 0, 0, 0, image->width, image->height, false); + if(priv->use_shm) + XShmPutImage(dpy, wnd, gc, priv->image, 0, 0, 0, 0, priv->image->width, priv->image->height, false); else - XPutImage(dpy, window.get_handle(), gc, image, 0, 0, 0, 0, image->width, image->height); + XPutImage(dpy, wnd, gc, priv->image, 0, 0, 0, 0, priv->image->width, priv->image->height); XFreeGC(dpy, gc); #endif diff --git a/source/gbase/drawcontext.h b/source/gbase/drawcontext.h index b21ac3c..1411294 100644 --- a/source/gbase/drawcontext.h +++ b/source/gbase/drawcontext.h @@ -1,18 +1,13 @@ /* $Id$ This file is part of libmspgbase -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ #ifndef MSP_GBASE_DRAWCONTEXT_H_ #define MSP_GBASE_DRAWCONTEXT_H_ -#ifndef WIN32 -#include -#include -#endif - namespace Msp { namespace Graphics { @@ -22,13 +17,11 @@ class Window; class DrawContext { private: + struct Private; + Display &display; Window &window; -#ifndef WIN32 - XImage *image; - bool use_shm; - XShmSegmentInfo shminfo; -#endif + Private *priv; public: DrawContext(Window &); diff --git a/source/gbase/glcontext.cpp b/source/gbase/glcontext.cpp index 4783e0c..6e02018 100644 --- a/source/gbase/glcontext.cpp +++ b/source/gbase/glcontext.cpp @@ -19,8 +19,8 @@ Distributed under the LGPL #include #include "display.h" #include "glcontext.h" -#include "types.h" #include "window.h" +#include "display_priv.h" namespace Msp { namespace Graphics { @@ -59,7 +59,7 @@ GLContext::GLContext(Window &wnd, const GLOptions &opts): priv=new Private; #ifdef WIN32 - HDC dc=GetDC(window.get_handle()); + HDC dc=GetDC(window.get_private().window); PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(pfd)); @@ -84,7 +84,7 @@ GLContext::GLContext(Window &wnd, const GLOptions &opts): priv->context=wglCreateContext(dc); wglMakeCurrent(dc, priv->context); - ReleaseDC(window.get_handle(), dc); + ReleaseDC(window.get_private().window, dc); #else std::vector attribs; @@ -115,7 +115,7 @@ GLContext::GLContext(Window &wnd, const GLOptions &opts): attribs.push_back(0); - ::Display *dpy=display.get_display(); + ::Display *dpy=display.get_private().display; XVisualInfo *vi=glXChooseVisual(dpy, DefaultScreen(dpy), &attribs.front()); if(!vi) @@ -125,8 +125,8 @@ GLContext::GLContext(Window &wnd, const GLOptions &opts): XSetWindowAttributes attr; attr.colormap=XCreateColormap(dpy, DefaultRootWindow(dpy), vi->visual, AllocNone); - priv->subwnd=XCreateWindow(dpy, window.get_handle(), 0, 0, window.get_width(), window.get_height(), 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr); - XMapWindow(display.get_display(), priv->subwnd); + priv->subwnd=XCreateWindow(dpy, window.get_private().window, 0, 0, window.get_width(), window.get_height(), 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr); + XMapWindow(dpy, priv->subwnd); XFree(vi); @@ -148,7 +148,7 @@ GLContext::~GLContext() wglMakeCurrent(0, 0); wglDeleteContext(priv->context); #else - ::Display *dpy=display.get_display(); + ::Display *dpy=display.get_private().display; glXMakeCurrent(dpy, 0, 0); glXDestroyContext(dpy, priv->context); @@ -162,11 +162,11 @@ void GLContext::swap_buffers() { #ifdef WITH_OPENGL #ifdef WIN32 - HDC dc=GetDC(window.get_handle()); + HDC dc=GetDC(window.get_private().window); SwapBuffers(dc); - ReleaseDC(window.get_handle(), dc); + ReleaseDC(window.get_private().window, dc); #else - glXSwapBuffers(display.get_display(), priv->subwnd); + glXSwapBuffers(display.get_private().display, priv->subwnd); #endif #endif } @@ -175,7 +175,7 @@ void GLContext::window_resized(unsigned w, unsigned h) { #ifdef WITH_OPENGL #ifndef WIN32 - XMoveResizeWindow(display.get_display(), priv->subwnd, 0, 0, w, h); + XMoveResizeWindow(display.get_private().display, priv->subwnd, 0, 0, w, h); #endif glViewport(0, 0, w, h); #else diff --git a/source/gbase/types.h b/source/gbase/types.h deleted file mode 100644 index e3524f3..0000000 --- a/source/gbase/types.h +++ /dev/null @@ -1,29 +0,0 @@ -/* $Id$ - -This file is part of libmspgbase -Copyright © 2007 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - -#ifndef MSP_GBASE_TYPES_H_ -#define MSP_GBASE_TYPES_H_ - -#ifdef WIN32 -#include -#else -#include -#endif - -namespace Msp { -namespace Graphics { - -#ifdef WIN32 -typedef HWND WindowHandle; -#else -typedef ::Window WindowHandle; -#endif - -} // namespace Graphics -} // namespace Msp - -#endif diff --git a/source/gbase/window.cpp b/source/gbase/window.cpp index 9f2361e..4aebc27 100644 --- a/source/gbase/window.cpp +++ b/source/gbase/window.cpp @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgbase -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -16,9 +16,37 @@ Distributed under the LGPL #include #include "display.h" #include "window.h" +#include "display_priv.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); +} +#endif + +} + namespace Msp { namespace Graphics { @@ -49,17 +77,17 @@ Window::Window(Display &dpy, const WindowOptions &opts): Window::~Window() { - if(window) + if(priv->window) #ifdef WIN32 - CloseWindow(window); + CloseWindow(priv->window); #else - XDestroyWindow(display.get_display(), window); + XDestroyWindow(display.get_private().display, priv->window); - if(invisible_cursor) - XFreeCursor(display.get_display(), invisible_cursor); + if(priv->invisible_cursor) + XFreeCursor(display.get_private().display, priv->invisible_cursor); #endif - display.remove_window(this); + display.remove_window(*this); if(options.fullscreen) display.restore_mode(); @@ -68,7 +96,7 @@ Window::~Window() void Window::set_title(const string &title) { #ifdef WIN32 - SetWindowText(window, title.c_str()); + SetWindowText(priv->window, title.c_str()); #else vector buf(title.begin(), title.end()); XTextProperty prop; @@ -76,7 +104,7 @@ void Window::set_title(const string &title) prop.encoding=XA_STRING; prop.format=8; prop.nitems=title.size(); - XSetWMName(display.get_display(), window, &prop); + XSetWMName(display.get_private().display, priv->window, &prop); display.check_error(); #endif } @@ -100,26 +128,24 @@ void Window::reconfigure(const WindowOptions &opts) if(fullscreen_changed) { hide(); - SetWindowLong(window, GWL_EXSTYLE, exstyle); - SetWindowLong(window, GWL_STYLE, style); + SetWindowLong(priv->window, GWL_EXSTYLE, exstyle); + SetWindowLong(priv->window, GWL_STYLE, style); show(); } if(options.fullscreen) - SetWindowPos(window, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOZORDER); + SetWindowPos(priv->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; + SetWindowPos(priv->window, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOMOVE|SWP_NOZORDER); #else - ::Display *dpy=display.get_display(); + ::Display *dpy=display.get_private().display; if(fullscreen_changed) { hide(); XSetWindowAttributes attr; attr.override_redirect=options.fullscreen; - XChangeWindowAttributes(dpy, window, CWOverrideRedirect, &attr); + XChangeWindowAttributes(dpy, priv->window, CWOverrideRedirect, &attr); show(); } @@ -132,12 +158,12 @@ void Window::reconfigure(const WindowOptions &opts) hints.min_width=hints.max_width=options.width; hints.min_height=hints.max_height=options.height; } - XSetWMNormalHints(dpy, window, &hints); + XSetWMNormalHints(dpy, priv->window, &hints); if(options.fullscreen) - XMoveResizeWindow(dpy, window, 0, 0, options.width, options.height); + XMoveResizeWindow(dpy, priv->window, 0, 0, options.width, options.height); else - XResizeWindow(dpy, window, options.width, options.height); + XResizeWindow(dpy, priv->window, options.width, options.height); #endif if(options.fullscreen) @@ -151,19 +177,19 @@ void Window::show_cursor(bool s) #ifdef WIN32 ShowCursor(s); #else - ::Display *dpy=display.get_display(); + ::Display *dpy=display.get_private().display; if(s) - XUndefineCursor(dpy, window); + XUndefineCursor(dpy, priv->window); else { - if(!invisible_cursor) + if(!priv->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); + Pixmap pm=XCreatePixmap(dpy, priv->window, 1, 1, 1); GC gc=XCreateGC(dpy, pm, 0, 0); XPutImage(dpy, pm, gc, img, 0, 0, 0, 0, 1, 1); @@ -171,14 +197,14 @@ void Window::show_cursor(bool s) black.pixel=BlackPixel(dpy, screen); XQueryColor(dpy, DefaultColormap(dpy, screen), &black); - invisible_cursor=XCreatePixmapCursor(dpy, pm, pm, &black, &black, 0, 0); + priv->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); + XDefineCursor(dpy, priv->window, priv->invisible_cursor); } #endif } @@ -186,9 +212,9 @@ void Window::show_cursor(bool s) void Window::show() { #ifdef WIN32 - ShowWindow(window, SW_SHOWNORMAL); + ShowWindow(priv->window, SW_SHOWNORMAL); #else - XMapRaised(display.get_display(), window); + XMapRaised(display.get_private().display, priv->window); display.check_error(); #endif } @@ -196,15 +222,17 @@ void Window::show() void Window::hide() { #ifdef WIN32 - ShowWindow(window, SW_HIDE); + ShowWindow(priv->window, SW_HIDE); #else - XUnmapWindow(display.get_display(), window); + XUnmapWindow(display.get_private().display, priv->window); display.check_error(); #endif } void Window::init() { + priv=new Private; + #ifdef WIN32 static bool wndclass_created=false; @@ -240,7 +268,7 @@ void Window::init() int exstyle=(options.fullscreen ? WS_EX_APPWINDOW : WS_EX_OVERLAPPEDWINDOW); AdjustWindowRectEx(&rect, style, false, exstyle); - window=CreateWindowEx(exstyle, + priv->window=CreateWindowEx(exstyle, "mspgbase", "Window", style, @@ -250,23 +278,23 @@ void Window::init() 0, reinterpret_cast(Application::get_data()), this); - if(!window) + if(!priv->window) throw Exception("CreateWindowEx failed"); if(options.fullscreen) display.set_mode(VideoMode(options.width, options.height)); #else - ::Display *dpy=display.get_display(); + ::Display *dpy=display.get_private().display; - wm_delete_window=XInternAtom(dpy, "WM_DELETE_WINDOW", true); - invisible_cursor=0; + 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; - window=XCreateWindow(dpy, + priv->window=XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, options.width, options.height, @@ -276,7 +304,7 @@ void Window::init() CopyFromParent, CWOverrideRedirect|CWEventMask, &attr); - XSetWMProtocols(dpy, window, &wm_delete_window, 1); + XSetWMProtocols(dpy, priv->window, &priv->wm_delete_window, 1); if(!options.resizable) { @@ -284,70 +312,26 @@ void Window::init() hints.flags=PMinSize|PMaxSize; hints.min_width=hints.max_width=options.width; hints.min_height=hints.max_height=options.height; - XSetWMNormalHints(dpy, window, &hints); + XSetWMNormalHints(dpy, priv->window, &hints); } if(options.fullscreen) { display.set_mode(VideoMode(options.width, options.height)); - XWarpPointer(dpy, None, window, 0, 0, 0, 0, options.width/2, options.height/2); + XWarpPointer(dpy, None, priv->window, 0, 0, 0, 0, options.width/2, options.height/2); } #endif - display.add_window(this); + display.add_window(*this); display.check_error(); } -#ifndef WIN32 -void Window::event(const XEvent &ev) +bool Window::event(const Event &evnt) { - switch(ev.type) - { - case ButtonPress: - signal_button_press.emit(ev.xbutton.x, ev.xbutton.y, ev.xbutton.button, ev.xbutton.state); - break; - case ButtonRelease: - signal_button_release.emit(ev.xbutton.x, ev.xbutton.y, ev.xbutton.button, ev.xbutton.state); - break; - case MotionNotify: - signal_pointer_motion.emit(ev.xmotion.x, ev.xmotion.y); - break; - case KeyPress: - { - char buf[16]; - XLookupString(const_cast(&ev.xkey), buf, sizeof(buf), 0, 0); - // XXX Handle the result according to locale - signal_key_press.emit(XKeycodeToKeysym(display.get_display(), ev.xkey.keycode, 0), ev.xkey.state, buf[0]); - } - break; - case KeyRelease: - signal_key_release.emit(XKeycodeToKeysym(display.get_display(), ev.xkey.keycode, 0), ev.xkey.state); - break; - case ConfigureNotify: - options.width=ev.xconfigure.width; - options.height=ev.xconfigure.height; - signal_resize.emit(options.width, options.height); - break; - case ClientMessage: - if(ev.xclient.data.l[0]==static_cast(wm_delete_window)) - signal_close.emit(); - break; - case EnterNotify: - XSetInputFocus(display.get_display(), window, RevertToParent, CurrentTime); - break; - case MapNotify: - if(options.fullscreen) - XGrabPointer(display.get_display(), window, true, None, GrabModeAsync, GrabModeAsync, window, None, CurrentTime); - break; - default:; - } -} -#endif - #ifdef WIN32 -int Window::wndproc(UINT msg, WPARAM wp, LPARAM lp) -{ - switch(msg) + WPARAM wp=evnt.wparam; + LPARAM lp=evnt.lparam; + switch(evnt.msg) { case WM_KEYDOWN: signal_key_press.emit(wp, 0, wp); @@ -385,29 +369,54 @@ int Window::wndproc(UINT msg, WPARAM wp, LPARAM lp) 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)); + return false; } - else +#else + const XEvent &ev=evnt.xevent; + switch(ev.type) { - Window *wnd=reinterpret_cast(GetWindowLong(hwnd, 0)); - if(wnd && wnd->wndproc(msg, wparam, lparam)) - return 0; + case ButtonPress: + signal_button_press.emit(ev.xbutton.x, ev.xbutton.y, ev.xbutton.button, ev.xbutton.state); + break; + case ButtonRelease: + signal_button_release.emit(ev.xbutton.x, ev.xbutton.y, ev.xbutton.button, ev.xbutton.state); + break; + case MotionNotify: + signal_pointer_motion.emit(ev.xmotion.x, ev.xmotion.y); + break; + case KeyPress: + { + char buf[16]; + XLookupString(const_cast(&ev.xkey), buf, sizeof(buf), 0, 0); + // XXX Handle the result according to locale + signal_key_press.emit(XKeycodeToKeysym(display.get_private().display, ev.xkey.keycode, 0), ev.xkey.state, buf[0]); + } + break; + case KeyRelease: + signal_key_release.emit(XKeycodeToKeysym(display.get_private().display, ev.xkey.keycode, 0), ev.xkey.state); + break; + case ConfigureNotify: + options.width=ev.xconfigure.width; + options.height=ev.xconfigure.height; + signal_resize.emit(options.width, options.height); + break; + case ClientMessage: + if(ev.xclient.data.l[0]==static_cast(priv->wm_delete_window)) + signal_close.emit(); + break; + case EnterNotify: + 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; } - - return DefWindowProc(hwnd, msg, wparam, lparam); -} #endif + return true; +} } // namespace Graphics } // namespace Msp diff --git a/source/gbase/window.h b/source/gbase/window.h index f422296..53c2d95 100644 --- a/source/gbase/window.h +++ b/source/gbase/window.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspgbase -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -10,7 +10,6 @@ Distributed under the LGPL #include #include -#include "types.h" namespace Msp { namespace Graphics { @@ -30,6 +29,9 @@ struct WindowOptions class Window { public: + struct Private; + struct Event; + sigc::signal signal_button_press; sigc::signal signal_button_release; sigc::signal signal_pointer_motion; @@ -41,11 +43,7 @@ public: protected: Display &display; WindowOptions options; - WindowHandle window; -#ifndef WIN32 - Atom wm_delete_window; - Cursor invisible_cursor; -#endif + Private *priv; public: Window(Display &, unsigned w, unsigned h, bool fs=false); @@ -60,20 +58,14 @@ public: const WindowOptions &get_options() const { return options; } unsigned get_width() const { return options.width; } unsigned get_height() const { return options.height; } - WindowHandle get_handle() const { return window; } + const Private &get_private() const { return *priv; } void show(); void hide(); -#ifndef WIN32 - void event(const XEvent &ev); -#endif + bool event(const Event &evnt); protected: void init(); -#ifdef WIN32 - int wndproc(UINT, WPARAM, LPARAM); - static LRESULT CALLBACK wndproc_(HWND, UINT, WPARAM, LPARAM); -#endif }; } // namespace Graphics diff --git a/source/gbase/window_priv.h b/source/gbase/window_priv.h new file mode 100644 index 0000000..ab1d549 --- /dev/null +++ b/source/gbase/window_priv.h @@ -0,0 +1,49 @@ +/* $Id$ + +This file is part of libmspgbase +Copyright © 2008 Mikko Rasa, Mikkosoft Productions +Distributed under the LGPL +*/ + +#ifndef MSP_GBASE_WINDOW_PRIV_H_ +#define MSP_GBASE_WINDOW_PRIV_H_ + +#ifdef WIN32 +#include +#else +#include +#endif + +namespace Msp { +namespace Graphics { + +#ifdef WIN32 +typedef HWND WindowHandle; +#else +typedef ::Window WindowHandle; +#endif + +struct Window::Private +{ + WindowHandle window; +#ifndef WIN32 + Atom wm_delete_window; + Cursor invisible_cursor; +#endif +}; + +struct Window::Event +{ +#ifdef WIN32 + UINT msg; + WPARAM wparam; + LPARAM lparam; +#else + XEvent xevent; +#endif +}; + +} // namespace Graphics +} // namespace Msp + +#endif diff --git a/source/input/keyboard.cpp b/source/input/keyboard.cpp index 1d7bb65..cef812c 100644 --- a/source/input/keyboard.cpp +++ b/source/input/keyboard.cpp @@ -1,10 +1,15 @@ /* $Id$ This file is part of libmspgbase -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ +#ifdef WIN32 +#include +#else +#include +#endif #include #include "../gbase/display.h" #include "keyboard.h" -- 2.43.0