From: Dana Jansens Date: Sun, 3 Nov 2002 10:07:16 +0000 (+0000) Subject: add an OBDisplay class and the old ScreenInfo class to the toolkit. X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=fa8cefef63feb1d559c40db3cf9407e5bd1ac4df;p=chaz%2Fopenbox add an OBDisplay class and the old ScreenInfo class to the toolkit. wrap the toolkit in the 'otk' namespace it compiles. broke the timer cache tho. --- diff --git a/otk/Makefile.am b/otk/Makefile.am index 075f4a41..e626fff2 100644 --- a/otk/Makefile.am +++ b/otk/Makefile.am @@ -4,8 +4,8 @@ INCLUDES= -I../src noinst_LIBRARIES=libotk.a -libotk_a_SOURCES= color.cc font.cc gccache.cc image.cc imagecontrol.cc \ - texture.cc +libotk_a_SOURCES= color.cc display.cc font.cc gccache.cc image.cc \ + imagecontrol.cc texture.cc MAINTAINERCLEANFILES= Makefile.in diff --git a/otk/color.cc b/otk/color.cc index ad30c7a3..b50c29d9 100644 --- a/otk/color.cc +++ b/otk/color.cc @@ -11,25 +11,25 @@ extern "C" { #include #include "color.hh" -#include "basedisplay.hh" +#include "display.hh" +#include "screeninfo.hh" +namespace otk { BColor::ColorCache BColor::colorcache; bool BColor::cleancache = false; -BColor::BColor(const BaseDisplay * const _display, unsigned int _screen) - : allocated(false), r(-1), g(-1), b(-1), p(0), dpy(_display), scrn(_screen) +BColor::BColor(unsigned int _screen) + : allocated(false), r(-1), g(-1), b(-1), p(0), scrn(_screen) {} -BColor::BColor(int _r, int _g, int _b, - const BaseDisplay * const _display, unsigned int _screen) - : allocated(false), r(_r), g(_g), b(_b), p(0), dpy(_display), scrn(_screen) +BColor::BColor(int _r, int _g, int _b, unsigned int _screen) + : allocated(false), r(_r), g(_g), b(_b), p(0), scrn(_screen) {} -BColor::BColor(const std::string &_name, - const BaseDisplay * const _display, unsigned int _screen) - : allocated(false), r(-1), g(-1), b(-1), p(0), dpy(_display), scrn(_screen), +BColor::BColor(const std::string &_name, unsigned int _screen) + : allocated(false), r(-1), g(-1), b(-1), p(0), scrn(_screen), colorname(_name) { parseColorName(); } @@ -40,16 +40,14 @@ BColor::~BColor(void) { } -void BColor::setDisplay(const BaseDisplay * const _display, - unsigned int _screen) { - if (_display == display() && _screen == screen()) { +void BColor::setScreen(unsigned int _screen) { + if (_screen == screen()) { // nothing to do return; } deallocate(); - dpy = _display; scrn = _screen; if (! colorname.empty()) { @@ -70,16 +68,14 @@ unsigned long BColor::pixel(void) const { void BColor::parseColorName(void) { - assert(dpy != 0); - if (colorname.empty()) { fprintf(stderr, "BColor: empty colorname, cannot parse (using black)\n"); setRGB(0, 0, 0); } if (scrn == ~(0u)) - scrn = DefaultScreen(display()->getXDisplay()); - Colormap colormap = display()->getScreenInfo(scrn)->getColormap(); + scrn = DefaultScreen(OBDisplay::display); + Colormap colormap = OBDisplay::screenInfo(scrn)->getColormap(); // get rgb values from colorname XColor xcol; @@ -88,7 +84,7 @@ void BColor::parseColorName(void) { xcol.blue = 0; xcol.pixel = 0; - if (! XParseColor(display()->getXDisplay(), colormap, + if (! XParseColor(OBDisplay::display, colormap, colorname.c_str(), &xcol)) { fprintf(stderr, "BColor::allocate: color parse error: \"%s\"\n", colorname.c_str()); @@ -101,10 +97,8 @@ void BColor::parseColorName(void) { void BColor::allocate(void) { - assert(dpy != 0); - - if (scrn == ~(0u)) scrn = DefaultScreen(display()->getXDisplay()); - Colormap colormap = display()->getScreenInfo(scrn)->getColormap(); + if (scrn == ~(0u)) scrn = DefaultScreen(OBDisplay::display); + Colormap colormap = OBDisplay::screenInfo(scrn)->getColormap(); if (! isValid()) { if (colorname.empty()) { @@ -116,7 +110,7 @@ void BColor::allocate(void) { } // see if we have allocated this color before - RGB rgb(display(), scrn, r, g, b); + RGB rgb(scrn, r, g, b); ColorCache::iterator it = colorcache.find(rgb); if (it != colorcache.end()) { // found @@ -133,7 +127,7 @@ void BColor::allocate(void) { xcol.blue = b | b << 8; xcol.pixel = 0; - if (! XAllocColor(display()->getXDisplay(), colormap, &xcol)) { + if (! XAllocColor(OBDisplay::display, colormap, &xcol)) { fprintf(stderr, "BColor::allocate: color alloc error: rgb:%x/%x/%x\n", r, g, b); xcol.pixel = 0; @@ -153,9 +147,7 @@ void BColor::deallocate(void) { if (! allocated) return; - assert(dpy != 0); - - ColorCache::iterator it = colorcache.find(RGB(display(), scrn, r, g, b)); + ColorCache::iterator it = colorcache.find(RGB(scrn, r, g, b)); if (it != colorcache.end()) { if ((*it).second.count >= 1) (*it).second.count--; @@ -173,7 +165,6 @@ BColor &BColor::operator=(const BColor &c) { setRGB(c.r, c.g, c.b); colorname = c.colorname; - dpy = c.dpy; scrn = c.scrn; return *this; } @@ -192,11 +183,11 @@ void BColor::doCacheCleanup(void) { return; } - const BaseDisplay* const display = (*it).first.display; unsigned long *pixels = new unsigned long[ colorcache.size() ]; - unsigned int i, count; + int i; + unsigned count; - for (i = 0; i < display->getNumberOfScreens(); i++) { + for (i = 0; i < ScreenCount(OBDisplay::display); i++) { count = 0; it = colorcache.begin(); @@ -213,11 +204,13 @@ void BColor::doCacheCleanup(void) { } if (count > 0) - XFreeColors(display->getXDisplay(), - display->getScreenInfo(i)->getColormap(), + XFreeColors(OBDisplay::display, + OBDisplay::screenInfo(i)->getColormap(), pixels, count, 0); } delete [] pixels; cleancache = false; } + +} diff --git a/otk/color.hh b/otk/color.hh index 5f3cb955..387c81bf 100644 --- a/otk/color.hh +++ b/otk/color.hh @@ -9,15 +9,13 @@ extern "C" { #include #include -class BaseDisplay; +namespace otk { class BColor { public: - BColor(const BaseDisplay * const _display = 0, unsigned int _screen = ~(0u)); - BColor(int _r, int _g, int _b, - const BaseDisplay * const _display, unsigned int _screen = ~(0u)); - BColor(const std::string &_name, - const BaseDisplay * const _display, unsigned int _screen = ~(0u)); + BColor(unsigned int _screen = ~(0u)); + BColor(int _r, int _g, int _b, unsigned int _screen = ~(0u)); + BColor(const std::string &_name, unsigned int _screen = ~(0u)); ~BColor(void); inline const std::string &name(void) const { return colorname; } @@ -32,10 +30,8 @@ public: b = _b; } - inline const BaseDisplay *display(void) const { return dpy; } inline unsigned int screen(void) const { return scrn; } - void setDisplay(const BaseDisplay * const _display, - unsigned int _screen = ~(0u)); + void setScreen(unsigned int _screen = ~(0u)); inline bool isAllocated(void) const { return allocated; } @@ -60,27 +56,23 @@ private: bool allocated; int r, g, b; unsigned long p; - const BaseDisplay *dpy; unsigned int scrn; std::string colorname; // global color allocator/deallocator struct RGB { - const BaseDisplay* const display; - const unsigned int screen; + const int screen; const int r, g, b; - RGB(void) : display(0), screen(~(0u)), r(-1), g(-1), b(-1) { } - RGB(const BaseDisplay * const a, const unsigned int b, - const int x, const int y, const int z) - : display(a), screen(b), r(x), g(y), b(z) {} + RGB(void) : screen(~(0u)), r(-1), g(-1), b(-1) { } + RGB(const int b, const int x, const int y, const int z) + : screen(b), r(x), g(y), b(z) {} RGB(const RGB &x) - : display(x.display), screen(x.screen), r(x.r), g(x.g), b(x.b) {} + : screen(x.screen), r(x.r), g(x.g), b(x.b) {} inline bool operator==(const RGB &x) const { - return display == x.display && - screen == x.screen && - r == x.r && g == x.g && b == x.b; + return screen == x.screen && + r == x.r && g == x.g && b == x.b; } inline bool operator<(const RGB &x) const { @@ -103,4 +95,6 @@ private: static void doCacheCleanup(void); }; +} + #endif // COLOR_HH diff --git a/otk/display.cc b/otk/display.cc new file mode 100644 index 00000000..9e6685b9 --- /dev/null +++ b/otk/display.cc @@ -0,0 +1,158 @@ +// -*- mode: C++; indent-tabs-mode: nil; -*- + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "display.hh" +#include "screeninfo.hh" +#include "gccache.hh" + +extern "C" { +#include + +#ifdef HAVE_STDIO_H +# include +#endif // HAVE_STDIO_H + +#ifdef HAVE_STDLIB_H +# include +#endif // HAVE_STDLIB_H + +#ifdef HAVE_SIGNAL_H +# include +#endif // HAVE_SIGNAL_H + +#ifdef HAVE_FCNTL_H +# include +#endif // HAVE_FCNTL_H + +#ifdef HAVE_UNISTD_H +# include +# include +#endif // HAVE_UNISTD_H + +#include "gettext.h" +#define _(str) gettext(str) +} + +namespace otk { + + +Display *display = (Display*) 0; + + +int OBDisplay::xerrorHandler(Display *d, XErrorEvent *e) +{ +#ifdef DEBUG + char errtxt[128]; + + XGetErrorText(d, e->error_code, errtxt, 128); + printf("X Error: %s\n", errtxt); +#else + (void)d; + (void)e; +#endif + + return false; +} + + +void OBDisplay::initialize(char *name) +{ + int junk; + (void)junk; + + // Open the X display + if (!(display = XOpenDisplay(name))) { + printf(_("Unable to open connection to the X server. Please set the \n\ +DISPLAY environment variable approriately, or use the '-display' command \n\ +line argument.\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); + } + + // set our error handler for X errors + XSetErrorHandler(xerrorHandler); + + // set the DISPLAY environment variable for any lauched children, to the + // display we're using, so they open in the right place. + // XXX rm -> std::string dtmp = "DISPLAY=" + DisplayString(display); + if (putenv(const_cast((std::string("DISPLAY=") + + DisplayString(display)).c_str()))) { + printf(_("warning: couldn't set environment variable 'DISPLAY'\n")); + perror("putenv()"); + } + + // find the availability of X extensions we like to use +#ifdef SHAPE + _shape = XShapeQueryExtension(display, &_shape_event_basep, &junk); +#else + _shape = false; +#endif + +#ifdef XINERAMA + _xinerama = XineramaQueryExtension(display, &_xinerama_event_basep, &junk); +#else + _xinerama = false; +#endif // XINERAMA + + // get lock masks that are defined by the display (not constant) + XModifierKeymap *modmap; + unsigned int NumLockMask = 0, ScrollLockMask = 0; + + modmap = XGetModifierMapping(display); + if (modmap && modmap->max_keypermod > 0) { + const int mask_table[] = { + ShiftMask, LockMask, ControlMask, Mod1Mask, + Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask + }; + const size_t size = (sizeof(mask_table) / sizeof(mask_table[0])) * + modmap->max_keypermod; + // get the values of the keyboard lock modifiers + // Note: Caps lock is not retrieved the same way as Scroll and Num lock + // since it doesn't need to be. + const KeyCode num_lock = XKeysymToKeycode(display, XK_Num_Lock); + const KeyCode scroll_lock = XKeysymToKeycode(display, XK_Scroll_Lock); + + for (size_t cnt = 0; cnt < size; ++cnt) { + if (! modmap->modifiermap[cnt]) continue; + + if (num_lock == modmap->modifiermap[cnt]) + NumLockMask = mask_table[cnt / modmap->max_keypermod]; + if (scroll_lock == modmap->modifiermap[cnt]) + ScrollLockMask = mask_table[cnt / modmap->max_keypermod]; + } + } + + if (modmap) XFreeModifiermap(modmap); + + _mask_list[0] = 0; + _mask_list[1] = LockMask; + _mask_list[2] = NumLockMask; + _mask_list[3] = LockMask | NumLockMask; + _mask_list[4] = ScrollLockMask; + _mask_list[5] = ScrollLockMask | LockMask; + _mask_list[6] = ScrollLockMask | NumLockMask; + _mask_list[7] = ScrollLockMask | LockMask | NumLockMask; + + // Get information on all the screens which are available. + _screenInfoList.reserve(ScreenCount(display)); + for (int i = 0; i < ScreenCount(display); ++i) + _screenInfoList.push_back(ScreenInfo(i)); + + _gccache = new BGCCache(_screenInfoList.size()); +} + + +void OBDisplay::destroy() +{ + delete _gccache; + XCloseDisplay(display); +} + + +} diff --git a/otk/display.hh b/otk/display.hh new file mode 100644 index 00000000..aa457bcd --- /dev/null +++ b/otk/display.hh @@ -0,0 +1,69 @@ +// -*- mode: C++; indent-tabs-mode: nil; -*- +#ifndef __display_hh +#define __display_hh + +extern "C" { +#include +} + +#include + +namespace otk { + +class ScreenInfo; +class BGCCache; + +class OBDisplay +{ +public: + static Display *display; // the X display + + typedef std::vector ScreenInfoList; + +private: + static bool _shape; // does the display have the shape extention? + static int _shape_event_basep; // base for shape events + + static bool _xinerama; // does the display have the xinerama extention? + static int _xinerama_event_basep;// base for xinerama events + + static unsigned int _mask_list[8];// a list of all combinations of lock masks + + static ScreenInfoList _screenInfoList; // info for all screens on the display + + static BGCCache *_gccache; + + static int xerrorHandler(Display *d, XErrorEvent *e); // handles X errors duh + + OBDisplay(); // this class cannot be instantiated + +public: + static void initialize(char *name); + static void destroy(); + + //! Returns the GC cache for the application + inline static BGCCache *gcCache() { return _gccache; } + + /*! + Returns a ScreenInfo class, which gives information on a screen on the + display. + \param snum The screen number of the screen to retrieve info on + \return Info on the requested screen, in a ScreenInfo class + */ + inline static const ScreenInfo* screenInfo(int snum) { + assert(snum >= 0); + assert(snum < static_cast(_screenInfoList.size())); + return &_screenInfoList[snum]; + } + + //! Returns if the display has the shape extention available + inline static bool shape() { return _shape; } + //! Returns the shape extension's event base + inline static int shapeEventBase() { return _shape_event_basep; } + //! Returns if the display has the xinerama extention available + inline static bool xinerama() { return _xinerama; } +}; + +} + +#endif // __display_hh diff --git a/otk/font.cc b/otk/font.cc index 91f8ffb6..3f1b11e5 100644 --- a/otk/font.cc +++ b/otk/font.cc @@ -21,14 +21,16 @@ using std::endl; #include "util.hh" #include "gccache.hh" #include "color.hh" +#include "screeninfo.hh" + +namespace otk { string BFont::_fallback_font = "fixed"; -BFont::BFont(Display *d, BScreen *screen, const string &family, int size, +BFont::BFont(int screen_num, const string &family, int size, bool bold, bool italic, bool shadow, unsigned char offset, unsigned char tint, bool antialias) : - _display(d), - _screen(screen), + _screen_num(screen_num), _family(family), _simplename(False), _size(size), @@ -41,7 +43,7 @@ BFont::BFont(Display *d, BScreen *screen, const string &family, int size, _xftfont(0) { _valid = False; - _xftfont = XftFontOpen(_display, _screen->getScreenNumber(), + _xftfont = XftFontOpen(OBDisplay::display, _screen_num, XFT_FAMILY, XftTypeString, _family.c_str(), XFT_SIZE, XftTypeInteger, _size, XFT_WEIGHT, XftTypeInteger, (_bold ? @@ -61,7 +63,7 @@ BFont::BFont(Display *d, BScreen *screen, const string &family, int size, BFont::~BFont(void) { if (_xftfont) - XftFontClose(_display, _xftfont); + XftFontClose(OBDisplay::display, _xftfont); } @@ -69,8 +71,9 @@ void BFont::drawString(Drawable d, int x, int y, const BColor &color, const string &string) const { assert(_valid); - XftDraw *draw = XftDrawCreate(_display, d, _screen->getVisual(), - _screen->getColormap()); + const ScreenInfo *info = OBDisplay::screenInfo(_screen_num); + XftDraw *draw = XftDrawCreate(OBDisplay::display, d, + info->getVisual(), info->getColormap()); assert(draw); if (_shadow) { @@ -79,7 +82,7 @@ void BFont::drawString(Drawable d, int x, int y, const BColor &color, c.color.green = 0; c.color.blue = 0; c.color.alpha = _tint | _tint << 8; // transparent shadow - c.pixel = BlackPixel(_display, _screen->getScreenNumber()); + c.pixel = BlackPixel(OBDisplay::display, _screen_num); XftDrawStringUtf8(draw, &c, _xftfont, x + _offset, _xftfont->ascent + y + _offset, @@ -107,8 +110,8 @@ unsigned int BFont::measureString(const string &string) const { XGlyphInfo info; - XftTextExtentsUtf8(_display, _xftfont, (XftChar8 *) string.c_str(), - string.size(), &info); + XftTextExtentsUtf8(OBDisplay::display, _xftfont, + (XftChar8 *) string.c_str(), string.size(), &info); return info.xOff + (_shadow ? _offset : 0); } @@ -126,3 +129,5 @@ unsigned int BFont::maxCharWidth(void) const { return _xftfont->max_advance_width; } + +} diff --git a/otk/font.hh b/otk/font.hh index c070bbff..8afd2bd1 100644 --- a/otk/font.hh +++ b/otk/font.hh @@ -4,19 +4,18 @@ extern "C" { #include - #include } #include - #include +namespace otk { + class BGCCache; class BGCCacheItem; class BColor; - -#include "screen.hh" +class ScreenInfo; class BFont { /* @@ -36,8 +35,7 @@ public: * instance members */ private: - Display *_display; - BScreen *_screen; + int _screen_num; std::string _family; bool _simplename; // true if not spec'd as a -*-* string @@ -58,7 +56,7 @@ private: public: // loads an Xft font - BFont(Display *d, BScreen *screen, const std::string &family, int size, + BFont(int screen_num, const std::string &family, int size, bool bold, bool italic, bool shadow, unsigned char offset, unsigned char tint, bool antialias = True); virtual ~BFont(void); @@ -79,4 +77,6 @@ public: const std::string &string) const; }; +} + #endif // __Font_hh diff --git a/otk/gccache.cc b/otk/gccache.cc index 2ab37f34..d741c711 100644 --- a/otk/gccache.cc +++ b/otk/gccache.cc @@ -9,14 +9,15 @@ extern "C" { } #include "gccache.hh" -#include "basedisplay.hh" #include "color.hh" #include "util.hh" +#include "screeninfo.hh" +namespace otk { BGCCacheContext::~BGCCacheContext(void) { if (gc) - XFreeGC(display->getXDisplay(), gc); + XFreeGC(OBDisplay::display, gc); } @@ -41,7 +42,7 @@ void BGCCacheContext::set(const BColor &_color, fontid = 0; } - XChangeGC(display->getXDisplay(), gc, mask, &gcv); + XChangeGC(OBDisplay::display, gc, mask, &gcv); } @@ -53,20 +54,18 @@ void BGCCacheContext::set(const XFontStruct * const _font) { XGCValues gcv; fontid = gcv.font = _font->fid; - XChangeGC(display->getXDisplay(), gc, GCFont, &gcv); + XChangeGC(OBDisplay::display, gc, GCFont, &gcv); } -BGCCache::BGCCache(const BaseDisplay * const _display, - unsigned int screen_count) - : display(_display), context_count(128u), - cache_size(16u), cache_buckets(8u * screen_count), +BGCCache::BGCCache(unsigned int screen_count) + : context_count(128u), cache_size(16u), cache_buckets(8u * screen_count), cache_total_size(cache_size * cache_buckets) { contexts = new BGCCacheContext*[context_count]; unsigned int i; for (i = 0; i < context_count; i++) { - contexts[i] = new BGCCacheContext(display); + contexts[i] = new BGCCacheContext(); } cache = new BGCCacheItem*[cache_total_size]; @@ -85,7 +84,7 @@ BGCCache::~BGCCache(void) { BGCCacheContext *BGCCache::nextContext(unsigned int scr) { - Window hd = display->getScreenInfo(scr)->getRootWindow(); + Window hd = OBDisplay::screenInfo(scr)->getRootWindow(); BGCCacheContext *c; @@ -93,7 +92,7 @@ BGCCacheContext *BGCCache::nextContext(unsigned int scr) { c = contexts[i]; if (! c->gc) { - c->gc = XCreateGC(display->getXDisplay(), hd, 0, 0); + c->gc = XCreateGC(OBDisplay::display, hd, 0, 0); c->used = false; c->screen = scr; } @@ -186,3 +185,5 @@ void BGCCache::purge(void) { } } } + +} diff --git a/otk/gccache.hh b/otk/gccache.hh index 499ed8a4..f0b316aa 100644 --- a/otk/gccache.hh +++ b/otk/gccache.hh @@ -6,9 +6,11 @@ extern "C" { #include } -#include "basedisplay.hh" +#include "display.hh" #include "color.hh" +namespace otk { + class BGCCacheItem; class BGCCacheContext { @@ -20,11 +22,10 @@ public: ~BGCCacheContext(void); private: - BGCCacheContext(const BaseDisplay * const _display) - : display(_display), gc(0), pixel(0ul), fontid(0ul), + BGCCacheContext() + : gc(0), pixel(0ul), fontid(0ul), function(0), subwindow(0), used(false), screen(~(0u)), linewidth(0) {} - const BaseDisplay *display; GC gc; unsigned long pixel; unsigned long fontid; @@ -61,7 +62,7 @@ private: class BGCCache { public: - BGCCache(const BaseDisplay * const _display, unsigned int screen_count); + BGCCache(unsigned int screen_count); ~BGCCache(void); // cleans up the cache @@ -78,8 +79,6 @@ private: // this is closely modelled after the Qt GC cache, but with some of the // complexity stripped out - const BaseDisplay *display; - const unsigned int context_count; const unsigned int cache_size; const unsigned int cache_buckets; @@ -94,7 +93,7 @@ public: int _linewidth = 0, int _function = GXcopy, int _subwindow = ClipByChildren) : color(_color), font(_font), linewidth(_linewidth), function(_function), - subwindow(_subwindow), cache(_color.display()->gcCache()), item(0) { } + subwindow(_subwindow), cache(OBDisplay::gcCache()), item(0) { } inline ~BPen(void) { if (item) cache->release(item); } @@ -115,5 +114,6 @@ private: mutable BGCCacheItem *item; }; +} #endif // GCCACHE_HH diff --git a/otk/image.cc b/otk/image.cc index 21e9d690..59c26ae6 100644 --- a/otk/image.cc +++ b/otk/image.cc @@ -12,12 +12,12 @@ using std::max; using std::min; -#include "blackbox.hh" -#include "basedisplay.hh" +#include "display.hh" #include "gccache.hh" #include "image.hh" #include "texture.hh" +namespace otk { BImage::BImage(BImageControl *c, int w, int h) { control = c; @@ -62,7 +62,7 @@ Pixmap BImage::render(const BTexture &texture) { Pixmap BImage::render_solid(const BTexture &texture) { - Pixmap pixmap = XCreatePixmap(control->getBaseDisplay()->getXDisplay(), + Pixmap pixmap = XCreatePixmap(OBDisplay::display, control->getDrawable(), width, height, control->getDepth()); if (pixmap == None) { @@ -70,70 +70,68 @@ Pixmap BImage::render_solid(const BTexture &texture) { return None; } - Display *display = control->getBaseDisplay()->getXDisplay(); - BPen pen(texture.color()); BPen penlight(texture.lightColor()); BPen penshadow(texture.shadowColor()); - XFillRectangle(display, pixmap, pen.gc(), 0, 0, width, height); + XFillRectangle(OBDisplay::display, pixmap, pen.gc(), 0, 0, width, height); if (texture.texture() & BTexture::Interlaced) { BPen peninterlace(texture.colorTo()); for (unsigned int i = 0; i < height; i += 2) - XDrawLine(display, pixmap, peninterlace.gc(), 0, i, width, i); + XDrawLine(OBDisplay::display, pixmap, peninterlace.gc(), 0, i, width, i); } int left = 0, top = 0, right = width - 1, bottom = height - 1; if (texture.texture() & BTexture::Border) { BPen penborder(texture.borderColor()); - XDrawRectangle(display, pixmap, penborder.gc(), + XDrawRectangle(OBDisplay::display, pixmap, penborder.gc(), left, top, right, bottom); } if (texture.texture() & BTexture::Bevel1) { if (texture.texture() & BTexture::Raised) { - XDrawLine(display, pixmap, penshadow.gc(), + XDrawLine(OBDisplay::display, pixmap, penshadow.gc(), left, bottom, right, bottom); - XDrawLine(display, pixmap, penshadow.gc(), + XDrawLine(OBDisplay::display, pixmap, penshadow.gc(), right, bottom, right, top); - XDrawLine(display, pixmap, penlight.gc(), + XDrawLine(OBDisplay::display, pixmap, penlight.gc(), left, top, right, top); - XDrawLine(display, pixmap, penlight.gc(), + XDrawLine(OBDisplay::display, pixmap, penlight.gc(), left, bottom, left, top); } else if (texture.texture() & BTexture::Sunken) { - XDrawLine(display, pixmap, penlight.gc(), + XDrawLine(OBDisplay::display, pixmap, penlight.gc(), left, bottom, right, bottom); - XDrawLine(display, pixmap, penlight.gc(), + XDrawLine(OBDisplay::display, pixmap, penlight.gc(), right, bottom, right, top); - XDrawLine(display, pixmap, penshadow.gc(), + XDrawLine(OBDisplay::display, pixmap, penshadow.gc(), left, top, right, top); - XDrawLine(display, pixmap, penshadow.gc(), + XDrawLine(OBDisplay::display, pixmap, penshadow.gc(), left, bottom, left, top); } } else if (texture.texture() & BTexture::Bevel2) { if (texture.texture() & BTexture::Raised) { - XDrawLine(display, pixmap, penshadow.gc(), + XDrawLine(OBDisplay::display, pixmap, penshadow.gc(), left + 1, bottom - 2, right - 2, bottom - 2); - XDrawLine(display, pixmap, penshadow.gc(), + XDrawLine(OBDisplay::display, pixmap, penshadow.gc(), right - 2, bottom - 2, right - 2, top + 1); - XDrawLine(display, pixmap, penlight.gc(), + XDrawLine(OBDisplay::display, pixmap, penlight.gc(), left + 1, top + 1, right - 2, top + 1); - XDrawLine(display, pixmap, penlight.gc(), + XDrawLine(OBDisplay::display, pixmap, penlight.gc(), left + 1, bottom - 2, left + 1, top + 1); } else if (texture.texture() & BTexture::Sunken) { - XDrawLine(display, pixmap, penlight.gc(), + XDrawLine(OBDisplay::display, pixmap, penlight.gc(), left + 1, bottom - 2, right - 2, bottom - 2); - XDrawLine(display, pixmap, penlight.gc(), + XDrawLine(OBDisplay::display, pixmap, penlight.gc(), right - 2, bottom - 2, right - 2, top + 1); - XDrawLine(display, pixmap, penshadow.gc(), + XDrawLine(OBDisplay::display, pixmap, penshadow.gc(), left + 1, top + 1, right - 2, top + 1); - XDrawLine(display, pixmap, penshadow.gc(), + XDrawLine(OBDisplay::display, pixmap, penshadow.gc(), left + 1, bottom - 2, left + 1, top + 1); } } @@ -427,7 +425,7 @@ void BImage::PseudoColorDither(int bytes_per_line, unsigned char *pixel_data) { XImage *BImage::renderXImage(void) { XImage *image = - XCreateImage(control->getBaseDisplay()->getXDisplay(), + XCreateImage(OBDisplay::display, control->getVisual(), control->getDepth(), ZPixmap, 0, 0, width, height, 32, 0); @@ -541,7 +539,7 @@ XImage *BImage::renderXImage(void) { Pixmap BImage::renderPixmap(void) { Pixmap pixmap = - XCreatePixmap(control->getBaseDisplay()->getXDisplay(), + XCreatePixmap(OBDisplay::display, control->getDrawable(), width, height, control->getDepth()); if (pixmap == None) { @@ -552,18 +550,18 @@ Pixmap BImage::renderPixmap(void) { XImage *image = renderXImage(); if (! image) { - XFreePixmap(control->getBaseDisplay()->getXDisplay(), pixmap); + XFreePixmap(OBDisplay::display, pixmap); return None; } if (! image->data) { XDestroyImage(image); - XFreePixmap(control->getBaseDisplay()->getXDisplay(), pixmap); + XFreePixmap(OBDisplay::display, pixmap); return None; } - XPutImage(control->getBaseDisplay()->getXDisplay(), pixmap, - DefaultGC(control->getBaseDisplay()->getXDisplay(), + XPutImage(OBDisplay::display, pixmap, + DefaultGC(OBDisplay::display, control->getScreenInfo()->getScreenNumber()), image, 0, 0, 0, 0, width, height); @@ -1675,3 +1673,5 @@ void BImage::cdgradient(void) { } } } + +} diff --git a/otk/image.hh b/otk/image.hh index 85ad287d..88165606 100644 --- a/otk/image.hh +++ b/otk/image.hh @@ -10,11 +10,14 @@ extern "C" { #include #include "timer.hh" -#include "basedisplay.hh" #include "color.hh" +#include "screeninfo.hh" + +namespace otk { class BImageControl; class BTexture; +class ScreenInfo; class BImage { private: @@ -72,17 +75,15 @@ public: unsigned long pixel1, pixel2, texture; }; - BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn, + BImageControl(const ScreenInfo *scrn, bool _dither= False, int _cpc = 4, unsigned long cache_timeout = 300000l, unsigned long cmax = 200l); virtual ~BImageControl(void); - inline BaseDisplay *getBaseDisplay(void) const { return basedisplay; } - inline bool doDither(void) { return dither; } - inline const ScreenInfo *getScreenInfo(void) { return screeninfo; } + inline const ScreenInfo* getScreenInfo() const { return screeninfo; } inline Window getDrawable(void) const { return window; } @@ -114,7 +115,6 @@ public: private: bool dither; - BaseDisplay *basedisplay; const ScreenInfo *screeninfo; BTimer *timer; @@ -139,6 +139,7 @@ private: const BColor &c1, const BColor &c2); }; +} #endif // __Image_hh diff --git a/otk/imagecontrol.cc b/otk/imagecontrol.cc index 7d091bb8..8378b65d 100644 --- a/otk/imagecontrol.cc +++ b/otk/imagecontrol.cc @@ -18,12 +18,13 @@ extern "C" { #include -#include "blackbox.hh" -#include "basedisplay.hh" +#include "display.hh" #include "color.hh" #include "image.hh" #include "texture.hh" +namespace otk { + static unsigned long bsqrt(unsigned long x) { if (x <= 0) return 0; if (x == 1) return 1; @@ -40,22 +41,22 @@ static unsigned long bsqrt(unsigned long x) { BImageControl *ctrl = 0; -BImageControl::BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn, +BImageControl::BImageControl(const ScreenInfo *scrn, bool _dither, int _cpc, unsigned long cache_timeout, unsigned long cmax) { if (! ctrl) ctrl = this; - basedisplay = dpy; screeninfo = scrn; setDither(_dither); setColorsPerChannel(_cpc); cache_max = cmax; if (cache_timeout) { - timer = new BTimer(basedisplay, this); + // XXX: FIX THIS + timer = 0;/*new BTimer(this); timer->setTimeout(cache_timeout); - timer->start(); + timer->start();*/ } else { timer = (BTimer *) 0; } @@ -74,7 +75,7 @@ BImageControl::BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn, colormap = screeninfo->getColormap(); int count; - XPixmapFormatValues *pmv = XListPixmapFormats(basedisplay->getXDisplay(), + XPixmapFormatValues *pmv = XListPixmapFormats(OBDisplay::display, &count); if (pmv) { bits_per_pixel = 0; @@ -167,7 +168,7 @@ BImageControl::BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn, } for (i = 0; i < ncolors; i++) { - if (! XAllocColor(basedisplay->getXDisplay(), colormap, &colors[i])) { + if (! XAllocColor(OBDisplay::display, colormap, &colors[i])) { fprintf(stderr, "couldn't alloc color %i %i %i\n", colors[i].red, colors[i].green, colors[i].blue); colors[i].flags = 0; @@ -182,7 +183,7 @@ BImageControl::BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn, for (i = 0; i < incolors; i++) icolors[i].pixel = i; - XQueryColors(basedisplay->getXDisplay(), colormap, icolors, incolors); + XQueryColors(OBDisplay::display, colormap, icolors, incolors); for (i = 0; i < ncolors; i++) { if (! colors[i].flags) { unsigned long chk = 0xffffffff, pixel, close = 0; @@ -204,7 +205,7 @@ BImageControl::BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn, colors[i].green = icolors[close].green; colors[i].blue = icolors[close].blue; - if (XAllocColor(basedisplay->getXDisplay(), colormap, + if (XAllocColor(OBDisplay::display, colormap, &colors[i])) { colors[i].flags = DoRed|DoGreen|DoBlue; break; @@ -261,7 +262,7 @@ BImageControl::BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn, colors[i].blue = (i * 0xffff) / (colors_per_channel - 1);; colors[i].flags = DoRed|DoGreen|DoBlue; - if (! XAllocColor(basedisplay->getXDisplay(), colormap, + if (! XAllocColor(OBDisplay::display, colormap, &colors[i])) { fprintf(stderr, "couldn't alloc color %i %i %i\n", colors[i].red, colors[i].green, colors[i].blue); @@ -278,7 +279,7 @@ BImageControl::BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn, for (i = 0; i < incolors; i++) icolors[i].pixel = i; - XQueryColors(basedisplay->getXDisplay(), colormap, icolors, incolors); + XQueryColors(OBDisplay::display, colormap, icolors, incolors); for (i = 0; i < ncolors; i++) { if (! colors[i].flags) { unsigned long chk = 0xffffffff, pixel, close = 0; @@ -300,7 +301,7 @@ BImageControl::BImageControl(BaseDisplay *dpy, const ScreenInfo *scrn, colors[i].green = icolors[close].green; colors[i].blue = icolors[close].blue; - if (XAllocColor(basedisplay->getXDisplay(), colormap, + if (XAllocColor(OBDisplay::display, colormap, &colors[i])) { colors[i].flags = DoRed|DoGreen|DoBlue; break; @@ -334,7 +335,7 @@ BImageControl::~BImageControl(void) { for (int i = 0; i < ncolors; i++) *(pixels + i) = (*(colors + i)).pixel; - XFreeColors(basedisplay->getXDisplay(), colormap, pixels, ncolors, 0); + XFreeColors(OBDisplay::display, colormap, pixels, ncolors, 0); delete [] colors; } @@ -347,7 +348,7 @@ BImageControl::~BImageControl(void) { CacheContainer::iterator it = cache.begin(); const CacheContainer::iterator end = cache.end(); for (; it != end; ++it) - XFreePixmap(basedisplay->getXDisplay(), it->pixmap); + XFreePixmap(OBDisplay::display, it->pixmap); } if (timer) { timer->stop(); @@ -498,7 +499,7 @@ void BImageControl::getGradientBuffers(unsigned int w, void BImageControl::installRootColormap(void) { int ncmap = 0; Colormap *cmaps = - XListInstalledColormaps(basedisplay->getXDisplay(), window, &ncmap); + XListInstalledColormaps(OBDisplay::display, window, &ncmap); if (cmaps) { bool install = True; @@ -507,7 +508,7 @@ void BImageControl::installRootColormap(void) { install = False; if (install) - XInstallColormap(basedisplay->getXDisplay(), colormap); + XInstallColormap(OBDisplay::display, colormap); XFree(cmaps); } @@ -543,19 +544,19 @@ struct ZeroRefCheck { }; struct CacheCleaner { - Display *display; ZeroRefCheck ref_check; - CacheCleaner(Display *d): display(d) {} + CacheCleaner() {} inline void operator()(const BImageControl::CachedImage& image) const { if (ref_check(image)) - XFreePixmap(display, image.pixmap); + XFreePixmap(OBDisplay::display, image.pixmap); } }; void BImageControl::timeout(void) { - CacheCleaner cleaner(basedisplay->getXDisplay()); + CacheCleaner cleaner; std::for_each(cache.begin(), cache.end(), cleaner); cache.remove_if(cleaner.ref_check); } +} diff --git a/otk/screeninfo.cc b/otk/screeninfo.cc new file mode 100644 index 00000000..22ec6d02 --- /dev/null +++ b/otk/screeninfo.cc @@ -0,0 +1,118 @@ +// -*- mode: C++; indent-tabs-mode: nil; -*- + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif // HAVE_CONFIG_H + +#include "screeninfo.hh" +#include "display.hh" + +using std::string; + +namespace otk { + +ScreenInfo::ScreenInfo(unsigned int num) { + screen_number = num; + + root_window = RootWindow(ob::OBDisplay::display, screen_number); + + rect.setSize(WidthOfScreen(ScreenOfDisplay(OBDisplay::display, + screen_number)), + HeightOfScreen(ScreenOfDisplay(OBDisplay::display, + screen_number))); + /* + 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. + */ + + depth = DefaultDepth(OBDisplay::display, screen_number); + visual = DefaultVisual(OBDisplay::display, screen_number); + colormap = DefaultColormap(OBDisplay::display, screen_number); + + 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_number; + vinfo_template.c_class = TrueColor; + + vinfo_return = XGetVisualInfo(OBDisplay::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(OBDisplay::display, root_window, visual, + AllocNone); + } + + XFree(vinfo_return); + } + + // get the default display string and strip the screen number + string default_string = DisplayString(OBDisplay::display); + const string::size_type pos = default_string.rfind("."); + if (pos != string::npos) + default_string.resize(pos); + + display_string = string("DISPLAY=") + default_string + '.' + + itostring(static_cast(screen_number)); + +#ifdef XINERAMA + xinerama_active = False; + + if (d->hasXineramaExtensions()) { + if (d->getXineramaMajorVersion() == 1) { + // we know the version 1(.1?) protocol + + /* + in this version of Xinerama, we can't query on a per-screen basis, but + in future versions we should be able, so the 'activeness' is checked + on a pre-screen basis anyways. + */ + if (XineramaIsActive(OBDisplay::display)) { + /* + If Xinerama is being used, there there is only going to be one screen + present. We still, of course, want to use the screen class, but that + is why no screen number is used in this function call. There should + never be more than one screen present with Xinerama active. + */ + int num; + XineramaScreenInfo *info = XineramaQueryScreens(OBDisplay::display, + &num); + if (num > 0 && info) { + xinerama_areas.reserve(num); + for (int i = 0; i < num; ++i) { + xinerama_areas.push_back(Rect(info[i].x_org, info[i].y_org, + info[i].width, info[i].height)); + } + XFree(info); + + // if we can't find any xinerama regions, then we act as if it is not + // active, even though it said it was + xinerama_active = True; + } + } + } + } +#endif // XINERAMA +} + +} diff --git a/otk/screeninfo.hh b/otk/screeninfo.hh new file mode 100644 index 00000000..5cb2f798 --- /dev/null +++ b/otk/screeninfo.hh @@ -0,0 +1,52 @@ +// -*- mode: C++; indent-tabs-mode: nil; -*- +#ifndef __screeninfo_hh +#define __screeninfo_hh + +#include "util.hh" + +extern "C" { +#include +} + +#include + +namespace otk { + +class ScreenInfo { +private: + Visual *visual; + Window root_window; + Colormap colormap; + + int depth; + unsigned int screen_number; + std::string display_string; + Rect rect; +#ifdef XINERAMA + RectList xinerama_areas; + bool xinerama_active; +#endif + +public: + ScreenInfo(unsigned int num); + + inline Visual *getVisual(void) const { return visual; } + inline Window getRootWindow(void) const { return root_window; } + inline Colormap getColormap(void) const { return colormap; } + inline int getDepth(void) const { return depth; } + inline unsigned int getScreenNumber(void) const + { return screen_number; } + inline const Rect& getRect(void) const { return rect; } + inline unsigned int getWidth(void) const { return rect.width(); } + inline unsigned int getHeight(void) const { return rect.height(); } + inline const std::string& displayString(void) const + { return display_string; } +#ifdef XINERAMA + inline const RectList &getXineramaAreas(void) const { return xinerama_areas; } + inline bool isXineramaActive(void) const { return xinerama_active; } +#endif +}; + +} + +#endif // __screeninfo_hh diff --git a/otk/texture.cc b/otk/texture.cc index 22454c59..7a651620 100644 --- a/otk/texture.cc +++ b/otk/texture.cc @@ -14,33 +14,30 @@ extern "C" { #include #include "texture.hh" -#include "basedisplay.hh" +#include "display.hh" #include "image.hh" -#include "screen.hh" -#include "blackbox.hh" using std::string; +namespace otk { -BTexture::BTexture(const BaseDisplay * const _display, - unsigned int _screen, BImageControl* _ctrl) - : c(_display, _screen), ct(_display, _screen), - lc(_display, _screen), sc(_display, _screen), bc(_display, _screen), t(0), - dpy(_display), ctrl(_ctrl), scrn(_screen) { } +BTexture::BTexture(unsigned int _screen, BImageControl* _ctrl) + : c(_screen), ct(_screen), + lc(_screen), sc(_screen), bc(_screen), t(0), + ctrl(_ctrl), scrn(_screen) { } -BTexture::BTexture(const string &d, const BaseDisplay * const _display, - unsigned int _screen, BImageControl* _ctrl) - : c(_display, _screen), ct(_display, _screen), - lc(_display, _screen), sc(_display, _screen), bc(_display, _screen), t(0), - dpy(_display), ctrl(_ctrl), scrn(_screen) { +BTexture::BTexture(const string &d,unsigned int _screen, BImageControl* _ctrl) + : c(_screen), ct(_screen), + lc(_screen), sc(_screen), bc(_screen), t(0), + ctrl(_ctrl), scrn(_screen) { setDescription(d); } void BTexture::setColor(const BColor &cc) { c = cc; - c.setDisplay(display(), screen()); + c.setScreen(screen()); unsigned char r, g, b, rr, gg, bb; @@ -54,7 +51,7 @@ void BTexture::setColor(const BColor &cc) { if (rr < r) rr = ~0; if (gg < g) gg = ~0; if (bb < b) bb = ~0; - lc = BColor(rr, gg, bb, display(), screen()); + lc = BColor(rr, gg, bb, screen()); // calculate the shadow color r = c.red(); @@ -66,7 +63,7 @@ void BTexture::setColor(const BColor &cc) { if (rr > r) rr = 0; if (gg > g) gg = 0; if (bb > b) bb = 0; - sc = BColor(rr, gg, bb, display(), screen()); + sc = BColor(rr, gg, bb, screen()); } @@ -127,20 +124,18 @@ void BTexture::setDescription(const string &d) { } } -void BTexture::setDisplay(const BaseDisplay * const _display, - const unsigned int _screen) { - if (_display == display() && _screen == screen()) { +void BTexture::setScreen(const unsigned int _screen) { + if (_screen == screen()) { // nothing to do return; } - dpy = _display; scrn = _screen; - c.setDisplay(_display, _screen); - ct.setDisplay(_display, _screen); - lc.setDisplay(_display, _screen); - sc.setDisplay(_display, _screen); - bc.setDisplay(_display, _screen); + c.setScreen(_screen); + ct.setScreen(_screen); + lc.setScreen(_screen); + sc.setScreen(_screen); + bc.setScreen(_screen); } @@ -152,7 +147,6 @@ BTexture& BTexture::operator=(const BTexture &tt) { bc = tt.bc; descr = tt.descr; t = tt.t; - dpy = tt.dpy; scrn = tt.scrn; ctrl = tt.ctrl; @@ -162,7 +156,6 @@ BTexture& BTexture::operator=(const BTexture &tt) { Pixmap BTexture::render(const unsigned int width, const unsigned int height, const Pixmap old) { - assert(display() != 0); assert(texture() != BTexture::NoTexture); if (texture() == (BTexture::Flat | BTexture::Solid)) @@ -171,7 +164,7 @@ Pixmap BTexture::render(const unsigned int width, const unsigned int height, return ParentRelative; if (screen() == ~(0u)) - scrn = DefaultScreen(display()->getXDisplay()); + scrn = DefaultScreen(OBDisplay::display); assert(ctrl != 0); Pixmap ret = ctrl->renderImage(width, height, *this); @@ -181,3 +174,5 @@ Pixmap BTexture::render(const unsigned int width, const unsigned int height, return ret; } + +} diff --git a/otk/texture.hh b/otk/texture.hh index 514a0584..d887a337 100644 --- a/otk/texture.hh +++ b/otk/texture.hh @@ -4,10 +4,13 @@ #include "color.hh" #include "util.hh" -class BImageControl; #include +namespace otk { + +class BImageControl; + class BTexture { public: enum Type { @@ -42,10 +45,8 @@ public: Interlaced = (1l<<18) }; - BTexture(const BaseDisplay * const _display = 0, - unsigned int _screen = ~(0u), BImageControl* _ctrl = 0); + BTexture(unsigned int _screen = ~(0u), BImageControl* _ctrl = 0); BTexture(const std::string &_description, - const BaseDisplay * const _display = 0, unsigned int _screen = ~(0u), BImageControl* _ctrl = 0); void setColor(const BColor &_color); @@ -69,10 +70,8 @@ public: inline bool operator!=(const BTexture &tt) { return (! operator==(tt)); } - const BaseDisplay *display(void) const { return dpy; } unsigned int screen(void) const { return scrn; } - void setDisplay(const BaseDisplay * const _display, - const unsigned int _screen); + void setScreen(const unsigned int _screen); void setImageControl(BImageControl* _ctrl) { ctrl = _ctrl; } const std::string &description(void) const { return descr; } void setDescription(const std::string &d); @@ -84,9 +83,10 @@ private: BColor c, ct, lc, sc, bc; std::string descr; unsigned long t; - const BaseDisplay *dpy; BImageControl *ctrl; unsigned int scrn; }; +} + #endif // TEXTURE_HH