-////////////////////////////////////////////////////////////////////////////////
-// This program is free software; you can redistribute it and/or //
-// modify it under the terms of the GNU General Public License //
-// version 2 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. //
-// //
-// Written and (C) by François Fleuret //
-// Contact <francois.fleuret@epfl.ch> for comments & bug reports //
-////////////////////////////////////////////////////////////////////////////////
-
-// $Id: simple_window.cc,v 1.2 2007-04-24 21:22:52 fleuret Exp $
+// Written and (C) by Francois Fleuret
+// Contact <francois.fleuret@idiap.ch> for comments & bug reports
+
+#include <string.h>
+#include <stdlib.h>
#include "simple_window.h"
SimpleEvent::SimpleEvent() : type(UNDEFINED) {}
-SimpleWindow::SimpleWindow(char *name, int x, int y, int w, int h) {
+SimpleWindow::SimpleWindow(const char *name, int x, int y, int w, int h) {
_width = w; _height = h;
if (_display) {
- Visual *v = XDefaultVisual(_display, DefaultScreen(_display));
+ _screen = DefaultScreen(_display);
+ _visual = XDefaultVisual(_display, _screen);
+
+ _blue_mask = _visual->blue_mask;
+ _green_mask = _visual->green_mask;
+ _red_mask = _visual->red_mask;
- _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) {
+ cerr << "Can not deal with the colors on that display.\n";
+ }
+
+ _red_shift = 1;
+ while(!(_red_mask & 1)) {
+ _red_mask = _red_mask >> 1;
+ _red_shift = _red_shift << 1;
+ }
- if(_blue_mask == 0 || _green_mask == 0 || _red_mask == 0) {
- cerr << "Can not deal with the colors on that display.\n";
- }
+ _green_shift = 1;
+ while(!(_green_mask & 1)) {
+ _green_mask = _green_mask >> 1;
+ _green_shift = _green_shift << 1;
+ }
- _red_shift = 1;
- while(!(_red_mask & 1)) {
- _red_mask = _red_mask >> 1;
- _red_shift = _red_shift << 1;
- }
+ _blue_shift = 1;
+ while(!(_blue_mask & 1)) {
+ _blue_mask = _blue_mask >> 1;
+ _blue_shift = _blue_shift << 1;
+ }
- _green_shift = 1;
- while(!(_green_mask & 1)) {
- _green_mask = _green_mask >> 1;
- _green_shift = _green_shift << 1;
- }
+ _gc = DefaultGC(_display, DefaultScreen(_display));
- _blue_shift = 1;
- while(!(_blue_mask & 1)) {
- _blue_mask = _blue_mask >> 1;
- _blue_shift = _blue_shift << 1;
- }
+ XSetWindowAttributes xswa;
- _gc = DefaultGC(_display, DefaultScreen(_display));
+ _pixmap = XCreatePixmap(_display, DefaultRootWindow(_display),
+ _width, _height, DisplayPlanes(_display, DefaultScreen(_display)));
- XSetWindowAttributes xswa;
+ xswa.background_pixmap = _pixmap;
+ xswa.event_mask = ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | KeyPressMask | KeyReleaseMask;
+ xswa.backing_store = Always;
- _pixmap = XCreatePixmap(_display, DefaultRootWindow(_display),
- _width, _height, DisplayPlanes(_display, DefaultScreen(_display)));
+ _window = XCreateWindow(_display, DefaultRootWindow(_display), x, y, _width, _height,
+ 0, 0, InputOutput, CopyFromParent,
+ CWBackPixmap | CWEventMask | CWBackingStore,
+ &xswa);
- xswa.background_pixmap = _pixmap;
- xswa.event_mask = ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | KeyPressMask | KeyReleaseMask;
- xswa.backing_store = Always;
+ XSizeHints size_hints;
+ size_hints.flags = PMinSize | PMaxSize | USPosition;
+ size_hints.x = x; // These two lines do not seem to be required
+ size_hints.y = y; // ...
+ size_hints.min_width = _width;
+ size_hints.min_height = _height;
+ size_hints.max_width = _width;
+ size_hints.max_height = _height;
+ XSetNormalHints(_display, _window, &size_hints);
- _window = XCreateWindow(_display, DefaultRootWindow(_display), x, y, _width, _height,
- 0, 0, InputOutput, CopyFromParent,
- CWBackPixmap | CWEventMask | CWBackingStore,
- &xswa);
+ XStoreName(_display, _window, name);
- XSizeHints size_hints;
- size_hints.flags = PMinSize | PMaxSize | USPosition;
- size_hints.x = x; // These two lines do not seem to be required
- size_hints.y = y; // ...
- size_hints.min_width = _width;
- size_hints.min_height = _height;
- size_hints.max_width = _width;
- size_hints.max_height = _height;
- XSetNormalHints(_display, _window, &size_hints);
+ XSetState(_display, _gc, 0, 0, GXcopy, AllPlanes);
+ XFillRectangle(_display, _pixmap, _gc, 0, 0, _width, _height);
+ XFlush(_display);
- XStoreName(_display, _window, name);
+#ifdef CAIRO_SUPPORT
+ _cairo_surface = cairo_xlib_surface_create(_display, _pixmap, _visual, _width, _height);
+ cairo_xlib_surface_set_size(_cairo_surface, _width, _height);
+ _cairo_context = cairo_create(_cairo_surface);
+#endif
- XSetState(_display, _gc, 0, 0, GXcopy, AllPlanes);
- XFillRectangle(_display, _pixmap, _gc, 0, 0, _width, _height);
- XFlush(_display);
- } else abort();
+ } else abort();
}
XUnmapWindow(_display, _window);
XDestroyWindow(_display, _window);
XCloseDisplay(_display);
+#ifdef CAIRO_SUPPORT
+ cairo_destroy(_cairo_context);
+ cairo_surface_destroy(_cairo_surface);
+#endif
}
int SimpleWindow::width() {
XDrawArc(_display, _pixmap, _gc, x-r, y-r, 2*r, 2*r, 0, 360*64);
}
-void SimpleWindow::draw_text(char *s, int x, int y) {
+void SimpleWindow::draw_text(const char *s, int x, int y) {
XDrawString(_display, _pixmap, _gc, x, y, s, strlen(s));
}
SimpleEvent SimpleWindow::event() {
SimpleEvent se;
+ KeySym mykey;
if(XPending(_display) > 0) {
case KeyPress:
se.type = SimpleEvent::KEY_PRESS;
- strncpy(se.key,
- XKeysymToString(XKeycodeToKeysym(_display, event.xkey.keycode, 0)),
- (sizeof(se.key)/sizeof(char) - 1));
+ mykey = XkbKeycodeToKeysym(_display,
+ event.xkey.keycode, 0,
+ event.xkey.state & ShiftMask ? 1 : 0);
+ strncpy(se.key, XKeysymToString(mykey), (sizeof(se.key)/sizeof(char) - 1));
break;
case KeyRelease:
se.type = SimpleEvent::KEY_RELEASE;
- strncpy(se.key,
- XKeysymToString(XKeycodeToKeysym(_display, event.xkey.keycode, 0)),
- (sizeof(se.key)/sizeof(char) - 1));
+ mykey = XkbKeycodeToKeysym(_display,
+ event.xkey.keycode, 0,
+ event.xkey.state & ShiftMask ? 1 : 0);
+ strncpy(se.key, XKeysymToString(mykey), (sizeof(se.key)/sizeof(char) - 1));
break;
default:
se.type = SimpleEvent::UNDEFINED;
break;
+
}
} else se.type = SimpleEvent::NO_EVENT;
return se;
}
+
+#ifdef CAIRO_SUPPORT
+cairo_t *SimpleWindow::get_cairo_context_resource() {
+ return _cairo_context;
+}
+#endif