summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Frank Erikson <kristian@kristian-desktop.(none)>2009-01-10 12:49:43 +1300
committerKristian Frank Erikson <kristian@kristian-desktop.(none)>2009-01-10 12:49:43 +1300
commit8bfbe01f25a1c4711a240271179f91dcb33c4368 (patch)
tree926ff8d0e936cefa5157878fae0bfdf2dd9ef1d1
parent62142fe9fe3bf0acf9fe6a401548e848e4fa4193 (diff)
downloadpython-compiz-manager-8bfbe01f25a1c4711a240271179f91dcb33c4368.tar.gz
python-compiz-manager-8bfbe01f25a1c4711a240271179f91dcb33c4368.tar.bz2
Adding getting the windowlist as a C extension. Still not complete though but compiles and runs
-rwxr-xr-xCompizManager.py12
-rw-r--r--CompizPyWindowList-setup.py19
-rw-r--r--CompizPyWindowList.c309
3 files changed, 333 insertions, 7 deletions
diff --git a/CompizManager.py b/CompizManager.py
index 0e504ee..13ddf20 100755
--- a/CompizManager.py
+++ b/CompizManager.py
@@ -202,7 +202,7 @@ class CompizManager(object):
# Go find out if mapped from xwininfo
xwininfo = os.popen("xwininfo -id " + str(windowId) + " -stats")
xwininfo = xwininfo.read()
- viewableCheck = xwininfo.find('IsViewable') # Check if we can see it.. Not not point otherwise
+ viewableCheck = xwininfo.find('IsViewable') # Check if we can see it.. Not much point otherwise
colormapCheck = xwininfo.find('Colormap: 0x0 (not installed)')
stateCheck = xwininfo.find('State: yes')
if viewableCheck != (-1) and colormapCheck == (-1) and stateCheck == (-1):
@@ -212,14 +212,12 @@ class CompizManager(object):
windowName = window[firstSpace+2:secondQuote] # Get the window name
windowList.addWindow(windowName, windowId)
print windowList.windowInfo(windowName)
- return window
class WindowList(object):
""" Attributes for each window, including info "xwininfo" returns as well as
Compiz Fusion specific details like which viewport or face of the cube, etc. """
# Next thing to do - start adding all the missing attributes
-
def __init__(self):
self.windows = {}
@@ -227,9 +225,9 @@ class WindowList(object):
self.windows[title] = windowId
def windowInfo(self, title): # Temp func for printing windows - dev
- self.windows[title]
return 'Window title: ' + title + ' id: ' + str(self.windows[title])
+
def AllToScreen():
""" Prints all Plugins with their actions and options to the screen """
@@ -257,12 +255,12 @@ if __name__ == '__main__':
manager = CompizManager()
# from CompizTests import *
- # Pre test setup
+ # Pre test setup
# preTestSetup()
- # Run the tests
+ # Run the tests
# suite = unittest.TestLoader().loadTestsFromTestCase(TestCompizManagerClasses)
# unittest.TextTestRunner(verbosity=2).run(suite)
- # Run the test cleanup
+ # Run the test cleanup
# postTestCleanup()
# Print a file with actions and options listed in it
diff --git a/CompizPyWindowList-setup.py b/CompizPyWindowList-setup.py
new file mode 100644
index 0000000..c8811ce
--- /dev/null
+++ b/CompizPyWindowList-setup.py
@@ -0,0 +1,19 @@
+# To rebuild this module the command is: python second-setup.py build_ext -i
+
+from distutils.core import setup, Extension
+
+module = Extension("CompizPyWindowList",
+ libraries = ['glib-2.0','X11'],
+ include_dirs = ['/usr/local/include/glib-2.0','/usr/local/lib/glib-2.0/include','/usr/include'],
+ sources = ["CompizPyWindowList.c"])
+
+setup(name="CompizPyWindowList",
+ version="1.0",
+ description="Lists active windows in X11",
+ author="Kristian Frank Erikson",
+ author_email="kristian@erikson.dk",
+ url="http://www.eyemagnet.com",
+ long_description='''
+This C extension queries X11 for information on active windows.
+ ''',
+ ext_modules=[module])
diff --git a/CompizPyWindowList.c b/CompizPyWindowList.c
new file mode 100644
index 0000000..a8e231d
--- /dev/null
+++ b/CompizPyWindowList.c
@@ -0,0 +1,309 @@
+#include <Python.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/cursorfont.h>
+#include <X11/Xmu/WinUtil.h>
+#include <glib.h>
+
+#define MAX_PROPERTY_VALUE_LEN 4096
+#define p_verbose(...) if (options.verbose) { \
+ fprintf(stderr, __VA_ARGS__); \
+}
+
+static char CompizPyWindowList_doc[] =
+"This module is just a simple example. It provides one function: func().";
+
+static Window *get_client_list (Display *disp, unsigned long *size);
+static int list_windows (Display *disp);
+static gchar *get_window_title (Display *disp, Window win);
+static gchar *get_window_class (Display *disp, Window win);
+static gchar *get_property (Display *disp, Window win,
+ Atom xa_prop_type, gchar *prop_name, unsigned long *size);
+
+static struct {
+ int verbose;
+ int force_utf8;
+ int show_class;
+ int show_pid;
+ int show_geometry;
+ int match_by_id;
+ int match_by_cls;
+ int full_window_title_match;
+ int wa_desktop_titles_invalid_utf8;
+ char *param_window;
+ char *param;
+} options;
+
+static gboolean envir_utf8;
+
+static PyObject*
+CompizPyWindowList_func(PyObject *self, PyObject *args)
+{
+ int ret = 1;
+
+ Display *disp;
+
+ if (! (disp = XOpenDisplay(NULL))) {
+ fputs("Cannot open display.\n", stderr);
+ return NULL;
+ }
+
+ // Should now have disp
+ ret = list_windows(disp);
+
+ // All done so close display
+ XCloseDisplay(disp);
+
+ // Here we should return a list
+ return ret;
+}
+
+static char CompizPyWindowList_func_doc[] =
+ "func(a, b)\n\
+ \n\
+ Return the sum of a and b.";
+
+static PyMethodDef CompizPyWindowList_methods[] = {
+ {"func", CompizPyWindowList_func, METH_VARARGS, CompizPyWindowList_func_doc},
+ {NULL, NULL}
+};
+
+PyMODINIT_FUNC
+initCompizPyWindowList(void)
+{
+ Py_InitModule3("CompizPyWindowList", CompizPyWindowList_methods, CompizPyWindowList_doc);
+}
+
+static gchar *get_output_str (gchar *str, gboolean is_utf8) {
+ gchar *out;
+
+ if (str == NULL) {
+ return NULL;
+ }
+
+ if (envir_utf8) {
+ if (is_utf8) {
+ out = g_strdup(str);
+ }
+ else {
+ if (! (out = g_locale_to_utf8(str, -1, NULL, NULL, NULL))) {
+ p_verbose("Cannot convert string from locale charset to UTF-8.\n");
+ out = g_strdup(str);
+ }
+ }
+ }
+ else {
+ if (is_utf8) {
+ if (! (out = g_locale_from_utf8(str, -1, NULL, NULL, NULL))) {
+ p_verbose("Cannot convert string from UTF-8 to locale charset.\n");
+ out = g_strdup(str);
+ }
+ }
+ else {
+ out = g_strdup(str);
+ }
+ }
+
+ return out;
+}
+
+static Window *get_client_list (Display *disp, unsigned long *size) {
+ Window *client_list;
+
+ if ((client_list = (Window *)get_property(disp, DefaultRootWindow(disp),
+ XA_WINDOW, "_NET_CLIENT_LIST", size)) == NULL) {
+ if ((client_list = (Window *)get_property(disp, DefaultRootWindow(disp),
+ XA_CARDINAL, "_WIN_CLIENT_LIST", size)) == NULL) {
+ fputs("Cannot get client list properties. \n"
+ "(_NET_CLIENT_LIST or _WIN_CLIENT_LIST)"
+ "\n", stderr);
+ return NULL;
+ }
+ }
+
+ return client_list;
+}
+
+static int list_windows (Display *disp) {
+ Window *client_list;
+ unsigned long client_list_size;
+ int i;
+ int max_client_machine_len = 0;
+
+ if ((client_list = get_client_list(disp, &client_list_size)) == NULL) {
+ return EXIT_FAILURE;
+ }
+
+ // find the longest client_machine name
+ for (i = 0; i < client_list_size / sizeof(Window); i++) {
+ gchar *client_machine;
+ if ((client_machine = get_property(disp, client_list[i],
+ XA_STRING, "WM_CLIENT_MACHINE", NULL))) {
+ max_client_machine_len = strlen(client_machine);
+ }
+ g_free(client_machine);
+ }
+
+ // print the list
+ for (i = 0; i < client_list_size / sizeof(Window); i++) {
+ gchar *title_utf8 = get_window_title(disp, client_list[i]); // UTF8
+ gchar *title_out = get_output_str(title_utf8, TRUE);
+ gchar *client_machine;
+ gchar *class_out = get_window_class(disp, client_list[i]); // UTF8
+ unsigned long *pid;
+ unsigned long *desktop;
+ int x, y, junkx, junky;
+ unsigned int wwidth, wheight, bw, depth;
+ Window junkroot;
+
+ // desktop ID
+ if ((desktop = (unsigned long *)get_property(disp, client_list[i],
+ XA_CARDINAL, "_NET_WM_DESKTOP", NULL)) == NULL) {
+ desktop = (unsigned long *)get_property(disp, client_list[i],
+ XA_CARDINAL, "_WIN_WORKSPACE", NULL);
+ }
+
+ // client machine
+ client_machine = get_property(disp, client_list[i],
+ XA_STRING, "WM_CLIENT_MACHINE", NULL);
+
+ // pid
+ pid = (unsigned long *)get_property(disp, client_list[i],
+ XA_CARDINAL, "_NET_WM_PID", NULL);
+
+ // geometry
+ XGetGeometry (disp, client_list[i], &junkroot, &junkx, &junky,
+ &wwidth, &wheight, &bw, &depth);
+ XTranslateCoordinates (disp, client_list[i], junkroot, junkx, junky,
+ &x, &y, &junkroot);
+
+ // special desktop ID -1 means "all desktops", so we
+ // have to convert the desktop value to signed long
+ printf("0x%.8lx %2ld", client_list[i],
+ desktop ? (signed long)*desktop : 0);
+ if (options.show_pid) {
+ printf(" %-6lu", pid ? *pid : 0);
+ }
+ if (options.show_geometry) {
+ printf(" %-4d %-4d %-4d %-4d", x, y, wwidth, wheight);
+ }
+ if (options.show_class) {
+ printf(" %-20s ", class_out ? class_out : "N/A");
+ }
+
+ printf(" %*s %s\n",
+ max_client_machine_len,
+ client_machine ? client_machine : "N/A",
+ title_out ? title_out : "N/A"
+ );
+ g_free(title_utf8);
+ g_free(title_out);
+ g_free(desktop);
+ g_free(client_machine);
+ g_free(class_out);
+ g_free(pid);
+ }
+ g_free(client_list);
+
+ return EXIT_SUCCESS;
+}
+
+static gchar *get_window_class (Display *disp, Window win) {
+ gchar *class_utf8;
+ gchar *wm_class;
+ unsigned long size;
+
+ wm_class = get_property(disp, win, XA_STRING, "WM_CLASS", &size);
+ if (wm_class) {
+ gchar *p_0 = strchr(wm_class, '\0');
+ if (wm_class + size - 1 > p_0) {
+ *(p_0) = '.';
+ }
+ class_utf8 = g_locale_to_utf8(wm_class, -1, NULL, NULL, NULL);
+ }
+ else {
+ class_utf8 = NULL;
+ }
+
+ g_free(wm_class);
+
+ return class_utf8;
+}
+
+static gchar *get_window_title (Display *disp, Window win) {
+ gchar *title_utf8;
+ gchar *wm_name;
+ gchar *net_wm_name;
+
+ wm_name = get_property(disp, win, XA_STRING, "WM_NAME", NULL);
+ net_wm_name = get_property(disp, win,
+ XInternAtom(disp, "UTF8_STRING", False), "_NET_WM_NAME", NULL);
+
+ if (net_wm_name) {
+ title_utf8 = g_strdup(net_wm_name);
+ }
+ else {
+ if (wm_name) {
+ title_utf8 = g_locale_to_utf8(wm_name, -1, NULL, NULL, NULL);
+ }
+ else {
+ title_utf8 = NULL;
+ }
+ }
+
+ g_free(wm_name);
+ g_free(net_wm_name);
+
+ return title_utf8;
+}
+
+
+static gchar *get_property (Display *disp, Window win,
+ Atom xa_prop_type, gchar *prop_name, unsigned long *size) {
+ Atom xa_prop_name;
+ Atom xa_ret_type;
+ int ret_format;
+ unsigned long ret_nitems;
+ unsigned long ret_bytes_after;
+ unsigned long tmp_size;
+ unsigned char *ret_prop;
+ gchar *ret;
+
+ xa_prop_name = XInternAtom(disp, prop_name, False);
+
+ /* MAX_PROPERTY_VALUE_LEN / 4 explanation (XGetWindowProperty manpage):
+ *
+ * long_length = Specifies the length in 32-bit multiples of the
+ * data to be retrieved.
+ */
+ if (XGetWindowProperty(disp, win, xa_prop_name, 0, MAX_PROPERTY_VALUE_LEN / 4, False,
+ xa_prop_type, &xa_ret_type, &ret_format,
+ &ret_nitems, &ret_bytes_after, &ret_prop) != Success) {
+ p_verbose("Cannot get %s property.\n", prop_name);
+ return NULL;
+ }
+
+ if (xa_ret_type != xa_prop_type) {
+ p_verbose("Invalid type of %s property.\n", prop_name);
+ XFree(ret_prop);
+ return NULL;
+ }
+
+ /* null terminate the result to make string handling easier */
+ tmp_size = (ret_format / 8) * ret_nitems;
+ ret = g_malloc(tmp_size + 1);
+ memcpy(ret, ret_prop, tmp_size);
+ ret[tmp_size] = '\0';
+
+ if (size) {
+ *size = tmp_size;
+ }
+
+ XFree(ret_prop);
+ return ret;
+}