+
+///////////////////////////////////////////////////////////////////////////
+// This program is free software: you can redistribute it and/or modify //
+// it under the terms of the version 3 of the GNU General Public License //
+// as published by the Free Software Foundation. //
+// //
+// This program is distributed in the hope that it will be useful, but //
+// WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see <http://www.gnu.org/licenses/>. //
+// //
+// Written by and Copyright (C) Francois Fleuret //
+// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
+///////////////////////////////////////////////////////////////////////////
+
+#include "simple_window.h"
+
+SimpleWindow::SimpleWindow(const char *name, int w, int h) {
+
+ width = w; height = h;
+
+ dpy = XOpenDisplay(0);
+
+ if (dpy) {
+
+ Visual *v = XDefaultVisual(dpy, DefaultScreen(dpy));
+
+ blue_mask = v->blue_mask;
+ green_mask = v->green_mask;
+ red_mask = v->red_mask;
+
+ if(blue_mask == 0 || green_mask == 0 || red_mask == 0) {
+ std::cerr << "Can not deal with the colors on that display.\n";
+ }
+
+ // We compute how many bits we have for each component, and
+ // compute the corresponding mask
+ red_shift = 1;
+ while(!(red_mask & 1)) {
+ red_mask = red_mask >> 1;
+ red_shift = red_shift << 1;
+ }
+
+ green_shift = 1;
+ while(!(green_mask & 1)) {
+ green_mask = green_mask >> 1;
+ green_shift = green_shift << 1;
+ }
+
+ blue_shift = 1;
+ while(!(blue_mask & 1)) {
+ blue_mask = blue_mask >> 1;
+ blue_shift = blue_shift << 1;
+ }
+
+ gc = DefaultGC(dpy, DefaultScreen(dpy));
+
+ XSetWindowAttributes xswa;
+
+ pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy),
+ width, height, DisplayPlanes(dpy, DefaultScreen(dpy)));
+
+ xswa.background_pixmap = pixmap;
+ xswa.event_mask = NoEventMask;
+ xswa.backing_store = Always;
+
+ window = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, width, height,
+ 0, 0, InputOutput, CopyFromParent,
+ CWBackPixmap | CWEventMask | CWBackingStore,
+ &xswa);
+
+ XSizeHints size_hints;
+ size_hints.flags = PMinSize | PMaxSize;
+ size_hints.min_width = width;
+ size_hints.min_height = height;
+ size_hints.max_width = width;
+ size_hints.max_height = height;
+ XSetNormalHints(dpy, window, &size_hints);
+
+ XStoreName(dpy, window, name);
+
+ XSetState(dpy, gc, 0, 0, GXcopy, AllPlanes);
+ XFillRectangle(dpy, pixmap, gc, 0, 0, width, height);
+ XFlush(dpy);
+ } else abort();
+}
+
+SimpleWindow::~SimpleWindow() {
+ XUnmapWindow(dpy, window);
+ XDestroyWindow(dpy, window);
+ XCloseDisplay(dpy);
+}
+
+int SimpleWindow::get_width() {
+ return width;
+}
+
+int SimpleWindow::get_height() {
+ return height;
+}
+
+void SimpleWindow::map() {
+ XMapWindow(dpy, window);
+ XFlush(dpy);
+}
+
+void SimpleWindow::unmap() {
+ XUnmapWindow(dpy, window);
+ XFlush(dpy);
+}
+
+void SimpleWindow::color(float red, float green, float blue) {
+ // We work under the assumption that the bits come in the
+ // red/green/blue order with the corresponding masks
+ XSetState(dpy, gc,
+ ((unsigned int) ( red * red_mask)) * red_shift
+ + ((unsigned int) (green * green_mask)) * green_shift
+ + ((unsigned int) ( blue * blue_mask)) * blue_shift,
+ 0, GXcopy, AllPlanes);
+}
+
+void SimpleWindow::draw_point(int x, int y) {
+ XDrawPoint(dpy, pixmap, gc, x, y);
+}
+
+void SimpleWindow::draw_line(int x1, int y1, int x2, int y2) {
+ XDrawLine(dpy, pixmap, gc, x1, y1, x2, y2);
+}
+
+void SimpleWindow::draw_circle(int x, int y, int r) {
+ XDrawArc(dpy, pixmap, gc, x-r, y-r, 2*r, 2*r, 0, 360*64);
+}
+
+void SimpleWindow::draw_text(char *s, int x, int y) {
+ XDrawString(dpy, pixmap, gc, x, y, s, strlen(s));
+}
+
+void SimpleWindow::fill_rectangle(int x, int y, int w, int h) {
+ XFillRectangle(dpy, pixmap, gc, x, y, w, h);
+}
+
+void SimpleWindow::show() {
+ XCopyArea(dpy, pixmap, window, gc, 0, 0, width, height, 0, 0);
+ XFlush(dpy);
+}
+
+void SimpleWindow::fill() {
+ XFillRectangle(dpy, pixmap, gc, 0, 0, width, height);
+}