]> git.tdb.fi Git - libs/gui.git/blobdiff - source/window.cpp
Initial revision
[libs/gui.git] / source / window.cpp
diff --git a/source/window.cpp b/source/window.cpp
new file mode 100644 (file)
index 0000000..75a88dc
--- /dev/null
@@ -0,0 +1,149 @@
+/* $Id$
+
+This file is part of libmspgbase
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <vector>
+#include <GL/glx.h>
+#include <msp/core/error.h>
+#include "window.h"
+
+using namespace std;
+
+#include <msp/strings/lexicalcast.h>
+
+namespace Msp {
+
+DisplayOptions::DisplayOptions():
+       width(640),
+       height(480),
+       fullscreen(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)
+{
+       options.width=w;
+       options.height=h;
+
+       init();
+}
+
+Window::Window(const DisplayOptions &dopt):
+       options(dopt)
+{
+       init();
+}
+
+Window::~Window()
+{
+       if(window)
+               XDestroyWindow(display, window);
+       if(display)
+               XCloseDisplay(display);
+}
+
+void Window::show()
+{
+       XMapRaised(display, window);
+}
+
+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");
+
+       //XSetErrorHandler(x_error_handler);
+}
+
+void Window::init()
+{
+       prepare();
+
+       window=XCreateWindow(display, DefaultRootWindow(display), 0, 0, options.width, options.height, 0, CopyFromParent, InputOutput, CopyFromParent, 0, 0);
+       if(!window)
+               throw Exception("Couldn't create a window");
+
+       XSelectInput(display, window, ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask);
+}
+
+void Window::process_event(const XEvent &event)
+{
+       switch(event.type)
+       {
+       case ButtonPress:
+               signal_button_press.emit(event.xbutton.x, event.xbutton.y, event.xbutton.button, event.xbutton.state);
+               break;
+       case ButtonRelease:
+               signal_button_release.emit(event.xbutton.x, event.xbutton.y, event.xbutton.button, event.xbutton.state);
+               break;
+       case MotionNotify:
+               signal_pointer_motion.emit(event.xmotion.x, event.xmotion.y);
+               break;
+       case KeyPress:
+               {
+                       char buf[16];
+                       XLookupString(const_cast<XKeyEvent *>(&event.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]);
+               }
+               break;
+       case KeyRelease:
+               signal_key_release.emit(event.xkey.keycode, event.xkey.state);
+               break;
+       case ConfigureNotify:
+               options.width=event.xconfigure.width;
+               options.height=event.xconfigure.height;
+               break;
+       default:;
+       }
+}
+
+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 Msp