]> git.tdb.fi Git - libs/gltk.git/blob - source/window.cpp
2ec55b97d03997c3cc11a851e46d6a666dcf8ed0
[libs/gltk.git] / source / window.cpp
1 #include <vector>
2 #include <GL/glx.h>
3 #include <msp/core/error.h>
4 #include "window.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace GLtk {
10
11 DisplayOptions::DisplayOptions():
12         width(640),
13         height(480),
14         depth(24),
15         alpha(false),
16         doublebuffer(false),
17         multisample(0),
18         fullscreen(false)
19 { }
20
21
22 Window::Window(unsigned w, unsigned h)
23 {
24         DisplayOptions dopt;
25         dopt.width=w;
26         dopt.height=h;
27
28         init(dopt);
29 }
30
31 Window::Window(const DisplayOptions &dopt)
32 {
33         init(dopt);
34 }
35
36 Window::~Window()
37 {
38         XCloseDisplay(display);
39 }
40
41 void Window::show()
42 {
43         XMapWindow(display, window);
44 }
45
46 void Window::tick()
47 {
48         while(1)
49         {
50                 int pending=XPending(display);
51                 if(pending==0)
52                         break;
53
54                 for(int i=0; i<pending; ++i)
55                 {
56                         XEvent event;
57                         XNextEvent(display, &event);
58                         process_event(event);
59                 }
60         }
61 }
62
63 void Window::init(const DisplayOptions &dopt)
64 {
65         options=dopt;
66
67         display=XOpenDisplay(0);
68         if(!display)
69                 throw Exception("Couldn't open X display");
70
71         vector<int> attribs;
72         attribs.push_back(GLX_BUFFER_SIZE);
73         attribs.push_back(dopt.depth);
74         attribs.push_back(GLX_DOUBLEBUFFER);
75         attribs.push_back(1);
76         if(dopt.multisample>0)
77         {
78                 attribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
79                 attribs.push_back(dopt.multisample);
80         }
81
82         XVisualInfo *visual=glXChooseVisual(display, DefaultScreen(display), &attribs.front());
83         if(!visual)
84                 throw Exception("Couldn't get a matching visual");
85
86         window=XCreateWindow(display, DefaultRootWindow(display), 0, 0, dopt.width, dopt.height, 0, CopyFromParent, InputOutput, visual->visual, 0, 0);
87
88         XSelectInput(display, window, ButtonPressMask|ButtonReleaseMask|MotionMask|KeyPressMask|KeyReleaseMask);
89 }
90
91 void Window::process_event(const XEvent &event)
92 {
93         switch(event.type)
94         {
95         case ButtonPress:
96                 signal_button_press.emit(event.button.x, event.button.y, event.button.button, event.button.state);
97                 break;
98         case ButtonRelease:
99                 signal_button_release.emit(event.button.x, event.button.y, event.button.button, event.button.state);
100                 break;
101         case PointerMotion:
102                 signal_pointer_motion.emit(event.motion.x, event.motion.y);
103                 break;
104         case KeyPress:
105                 {
106                         char buf[16];
107                         XLookupString(event.key, buf, sizeof(buf), 0, 0);
108                         // XXX Handle the result according to locale
109                         signal_key_press.emit(event.key.keycode, event.key.state, buf[0]);
110                 }
111                 break;
112         case KeyRelease:
113                 signal_key_release.emit(event.key.keycode, event.key.state);
114                 break;
115         default:;
116         }
117 }
118
119 } // namespace GLtk
120 } // namespace Msp