X-Git-Url: https://fleuret.org/cgi-bin/gitweb/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=simple_window.cc;h=cbb35062820d3a75d75a69a809a93d63b2d54933;hb=60156e872a7ddc20c7bb972f357c6f8030a77652;hp=3ab3c81f3925ea40754cf3799a9066f6839cc325;hpb=3caf13085a6ae1ae41d6f489c8b69206b0ffa48d;p=universe.git diff --git a/simple_window.cc b/simple_window.cc index 3ab3c81..cbb3506 100644 --- a/simple_window.cc +++ b/simple_window.cc @@ -2,6 +2,9 @@ // Written and (C) by Francois Fleuret // Contact for comments & bug reports +#include +#include + #include "simple_window.h" SimpleEvent::SimpleEvent() : type(UNDEFINED) {} @@ -14,66 +17,74 @@ SimpleWindow::SimpleWindow(const char *name, int x, int y, int w, int 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(); } @@ -81,6 +92,10 @@ SimpleWindow::~SimpleWindow() { XUnmapWindow(_display, _window); XDestroyWindow(_display, _window); XCloseDisplay(_display); +#ifdef CAIRO_SUPPORT + cairo_destroy(_cairo_context); + cairo_surface_destroy(_cairo_surface); +#endif } int SimpleWindow::width() { @@ -153,6 +168,7 @@ int SimpleWindow::file_descriptor() { SimpleEvent SimpleWindow::event() { SimpleEvent se; + KeySym mykey; if(XPending(_display) > 0) { @@ -184,22 +200,31 @@ SimpleEvent SimpleWindow::event() { 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