epist now handles -display on the command line, and gets the client list and act
authorDana Jansens <danakj@orodu.net>
Thu, 11 Jul 2002 18:13:38 +0000 (18:13 +0000)
committerDana Jansens <danakj@orodu.net>
Thu, 11 Jul 2002 18:13:38 +0000 (18:13 +0000)
ive window

util/epist/epist.cc [moved from util/epist/main.cc with 62% similarity]
util/epist/epist.hh [new file with mode: 0644]
util/epist/process.cc [new file with mode: 0644]
util/epist/process.hh [new file with mode: 0644]
util/epist/window.cc [new file with mode: 0644]
util/epist/window.hh [new file with mode: 0644]

similarity index 62%
rename from util/epist/main.cc
rename to util/epist/epist.cc
index c7c1a76..7bb16d9 100644 (file)
@@ -1,5 +1,5 @@
 // -*- mode: C++; indent-tabs-mode: nil; -*-
-// main.cc for Epistory - a key handler for NETWM/EWMH window managers.
+// epist.cc for Epistory - a key handler for NETWM/EWMH window managers.
 // Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
 //
 // Permission is hereby granted, free of charge, to any person obtaining a
 #endif // HAVE_CONFIG_H
 
 extern "C" {
-#include <X11/Xlib.h>
-
 #ifdef    HAVE_UNISTD_H
 #  include <sys/types.h>
 #  include <unistd.h>
 #endif // HAVE_UNISTD_H
 
+#ifdef    HAVE_STDLIB_H
+#  include <stdlib.h>
+#endif // HAVE_STDLIB_H
+
 #ifdef    HAVE_SIGNAL_H
 #  include <signal.h>
 #endif // HAVE_SIGNAL_H
 
-#ifdef    HAVE_SYS_SIGNAL_H
-#  include <sys/signal.h>
-#endif // HAVE_SYS_SIGNAL_H
-
 #ifdef    HAVE_LIBGEN_H
 #  include <libgen.h>
 #endif // HAVE_LIBGEN_H
 }
 
 #include <iostream>
+#include <string>
 
 using std::cout;
 using std::endl;
+using std::string;
+
+#include "epist.hh"
+#include "process.hh"
+#include "../../src/XAtom.hh"
 
 bool _shutdown = false;
 char **_argv;
 char *_display_name = 0;
 Display *_display = 0;
+Window _root = None;
+XAtom *_xatom;
+
 
 #ifdef   HAVE_SIGACTION
 static void signalhandler(int sig)
@@ -63,10 +70,10 @@ static RETSIGTYPE signalhandler(int sig)
 {
   switch (sig) {
   case SIGSEGV:
-    cout << "Segmentation fault. Aborting and dumping core.\n";
+    cout << "epist: Segmentation fault. Aborting and dumping core.\n";
     abort();
   case SIGHUP:
-    cout << "Restarting on request.\n";
+    cout << "epist: Restarting on request.\n";
     execvp(_argv[0], _argv);
     execvp(basename(_argv[0]), _argv);
   }
@@ -79,9 +86,41 @@ static RETSIGTYPE signalhandler(int sig)
 }
 
 
-int main(int, char **argv) {
+void parseCommandLine(int argc, char **argv) {
   _argv = argv;
 
+  for (int i = 1; i < argc; ++i) {
+    if (string(argv[i]) == "-display") {
+      if (++i >= argc) {
+        cout << "error:: '-display' requires an argument\n";
+        exit(1);
+      }
+      _display_name = argv[i];
+
+      string dtmp = (string)"DISPLAY=" + _display_name;
+      if (putenv(const_cast<char*>(dtmp.c_str()))) {
+        cout << "warning: couldn't set environment variable 'DISPLAY'\n";
+        perror("putenv()");
+      }
+    }
+  }
+}
+
+  
+bool findSupportingWM() {
+  Window support_win;
+  if (! _xatom->getValue(_root, XAtom::net_supporting_wm_check, XAtom::window,
+                         support_win) || support_win == None)
+    return false;
+
+  string title;
+  _xatom->getValue(support_win, XAtom::net_wm_name, XAtom::utf8, title);
+  cout << "Found compatible window manager: " << title << endl;
+  return true;
+}
+
+
+int main(int argc, char **argv) {
 #ifdef    HAVE_SIGACTION
   struct sigaction action;
 
@@ -104,16 +143,37 @@ int main(int, char **argv) {
   signal(SIGHUP, (RETSIGTYPE (*)(int)) signalhandler);
 #endif // HAVE_SIGACTION
 
+  parseCommandLine(argc, argv);
+
   _display = XOpenDisplay(_display_name);
   if (! _display) {
     cout << "Connection to X server '" << _display_name << "' failed.\n";
     return 1;
   }
+  _root = RootWindow(_display, DefaultScreen(_display));
+  _xatom = new XAtom(_display);
+
+  XSelectInput(_display, _root, PropertyChangeMask);
 
+  // find a window manager supporting NETWM, waiting for it to load if we must
+  while (! (_shutdown || findSupportingWM()));
+  if (! _shutdown) {
+    updateClientList();
+    updateActiveWindow();
+  }
+  
   while (! _shutdown) {
-    usleep(500);
+    if (XPending(_display)) {
+      XEvent e;
+      XNextEvent(_display, &e);
+      processEvent(e);
+    } else {
+      usleep(300);
+    }
   }
 
+  delete _xatom;
   XCloseDisplay(_display);
   return 0;
 }
diff --git a/util/epist/epist.hh b/util/epist/epist.hh
new file mode 100644 (file)
index 0000000..2f5d739
--- /dev/null
@@ -0,0 +1,37 @@
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// epist.hh for Epistory - a key handler for NETWM/EWMH window managers.
+// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef   __epist_hh
+#define   __epist_hh
+
+extern "C" {
+#include <X11/Xlib.h>
+}
+
+class XAtom;
+
+extern bool _shutdown;
+extern Display *_display;
+extern Window _root;
+extern XAtom *_xatom;
+
+#endif // __epist_hh
diff --git a/util/epist/process.cc b/util/epist/process.cc
new file mode 100644 (file)
index 0000000..dab1f16
--- /dev/null
@@ -0,0 +1,112 @@
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// process.cc for Epistory - a key handler for NETWM/EWMH window managers.
+// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include "process.hh"
+#include "epist.hh"
+#include "window.hh"
+
+#ifdef    HAVE_CONFIG_H
+#  include "../../config.h"
+#endif // HAVE_CONFIG_H
+
+#include <iostream>
+
+using std::cout;
+using std::endl;
+
+#include "../../src/XAtom.hh"
+
+WindowList _clients;
+WindowList::iterator _active = _clients.end();
+
+void processEvent(const XEvent &e) {
+  switch (e.type) {
+  case PropertyNotify:
+    if (e.xproperty.atom == _xatom->getAtom(XAtom::net_active_window))
+      updateActiveWindow();
+    if (e.xproperty.atom == _xatom->getAtom(XAtom::net_client_list))
+      updateClientList();
+    break;
+  }
+}
+
+
+void updateClientList() {
+  WindowList::iterator insert_point = _active;
+  if (insert_point != _clients.end())
+    ++insert_point; // get to the item client the focused client
+  
+  // get the client list from the root window
+  Window *rootclients = 0;
+  unsigned long num = (unsigned) -1;
+  if (! _xatom->getValue(_root, XAtom::net_client_list, XAtom::window, num,
+                         &rootclients)) {
+    _clients.clear(); // no clients left
+    if (rootclients) delete [] rootclients;
+    return;
+  }
+  
+  WindowList::iterator it, end = _clients.end();
+  unsigned long i;
+  
+  // insert new clients after the active window
+  for (i = 0; i < num; ++i) {
+    for (it = _clients.begin(); it != end; ++it)
+      if (*it == rootclients[i])
+        break;
+    if (it == end) {  // didn't already exist
+      _clients.insert(insert_point, rootclients[i]);
+      cout << "Added window: " << rootclients[i] << endl;
+    }
+  }
+
+  // remove clients that no longer exist
+  for (it = _clients.begin(); it != end;) {
+    WindowList::iterator it2 = it++;
+    for (i = 0; i < num; ++i)
+      if (*it2 == rootclients[i])
+        break;
+    if (i == num)  { // no longer exists
+      _clients.erase(it2);
+      cout << "Removed window: " << it2->window() << endl;
+    }
+  }
+
+  if (rootclients) delete [] rootclients;
+}
+
+
+void updateActiveWindow() {
+  Window a = None;
+  _xatom->getValue(_root, XAtom::net_active_window, XAtom::window, a);
+  
+  WindowList::iterator it, end = _clients.end();
+  for (it = _clients.begin(); it != end; ++it) {
+    if (*it == a)
+      break;
+  }
+  _active = it;
+
+  cout << "Active window is now: ";
+  if (_active == _clients.end()) cout << "None\n";
+  else cout << _active->window() << endl;
+}
diff --git a/util/epist/process.hh b/util/epist/process.hh
new file mode 100644 (file)
index 0000000..e8fd369
--- /dev/null
@@ -0,0 +1,34 @@
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// process.hh for Epistory - a key handler for NETWM/EWMH window managers.
+// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef   __process_hh
+#define   __process_hh
+
+extern "C" {
+#include "X11/Xlib.h"
+}
+
+void processEvent(const XEvent &e);
+void updateClientList();
+void updateActiveWindow();
+
+#endif // __process_hh
diff --git a/util/epist/window.cc b/util/epist/window.cc
new file mode 100644 (file)
index 0000000..ebe458d
--- /dev/null
@@ -0,0 +1,37 @@
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// window.cc for Epistory - a key handler for NETWM/EWMH window managers.
+// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifdef    HAVE_CONFIG_H
+#  include "../../config.h"
+#endif // HAVE_CONFIG_H
+
+#include "window.hh"
+
+
+XWindow::XWindow(Window window) : _window(window) {
+}
+
+
+XWindow::~XWindow() {
+}
+
+
diff --git a/util/epist/window.hh b/util/epist/window.hh
new file mode 100644 (file)
index 0000000..01cb2a8
--- /dev/null
@@ -0,0 +1,60 @@
+// -*- mode: C++; indent-tabs-mode: nil; -*-
+// window.hh for Epistory - a key handler for NETWM/EWMH window managers.
+// Copyright (c) 2002 - 2002 Ben Jansens <ben at orodu.net>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef   __window_hh
+#define   __window_hh
+
+extern "C" {
+#include <X11/Xlib.h>
+}
+
+#include <list>
+
+class XWindow;
+
+typedef std::list<XWindow> WindowList;
+
+class XWindow {
+private:
+  Window _window;
+  unsigned int _desktop;
+  bool _shaded;
+  bool _iconic;
+  bool _max_vert;
+  bool _max_horz;
+
+public:
+  XWindow(Window window);
+  virtual ~XWindow();
+
+  inline Window window() const { return _window; }
+  inline unsigned int desktop() const { return _desktop; }
+  inline bool shaded() const { return _shaded; }
+  inline bool iconic() const { return _iconic; }
+  inline bool maxVert() const { return _max_vert; }
+  inline bool maxHorz() const { return _max_horz; }
+
+  bool operator == (const XWindow &w) const { return w._window == _window; }
+  bool operator == (const Window &w) const { return w == _window; }
+};
+
+#endif // __window_hh