Initial commit
[simple-window] / simple_window.cc
1
2 ///////////////////////////////////////////////////////////////////////////
3 // This program is free software: you can redistribute it and/or modify  //
4 // it under the terms of the version 3 of the GNU General Public License //
5 // as published by the Free Software Foundation.                         //
6 //                                                                       //
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.                              //
11 //                                                                       //
12 // You should have received a copy of the GNU General Public License     //
13 // along with this program. If not, see <http://www.gnu.org/licenses/>.  //
14 //                                                                       //
15 // Written by and Copyright (C) Francois Fleuret                         //
16 // Contact <francois.fleuret@idiap.ch> for comments & bug reports        //
17 ///////////////////////////////////////////////////////////////////////////
18
19 #include "simple_window.h"
20
21 SimpleWindow::SimpleWindow(const char *name, int w, int h) {
22
23   width = w; height = h;
24
25   dpy = XOpenDisplay(0);
26
27   if (dpy) {
28
29       Visual *v = XDefaultVisual(dpy, DefaultScreen(dpy));
30
31       blue_mask = v->blue_mask;
32       green_mask = v->green_mask;
33       red_mask = v->red_mask;
34
35       if(blue_mask == 0 || green_mask == 0 || red_mask == 0) {
36         std::cerr << "Can not deal with the colors on that display.\n";
37       }
38
39       // We compute how many bits we have for each component, and
40       // compute the corresponding mask
41       red_shift = 1;
42       while(!(red_mask & 1)) {
43         red_mask = red_mask >> 1;
44         red_shift = red_shift << 1;
45       }
46
47       green_shift = 1;
48       while(!(green_mask & 1)) {
49         green_mask = green_mask >> 1;
50         green_shift = green_shift << 1;
51       }
52
53       blue_shift = 1;
54       while(!(blue_mask & 1)) {
55         blue_mask = blue_mask >> 1;
56         blue_shift = blue_shift << 1;
57       }
58
59       gc = DefaultGC(dpy, DefaultScreen(dpy));
60
61       XSetWindowAttributes xswa;
62
63       pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy),
64                              width, height, DisplayPlanes(dpy, DefaultScreen(dpy)));
65
66       xswa.background_pixmap = pixmap;
67       xswa.event_mask = NoEventMask;
68       xswa.backing_store = Always;
69
70       window = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height,
71                              0, 0, InputOutput, CopyFromParent,
72                              CWBackPixmap | CWEventMask | CWBackingStore,
73                              &xswa);
74
75       XSizeHints size_hints;
76       size_hints.flags = PMinSize | PMaxSize;
77       size_hints.min_width = width;
78       size_hints.min_height = height;
79       size_hints.max_width = width;
80       size_hints.max_height = height;
81       XSetNormalHints(dpy, window, &size_hints);
82
83       XStoreName(dpy, window, name);
84
85       XSetState(dpy, gc, 0, 0, GXcopy, AllPlanes);
86       XFillRectangle(dpy, pixmap, gc, 0, 0, width, height);
87       XFlush(dpy);
88     } else abort();
89 }
90
91 SimpleWindow::~SimpleWindow() {
92   XUnmapWindow(dpy, window);
93   XDestroyWindow(dpy, window);
94   XCloseDisplay(dpy);
95 }
96
97 int SimpleWindow::get_width() {
98   return width;
99 }
100
101 int SimpleWindow::get_height() {
102   return height;
103 }
104
105 void SimpleWindow::map() {
106   XMapWindow(dpy, window);
107   XFlush(dpy);
108 }
109
110 void SimpleWindow::unmap() {
111   XUnmapWindow(dpy, window);
112   XFlush(dpy);
113 }
114
115 void SimpleWindow::color(float red, float green, float blue) {
116   // We work under the assumption that the bits come in the
117   // red/green/blue order with the corresponding masks
118   XSetState(dpy, 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);
123 }
124
125 void SimpleWindow::draw_point(int x, int y) {
126   XDrawPoint(dpy, pixmap, gc, x, y);
127 }
128
129 void SimpleWindow::draw_line(int x1, int y1, int x2, int y2) {
130   XDrawLine(dpy, pixmap, gc, x1, y1, x2, y2);
131 }
132
133 void SimpleWindow::draw_circle(int x, int y, int r) {
134   XDrawArc(dpy, pixmap, gc, x-r, y-r, 2*r, 2*r, 0, 360*64);
135 }
136
137 void SimpleWindow::draw_text(char *s, int x, int y) {
138   XDrawString(dpy, pixmap, gc, x, y, s, strlen(s));
139 }
140
141 void SimpleWindow::fill_rectangle(int x, int y, int w, int h) {
142   XFillRectangle(dpy, pixmap, gc, x, y, w, h);
143 }
144
145 void SimpleWindow::show() {
146   XCopyArea(dpy, pixmap, window, gc, 0, 0, width, height, 0, 0);
147   XFlush(dpy);
148 }
149
150 void SimpleWindow::fill() {
151   XFillRectangle(dpy, pixmap, gc, 0, 0, width, height);
152 }