2 ////////////////////////////////////////////////////////////////////////////////
3 // This program is free software; you can redistribute it and/or //
4 // modify it under the terms of the GNU General Public License //
5 // version 2 as published by the Free Software Foundation. //
7 // This program is distributed in the hope that it will be useful, but //
8 // WITHOUT ANY WARRANTY; without even the implied warranty of //
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
10 // General Public License for more details. //
12 // Written and (C) by François Fleuret //
13 // Contact <francois.fleuret@epfl.ch> for comments & bug reports //
14 ////////////////////////////////////////////////////////////////////////////////
16 // $Id: simple_window.cc,v 1.2 2007-04-24 21:22:52 fleuret Exp $
18 #include "simple_window.h"
20 SimpleEvent::SimpleEvent() : type(UNDEFINED) {}
22 SimpleWindow::SimpleWindow(char *name, int x, int y, int w, int h) {
24 _width = w; _height = h;
26 _display = XOpenDisplay(0);
30 Visual *v = XDefaultVisual(_display, DefaultScreen(_display));
32 _blue_mask = v->blue_mask;
33 _green_mask = v->green_mask;
34 _red_mask = v->red_mask;
36 if(_blue_mask == 0 || _green_mask == 0 || _red_mask == 0) {
37 cerr << "Can not deal with the colors on that display.\n";
41 while(!(_red_mask & 1)) {
42 _red_mask = _red_mask >> 1;
43 _red_shift = _red_shift << 1;
47 while(!(_green_mask & 1)) {
48 _green_mask = _green_mask >> 1;
49 _green_shift = _green_shift << 1;
53 while(!(_blue_mask & 1)) {
54 _blue_mask = _blue_mask >> 1;
55 _blue_shift = _blue_shift << 1;
58 _gc = DefaultGC(_display, DefaultScreen(_display));
60 XSetWindowAttributes xswa;
62 _pixmap = XCreatePixmap(_display, DefaultRootWindow(_display),
63 _width, _height, DisplayPlanes(_display, DefaultScreen(_display)));
65 xswa.background_pixmap = _pixmap;
66 xswa.event_mask = ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | KeyPressMask | KeyReleaseMask;
67 xswa.backing_store = Always;
69 _window = XCreateWindow(_display, DefaultRootWindow(_display), x, y, _width, _height,
70 0, 0, InputOutput, CopyFromParent,
71 CWBackPixmap | CWEventMask | CWBackingStore,
74 XSizeHints size_hints;
75 size_hints.flags = PMinSize | PMaxSize | USPosition;
76 size_hints.x = x; // These two lines do not seem to be required
77 size_hints.y = y; // ...
78 size_hints.min_width = _width;
79 size_hints.min_height = _height;
80 size_hints.max_width = _width;
81 size_hints.max_height = _height;
82 XSetNormalHints(_display, _window, &size_hints);
84 XStoreName(_display, _window, name);
86 XSetState(_display, _gc, 0, 0, GXcopy, AllPlanes);
87 XFillRectangle(_display, _pixmap, _gc, 0, 0, _width, _height);
93 SimpleWindow::~SimpleWindow() {
94 XUnmapWindow(_display, _window);
95 XDestroyWindow(_display, _window);
96 XCloseDisplay(_display);
99 int SimpleWindow::width() {
103 int SimpleWindow::height() {
107 void SimpleWindow::map() {
108 XMapWindow(_display, _window);
112 void SimpleWindow::unmap() {
113 XUnmapWindow(_display, _window);
117 void SimpleWindow::color(float red, float green, float blue) {
118 XSetState(_display, _gc,
119 ((unsigned int) ( red * _red_mask)) * _red_shift
120 + ((unsigned int) (green * _green_mask)) * _green_shift
121 + ((unsigned int) ( blue * _blue_mask)) * _blue_shift,
122 0, GXcopy, AllPlanes);
125 void SimpleWindow::draw_point(int x, int y) {
126 XDrawPoint(_display, _pixmap, _gc, x, y);
129 void SimpleWindow::draw_line(int x1, int y1, int x2, int y2) {
130 XDrawLine(_display, _pixmap, _gc, x1, y1, x2, y2);
133 void SimpleWindow::draw_circle(int x, int y, int r) {
134 XDrawArc(_display, _pixmap, _gc, x-r, y-r, 2*r, 2*r, 0, 360*64);
137 void SimpleWindow::draw_text(char *s, int x, int y) {
138 XDrawString(_display, _pixmap, _gc, x, y, s, strlen(s));
141 void SimpleWindow::fill_rectangle(int x, int y, int w, int h) {
142 XFillRectangle(_display, _pixmap, _gc, x, y, w, h);
145 void SimpleWindow::fill_polygon(int nb, int *x, int *y) {
147 for(int n = 0; n < nb; n++) {
151 XFillPolygon(_display, _pixmap, _gc, points, nb, Nonconvex, CoordModeOrigin);
154 void SimpleWindow::show() {
155 XCopyArea(_display, _pixmap, _window, _gc, 0, 0, _width, _height, 0, 0);
159 void SimpleWindow::fill() {
160 XFillRectangle(_display, _pixmap, _gc, 0, 0, _width, _height);
163 int SimpleWindow::file_descriptor() {
164 return XConnectionNumber(_display);
167 SimpleEvent SimpleWindow::event() {
170 if(XPending(_display) > 0) {
173 XNextEvent(_display, &event);
175 switch (event.type) {
178 se.type = SimpleEvent::MOUSE_CLICK_PRESS;
179 se.button = event.xbutton.button;
180 se.x = event.xbutton.x;
181 se.y = event.xbutton.y;
185 se.type = SimpleEvent::MOUSE_CLICK_RELEASE;
186 se.button = event.xbutton.button;
187 se.x = event.xbutton.x;
188 se.y = event.xbutton.y;
192 se.type = SimpleEvent::MOUSE_MOTION;
193 se.button = event.xbutton.button;
194 se.x = event.xbutton.x;
195 se.y = event.xbutton.y;
199 se.type = SimpleEvent::KEY_PRESS;
201 XKeysymToString(XKeycodeToKeysym(_display, event.xkey.keycode, 0)),
202 (sizeof(se.key)/sizeof(char) - 1));
206 se.type = SimpleEvent::KEY_RELEASE;
208 XKeysymToString(XKeycodeToKeysym(_display, event.xkey.keycode, 0)),
209 (sizeof(se.key)/sizeof(char) - 1));
213 se.type = SimpleEvent::UNDEFINED;
216 } else se.type = SimpleEvent::NO_EVENT;