From: Dana Jansens Date: Fri, 17 May 2002 02:49:26 +0000 (+0000) Subject: new versions of the X classes X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=20d7381ffb3b7b918c0f6120cce8c0343a50ce83;p=chaz%2Fopenbox new versions of the X classes added an Atom in XAtom and functionality in XScreen and XDisplay --- diff --git a/src/XAtom.cc b/src/XAtom.cc index 5f5fa9ed..98f7d8d1 100644 --- a/src/XAtom.cc +++ b/src/XAtom.cc @@ -27,6 +27,10 @@ XAtom::XAtom(const XDisplay *display) { _display = display->_display; +#ifdef HAVE_GETPID + openbox_pid = getAtom("_BLACKBOX_PID"); +#endif // HAVE_GETPID + wm_colormap_windows = getAtom("WM_COLORMAP_WINDOWS"); wm_protocols = getAtom("WM_PROTOCOLS"); wm_state = getAtom("WM_STATE"); diff --git a/src/XAtom.h b/src/XAtom.h index 424603ec..87afe2e4 100644 --- a/src/XAtom.h +++ b/src/XAtom.h @@ -22,6 +22,8 @@ #ifndef __XAtom_h #define __XAtom_h +#include "../config.h" + #include #include #include @@ -37,6 +39,10 @@ class XAtom { SupportWindows _support_windows; Atom +#ifdef HAVE_GETPID + openbox_pid, +#endif // HAVE_GETPID + // window hints wm_colormap_windows, wm_protocols, @@ -140,6 +146,10 @@ public: void eraseValue(Window win, Atom atom) const; +#ifdef HAVE_GETPID + inline Atom openboxPid() const { return openbox_pid; } +#endif // HAVE_GETPID + inline Atom wmChangeState() const { return wm_change_state; } inline Atom wmState() const { return wm_state; } inline Atom wmDelete() const { return wm_delete_window; } diff --git a/src/XDisplay.cc b/src/XDisplay.cc index 822f244a..1addb2d5 100644 --- a/src/XDisplay.cc +++ b/src/XDisplay.cc @@ -36,7 +36,6 @@ #endif #include "XDisplay.h" -#include "XScreen.h" #include "Util.h" #include #include @@ -51,7 +50,7 @@ Window XDisplay::_last_bad_window = None; * X error handler to handle all X errors while the application is * running. */ -int XDisplay::XErrorHandler(Display *d, XErrorEvent *e) { +int XDisplay::errorHandler(Display *d, XErrorEvent *e) { #ifdef DEBUG char errtxt[128]; XGetErrorText(d, e->error_code, errtxt, sizeof(errtxt)/sizeof(char)); @@ -86,17 +85,16 @@ XDisplay::XDisplay(const std::string &application_name, const char *dpyname) { } _name = XDisplayName(dpyname); - XSetErrorHandler(XErrorHandler); + XSetErrorHandler(errorHandler); #ifdef SHAPE int waste; _hasshape = XShapeQueryExtension(_display, &_shape_event_base, &waste); #endif // SHAPE - const unsigned int scount = ScreenCount(_display); - _screens.reserve(scount); - for (unsigned int s = 0; s < scount; s++) - _screens.push_back(new XScreen(this, s)); +#ifndef NOCLOBBER + getLockModifiers(); +#endif } @@ -106,15 +104,6 @@ XDisplay::~XDisplay() { } -/* - * Return information about a screen. - */ -XScreen *XDisplay::screen(unsigned int s) const { - ASSERT(s < _screens.size()); - return _screens[s]; -} - - /* * Grab the X server */ @@ -153,3 +142,119 @@ bool XDisplay::nextEvent(XEvent &e) { } return true; } + + +int XDisplay::connectionNumber() const { + return ConnectionNumber(_display); +} + + +/* + * Creates a font cursor in the X server and returns it. + */ +Cursor createCursor(unsigned int shape) const { + return XCreateFontCursor(_display, shape); +} + + +#ifndef NOCLOBBER +void XDisplay::getLockModifers() { + NumLockMask = ScrollLockMask = 0; + + const XModifierKeymap* const 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_code = XKeysymToKeycode(display, XK_Num_Lock); + const KeyCode scroll_lock_code = XKeysymToKeycode(display, XK_Scroll_Lock); + + for (size_t cnt = 0; cnt < size; ++cnt) { + if (! modmap->modifiermap[cnt]) continue; + + if (num_lock_code == modmap->modifiermap[cnt]) + NumLockMask = mask_table[cnt / modmap->max_keypermod]; + if (scroll_lock_code == modmap->modifiermap[cnt]) + ScrollLockMask = mask_table[cnt / modmap->max_keypermod]; + } + } + + MaskList[0] = 0; + MaskList[1] = LockMask; + MaskList[2] = NumLockMask; + MaskList[3] = ScrollLockMask; + MaskList[4] = LockMask | NumLockMask; + MaskList[5] = NumLockMask | ScrollLockMask; + MaskList[6] = LockMask | ScrollLockMask; + MaskList[7] = LockMask | NumLockMask | ScrollLockMask; + + if (modmap) XFreeModifiermap(const_cast(modmap)); +} +#endif // NOCLOBBER + +unsigned int XDisplay::stripModifiers(const unsigned int state) const { +#ifndef NOCLOBBER + return state &= ~(NumLockMask() | ScrollLockMask | LockMask); +#else + return state &= ~LockMask; +#endif +} + + +/* + * Verifies that a window has not requested to be destroyed/unmapped, so + * if it is a valid window or not. + * Returns: true if the window is valid; false if it is no longer valid. + */ +bool XDisplay::validateWindow(Window window) { + XEvent event; + if (XCheckTypedWindowEvent(_display, window, DestroyNotify, &event)) { + XPutBackEvent(display, &event); + return false; + } + return true; +} + + +/* + * Grabs a button, but also grabs the button in every possible combination with + * the keyboard lock keys, so that they do not cancel out the event. + */ +void BaseDisplay::grabButton(unsigned int button, unsigned int modifiers, + Window grab_window, Bool owner_events, + unsigned int event_mask, int pointer_mode, + int keybaord_mode, Window confine_to, + Cursor cursor) const +{ +#ifndef NOCLOBBER + for (size_t cnt = 0; cnt < 8; ++cnt) + XGrabButton(_display, button, modifiers | MaskList[cnt], grab_window, + owner_events, event_mask, pointer_mode, keybaord_mode, + confine_to, cursor); +#else // NOCLOBBER + XGrabButton(_display, button, modifiers, grab_window, + owner_events, event_mask, pointer_mode, keybaord_mode, + confine_to, cursor); +#endif // NOCLOBBER +} + + +/* + * Releases the grab on a button, and ungrabs all possible combinations of the + * keyboard lock keys. + */ +void BaseDisplay::ungrabButton(unsigned int button, unsigned int modifiers, + Window grab_window) const { +#ifndef NOCLOBBER + for (size_t cnt = 0; cnt < 8; ++cnt) + XUngrabButton(display, button, modifiers | MaskList[cnt], grab_window); +#else // NOCLOBBER + XUngrabButton(display, button, modifiers, grab_window); +#endif // NOCLOBBER +} diff --git a/src/XDisplay.h b/src/XDisplay.h index b736fd42..3c4230bd 100644 --- a/src/XDisplay.h +++ b/src/XDisplay.h @@ -39,11 +39,17 @@ private: bool _hasshape; int _shape_event_base; - typedef std::vector XScreenList; - XScreenList _screens; +#ifndef NOCLOBBER + // the server's values for the lock key modifiers + void getLockModifiers(); + unsigned int MaskList[8]; + // the masks of the modifiers which are ignored in button events. + int NumLockMask, ScrollLockMask; +#endif // NOCLOBBER + // X error handling - static int XErrorHandler(Display *d, XErrorEvent *e); + static int errorHandler(Display *d, XErrorEvent *e); static std::string _app_name; static Window _last_bad_window; @@ -58,27 +64,34 @@ public: XDisplay(const std::string &application_name, const char *dpyname = 0); virtual ~XDisplay(); - XScreen *screen(unsigned int s) const; - inline unsigned int screenCount() const { return _screens.size(); } + inline virtual unsigned int screenCount() const + { return ScreenCount(_display); } inline bool hasShape() const { return _hasshape; } inline int shapeEventBase() const { return _shape_event_base; } //inline Display *display() const { return _display; } + inline std::string applicationName() const { return _app_name; } inline std::string name() const { return _name; } - - // these belong in Xwindow - //const bool validateWindow(Window); - //void grabButton(unsigned int, unsigned int, Window, Bool, unsigned int, int, - // int, Window, Cursor) const; - //void ungrabButton(unsigned int button, unsigned int modifiers, - // Window grab_window) const; void grab(); void ungrab(); bool nextEvent(XEvent &e); + + int connectionNumber() const; + + Cursor createCursor(unsigned int shape) const; + + unsigned int stripModifiers(const unsigned int state) const; + + // these belong in Xwindow + const bool validateWindow(Window); + void grabButton(unsigned int, unsigned int, Window, Bool, unsigned int, int, + int, Window, Cursor) const; + void ungrabButton(unsigned int button, unsigned int modifiers, + Window grab_window) const; }; #endif // _XDisplay_h diff --git a/src/XScreen.cc b/src/XScreen.cc index fc53385d..5ae8becd 100644 --- a/src/XScreen.cc +++ b/src/XScreen.cc @@ -71,3 +71,16 @@ void XScreen::setColorData() { _colormap = DefaultColormap(_display, _number); } } + + +/* + * Creates a window on screen. + */ +Window createWindow(Window parent, const Rect &area, int borderw, + unsigned int winclass, unsigned long attrib_mask, + XSetWindowAttributes *attrib) const { + return XCreateWindow(_display, parent, + area.x(), area.y(), area.w(), area.h(), + borderw, depth(), winclass, visual(), + attrib_mask, attrib); +} diff --git a/src/XScreen.h b/src/XScreen.h index 6a6c6926..cdfd4257 100644 --- a/src/XScreen.h +++ b/src/XScreen.h @@ -53,6 +53,11 @@ public: inline unsigned int depth() const { return _depth; } inline unsigned int number() const { return _number; } inline const Size &size() const { return _size; } + + Window createWindow(Window parent, const Rect &area, int borderw, + unsigned int winclass, + unsigned long attrib_mask, + XSetWindowAttributes *attrib) const; }; #endif // __XScreen_h