"Fossies" - the Fresh Open Source Software Archive

Member "bbkeys-0.9.1/src/Netclient.cpp" (22 Dec 2008, 10096 Bytes) of package /linux/privat/old/bbkeys-0.9.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Netclient.cpp" see the Fossies "Dox" file reference documentation.

    1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
    2 // -- Netclient.cpp --
    3 // Copyright (c) 2001 - 2003 Jason 'vanRijn' Kasper <vR at movingparts dot net>
    4 //
    5 // Permission is hereby granted, free of charge, to any person obtaining a
    6 // copy of this software and associated documentation files (the "Software"),
    7 // to deal in the Software without restriction, including without limitation
    8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
    9 // and/or sell copies of the Software, and to permit persons to whom the
   10 // Software is furnished to do so, subject to the following conditions:
   11 //
   12 // The above copyright notice and this permission notice shall be included in
   13 // all copies or substantial portions of the Software.
   14 //
   15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   21 // DEALINGS IN THE SOFTWARE.
   22 
   23 // E_O_H_VR
   24 
   25 // Methods, ideas, implementations taken from Openbox's XAtom class *sigh*
   26 
   27 #include "Netclient.h"
   28 #include <string.h>
   29 
   30 Netclient::Netclient (const bt::Display &display)
   31   : bt::EWMH(display), _display(display)
   32 {
   33   init_icccm();
   34   init_extras();
   35   init_blackbox();
   36 }
   37                       
   38 Netclient::~Netclient ()
   39 {
   40 }
   41 
   42 void Netclient::init_icccm(void) {
   43   char* atoms[9] = {
   44     "WM_COLORMAP_WINDOWS",
   45     "WM_PROTOCOLS",
   46     "WM_NAME",
   47     "WM_STATE",
   48     "WM_CLASS",
   49     "WM_CHANGE_STATE",
   50     "WM_DELETE_WINDOW",
   51     "WM_TAKE_FOCUS",
   52     "_MOTIF_WM_HINTS"
   53   };
   54   Atom atoms_return[9];
   55   XInternAtoms(_display.XDisplay(), atoms, 9, False, atoms_return);
   56   xa_wm_colormap_windows = atoms_return[0];
   57   xa_wm_protocols = atoms_return[1];
   58   xa_wm_name = atoms_return[2];
   59   xa_wm_state = atoms_return[3];
   60   xa_wm_class = atoms_return[4];
   61   xa_wm_change_state = atoms_return[5];
   62   xa_wm_delete_window = atoms_return[6];
   63   xa_wm_take_focus = atoms_return[7];
   64   motif_wm_hints = atoms_return[8];
   65 
   66 }
   67 
   68 void Netclient::init_extras(void) {
   69   char* atoms[4] = {
   70     "_OPENBOX_SHOW_ROOT_MENU",
   71     "_OPENBOX_SHOW_WORKSPACE_MENU",
   72     "ENLIGHTENMENT_DESKTOP",
   73     "_NET_VIRTUAL_ROOTS"
   74   };
   75   Atom atoms_return[4];
   76   XInternAtoms(_display.XDisplay(), atoms, 2, False, atoms_return);
   77   openbox_show_root_menu = atoms_return[0];
   78   openbox_show_workspace_menu = atoms_return[1];
   79   enlightenment_desktop = atoms_return[2];
   80   net_virtual_roots = atoms_return[3];
   81 
   82 }
   83 
   84 void Netclient::init_blackbox(void) {
   85   char* atoms[3] = {
   86     "_BLACKBOX_HINTS",
   87     "_BLACKBOX_ATTRIBUTES",
   88     "_BLACKBOX_CHANGE_ATTRIBUTES"
   89   };
   90   Atom atoms_return[3];
   91   XInternAtoms(_display.XDisplay(), atoms, 3, False, atoms_return);
   92   blackbox_hints = atoms_return[0];
   93   blackbox_attributes = atoms_return[1];
   94   blackbox_change_attributes = atoms_return[2];
   95 
   96 }
   97 
   98 std::string Netclient::getWindowTitle(Window win) const
   99 {
  100 
  101   std::string _title = "";
  102 
  103   // try ewmh
  104   if (! getValue(win, wmName(), utf8, _title)) {
  105     // try old x stuff
  106     getValue(win, XA_WM_NAME, ansi, _title);
  107   }
  108 
  109   if (_title.empty())
  110     _title = "Unnamed";
  111 
  112   return _title;
  113 }
  114 
  115 unsigned int Netclient::getDesktop(Window win) const {
  116   unsigned long _desktop = 0ul;
  117   
  118   if (! getValue(win, wmDesktop(), XA_CARDINAL, _desktop))
  119     _desktop = 0ul;
  120 
  121   return static_cast<unsigned int>(_desktop);
  122 }
  123 
  124 /*
  125  * Internal getValue function used by all of the typed getValue functions.
  126  * Gets an property's value from a window.
  127  * Returns True if the property was successfully retrieved; False if the
  128  * property did not exist on the window, or has a different type/size format
  129  * than the user tried to retrieve.
  130  */
  131 bool Netclient::getValue(Window win, Atom atom, Atom type,
  132                          unsigned long &nelements, unsigned char **value,
  133                          int size) const {
  134   assert(win != None); assert(atom != None); assert(type != None);
  135   assert(size == 8 || size == 16 || size == 32);
  136   assert(nelements > 0);
  137   unsigned char *c_val = 0;        // value alloc'd in Xlib, must be XFree()d
  138   Atom ret_type;
  139   int ret_size;
  140   unsigned long ret_bytes;
  141   int result;
  142   unsigned long maxread = nelements;
  143   bool ret = False;
  144 
  145   // try get the first element
  146   result = XGetWindowProperty(_display.XDisplay(), win, atom, 0l, 1l, False,
  147                               AnyPropertyType, &ret_type, &ret_size,
  148                               &nelements, &ret_bytes, &c_val);
  149   ret = (result == Success && ret_type == type && ret_size == size &&
  150          nelements > 0);
  151   if (ret) {
  152     if (ret_bytes == 0 || maxread <= nelements) {
  153       // we got the whole property's value
  154       *value = new unsigned char[nelements * size/8 + 1];
  155       memcpy(*value, c_val, nelements * size/8 + 1);
  156     } else {
  157       // get the entire property since it is larger than one long
  158       XFree(c_val);
  159       // the number of longs that need to be retreived to get the property's
  160       // entire value. The last + 1 is the first long that we retrieved above.
  161       int remain = (ret_bytes - 1)/sizeof(long) + 1 + 1;
  162       if (remain > size/8 * (signed)maxread) // dont get more than the max
  163         remain = size/8 * (signed)maxread;
  164       result = XGetWindowProperty(_display.XDisplay(), win, atom, 0l, remain, False, type,
  165                                   &ret_type, &ret_size, &nelements, &ret_bytes,
  166                                   &c_val);
  167       ret = (result == Success && ret_type == type && ret_size == size &&
  168              ret_bytes == 0);
  169       /*
  170         If the property has changed type/size, or has grown since our first
  171         read of it, then stop here and try again. If it shrank, then this will
  172         still work.
  173       */
  174       if (! ret)
  175         return getValue(win, atom, type, maxread, value, size);
  176   
  177       *value = new unsigned char[nelements * size/8 + 1];
  178       memcpy(*value, c_val, nelements * size/8 + 1);
  179     }    
  180   }
  181   if (c_val) XFree(c_val);
  182   return ret;
  183 }
  184 
  185 
  186 /*
  187  * Gets a 32-bit property's value from a window.
  188  */
  189 bool Netclient::getValue(Window win, Atom atom, Atom type,
  190                          unsigned long &nelements,
  191                          unsigned long **value) const {
  192   return getValue(win, atom, type, nelements,
  193                   reinterpret_cast<unsigned char **>(value), 32);
  194 }
  195 
  196 
  197 /*
  198  * Gets a single 32-bit property's value from a window.
  199  */
  200 bool Netclient::getValue(Window win, Atom atom, Atom type,
  201                          unsigned long &value) const {
  202   unsigned long *temp;
  203   unsigned long num = 1;
  204   if (! getValue(win, atom, type, num,
  205                  reinterpret_cast<unsigned char **>(&temp), 32))
  206     return False;
  207 
  208   value = temp[0];
  209   delete [] temp;
  210   return True;
  211 }
  212 
  213 
  214 /*
  215  * Gets an string property's value from a window.
  216  */
  217 bool Netclient::getValue(Window win, Atom atom, StringType type,
  218                          std::string &value) const {
  219   unsigned long n = 1;
  220   StringVect s;
  221   if (getValue(win, atom, type, n, s)) {
  222     value = s[0];
  223     return True;
  224   }
  225   return False;
  226 }
  227 
  228 
  229 bool Netclient::getValue(Window win, Atom atom, StringType type,
  230                          unsigned long &nelements, StringVect &strings) const {
  231   assert(win != None); assert(atom != None);
  232   assert(nelements > 0);
  233 
  234   Atom t;
  235   switch (type) {
  236   case ansi: t = XA_STRING; break;
  237   case utf8: t = utf8String(); break;
  238   default: assert(False); return False; // unhandled StringType
  239   }
  240 
  241   unsigned char *value;
  242   unsigned long elements = (unsigned) -1;
  243   if (!getValue(win, atom, t, elements, &value, 8) || elements < 1)
  244     return False;
  245 
  246   std::string s(reinterpret_cast<char *>(value), elements);
  247   delete [] value;
  248 
  249   std::string::const_iterator it = s.begin(), end = s.end();
  250   unsigned long num = 0;
  251   while(num < nelements) {
  252     std::string::const_iterator tmp = it; // current string.begin()
  253     it = std::find(tmp, end, '\0');       // look for null between tmp and end
  254     strings.push_back(std::string(tmp, it));   // s[tmp:it)
  255     ++num;
  256     if (it == end) break;
  257     ++it;
  258     if (it == end) break;
  259   }
  260 
  261   nelements = num;
  262 
  263   return True;
  264 }
  265 
  266 
  267 /*
  268  * Removes a property entirely from a window.
  269  */
  270 void Netclient::eraseValue(Window win, Atom atom) const {
  271   XDeleteProperty(_display.XDisplay(), win, atom);
  272 }
  273 
  274 
  275 void Netclient::sendClientMessage(Window target, Atom type, Window about,
  276                                   long data, long data1, long data2,
  277                                   long data3, long data4) const {
  278   assert(target != None);
  279 
  280   XEvent e;
  281   e.xclient.type = ClientMessage;
  282   e.xclient.format = 32;
  283   e.xclient.message_type = type;
  284   e.xclient.window = about;
  285   e.xclient.data.l[0] = data;
  286   e.xclient.data.l[1] = data1;
  287   e.xclient.data.l[2] = data2;
  288   e.xclient.data.l[3] = data3;
  289   e.xclient.data.l[4] = data4;
  290 
  291   XSendEvent(_display.XDisplay(), target, False,
  292              SubstructureRedirectMask | SubstructureNotifyMask,
  293              &e);
  294 }
  295 
  296 bool Netclient::isAtomSupported(Window win, Atom atom) const {
  297 
  298   bool supported = False;
  299 
  300   bt::EWMH::AtomList atoms;
  301 
  302   if (readSupported(win, atoms) && atoms.size() > 0) {
  303     if (std::find(atoms.begin(), atoms.end(), atom) != atoms.end()) {
  304       supported = True;
  305     }
  306   }
  307 
  308   return supported;
  309 }
  310 
  311 Window * Netclient::getNetVirtualRootList(Window win) {
  312 
  313   Atom type_ret;
  314   int format_ret;
  315   unsigned long nitems_ret, unused;
  316   unsigned char *data_ret;
  317   Window *winsReturn = 0;
  318 
  319   int e = XGetWindowProperty(_display.XDisplay(), win, xaNetVirtualRoots(),
  320                              0, 0, False, XA_WINDOW, &type_ret,
  321                              &format_ret, &nitems_ret, &unused, &data_ret);
  322   
  323   if (e == Success && type_ret == XA_WINDOW && format_ret == 32) {
  324     Window *wins = (Window *) data_ret;
  325  
  326     winsReturn = new Window[nitems_ret];
  327     while (nitems_ret--) winsReturn[nitems_ret] = wins[nitems_ret];
  328   }
  329 
  330   if ( data_ret )
  331     XFree(data_ret);
  332 
  333   return winsReturn;
  334 
  335 }