]> git.tdb.fi Git - libs/gui.git/commitdiff
Redesign and refactor
authorMikko Rasa <tdb@tdb.fi>
Thu, 13 Dec 2007 15:07:01 +0000 (15:07 +0000)
committerMikko Rasa <tdb@tdb.fi>
Thu, 13 Dec 2007 15:07:01 +0000 (15:07 +0000)
Add class Display for access to the graphical environemnt before any windows are created
Replace GLWindow with an independent GLContext class
Put stuff into namespace Graphics
Support for querying and changing video modes
Handle Xlib errors

14 files changed:
Build
source/display.cpp [new file with mode: 0644]
source/display.h [new file with mode: 0644]
source/glcontext.cpp [new file with mode: 0644]
source/glcontext.h [new file with mode: 0644]
source/glwindow.cpp [deleted file]
source/glwindow.h [deleted file]
source/keyboard.cpp
source/keyboard.h
source/mouse.cpp
source/mouse.h
source/types.h [new file with mode: 0644]
source/window.cpp
source/window.h

diff --git a/Build b/Build
index 2cf2f263659d985cc8d90e803d0ac9c7a14800e0..efb857bc0be93e8f5c4503bfdac0a416cac82774 100644 (file)
--- a/Build
+++ b/Build
@@ -9,6 +9,11 @@ package "mspgbase"
        require "sigc++-2.0";
        require "xlib";
 
+       build_info
+       {
+               library "Xxf86vm";
+       };
+
        library "mspgbase"
        {
                source "source";
diff --git a/source/display.cpp b/source/display.cpp
new file mode 100644 (file)
index 0000000..724318a
--- /dev/null
@@ -0,0 +1,149 @@
+/* $Id$
+
+This file is part of libmspgbase
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <iostream>
+#include <X11/Xlib.h>
+#include <X11/extensions/xf86vmode.h>
+#include <msp/core/except.h>
+#include <msp/strings/formatter.h>
+#include <msp/strings/lexicalcast.h>
+#include "display.h"
+#include "window.h"
+
+using namespace std;
+
+namespace {
+
+bool error_flag=false;
+std::string error_msg;
+
+int x_error_handler(Display *display, XErrorEvent *event)
+{
+       char err[128];
+       XGetErrorText(display, event->error_code, err, sizeof(err));
+
+       string request_code=Msp::lexical_cast(static_cast<int>(event->request_code));
+       char req[128];
+       XGetErrorDatabaseText(display, "XRequest", request_code.c_str(), request_code.c_str(), req, sizeof(req));
+
+       string msg=Msp::format("Request %s failed with %s [%08X]", req, err, event->resourceid);
+       if(error_flag)
+               cerr<<"Discarding error: "<<msg<<'\n';
+       else
+       {
+               cerr<<msg<<'\n';
+               error_msg=msg;
+               error_flag=true;
+       }
+
+       return 0;
+}
+
+}
+
+namespace Msp {
+namespace Graphics {
+
+Display::Display(const string &disp_name)
+{
+       if(disp_name.empty())
+               display=XOpenDisplay(0);
+       else
+               display=XOpenDisplay(disp_name.c_str());
+       if(!display)
+               throw Exception("Couldn't open X display");
+
+       XSetErrorHandler(x_error_handler);
+
+       int nmodes;
+       XF86VidModeModeInfo **infos;
+       XF86VidModeGetAllModeLines(display, DefaultScreen(display), &nmodes, &infos);
+       for(int i=0; i<nmodes; ++i)
+       {
+               XF86VidModeModeInfo &info=*infos[i];
+       
+               VideoMode mode;
+               mode.width=info.hdisplay;
+               mode.height=info.vdisplay;
+               mode.rate=info.dotclock/(info.htotal*info.vtotal);
+               modes.push_back(mode);
+       }
+}
+
+Display::~Display()
+{
+       XCloseDisplay(display);
+       display=0;
+}
+
+void Display::add_window(Window *wnd)
+{
+       windows[wnd->get_handle()]=wnd;
+}
+
+void Display::remove_window(Window *wnd)
+{
+       windows.erase(wnd->get_handle());
+}
+
+void Display::set_mode(const VideoMode &mode)
+{
+       int screen=DefaultScreen(display);
+
+       int nmodes;
+       XF86VidModeModeInfo **infos;
+       XF86VidModeGetAllModeLines(display, screen, &nmodes, &infos);
+       for(int i=0; i<nmodes; ++i)
+       {
+               XF86VidModeModeInfo &info=*infos[i];
+
+               unsigned rate=info.dotclock/(info.htotal*info.vtotal);
+               if(info.hdisplay==mode.width && info.vdisplay==mode.height && rate==mode.rate)
+               {
+                       XF86VidModeSwitchToMode(display, screen, &info);
+                       return;
+               }
+       }
+
+       throw InvalidParameterValue("Requested mode not supported");
+}
+
+void Display::tick()
+{
+       check_error();
+
+       while(1)
+       {
+               int pending=XPending(display);
+               if(pending==0)
+                       break;
+
+               for(int i=0; i<pending; ++i)
+               {
+                       XEvent event;
+                       XNextEvent(display, &event);
+
+                       check_error();
+
+                       map<WindowHandle, Window *>::iterator j=windows.find(event.xany.window);
+                       if(j!=windows.end())
+                               j->second->event(event);
+               }
+       }
+}
+
+void Display::check_error()
+{
+       if(error_flag)
+       {
+               error_flag=false;
+               throw Exception(error_msg);
+       }
+}
+
+} // namespace Graphics
+} // namespace Msp
diff --git a/source/display.h b/source/display.h
new file mode 100644 (file)
index 0000000..0433eab
--- /dev/null
@@ -0,0 +1,54 @@
+/* $Id$
+
+This file is part of libmspgbase
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GBASE_DISPLAY_H_
+#define MSP_GBASE_DISPLAY_H_
+
+#include <list>
+#include <map>
+#include <string>
+#include "types.h"
+
+namespace Msp {
+namespace Graphics {
+
+class Window;
+
+struct VideoMode
+{
+       unsigned width;
+       unsigned height;
+       unsigned rate;
+};
+
+class Display
+{
+private:
+       ::Display *display;
+       std::list<VideoMode> modes;
+       std::map<WindowHandle, Window *> windows;
+
+public:
+       Display(const std::string &disp_name=std::string());
+       ~Display();
+
+       ::Display *get_display() const { return display; }
+
+       void add_window(Window *);
+       void remove_window(Window *);
+
+       const std::list<VideoMode> &get_modes() const { return modes; }
+       void set_mode(const VideoMode &);
+
+       void tick();
+       void check_error();
+};
+
+} // namespace Graphics
+} // namespace Msp
+
+#endif
diff --git a/source/glcontext.cpp b/source/glcontext.cpp
new file mode 100644 (file)
index 0000000..5995384
--- /dev/null
@@ -0,0 +1,92 @@
+/* $Id$
+
+This file is part of libmspgbase
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <vector>
+#include <msp/core/except.h>
+#include "display.h"
+#include "glcontext.h"
+#include "window.h"
+
+namespace Msp {
+namespace Graphics {
+
+GLOptions::GLOptions():
+       alpha(false),
+       stencil(false),
+       doublebuffer(true),
+       multisample(0)
+{ }
+
+
+GLContext::GLContext(Display &d, const GLOptions &opts):
+       display(d)
+{
+       std::vector<int> attribs;
+       
+       attribs.push_back(GLX_RGBA);
+       attribs.push_back(GLX_DEPTH_SIZE);
+       attribs.push_back(1);
+       
+       if(opts.alpha)
+       {
+               attribs.push_back(GLX_ALPHA_SIZE);
+               attribs.push_back(1);
+       }
+       
+       if(opts.stencil)
+       {
+               attribs.push_back(GLX_STENCIL_SIZE);
+               attribs.push_back(1);
+       }
+       
+       if(opts.doublebuffer)
+               attribs.push_back(GLX_DOUBLEBUFFER);
+       
+       if(opts.multisample>0)
+       {
+               attribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
+               attribs.push_back(opts.multisample);
+       }
+       
+       attribs.push_back(0);
+
+       ::Display *dpy=display.get_display();
+       XVisualInfo *vi=glXChooseVisual(dpy, DefaultScreen(dpy), &attribs.front());
+       if(!vi)
+               throw Exception("Couldn't find a GLX visual");
+       context=glXCreateContext(dpy, vi, 0, true);
+
+       XSetWindowAttributes attr;
+       attr.colormap=XCreateColormap(dpy, DefaultRootWindow(dpy), vi->visual, AllocNone);
+
+       window=XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, 1024, 768, 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr);
+
+       glXMakeCurrent(dpy, window, context);
+}
+
+void GLContext::attach(Window &wnd)
+{
+       XReparentWindow(display.get_display(), window, wnd.get_handle(), 0, 0);
+       XMapWindow(display.get_display(), window);
+
+       wnd.signal_resize.connect(sigc::mem_fun(this, &GLContext::window_resized));
+       window_resized(wnd.get_width(), wnd.get_height());
+}
+
+void GLContext::swap_buffers()
+{
+       glXSwapBuffers(display.get_display(), window);
+}
+
+void GLContext::window_resized(unsigned w, unsigned h)
+{
+       XMoveResizeWindow(display.get_display(), window, 0, 0, w, h);
+       glViewport(0, 0, w, h);
+}
+
+} // namespace Graphics
+} // namespace Msp
diff --git a/source/glcontext.h b/source/glcontext.h
new file mode 100644 (file)
index 0000000..1156b53
--- /dev/null
@@ -0,0 +1,50 @@
+/* $Id$
+
+This file is part of libmspgbase
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GBASE_GLCONTEXT_H_
+#define MSP_GBASE_GLCONTEXT_H_
+
+#include <GL/glx.h>
+#include "types.h"
+
+namespace Msp {
+namespace Graphics {
+
+class Display;
+
+struct GLOptions
+{
+       bool alpha;
+       bool stencil;
+       bool doublebuffer;
+       unsigned multisample;
+
+       GLOptions();
+};
+
+class GLContext
+{
+private:
+       typedef GLXContext Context;
+
+       Display &display;
+       Context context;
+       GLXWindow glx_wnd;
+       WindowHandle window;
+
+public:
+       GLContext(Display &dpy, const GLOptions &opts);
+       void attach(Window &wnd);
+       void swap_buffers();
+private:
+       void window_resized(unsigned, unsigned);
+};
+
+} // namespace Graphics
+} // namespace Msp
+
+#endif
diff --git a/source/glwindow.cpp b/source/glwindow.cpp
deleted file mode 100644 (file)
index fb585f0..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/* $Id$
-
-This file is part of libmspgbase
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
-Distributed under the LGPL
-*/
-
-#include <vector>
-#include <msp/core/except.h>
-#include "glwindow.h"
-
-using namespace std;
-
-namespace Msp {
-
-GLDisplayOptions::GLDisplayOptions():
-       alpha(false),
-       stencil(false),
-       doublebuffer(true),
-       multisample(0)
-{ }
-
-
-GLWindow::GLWindow(unsigned w, unsigned h)
-{
-       options.width=w;
-       options.height=h;
-       init();
-}
-
-GLWindow::GLWindow(const DisplayOptions &dopt, const GLDisplayOptions &gl_dopt)
-{
-       options=dopt;
-       gl_options=gl_dopt;
-       init();
-}
-
-GLWindow::~GLWindow()
-{
-       glXMakeContextCurrent(display, 0, 0, 0);
-       glXDestroyWindow(display, glx_wnd);
-       glXDestroyContext(display, context);
-}
-
-void GLWindow::swap_buffers()
-{
-       glXSwapBuffers(display, glx_wnd);
-}
-
-void GLWindow::init()
-{
-       prepare();
-
-       vector<int> attribs;
-       
-       attribs.push_back(GLX_RENDER_TYPE);
-       attribs.push_back(GLX_RGBA_BIT);
-       
-       attribs.push_back(GLX_DRAWABLE_TYPE);
-       attribs.push_back(GLX_WINDOW_BIT);
-       
-       attribs.push_back(GLX_DEPTH_SIZE);
-       attribs.push_back(1);
-       
-       if(gl_options.alpha)
-       {
-               attribs.push_back(GLX_ALPHA_SIZE);
-               attribs.push_back(1);
-       }
-       
-       if(gl_options.stencil)
-       {
-               attribs.push_back(GLX_STENCIL_SIZE);
-               attribs.push_back(1);
-       }
-       
-       if(gl_options.doublebuffer)
-       {
-               attribs.push_back(GLX_DOUBLEBUFFER);
-               attribs.push_back(true);
-       }
-       
-       if(gl_options.multisample>0)
-       {
-               attribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
-               attribs.push_back(gl_options.multisample);
-       }
-       
-       attribs.push_back(None);
-
-       int count;
-       GLXFBConfig *config=glXChooseFBConfig(display, DefaultScreen(display), &attribs.front(), &count);
-       if(!config)
-               throw Exception("Couldn't get a GLX framebuffer configuration");
-
-       context=glXCreateNewContext(display, config[0], GLX_RGBA_TYPE, 0, true);
-       if(!context)
-               throw Exception("Couldn't create a GLX context");
-
-       XVisualInfo *vi=glXGetVisualFromFBConfig(display, config[0]);
-       Handle root=RootWindow(display, vi->screen);
-
-       Colormap cmap=XCreateColormap(display, root, vi->visual, AllocNone);
-       XSetWindowAttributes attr;
-       attr.colormap=cmap;
-       attr.override_redirect=options.fullscreen;
-
-       Handle wnd=XCreateWindow(display, root, 0, 0, options.width, options.height, 0, vi->depth, InputOutput, vi->visual, CWColormap|CWOverrideRedirect, &attr);
-       set_window(wnd);
-
-       glx_wnd=glXCreateWindow(display, config[0], wnd, 0);
-
-       glXMakeContextCurrent(display, glx_wnd, glx_wnd, context);
-
-       XFree(config);
-}
-
-void GLWindow::on_event(const XEvent &event)
-{
-       if(event.type==ConfigureNotify)
-               glViewport(0, 0, options.width, options.height);
-}
-
-} // namespace Msp
diff --git a/source/glwindow.h b/source/glwindow.h
deleted file mode 100644 (file)
index dd6e59f..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* $Id$
-
-This file is part of libmspgbase
-Copyright © 2007 Mikko Rasa, Mikkosoft Productions
-Distributed under the LGPL
-*/
-
-#ifndef MSP_GBASE_GLWINDOW_H_
-#define MSP_GBASE_GLWINDOW_H_
-
-#include <GL/glx.h>
-#include "window.h"
-
-namespace Msp {
-
-struct GLDisplayOptions
-{
-       bool alpha;
-       bool stencil;
-       bool doublebuffer;
-       unsigned multisample;
-
-       GLDisplayOptions();
-};
-
-class GLWindow: public Window
-{
-protected:
-       typedef GLXContext Context;
-
-       GLDisplayOptions gl_options;
-       GLXWindow glx_wnd;
-       Context context;
-
-public:
-       GLWindow(unsigned, unsigned);
-       GLWindow(const DisplayOptions &, const GLDisplayOptions &);
-       ~GLWindow();
-
-       void swap_buffers();
-protected:
-       void init();
-       virtual void on_event(const XEvent &event);
-};
-
-} // namespace Msp
-
-#endif
index 45ef0920448a12889a2ad9b1b7387c7b4c4987f3..ab01e6261eff14eb7345de57c34e1cd0412607bd 100644 (file)
@@ -6,12 +6,11 @@ Distributed under the LGPL
 */
 
 #include "keyboard.h"
-#include "window.h"
 
 namespace Msp {
 namespace Input {
 
-Keyboard::Keyboard(Window &window)
+Keyboard::Keyboard(Graphics::Window &window)
 {
        buttons.resize(256, false);
 
index 65b3dbaeef1e0958a8a0409b1bf51c7d7b5ca299..e3006034e359a3aee66e8a180942045e0cbfbe13 100644 (file)
@@ -9,17 +9,15 @@ Distributed under the LGPL
 #define MSP_GBASE_KEYBOARD_H_
 
 #include "inputdevice.h"
+#include "window.h"
 
 namespace Msp {
-
-class Window;
-
 namespace Input {
 
 class Keyboard: public Device
 {
 public:
-       Keyboard(Window &);
+       Keyboard(Graphics::Window &);
 protected:
        void key_press(unsigned, unsigned, unsigned);
        void key_release(unsigned, unsigned);
index b32b70fb48a1a3a1e200658d9cebd1a89b573b1f..dc361252bc988150c97c7aed5c1b8fb71699d70e 100644 (file)
@@ -6,12 +6,11 @@ Distributed under the LGPL
 */
 
 #include "mouse.h"
-#include "window.h"
 
 namespace Msp {
 namespace Input {
 
-Mouse::Mouse(Window &w):
+Mouse::Mouse(Graphics::Window &w):
        window(w),
        axis_scale(0.01)
 {
index 6260f3bbf6bb39a378447294699efb164d33cd4e..4199f844b29d47c89fd03931c0a2374e75c2a2b3 100644 (file)
@@ -9,21 +9,19 @@ Distributed under the LGPL
 #define MSP_GBASE_MOUSE_H_
 
 #include "inputdevice.h"
+#include "window.h"
 
 namespace Msp {
-
-class Window;
-
 namespace Input {
 
 class Mouse: public Device
 {
 private:
-       Window &window;
+       Graphics::Window &window;
        float axis_scale;
 
 public:
-       Mouse(Window &);
+       Mouse(Graphics::Window &);
 private:
        void button_press(int, int, unsigned, unsigned);
        void button_release(int, int, unsigned, unsigned);
diff --git a/source/types.h b/source/types.h
new file mode 100644 (file)
index 0000000..1badc5d
--- /dev/null
@@ -0,0 +1,21 @@
+/* $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_
+
+#include <X11/Xlib.h>
+
+namespace Msp {
+namespace Graphics {
+
+typedef ::Window WindowHandle;
+
+} // namespace Graphics
+} // namespace Msp
+
+#endif
index ee5bec90d93f6165c742e13316fca7d621d79d10..f867faf6e58e3a775c08248f943eb17c1159b71e 100644 (file)
@@ -9,38 +9,35 @@ Distributed under the LGPL
 #include <X11/Xatom.h>
 #include <X11/Xutil.h>
 #include <msp/core/except.h>
+#include "display.h"
 #include "window.h"
 
 using namespace std;
 
 namespace Msp {
+namespace Graphics {
 
-DisplayOptions::DisplayOptions():
+WindowOptions::WindowOptions():
        width(640),
        height(480),
-       fullscreen(false)
+       fullscreen(false),
+       resizable(false)
 { }
 
 
-/**
-Initializes the class but does not open the window.  Intended for use by
-derived classes.
-*/
-Window::Window():
-       display(0),
-       window(0)
-{ }
-
-Window::Window(unsigned w, unsigned h)
+Window::Window(Display &dpy, unsigned w, unsigned h, bool fs):
+       display(dpy)
 {
        options.width=w;
        options.height=h;
+       options.fullscreen=fs;
 
        init();
 }
 
-Window::Window(const DisplayOptions &dopt):
-       options(dopt)
+Window::Window(Display &dpy, const WindowOptions &opts):
+       display(dpy),
+       options(opts)
 {
        init();
 }
@@ -48,9 +45,9 @@ Window::Window(const DisplayOptions &dopt):
 Window::~Window()
 {
        if(window)
-               XDestroyWindow(display, window);
-       if(display)
-               XCloseDisplay(display);
+               XDestroyWindow(display.get_display(), window);
+
+       display.remove_window(this);
 }
 
 void Window::set_title(const string &title)
@@ -61,123 +58,79 @@ void Window::set_title(const string &title)
        prop.encoding=XA_STRING;
        prop.format=8;
        prop.nitems=title.size();
-       XSetWMName(display, window, &prop);
+       XSetWMName(display.get_display(), window, &prop);
+       display.check_error();
 }
 
 void Window::show()
 {
-       XMapRaised(display, window);
+       XMapRaised(display.get_display(), window);
+       display.check_error();
 }
 
 void Window::hide()
 {
-       XUnmapWindow(display, window);
-}
-
-void Window::tick()
-{
-       while(1)
-       {
-               int pending=XPending(display);
-               if(pending==0)
-                       break;
-
-               for(int i=0; i<pending; ++i)
-               {
-                       XEvent event;
-                       XNextEvent(display, &event);
-                       process_event(event);
-               }
-       }
-}
-
-void Window::prepare()
-{
-       if(options.display.empty())
-               display=XOpenDisplay(0);
-       else
-               display=XOpenDisplay(options.display.c_str());
-       if(!display)
-               throw Exception("Couldn't open X display");
-
-       wm_delete_window=XInternAtom(display, "WM_DELETE_WINDOW", true);
-
-       /* Throwing from the error handler doesn't work too well and I don't know
-          how to dig up all the information that Xlib gives by default, so disable
-               custom error handling for now. */
-       //XSetErrorHandler(x_error_handler);
-}
-
-void Window::set_window(Handle wnd)
-{
-       window=wnd;
-
-       XSelectInput(display, window, ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask|EnterWindowMask);
-
-       XSetWMProtocols(display, window, &wm_delete_window, 1);
+       XUnmapWindow(display.get_display(), window);
+       display.check_error();
 }
 
 void Window::init()
 {
-       prepare();
+       ::Display *dpy=display.get_display();
+
+       wm_delete_window=XInternAtom(dpy, "WM_DELETE_WINDOW", true);
 
        XSetWindowAttributes attr;
        attr.override_redirect=options.fullscreen;
+       attr.event_mask=ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask|EnterWindowMask;
 
-       Handle wnd=XCreateWindow(display, DefaultRootWindow(display), 0, 0, options.width, options.height, 0, CopyFromParent, InputOutput, CopyFromParent, CWOverrideRedirect, &attr);
-       set_window(wnd);
+       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);
+
+       display.add_window(this);
+       display.check_error();
 }
 
-void Window::process_event(const XEvent &event)
+void Window::event(const XEvent &ev)
 {
-       switch(event.type)
+       switch(ev.type)
        {
        case ButtonPress:
-               signal_button_press.emit(event.xbutton.x, event.xbutton.y, event.xbutton.button, event.xbutton.state);
+               signal_button_press.emit(ev.xbutton.x, ev.xbutton.y, ev.xbutton.button, ev.xbutton.state);
                break;
        case ButtonRelease:
-               signal_button_release.emit(event.xbutton.x, event.xbutton.y, event.xbutton.button, event.xbutton.state);
+               signal_button_release.emit(ev.xbutton.x, ev.xbutton.y, ev.xbutton.button, ev.xbutton.state);
                break;
        case MotionNotify:
-               signal_pointer_motion.emit(event.xmotion.x, event.xmotion.y);
+               signal_pointer_motion.emit(ev.xmotion.x, ev.xmotion.y);
                break;
        case KeyPress:
                {
                        char buf[16];
-                       XLookupString(const_cast<XKeyEvent *>(&event.xkey), buf, sizeof(buf), 0, 0);
+                       XLookupString(const_cast<XKeyEvent *>(&ev.xkey), buf, sizeof(buf), 0, 0);
                        // XXX Handle the result according to locale
-                       signal_key_press.emit(event.xkey.keycode, event.xkey.state, buf[0]);
+                       signal_key_press.emit(ev.xkey.keycode, ev.xkey.state, buf[0]);
                }
                break;
        case KeyRelease:
-               signal_key_release.emit(event.xkey.keycode, event.xkey.state);
+               signal_key_release.emit(ev.xkey.keycode, ev.xkey.state);
                break;
        case ConfigureNotify:
-               options.width=event.xconfigure.width;
-               options.height=event.xconfigure.height;
+               options.width=ev.xconfigure.width;
+               options.height=ev.xconfigure.height;
                signal_resize.emit(options.width, options.height);
                break;
        case ClientMessage:
-               if(event.xclient.data.l[0]==static_cast<long>(wm_delete_window))
+               if(ev.xclient.data.l[0]==static_cast<long>(wm_delete_window))
                        signal_close.emit();
                break;
        case EnterNotify:
-               XSetInputFocus(display, window, RevertToParent, CurrentTime);
+               XSetInputFocus(display.get_display(), window, RevertToParent, CurrentTime);
                break;
        default:;
        }
-
-       on_event(event);
-}
-
-int Window::x_error_handler(Display *display, XErrorEvent *error)
-{
-       char buf[128];
-       XGetErrorText(display, error->error_code, buf, sizeof(buf));
-       /*string request_code=lexical_cast(error->request_code);
-       char buf2[1024];
-       XGetErrorDatabaseText(display, "XRequest", request_code.c_str(), buf, buf2, sizeof(buf2));*/
-       throw Exception(buf);
 }
 
+} // namespace Graphics
 } // namespace Msp
index a8ad867cca9acac780cf3f34535d69c21df286b1..1047038366917854f776f22fae72de60e87ad480 100644 (file)
@@ -9,19 +9,22 @@ Distributed under the LGPL
 #define MSP_GBASE_WINDOW_H_
 
 #include <string>
-#include <X11/Xlib.h>
 #include <sigc++/signal.h>
+#include "types.h"
 
 namespace Msp {
+namespace Graphics {
 
-struct DisplayOptions
+class Display;
+
+struct WindowOptions
 {
-       std::string display;
        unsigned width;
        unsigned height;
        bool fullscreen;
+       bool resizable;
 
-       DisplayOptions();
+       WindowOptions();
 };
 
 class Window
@@ -36,36 +39,31 @@ public:
        sigc::signal<void> signal_close;
 
 protected:
-       typedef ::Window Handle;
-
-       Display *display;
-       DisplayOptions options;
-       Handle  window;
-       Atom    wm_delete_window;
+       Display &display;
+       WindowOptions options;
+       WindowHandle window;
+       Atom wm_delete_window;
 
-       Window();
 public:
-       Window(unsigned w, unsigned h);
-       Window(const DisplayOptions &dopt);
-       virtual ~Window();
+       Window(Display &, unsigned w, unsigned h, bool fs=false);
+       Window(Display &, const WindowOptions &);
+       ~Window();
 
        void set_title(const std::string &);
 
        unsigned get_width() const  { return options.width; }
        unsigned get_height() const { return options.height; }
+       WindowHandle get_handle() const { return window; }
+
        void show();
        void hide();
-       void tick();
+
+       void event(const XEvent &ev);
 protected:
-       void prepare();
-       void set_window(Handle wnd);
        void init();
-       void process_event(const XEvent &event);
-       virtual void on_event(const XEvent &event) { (void)event; }
-
-       static int x_error_handler(Display *, XErrorEvent *);
 };
 
+} // namespace Graphics
 } // namespace Msp
 
 #endif