summaryrefslogtreecommitdiffstats
path: root/x11/x11globalcomm_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'x11/x11globalcomm_impl.cpp')
-rw-r--r--x11/x11globalcomm_impl.cpp184
1 files changed, 184 insertions, 0 deletions
diff --git a/x11/x11globalcomm_impl.cpp b/x11/x11globalcomm_impl.cpp
new file mode 100644
index 0000000..8d5e620
--- /dev/null
+++ b/x11/x11globalcomm_impl.cpp
@@ -0,0 +1,184 @@
+/*
+ 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
+ * tdelibs/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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include "x11globalcomm.h"
+#include "debug.h"
+#include <iostream>
+
+using namespace std;
+using namespace Arts;
+
+class X11GlobalComm_impl : virtual public X11GlobalComm_skel {
+protected:
+ Display *X11display;
+ Window rootWin;
+ Atom atom;
+ map<string,string> 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<string,string>::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);