1 #include "openboxwrap.h"
6 /***************************************************************************
8 Define the type 'OpenboxWrap'
10 ***************************************************************************/
12 #define IS_OWRAP(v) ((v)->ob_type == &OpenboxWrapType)
13 #define CHECK_OWRAP(self, funcname) { \
14 if (!IS_OWRAP(self)) { \
15 PyErr_SetString(PyExc_TypeError, \
16 "descriptor '" funcname "' requires a 'Openbox' " \
23 staticforward PyTypeObject OpenboxWrapType
;
25 /***************************************************************************
29 ***************************************************************************/
31 static PyObject
*owrap_shutdown(OpenboxWrap
*self
, PyObject
*args
)
33 CHECK_OWRAP(self
, "shutdown");
34 if (!PyArg_ParseTuple(args
, ":shutdown"))
41 static PyObject
*owrap_restart(OpenboxWrap
*self
, PyObject
*args
)
45 CHECK_OWRAP(self
, "restart");
46 if (!PyArg_ParseTuple(args
, "|s:restart", &path
))
48 ob_shutdown
= ob_restart
= TRUE
;
49 ob_restart_path
= path
;
54 static PyObject
*owrap_state(OpenboxWrap
*self
, PyObject
*args
)
56 CHECK_OWRAP(self
, "state");
57 if (!PyArg_ParseTuple(args
, ":state"))
59 return PyInt_FromLong(ob_state
);
62 static PyObject
*owrap_desktop(OpenboxWrap
*self
, PyObject
*args
)
64 CHECK_OWRAP(self
, "desktop");
65 if (!PyArg_ParseTuple(args
, ":desktop"))
67 return PyInt_FromLong(screen_desktop
);
70 static PyObject
*owrap_setDesktop(OpenboxWrap
*self
, PyObject
*args
)
74 CHECK_OWRAP(self
, "setDesktop");
75 if (!PyArg_ParseTuple(args
, "i:setDesktop", &desktop
))
77 if (desktop
< 0 || (unsigned)desktop
>= screen_num_desktops
) {
78 PyErr_SetString(PyExc_ValueError
, "invalid desktop");
81 screen_set_desktop(desktop
);
86 static PyObject
*owrap_setNextDesktop(OpenboxWrap
*self
, PyObject
*args
)
91 CHECK_OWRAP(self
, "setNextDesktop");
92 if (!PyArg_ParseTuple(args
, "|i:setNextDesktop", &wrap
))
94 d
= screen_desktop
+ 1;
95 if (d
>= screen_num_desktops
&& wrap
)
97 if (d
< screen_num_desktops
)
98 screen_set_desktop(d
);
103 static PyObject
*owrap_setPreviousDesktop(OpenboxWrap
*self
, PyObject
*args
)
105 gboolean wrap
= TRUE
;
108 CHECK_OWRAP(self
, "setPreviousDesktop");
109 if (!PyArg_ParseTuple(args
, "|i:setPreviousDesktop", &wrap
))
111 d
= screen_desktop
- 1;
112 if (d
>= screen_num_desktops
&& wrap
)
113 d
= screen_num_desktops
- 1;
114 if (d
< screen_num_desktops
)
115 screen_set_desktop(d
);
120 static PyObject
*owrap_numDesktops(OpenboxWrap
*self
, PyObject
*args
)
122 CHECK_OWRAP(self
, "numDesktops");
123 if (!PyArg_ParseTuple(args
, ":numDesktops"))
125 return PyInt_FromLong(screen_num_desktops
);
128 static PyObject
*owrap_setNumDesktops(OpenboxWrap
*self
, PyObject
*args
)
132 CHECK_OWRAP(self
, "setNumDesktops");
133 if (!PyArg_ParseTuple(args
, "i:setNumDesktops", &desktops
))
136 PyErr_SetString(PyExc_ValueError
, "invalid number of desktops");
139 screen_set_num_desktops(desktops
);
144 static PyObject
*owrap_desktopNames(OpenboxWrap
*self
, PyObject
*args
)
149 CHECK_OWRAP(self
, "desktopNames");
150 if (!PyArg_ParseTuple(args
, ":desktopNames"))
152 s
= screen_desktop_names
->len
;
153 tuple
= PyTuple_New(s
);
154 for (i
= 0; i
< s
; ++i
)
155 PyTuple_SET_ITEM(tuple
, i
, g_ptr_array_index(screen_desktop_names
, i
));
159 static PyObject
*owrap_setDesktopNames(OpenboxWrap
*self
, PyObject
*args
)
165 CHECK_OWRAP(self
, "setDesktopNames");
166 if (!PyArg_ParseTuple(args
, "O:setDesktopNames", &seq
))
168 if (!PySequence_Check(seq
))
169 PyErr_SetString(PyExc_TypeError
, "expected a sequence");
172 s
= PySequence_Size(seq
);
173 for (i
= 0; i
< s
; ++i
) {
176 item
= PySequence_GetItem(seq
, i
); /* new */
177 check
= PyString_Check(item
);
180 PyErr_SetString(PyExc_TypeError
, "expected a sequence of strings");
185 data
= g_ptr_array_sized_new(s
);
186 for (i
= 0; i
< s
; ++i
) {
188 item
= PySequence_GetItem(seq
, i
); /* new */
189 g_ptr_array_index(data
, i
) = PyString_AsString(item
); /* borrowed */
193 PROP_SETSA(ob_root
, net_desktop_names
, utf8
, data
);
194 g_ptr_array_free(data
, TRUE
);
200 static PyObject
*owrap_showingDesktop(OpenboxWrap
*self
, PyObject
*args
)
202 CHECK_OWRAP(self
, "showingDesktop");
203 if (!PyArg_ParseTuple(args
, ":showingDesktop"))
205 return PyInt_FromLong(!!screen_showing_desktop
);
208 static PyObject
*owrap_setShowingDesktop(OpenboxWrap
*self
, PyObject
*args
)
212 CHECK_OWRAP(self
, "setShowingDesktop");
213 if (!PyArg_ParseTuple(args
, "i:setShowingDesktop", &show
))
215 screen_show_desktop(show
);
220 static PyObject
*owrap_screenArea(OpenboxWrap
*self
, PyObject
*args
)
226 CHECK_OWRAP(self
, "screenArea");
227 if (!PyArg_ParseTuple(args
, "i:screenArea", &desktop
))
230 area
= screen_area(desktop
);
232 PyErr_SetString(PyExc_ValueError
, "invalid desktop");
236 tuple
= PyTuple_New(4);
237 PyTuple_SET_ITEM(tuple
, 0, PyInt_FromLong(area
->x
));
238 PyTuple_SET_ITEM(tuple
, 1, PyInt_FromLong(area
->y
));
239 PyTuple_SET_ITEM(tuple
, 2, PyInt_FromLong(area
->width
));
240 PyTuple_SET_ITEM(tuple
, 3, PyInt_FromLong(area
->height
));
244 static PyObject
*owrap_screenStrut(OpenboxWrap
*self
, PyObject
*args
)
250 CHECK_OWRAP(self
, "screenStrut");
251 if (!PyArg_ParseTuple(args
, "i:screenStrut", &desktop
))
254 strut
= screen_strut(desktop
);
256 PyErr_SetString(PyExc_ValueError
, "invalid desktop");
260 tuple
= PyTuple_New(4);
261 PyTuple_SET_ITEM(tuple
, 0, PyInt_FromLong(strut
->left
));
262 PyTuple_SET_ITEM(tuple
, 1, PyInt_FromLong(strut
->top
));
263 PyTuple_SET_ITEM(tuple
, 2, PyInt_FromLong(strut
->right
));
264 PyTuple_SET_ITEM(tuple
, 3, PyInt_FromLong(strut
->bottom
));
268 static PyObject
*owrap_physicalSize(OpenboxWrap
*self
, PyObject
*args
)
272 CHECK_OWRAP(self
, "physicalSize");
273 if (!PyArg_ParseTuple(args
, ":physicalSize"))
276 tuple
= PyTuple_New(2);
277 PyTuple_SET_ITEM(tuple
, 0, PyInt_FromLong(screen_physical_size
.width
));
278 PyTuple_SET_ITEM(tuple
, 1, PyInt_FromLong(screen_physical_size
.height
));
282 static PyObject
*owrap_screenNumber(OpenboxWrap
*self
, PyObject
*args
)
284 CHECK_OWRAP(self
, "screenNumber");
285 if (!PyArg_ParseTuple(args
, ":screenNumber"))
287 return PyInt_FromLong(ob_screen
);
290 static PyObject
*owrap_rootWindow(OpenboxWrap
*self
, PyObject
*args
)
292 CHECK_OWRAP(self
, "rootWindow");
293 if (!PyArg_ParseTuple(args
, ":rootWindow"))
295 return PyInt_FromLong(ob_root
);
298 static PyObject
*owrap_clientList(OpenboxWrap
*self
, PyObject
*args
)
300 CHECK_OWRAP(self
, "clientList");
301 if (!PyArg_ParseTuple(args
, ":clientList"))
303 Py_INCREF(self
->client_list
);
304 return self
->client_list
;
307 #define METH(n, d) {#n, (PyCFunction)owrap_##n, METH_VARARGS, #d}
309 static PyMethodDef OpenboxWrapMethods
[] = {
311 "Causes Openbox to shutdown and exit."),
313 "Causes Openbox to shutdown and restart. If path is specified, "
314 "Openbox will shutdown and attempt to run the specified executable "
315 "instead of restarting itself. If that fails, however, it will "
318 "Returns Openbox's current state, this will be one of the State "
321 "Returns the number of the currently visible desktop. This will be "
322 "in the range of [0, numDesktops())."),
324 "Sets the specified desktop as the visible desktop."),
326 "Sets the visible desktop to the next desktop, optionally wrapping "
327 "around when reaching the last."),
328 METH(setPreviousDesktop
,
329 "Sets the visible desktop to the previous desktop, optionally "
330 "wrapping around when reaching the first."),
332 "Returns the number of desktops available."),
334 "Returns a tuple of names, containing a name for each desktop. The "
335 "tuple may have a length greater than numDesktops() if more names "
336 "have been specified."),
337 METH(setDesktopNames
,
338 "Sets the names for the desktops."),
340 "Returns True or False, depicting if Openbox is in 'showing the "
341 "desktop' mode. In 'showing the desktop' mode, all normal clients "
342 "are hidden and the desktop is given focus if possible."),
343 METH(setShowingDesktop
,
344 "Enters or leaves 'showing the desktop' mode. See showingDesktop() "
345 "for a description of this mode."),
347 "Returns the on-screen available area. This is the area not reserved "
348 "by applications' struts. Windows should be placed within this area, "
349 "not within the physicalSize()."),
351 "Returns the combined strut which has been reserved by all "
352 "applications on the desktops."),
354 "Returns the physical size of the display device (in pixels)."),
356 "Returns the number of the screen on which Openbox is running."),
358 "Return the window id of the root window."),
360 "Returns a all clients currently being managed by Openbox. This list "
361 "is updated as clients are managed and closed/destroyed/released."),
362 { NULL
, NULL
, 0, NULL
}
365 /***************************************************************************
369 ***************************************************************************/
371 /*static PyObject *owrap_getattr(OpenboxWrap *self, char *name)
373 CHECK_OWRAP(self, "getattr");
374 return Py_FindMethod(OpenboxWrapAttributeMethods, (PyObject*)self, name);
377 static void owrap_dealloc(OpenboxWrap
*self
)
379 PyObject_Del((PyObject
*) self
);
382 static PyTypeObject OpenboxWrapType
= {
383 PyObject_HEAD_INIT(NULL
)
388 (destructor
) owrap_dealloc
, /*tp_dealloc*/
395 0, /*tp_as_sequence*/
400 /***************************************************************************
402 Define the type 'OpenboxState'
404 ***************************************************************************/
406 #define IS_OSTATE(v) ((v)->ob_type == &OpenboxStateType)
407 #define CHECK_OSTATE(self, funcname) { \
408 if (!IS_OSTATE(self)) { \
409 PyErr_SetString(PyExc_TypeError, \
410 "descriptor '" funcname "' requires a 'State' " \
416 staticforward PyTypeObject OpenboxStateType
;
418 typedef struct OpenboxState
{
422 static void ostate_dealloc(PyObject
*self
)
427 static PyObject
*ostate_getattr(OpenboxState
*self
, char *name
)
429 struct S
{ char *name
; int val
; };
431 { "Starting", State_Starting
},
432 { "Running", State_Running
},
433 { "Exiting", State_Exiting
},
437 CHECK_OSTATE(self
, "__getattr__");
439 for (i
= 0; s
[i
].name
!= NULL
; ++i
)
440 if (!strcmp(s
[i
].name
, name
))
441 return PyInt_FromLong(s
[i
].val
);
442 PyErr_SetString(PyExc_AttributeError
, "invalid attribute");
446 static PyTypeObject OpenboxStateType
= {
447 PyObject_HEAD_INIT(NULL
)
450 sizeof(OpenboxState
),
452 (destructor
) ostate_dealloc
, /*tp_dealloc*/
454 (getattrfunc
) ostate_getattr
, /*tp_getattr*/
459 0, /*tp_as_sequence*/
464 /***************************************************************************
468 ***************************************************************************/
470 void openboxwrap_startup()
472 PyObject
*ob
, *obdict
, *state
;
474 OpenboxWrapType
.ob_type
= &PyType_Type
;
475 OpenboxWrapType
.tp_methods
= OpenboxWrapMethods
;
476 PyType_Ready(&OpenboxWrapType
);
478 /* get the ob module/dict */
479 ob
= PyImport_ImportModule("ob"); /* new */
480 g_assert(ob
!= NULL
);
481 obdict
= PyModule_GetDict(ob
); /* borrowed */
482 g_assert(obdict
!= NULL
);
484 /* add an Openbox instance to the ob module */
485 openboxwrap_obj
= PyObject_New(OpenboxWrap
, &OpenboxWrapType
);
486 openboxwrap_obj
->client_list
= PyList_New(0);
488 PyDict_SetItemString(obdict
, "Openbox", (PyObject
*) openboxwrap_obj
);
490 /* add an instance of OpenboxState */
491 state
= (PyObject
*) PyObject_New(OpenboxState
, &OpenboxStateType
);
492 PyDict_SetItemString(obdict
, "State", state
);
498 void openboxwrap_shutdown()
500 Py_DECREF(openboxwrap_obj
->client_list
);
501 Py_DECREF(openboxwrap_obj
);