/* Copyright (C) 1997 Mark Donohoe (donohoe@kde.org) Copyright (C) 2000 Stefan Westerfeld (stefan@space.twc.de) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * This is based on Mark Donohoe's nice KRootProp class (found in * kdelibs/tdecore/krootprop.cpp). I couldn't use KRootProp directly, since * I wanted aRts (and even it's X11 support) to work without KDE and/or Qt * installed at all. */ #include #include #include #include #include #include "x11globalcomm.h" #include "debug.h" #include using namespace std; using namespace Arts; class X11GlobalComm_impl : virtual public X11GlobalComm_skel { protected: Display *X11display; Window rootWin; Atom atom; map propertyMap; bool init; void warn(const char *what) { arts_warning("X11GlobalComm: %s", what); } public: X11GlobalComm_impl() :rootWin(0), atom(0) { X11display = XOpenDisplay(NULL); if(!X11display) { warn("Can't connect to the XServer - Initial references won't work."); init = false; } else { rootWin = DefaultRootWindow(X11display); atom = XInternAtom( X11display, "MCOPGLOBALS" , False); init = true; } } ~X11GlobalComm_impl() { if(X11display) XCloseDisplay(X11display); } void read() { if(!init) return; Atom type; int format; unsigned long nitems; unsigned long bytes_after; long offset; unsigned char *buf; propertyMap.clear(); // If a property has already been opened write // the dictionary back to the root window string s; offset = 0; bytes_after = 1; while (bytes_after != 0) { XGetWindowProperty( X11display, rootWin, atom, offset, 256, False, XA_STRING, &type, &format, &nitems, &bytes_after, &buf); if(type == None) // no property -> no contents return; s += (char*) buf; offset += nitems/4; if (buf) XFree((char*) buf); } // Parse through the property string stripping out key value pairs // and putting them in the dictionary while(s.length() >0 ) { // parse the string for first key-value pair separator '\n' int i = s.find("\n",0); // extract the key-values pair and remove from string string keypair = s.substr(0,i); s = s.substr(i+1,s.size()-(i+1)); // split key and value and add to dictionary i = keypair.find( "=" ); if( i != -1 ) { string key = keypair.substr( 0, i ); string value = keypair.substr( i+1, keypair.size()-(i+1) ); propertyMap[key] = value; } } } void write() { if(!init) return; // bring map in the variable=value form with \n as seperator string propString; map::iterator i = propertyMap.begin(); for(i = propertyMap.begin(); i != propertyMap.end(); i++) propString += i->first + "=" + i->second + "\n"; // send to the X11 server XChangeProperty( X11display, rootWin, atom, XA_STRING, 8, PropModeReplace, (const unsigned char *)propString.c_str(), propString.size()+1); XFlush(X11display); } bool put(const string& variable, const string& value) { if(!init) return false; read(); if(propertyMap[variable].empty()) { propertyMap[variable] = value; write(); return true; } return false; } string get(const string& variable) { if(!init) return ""; read(); return propertyMap[variable]; } void erase(const string& variable) { if(!init) return; read(); propertyMap.erase(variable); write(); } }; REGISTER_IMPLEMENTATION(X11GlobalComm_impl);