X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=otk%2Fdisplay.cc;h=d4580a0e4e4d8430b4ba6d8301a9b6851a73c843;hb=bfea000a7407e51b5659590415e410a47f6f046b;hp=21c348eab3ef2af4ca82044c069e1458d41d81d5;hpb=2a195d71e20689fd90544543a6b049fae615a55f;p=chaz%2Fopenbox diff --git a/otk/display.cc b/otk/display.cc index 21c348ea..d4580a0e 100644 --- a/otk/display.cc +++ b/otk/display.cc @@ -1,12 +1,8 @@ // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif +#include "config.h" #include "display.hh" -#include "screeninfo.hh" -#include "rendercontrol.hh" #include "util.hh" extern "C" { @@ -24,10 +20,6 @@ extern "C" { #include #endif // XINERAMA -#ifdef HAVE_STDIO_H -# include -#endif // HAVE_STDIO_H - #ifdef HAVE_SIGNAL_H # include #endif // HAVE_SIGNAL_H @@ -45,6 +37,8 @@ extern "C" { #define _(str) gettext(str) } +#include + namespace otk { @@ -52,27 +46,28 @@ Display *display = (Display*) 0; static int xerrorHandler(::Display *d, XErrorEvent *e) { + if (!display->ignoreErrors()) { #ifdef DEBUG - char errtxt[128]; - - //if (e->error_code != BadWindow) - { - XGetErrorText(d, e->error_code, errtxt, 128); - printf("X Error: %s\n", errtxt); - if (e->error_code != BadWindow) - abort(); - } + char errtxt[128]; + + //if (e->error_code != BadWindow) + { + XGetErrorText(d, e->error_code, errtxt, 127); + printf("X Error: %s\n", errtxt); + if (e->error_code != BadWindow) + abort(); + } #else - (void)d; - (void)e; + (void)d; + (void)e; #endif - + } return false; } -Display::Display() - : _display(0), +Display::Display(::Display *d) + : _display(d), _xkb(false), _xkb_event_basep(0), _shape(false), @@ -82,21 +77,15 @@ Display::Display() _mask_list(), _num_lock_mask(0), _scroll_lock_mask(0), - _grab_count(0), - _screeninfo_list(0), - _rendercontrol_list(0) + _grab_count(0) { int junk; (void)junk; + assert(_display); + display = this; - // Open the X display - if (!(_display = XOpenDisplay(NULL))) { - printf(_("Unable to open connection to the X server. Please set the \n\ -DISPLAY environment variable approriately.\n\n")); - ::exit(1); - } if (fcntl(ConnectionNumber(_display), F_SETFD, 1) == -1) { printf(_("Couldn't mark display connection as close-on-exec.\n\n")); ::exit(1); @@ -162,13 +151,51 @@ DISPLAY environment variable approriately.\n\n")); _mask_list[6] = _scroll_lock_mask | _num_lock_mask; _mask_list[7] = _scroll_lock_mask | LockMask | _num_lock_mask; - // Get information on all the screens which are available, and create their - // RenderControl - _screeninfo_list = new ScreenInfo*[ScreenCount(_display)]; - _rendercontrol_list = new RenderControl*[ScreenCount(_display)]; - for (int i = 0; i < ScreenCount(_display); ++i) { - _screeninfo_list[i] = new ScreenInfo(i); - _rendercontrol_list[i] = RenderControl::getRenderControl(i); + /* + If the default depth is at least 8 we will use that, + otherwise we try to find the largest TrueColor visual. + Preference is given to 24 bit over larger depths if 24 bit is an option. + */ + + int screen = DefaultScreen(_display); + _depth = DefaultDepth(_display, screen); + _visual = DefaultVisual(_display, screen); + _colormap = DefaultColormap(_display, screen); + + if (_depth < 8) { + // search for a TrueColor Visual... if we can't find one... + // we will use the default visual for the screen + XVisualInfo vinfo_template, *vinfo_return; + int vinfo_nitems; + int best = -1; + + vinfo_template.screen = screen; + vinfo_template.c_class = TrueColor; + + vinfo_return = XGetVisualInfo(_display, + VisualScreenMask | VisualClassMask, + &vinfo_template, &vinfo_nitems); + if (vinfo_return) { + int max_depth = 1; + for (int i = 0; i < vinfo_nitems; ++i) { + if (vinfo_return[i].depth > max_depth) { + if (max_depth == 24 && vinfo_return[i].depth > 24) + break; // prefer 24 bit over 32 + max_depth = vinfo_return[i].depth; + best = i; + } + } + if (max_depth < _depth) best = -1; + } + + if (best != -1) { + _depth = vinfo_return[best].depth; + _visual = vinfo_return[best].visual; + _colormap = XCreateColormap(_display, RootWindow(_display, screen), + _visual, AllocNone); + } + + XFree(vinfo_return); } } @@ -180,46 +207,23 @@ Display::~Display() XFreeModifiermap(_modmap); - for (int i = 0; i < ScreenCount(_display); ++i) { - delete _rendercontrol_list[i]; - delete _screeninfo_list[i]; - } - delete [] _rendercontrol_list; - delete [] _screeninfo_list; - XCloseDisplay(_display); } -const ScreenInfo* Display::screenInfo(int snum) const -{ - assert(snum >= 0); - assert(snum < (signed) ScreenCount(_display)); - return _screeninfo_list[snum]; -} - - -const ScreenInfo* Display::findScreen(Window root) const -{ - for (int i = 0; i < ScreenCount(_display); ++i) - if (_screeninfo_list[i]->rootWindow() == root) - return _screeninfo_list[i]; - return 0; -} - - -const RenderControl *Display::renderControl(int snum) const +void Display::setIgnoreErrors(bool t) { - assert(snum >= 0); - assert(snum < (signed) ScreenCount(_display)); - return _rendercontrol_list[snum]; + // sync up so that anything already sent is/isn't ignored! + XSync(_display, false); + _ignore_errors = t; } - void Display::grab() { - if (_grab_count == 0) + if (_grab_count == 0) { XGrabServer(_display); + XSync(_display, false); // make sure it kicks in + } _grab_count++; } @@ -228,8 +232,10 @@ void Display::ungrab() { if (_grab_count == 0) return; _grab_count--; - if (_grab_count == 0) + if (_grab_count == 0) { XUngrabServer(_display); + XFlush(_display); // ungrab as soon as possible + } } @@ -292,4 +298,9 @@ void Display::ungrabKey(unsigned int keycode, unsigned int modifiers, grab_window); } +void Display::ungrabAllKeys(Window grab_window) const +{ + XUngrabKey(_display, AnyKey, AnyModifier, grab_window); +} + }