2 // Written and (C) by Francois Fleuret
3 // Contact <francois.fleuret@idiap.ch> for comments & bug reports
5 #include "simple_window.h"
7 SimpleEvent::SimpleEvent() : type(UNDEFINED) {}
9 SimpleWindow::SimpleWindow(const char *name, int x, int y, int w, int h) {
11 _width = w; _height = h;
13 _display = XOpenDisplay(0);
17 Visual *v = XDefaultVisual(_display, DefaultScreen(_display));
19 _blue_mask = v->blue_mask;
20 _green_mask = v->green_mask;
21 _red_mask = v->red_mask;
23 if(_blue_mask == 0 || _green_mask == 0 || _red_mask == 0) {
24 cerr << "Can not deal with the colors on that display.\n";
28 while(!(_red_mask & 1)) {
29 _red_mask = _red_mask >> 1;
30 _red_shift = _red_shift << 1;
34 while(!(_green_mask & 1)) {
35 _green_mask = _green_mask >> 1;
36 _green_shift = _green_shift << 1;
40 while(!(_blue_mask & 1)) {
41 _blue_mask = _blue_mask >> 1;
42 _blue_shift = _blue_shift << 1;
45 _gc = DefaultGC(_display, DefaultScreen(_display));
47 XSetWindowAttributes xswa;
49 _pixmap = XCreatePixmap(_display, DefaultRootWindow(_display),
50 _width, _height, DisplayPlanes(_display, DefaultScreen(_display)));
52 xswa.background_pixmap = _pixmap;
53 xswa.event_mask = ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | KeyPressMask | KeyReleaseMask;
54 xswa.backing_store = Always;
56 _window = XCreateWindow(_display, DefaultRootWindow(_display), x, y, _width, _height,
57 0, 0, InputOutput, CopyFromParent,
58 CWBackPixmap | CWEventMask | CWBackingStore,
61 XSizeHints size_hints;
62 size_hints.flags = PMinSize | PMaxSize | USPosition;
63 size_hints.x = x; // These two lines do not seem to be required
64 size_hints.y = y; // ...
65 size_hints.min_width = _width;
66 size_hints.min_height = _height;
67 size_hints.max_width = _width;
68 size_hints.max_height = _height;
69 XSetNormalHints(_display, _window, &size_hints);
71 XStoreName(_display, _window, name);
73 XSetState(_display, _gc, 0, 0, GXcopy, AllPlanes);
74 XFillRectangle(_display, _pixmap, _gc, 0, 0, _width, _height);
80 SimpleWindow::~SimpleWindow() {
81 XUnmapWindow(_display, _window);
82 XDestroyWindow(_display, _window);
83 XCloseDisplay(_display);
86 int SimpleWindow::width() {
90 int SimpleWindow::height() {
94 void SimpleWindow::map() {
95 XMapWindow(_display, _window);
99 void SimpleWindow::unmap() {
100 XUnmapWindow(_display, _window);
104 void SimpleWindow::color(float red, float green, float blue) {
105 XSetState(_display, _gc,
106 ((unsigned int) ( red * _red_mask)) * _red_shift
107 + ((unsigned int) (green * _green_mask)) * _green_shift
108 + ((unsigned int) ( blue * _blue_mask)) * _blue_shift,
109 0, GXcopy, AllPlanes);
112 void SimpleWindow::draw_point(int x, int y) {
113 XDrawPoint(_display, _pixmap, _gc, x, y);
116 void SimpleWindow::draw_line(int x1, int y1, int x2, int y2) {
117 XDrawLine(_display, _pixmap, _gc, x1, y1, x2, y2);
120 void SimpleWindow::draw_circle(int x, int y, int r) {
121 XDrawArc(_display, _pixmap, _gc, x-r, y-r, 2*r, 2*r, 0, 360*64);
124 void SimpleWindow::draw_text(const char *s, int x, int y) {
125 XDrawString(_display, _pixmap, _gc, x, y, s, strlen(s));
128 void SimpleWindow::fill_rectangle(int x, int y, int w, int h) {
129 XFillRectangle(_display, _pixmap, _gc, x, y, w, h);
132 void SimpleWindow::fill_polygon(int nb, int *x, int *y) {
134 for(int n = 0; n < nb; n++) {
138 XFillPolygon(_display, _pixmap, _gc, points, nb, Nonconvex, CoordModeOrigin);
141 void SimpleWindow::show() {
142 XCopyArea(_display, _pixmap, _window, _gc, 0, 0, _width, _height, 0, 0);
146 void SimpleWindow::fill() {
147 XFillRectangle(_display, _pixmap, _gc, 0, 0, _width, _height);
150 int SimpleWindow::file_descriptor() {
151 return XConnectionNumber(_display);
154 SimpleEvent SimpleWindow::event() {
157 if(XPending(_display) > 0) {
160 XNextEvent(_display, &event);
162 switch (event.type) {
165 se.type = SimpleEvent::MOUSE_CLICK_PRESS;
166 se.button = event.xbutton.button;
167 se.x = event.xbutton.x;
168 se.y = event.xbutton.y;
172 se.type = SimpleEvent::MOUSE_CLICK_RELEASE;
173 se.button = event.xbutton.button;
174 se.x = event.xbutton.x;
175 se.y = event.xbutton.y;
179 se.type = SimpleEvent::MOUSE_MOTION;
180 se.button = event.xbutton.button;
181 se.x = event.xbutton.x;
182 se.y = event.xbutton.y;
186 se.type = SimpleEvent::KEY_PRESS;
188 XKeysymToString(XKeycodeToKeysym(_display, event.xkey.keycode, 0)),
189 (sizeof(se.key)/sizeof(char) - 1));
193 se.type = SimpleEvent::KEY_RELEASE;
195 XKeysymToString(XKeycodeToKeysym(_display, event.xkey.keycode, 0)),
196 (sizeof(se.key)/sizeof(char) - 1));
200 se.type = SimpleEvent::UNDEFINED;
203 } else se.type = SimpleEvent::NO_EVENT;