/* * xutils.c - a Python wrapper for common Xlib ops * * Copyright (C) 2002 Red Hat, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Author(s): Michael Fulbright */ #include #include #include #include static PyObject * setRootResource(PyObject * s, PyObject * args); static PyObject * getXatom(PyObject *s, PyObject *args); static PyMethodDef xutilsMethods[] = { { "setRootResource", setRootResource, 1, NULL }, { "getXatom", getXatom, 1, NULL }, { NULL, NULL, 0, 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); } 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, (unsigned char *)rstring, strlen(rstring)); free(rstring); freeResources(resources); closeDisplay(dpy); Py_INCREF(Py_None); return Py_None; } /* this assumes you've already imported gtk and thus have a display */ static PyObject * getXatom(PyObject *s, PyObject *args) { char *atomname; Atom theatom; if (!PyArg_ParseTuple(args, "s", &atomname)) { return NULL; } theatom = gdk_x11_get_xatom_by_name(atomname); if (XGetSelectionOwner (GDK_DISPLAY(), theatom) != None) { Py_INCREF(Py_True); return Py_True; } Py_INCREF(Py_False); return Py_False; } void initxutils () { PyObject * d; d = Py_InitModule ("xutils", xutilsMethods); }