]> git.tdb.fi Git - libs/gui.git/blob - source/window.cpp
Initial revision
[libs/gui.git] / source / window.cpp
1 /* $Id$
2
3 This file is part of libmspgbase
4 Copyright © 2007 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <vector>
9 #include <GL/glx.h>
10 #include <msp/core/error.h>
11 #include "window.h"
12
13 using namespace std;
14
15 #include <msp/strings/lexicalcast.h>
16
17 namespace Msp {
18
19 DisplayOptions::DisplayOptions():
20         width(640),
21         height(480),
22         fullscreen(false)
23 { }
24
25
26 /**
27 Initializes the class but does not open the window.  Intended for use by
28 derived classes.
29 */
30 Window::Window():
31         display(0),
32         window(0)
33 { }
34
35 Window::Window(unsigned w, unsigned h)
36 {
37         options.width=w;
38         options.height=h;
39
40         init();
41 }
42
43 Window::Window(const DisplayOptions &dopt):
44         options(dopt)
45 {
46         init();
47 }
48
49 Window::~Window()
50 {
51         if(window)
52                 XDestroyWindow(display, window);
53         if(display)
54                 XCloseDisplay(display);
55 }
56
57 void Window::show()
58 {
59         XMapRaised(display, window);
60 }
61
62 void Window::hide()
63 {
64         XUnmapWindow(display, window);
65 }
66
67 void Window::tick()
68 {
69         while(1)
70         {
71                 int pending=XPending(display);
72                 if(pending==0)
73                         break;
74
75                 for(int i=0; i<pending; ++i)
76                 {
77                         XEvent event;
78                         XNextEvent(display, &event);
79                         process_event(event);
80                 }
81         }
82 }
83
84 void Window::prepare()
85 {
86         if(options.display.empty())
87                 display=XOpenDisplay(0);
88         else
89                 display=XOpenDisplay(options.display.c_str());
90         if(!display)
91                 throw Exception("Couldn't open X display");
92
93         //XSetErrorHandler(x_error_handler);
94 }
95
96 void Window::init()
97 {
98         prepare();
99
100         window=XCreateWindow(display, DefaultRootWindow(display), 0, 0, options.width, options.height, 0, CopyFromParent, InputOutput, CopyFromParent, 0, 0);
101         if(!window)
102                 throw Exception("Couldn't create a window");
103
104         XSelectInput(display, window, ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask);
105 }
106
107 void Window::process_event(const XEvent &event)
108 {
109         switch(event.type)
110         {
111         case ButtonPress:
112                 signal_button_press.emit(event.xbutton.x, event.xbutton.y, event.xbutton.button, event.xbutton.state);
113                 break;
114         case ButtonRelease:
115                 signal_button_release.emit(event.xbutton.x, event.xbutton.y, event.xbutton.button, event.xbutton.state);
116                 break;
117         case MotionNotify:
118                 signal_pointer_motion.emit(event.xmotion.x, event.xmotion.y);
119                 break;
120         case KeyPress:
121                 {
122                         char buf[16];
123                         XLookupString(const_cast<XKeyEvent *>(&event.xkey), buf, sizeof(buf), 0, 0);
124                         // XXX Handle the result according to locale
125                         signal_key_press.emit(event.xkey.keycode, event.xkey.state, buf[0]);
126                 }
127                 break;
128         case KeyRelease:
129                 signal_key_release.emit(event.xkey.keycode, event.xkey.state);
130                 break;
131         case ConfigureNotify:
132                 options.width=event.xconfigure.width;
133                 options.height=event.xconfigure.height;
134                 break;
135         default:;
136         }
137 }
138
139 int Window::x_error_handler(Display *display, XErrorEvent *error)
140 {
141         char buf[128];
142         XGetErrorText(display, error->error_code, buf, sizeof(buf));
143         /*string request_code=lexical_cast(error->request_code);
144         char buf2[1024];
145         XGetErrorDatabaseText(display, "XRequest", request_code.c_str(), buf, buf2, sizeof(buf2));*/
146         throw Exception(buf);
147 }
148
149 } // namespace Msp