/* * xutils.c - a Python wrapper for common Xlib ops * * Michael Fulbright * * Copyright 2002 Red Hat, Inc. * * This software may be freely redistributed under the terms of the GNU * public license. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include static PyObject * getRootResources(PyObject *s, PyObject *args); static PyObject * setRootResource(PyObject * s, PyObject * args); static PyObject * screenHeight (PyObject * s, PyObject * args); static PyObject * screenWidth (PyObject * s, PyObject * args); static PyMethodDef xutilsMethods[] = { { "getRootResources", getRootResources, 1 }, { "setRootResource", setRootResource, 1 }, { "screenHeight", screenHeight, 1 }, { "screenWidth", screenWidth, 1 }, { NULL, NULL } }; typedef struct _Resource { char *key, *val; } Resource; static int openDisplay(Display **dpy, Window *root) { int scrn; *dpy=XOpenDisplay(""); if (!*dpy) return -1; scrn=DefaultScreen(*dpy); *root = RootWindow(*dpy, scrn); return 0; } static void closeDisplay(Display *dpy) { XCloseDisplay(dpy); } static Resource ** getCurrentResources(Display *dpy) { char *resource_string, *p; Resource **rc; int nrec; /* read through current resources, split on newlines */ resource_string = XResourceManagerString(dpy); if (!resource_string) return NULL; rc = (Resource **)malloc(sizeof(Resource *)); p = resource_string; nrec = 0; while (1) { char *eol; char *sep; int nleft; /* find next newline, defines end of current record */ eol = strchr(p, '\n'); if (!eol) break; /* find colon separating key and value */ /* if no colon skip this record */ sep = strchr(p, ':'); if (sep) { int len; Resource *newrec; newrec = (Resource *) malloc(sizeof(Resource)); len = sep - p + 1; newrec->key = (char *) malloc(len*sizeof(char)); memcpy(newrec->key, p, len); newrec->key[len-1] = '\0'; len = eol - sep; newrec->val = (char *) malloc(len*sizeof(char)); memcpy(newrec->val, sep+1, len); newrec->val[len-1] = '\0'; rc = (Resource **) realloc(rc, (nrec+1) * sizeof(Resource *)); rc[nrec] = newrec; nrec = nrec + 1; } nleft = strlen(resource_string) - (eol-resource_string); if (nleft <= 0) break; p = eol + 1; } if (nrec > 0) { rc = (Resource **) realloc(rc, (nrec+1) * sizeof(Resource *)); rc[nrec] = NULL; } else { rc = NULL; } return rc; } static void freeResources(Resource **rc) { int idx; if (!rc) return; idx = 0; while (rc[idx]) { free(rc[idx]->key); free(rc[idx]->val); free(rc[idx]); idx++; } free(rc); } /* return dictionary of resources on root display */ PyObject * getRootResources(PyObject *s, PyObject *args) { Display *dpy; Window root; Resource **resources, **p; PyObject *rc; if (openDisplay(&dpy, &root) < 0) { PyErr_SetString(PyExc_SystemError, "Could not open display."); return NULL; } resources = getCurrentResources(dpy); if (!resources) { closeDisplay(dpy); Py_INCREF(Py_None); return Py_None; } rc = PyDict_New(); p = resources; while (*p) { PyDict_SetItemString(rc, (*p)->key, Py_BuildValue("s", (*p)->val)); p++; } freeResources(resources); closeDisplay(dpy); return rc; } static PyObject * setRootResource(PyObject *s, PyObject *args) { Display *dpy; Window root; Resource **resources, **p; char *key, *val, *rstring; int fnd, nrec; if (!PyArg_ParseTuple(args, "ss", &key, &val)) { return NULL; } if (openDisplay(&dpy, &root) < 0) { PyErr_SetString(PyExc_SystemError, "Could not open display."); return NULL; } resources = getCurrentResources(dpy); fnd = 0; nrec = 0; if (resources) { p = resources; while (*p) { if (!strcmp(key, (*p)->key)) { free((*p)->val); (*p)->val = strdup(val); fnd = 1; break; } p++; } p = resources; while (*p) { nrec++; p++; } } if (!fnd) { Resource *newrec; newrec = (Resource *) malloc(sizeof(Resource)); newrec->key = strdup(key); newrec->val = strdup(val); if (nrec > 0) resources = (Resource **) realloc(resources, (nrec+2) * sizeof(Resource *)); else resources = (Resource **) malloc(2*sizeof(Resource *)); resources[nrec] = newrec; resources[nrec+1] = NULL; } rstring = NULL; p = resources; while (*p) { int len; char *tmpstr; len = strlen((*p)->key) + strlen((*p)->val) + 3; tmpstr = (char *) malloc(len*sizeof(char)); strcpy(tmpstr, (*p)->key); strcat(tmpstr, ":"); strcat(tmpstr, (*p)->val); strcat(tmpstr, "\n"); if (rstring) { rstring = (char *)realloc(rstring, (strlen(rstring)+len+1)*sizeof(char)); strcat(rstring, tmpstr); } else { rstring = tmpstr; } p++; } XChangeProperty(dpy, root, XA_RESOURCE_MANAGER, XA_STRING, 8, PropModeReplace, rstring, strlen(rstring)); free(rstring); freeResources(resources); closeDisplay(dpy); Py_INCREF(Py_None); return Py_None; } static PyObject * screenHeight(PyObject *s, PyObject *args) { Display *dpy; Window root; int scrn; PyObject *rc; if (openDisplay(&dpy, &root) < 0) { PyErr_SetString(PyExc_SystemError, "Could not open display."); return NULL; } scrn=DefaultScreen(dpy); rc = Py_BuildValue("i", DisplayHeight(dpy, scrn)); closeDisplay(dpy); return rc; } static PyObject * screenWidth(PyObject *s, PyObject *args) { Display *dpy; Window root; int scrn; PyObject *rc; if (openDisplay(&dpy, &root) < 0) { PyErr_SetString(PyExc_SystemError, "Could not open display."); return NULL; } scrn=DefaultScreen(dpy); rc = Py_BuildValue("i", DisplayWidth(dpy, scrn)); closeDisplay(dpy); return rc; } void initxutils () { PyObject * d; d = Py_InitModule ("xutils", xutilsMethods); }