]> Dogcows Code - chaz/openbox/blobdiff - openbox/openboxwrap.c
merge the C branch into HEAD
[chaz/openbox] / openbox / openboxwrap.c
diff --git a/openbox/openboxwrap.c b/openbox/openboxwrap.c
new file mode 100644 (file)
index 0000000..c73e725
--- /dev/null
@@ -0,0 +1,502 @@
+#include "openboxwrap.h"
+#include "openbox.h"
+#include "screen.h"
+#include "prop.h"
+
+/***************************************************************************
+   Define the type 'OpenboxWrap'
+
+ ***************************************************************************/
+
+#define IS_OWRAP(v)  ((v)->ob_type == &OpenboxWrapType)
+#define CHECK_OWRAP(self, funcname) { \
+    if (!IS_OWRAP(self)) { \
+        PyErr_SetString(PyExc_TypeError, \
+                       "descriptor '" funcname "' requires a 'Openbox' " \
+                       "object"); \
+       return NULL; \
+    } \
+}
+
+
+staticforward PyTypeObject OpenboxWrapType;
+
+/***************************************************************************
+   Attribute methods
+ ***************************************************************************/
+
+static PyObject *owrap_shutdown(OpenboxWrap *self, PyObject *args)
+{
+    CHECK_OWRAP(self, "shutdown");
+    if (!PyArg_ParseTuple(args, ":shutdown"))
+       return NULL;
+    ob_shutdown = TRUE;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *owrap_restart(OpenboxWrap *self, PyObject *args)
+{
+    char *path = NULL;
+
+    CHECK_OWRAP(self, "restart");
+    if (!PyArg_ParseTuple(args, "|s:restart", &path))
+       return NULL;
+    ob_shutdown = ob_restart = TRUE;
+    ob_restart_path = path;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *owrap_state(OpenboxWrap *self, PyObject *args)
+{
+    CHECK_OWRAP(self, "state");
+    if (!PyArg_ParseTuple(args, ":state"))
+       return NULL;
+    return PyInt_FromLong(ob_state);
+}
+
+static PyObject *owrap_desktop(OpenboxWrap *self, PyObject *args)
+{
+    CHECK_OWRAP(self, "desktop");
+    if (!PyArg_ParseTuple(args, ":desktop"))
+       return NULL;
+    return PyInt_FromLong(screen_desktop);
+}
+
+static PyObject *owrap_setDesktop(OpenboxWrap *self, PyObject *args)
+{
+    int desktop;
+
+    CHECK_OWRAP(self, "setDesktop");
+    if (!PyArg_ParseTuple(args, "i:setDesktop", &desktop))
+       return NULL;
+    if (desktop < 0 || (unsigned)desktop >= screen_num_desktops) {
+       PyErr_SetString(PyExc_ValueError, "invalid desktop");
+       return NULL;
+    }
+    screen_set_desktop(desktop);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *owrap_setNextDesktop(OpenboxWrap *self, PyObject *args)
+{
+    gboolean wrap = TRUE;
+    guint d;
+
+    CHECK_OWRAP(self, "setNextDesktop");
+    if (!PyArg_ParseTuple(args, "|i:setNextDesktop", &wrap))
+       return NULL;
+    d = screen_desktop + 1;
+    if (d >= screen_num_desktops && wrap)
+        d = 0;
+    if (d < screen_num_desktops)
+        screen_set_desktop(d);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *owrap_setPreviousDesktop(OpenboxWrap *self, PyObject *args)
+{
+    gboolean wrap = TRUE;
+    guint d;
+
+    CHECK_OWRAP(self, "setPreviousDesktop");
+    if (!PyArg_ParseTuple(args, "|i:setPreviousDesktop", &wrap))
+       return NULL;
+    d = screen_desktop - 1;
+    if (d >= screen_num_desktops && wrap)
+        d = screen_num_desktops - 1;
+    if (d < screen_num_desktops)
+        screen_set_desktop(d);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *owrap_numDesktops(OpenboxWrap *self, PyObject *args)
+{
+    CHECK_OWRAP(self, "numDesktops");
+    if (!PyArg_ParseTuple(args, ":numDesktops"))
+       return NULL;
+    return PyInt_FromLong(screen_num_desktops);
+}
+
+static PyObject *owrap_setNumDesktops(OpenboxWrap *self, PyObject *args)
+{
+    int desktops;
+
+    CHECK_OWRAP(self, "setNumDesktops");
+    if (!PyArg_ParseTuple(args, "i:setNumDesktops", &desktops))
+       return NULL;
+    if (desktops <= 0) {
+       PyErr_SetString(PyExc_ValueError, "invalid number of desktops");
+       return NULL;
+    }
+    screen_set_num_desktops(desktops);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *owrap_desktopNames(OpenboxWrap *self, PyObject *args)
+{
+    PyObject *tuple;
+    int i, s;
+
+    CHECK_OWRAP(self, "desktopNames");
+    if (!PyArg_ParseTuple(args, ":desktopNames"))
+       return NULL;
+    s = screen_desktop_names->len;
+    tuple = PyTuple_New(s);
+    for (i = 0; i < s; ++i)
+       PyTuple_SET_ITEM(tuple, i, g_ptr_array_index(screen_desktop_names, i));
+    return tuple;
+}
+
+static PyObject *owrap_setDesktopNames(OpenboxWrap *self, PyObject *args)
+{
+    PyObject *seq;
+    int i, s;
+    GPtrArray *data;
+
+    CHECK_OWRAP(self, "setDesktopNames");
+    if (!PyArg_ParseTuple(args, "O:setDesktopNames", &seq))
+       return NULL;
+    if (!PySequence_Check(seq))
+       PyErr_SetString(PyExc_TypeError, "expected a sequence");
+    return NULL;
+
+    s = PySequence_Size(seq);
+    for (i = 0; i < s; ++i) {
+       PyObject *item;
+       gboolean check;
+       item = PySequence_GetItem(seq, i); /* new */
+       check = PyString_Check(item);
+       Py_DECREF(item);
+       if (!check) {
+           PyErr_SetString(PyExc_TypeError, "expected a sequence of strings");
+           return NULL;
+       }
+    }
+
+    data = g_ptr_array_sized_new(s);
+    for (i = 0; i < s; ++i) {
+       PyObject *item;
+       item = PySequence_GetItem(seq, i); /* new */
+       g_ptr_array_index(data, i) = PyString_AsString(item); /* borrowed */
+       Py_DECREF(item);
+    }
+
+    PROP_SETSA(ob_root, net_desktop_names, utf8, data);
+    g_ptr_array_free(data, TRUE);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *owrap_showingDesktop(OpenboxWrap *self, PyObject *args)
+{
+    CHECK_OWRAP(self, "showingDesktop");
+    if (!PyArg_ParseTuple(args, ":showingDesktop"))
+       return NULL;
+    return PyInt_FromLong(!!screen_showing_desktop);
+}
+
+static PyObject *owrap_setShowingDesktop(OpenboxWrap *self, PyObject *args)
+{
+    int show;
+
+    CHECK_OWRAP(self, "setShowingDesktop");
+    if (!PyArg_ParseTuple(args, "i:setShowingDesktop", &show))
+       return NULL;
+    screen_show_desktop(show);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *owrap_screenArea(OpenboxWrap *self, PyObject *args)
+{
+    int desktop;
+    Rect *area;
+    PyObject *tuple;
+
+    CHECK_OWRAP(self, "screenArea");
+    if (!PyArg_ParseTuple(args, "i:screenArea", &desktop))
+       return NULL;
+
+    area = screen_area(desktop);
+    if (area == NULL) {
+       PyErr_SetString(PyExc_ValueError, "invalid desktop");
+       return NULL;
+    }
+
+    tuple = PyTuple_New(4);
+    PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(area->x));
+    PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(area->y));
+    PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(area->width));
+    PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(area->height));
+    return tuple;
+}
+
+static PyObject *owrap_screenStrut(OpenboxWrap *self, PyObject *args)
+{
+    int desktop;
+    Strut *strut;
+    PyObject *tuple;
+
+    CHECK_OWRAP(self, "screenStrut");
+    if (!PyArg_ParseTuple(args, "i:screenStrut", &desktop))
+       return NULL;
+
+    strut = screen_strut(desktop);
+    if (strut == NULL) {
+       PyErr_SetString(PyExc_ValueError, "invalid desktop");
+       return NULL;
+    }
+
+    tuple = PyTuple_New(4);
+    PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(strut->left));
+    PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(strut->top));
+    PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(strut->right));
+    PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(strut->bottom));
+    return tuple;
+}
+
+static PyObject *owrap_physicalSize(OpenboxWrap *self, PyObject *args)
+{
+    PyObject *tuple;
+
+    CHECK_OWRAP(self, "physicalSize");
+    if (!PyArg_ParseTuple(args, ":physicalSize"))
+       return NULL;
+
+    tuple = PyTuple_New(2);
+    PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(screen_physical_size.width));
+    PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(screen_physical_size.height));
+    return tuple;
+}
+
+static PyObject *owrap_screenNumber(OpenboxWrap *self, PyObject *args)
+{
+    CHECK_OWRAP(self, "screenNumber");
+    if (!PyArg_ParseTuple(args, ":screenNumber"))
+       return NULL;
+    return PyInt_FromLong(ob_screen);
+}
+
+static PyObject *owrap_rootWindow(OpenboxWrap *self, PyObject *args)
+{
+    CHECK_OWRAP(self, "rootWindow");
+    if (!PyArg_ParseTuple(args, ":rootWindow"))
+       return NULL;
+    return PyInt_FromLong(ob_root);
+}
+
+static PyObject *owrap_clientList(OpenboxWrap *self, PyObject *args)
+{
+    CHECK_OWRAP(self, "clientList");
+    if (!PyArg_ParseTuple(args, ":clientList"))
+       return NULL;
+    Py_INCREF(self->client_list);
+    return self->client_list;
+}
+
+#define METH(n, d) {#n, (PyCFunction)owrap_##n, METH_VARARGS, #d}
+
+static PyMethodDef OpenboxWrapMethods[] = {
+    METH(shutdown,
+        "Causes Openbox to shutdown and exit."),
+    METH(restart,
+        "Causes Openbox to shutdown and restart. If path is specified, "
+        "Openbox will shutdown and attempt to run the specified executable "
+        "instead of restarting itself. If that fails, however, it will "
+        "restart itself."),
+    METH(state,
+        "Returns Openbox's current state, this will be one of the State "
+        "constants."),
+    METH(desktop,
+        "Returns the number of the currently visible desktop. This will be "
+        "in the range of [0, numDesktops())."),
+    METH(setDesktop,
+        "Sets the specified desktop as the visible desktop."),
+    METH(setNextDesktop,
+         "Sets the visible desktop to the next desktop, optionally wrapping "
+         "around when reaching the last."),
+    METH(setPreviousDesktop,
+         "Sets the visible desktop to the previous desktop, optionally "
+         "wrapping around when reaching the first."),
+    METH(numDesktops,
+        "Returns the number of desktops available."),
+    METH(desktopNames,
+        "Returns a tuple of names, containing a name for each desktop. The "
+        "tuple may have a length greater than numDesktops() if more names "
+        "have been specified."),
+    METH(setDesktopNames,
+        "Sets the names for the desktops."),
+    METH(showingDesktop,
+        "Returns True or False, depicting if Openbox is in 'showing the "
+        "desktop' mode. In 'showing the desktop' mode, all normal clients "
+        "are hidden and the desktop is given focus if possible."),
+    METH(setShowingDesktop,
+        "Enters or leaves 'showing the desktop' mode. See showingDesktop() "
+        "for a description of this mode."),
+    METH(screenArea,
+        "Returns the on-screen available area. This is the area not reserved "
+        "by applications' struts. Windows should be placed within this area, "
+        "not within the physicalSize()."),
+    METH(screenStrut,
+        "Returns the combined strut which has been reserved by all "
+        "applications on the desktops."),
+    METH(physicalSize,
+        "Returns the physical size of the display device (in pixels)."),
+    METH(screenNumber,
+        "Returns the number of the screen on which Openbox is running."),
+    METH(rootWindow,
+        "Return the window id of the root window."),
+    METH(clientList,
+        "Returns a all clients currently being managed by Openbox. This list "
+        "is updated as clients are managed and closed/destroyed/released."),
+    { NULL, NULL, 0, NULL }
+};
+
+/***************************************************************************
+   Type methods/struct
+ ***************************************************************************/
+
+/*static PyObject *owrap_getattr(OpenboxWrap *self, char *name)
+{
+    CHECK_OWRAP(self, "getattr");
+    return Py_FindMethod(OpenboxWrapAttributeMethods, (PyObject*)self, name);
+}*/
+
+static void owrap_dealloc(OpenboxWrap *self)
+{
+    PyObject_Del((PyObject*) self);
+}
+
+static PyTypeObject OpenboxWrapType = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "Openbox",
+    sizeof(OpenboxWrap),
+    0,
+    (destructor) owrap_dealloc,     /*tp_dealloc*/
+    0,                              /*tp_print*/
+    0,                              /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+};
+
+/***************************************************************************
+   Define the type 'OpenboxState'
+
+ ***************************************************************************/
+
+#define IS_OSTATE(v)  ((v)->ob_type == &OpenboxStateType)
+#define CHECK_OSTATE(self, funcname) { \
+    if (!IS_OSTATE(self)) { \
+        PyErr_SetString(PyExc_TypeError, \
+                       "descriptor '" funcname "' requires a 'State' " \
+                       "object"); \
+       return NULL; \
+    } \
+}
+
+staticforward PyTypeObject OpenboxStateType;
+
+typedef struct OpenboxState {
+    PyObject_HEAD
+} OpenboxState;
+
+static void ostate_dealloc(PyObject *self)
+{
+    PyObject_Del(self);
+}
+
+static PyObject *ostate_getattr(OpenboxState *self, char *name)
+{
+    struct S { char *name; int val; };
+    struct S s[] = {
+       { "Starting", State_Starting },
+       { "Running", State_Running },
+       { "Exiting", State_Exiting },
+       { NULL, 0 } };
+    int i;
+
+    CHECK_OSTATE(self, "__getattr__");
+
+    for (i = 0; s[i].name != NULL; ++i)
+       if (!strcmp(s[i].name, name))
+           return PyInt_FromLong(s[i].val);
+    PyErr_SetString(PyExc_AttributeError, "invalid attribute");
+    return NULL;
+}
+
+static PyTypeObject OpenboxStateType = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "State",
+    sizeof(OpenboxState),
+    0,
+    (destructor) ostate_dealloc,    /*tp_dealloc*/
+    0,                              /*tp_print*/
+    (getattrfunc) ostate_getattr,   /*tp_getattr*/
+    0,                              /*tp_setattr*/
+    0,                              /*tp_compare*/
+    0,                              /*tp_repr*/
+    0,                              /*tp_as_number*/
+    0,                              /*tp_as_sequence*/
+    0,                              /*tp_as_mapping*/
+    0,                              /*tp_hash */
+};
+
+/***************************************************************************
+   External methods
+ ***************************************************************************/
+
+void openboxwrap_startup()
+{
+    PyObject *ob, *obdict, *state;
+
+    OpenboxWrapType.ob_type = &PyType_Type;
+    OpenboxWrapType.tp_methods = OpenboxWrapMethods;
+    PyType_Ready(&OpenboxWrapType);
+
+    /* get the ob module/dict */
+    ob = PyImport_ImportModule("ob"); /* new */
+    g_assert(ob != NULL);
+    obdict = PyModule_GetDict(ob); /* borrowed */
+    g_assert(obdict != NULL);
+
+    /* add an Openbox instance to the ob module */
+    openboxwrap_obj = PyObject_New(OpenboxWrap, &OpenboxWrapType);
+    openboxwrap_obj->client_list = PyList_New(0);
+
+    PyDict_SetItemString(obdict, "Openbox", (PyObject*) openboxwrap_obj);
+
+    /* add an instance of OpenboxState */
+    state = (PyObject*) PyObject_New(OpenboxState, &OpenboxStateType);
+    PyDict_SetItemString(obdict, "State", state);
+    Py_DECREF(state);
+
+    Py_DECREF(ob);
+}
+
+void openboxwrap_shutdown()
+{
+    Py_DECREF(openboxwrap_obj->client_list);
+    Py_DECREF(openboxwrap_obj);
+}
This page took 0.030049 seconds and 4 git commands to generate.