]> Dogcows Code - chaz/openbox/blob - openbox/openboxwrap.c
merge the C branch into HEAD
[chaz/openbox] / openbox / openboxwrap.c
1 #include "openboxwrap.h"
2 #include "openbox.h"
3 #include "screen.h"
4 #include "prop.h"
5
6 /***************************************************************************
7
8 Define the type 'OpenboxWrap'
9
10 ***************************************************************************/
11
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' " \
17 "object"); \
18 return NULL; \
19 } \
20 }
21
22
23 staticforward PyTypeObject OpenboxWrapType;
24
25 /***************************************************************************
26
27 Attribute methods
28
29 ***************************************************************************/
30
31 static PyObject *owrap_shutdown(OpenboxWrap *self, PyObject *args)
32 {
33 CHECK_OWRAP(self, "shutdown");
34 if (!PyArg_ParseTuple(args, ":shutdown"))
35 return NULL;
36 ob_shutdown = TRUE;
37 Py_INCREF(Py_None);
38 return Py_None;
39 }
40
41 static PyObject *owrap_restart(OpenboxWrap *self, PyObject *args)
42 {
43 char *path = NULL;
44
45 CHECK_OWRAP(self, "restart");
46 if (!PyArg_ParseTuple(args, "|s:restart", &path))
47 return NULL;
48 ob_shutdown = ob_restart = TRUE;
49 ob_restart_path = path;
50 Py_INCREF(Py_None);
51 return Py_None;
52 }
53
54 static PyObject *owrap_state(OpenboxWrap *self, PyObject *args)
55 {
56 CHECK_OWRAP(self, "state");
57 if (!PyArg_ParseTuple(args, ":state"))
58 return NULL;
59 return PyInt_FromLong(ob_state);
60 }
61
62 static PyObject *owrap_desktop(OpenboxWrap *self, PyObject *args)
63 {
64 CHECK_OWRAP(self, "desktop");
65 if (!PyArg_ParseTuple(args, ":desktop"))
66 return NULL;
67 return PyInt_FromLong(screen_desktop);
68 }
69
70 static PyObject *owrap_setDesktop(OpenboxWrap *self, PyObject *args)
71 {
72 int desktop;
73
74 CHECK_OWRAP(self, "setDesktop");
75 if (!PyArg_ParseTuple(args, "i:setDesktop", &desktop))
76 return NULL;
77 if (desktop < 0 || (unsigned)desktop >= screen_num_desktops) {
78 PyErr_SetString(PyExc_ValueError, "invalid desktop");
79 return NULL;
80 }
81 screen_set_desktop(desktop);
82 Py_INCREF(Py_None);
83 return Py_None;
84 }
85
86 static PyObject *owrap_setNextDesktop(OpenboxWrap *self, PyObject *args)
87 {
88 gboolean wrap = TRUE;
89 guint d;
90
91 CHECK_OWRAP(self, "setNextDesktop");
92 if (!PyArg_ParseTuple(args, "|i:setNextDesktop", &wrap))
93 return NULL;
94 d = screen_desktop + 1;
95 if (d >= screen_num_desktops && wrap)
96 d = 0;
97 if (d < screen_num_desktops)
98 screen_set_desktop(d);
99 Py_INCREF(Py_None);
100 return Py_None;
101 }
102
103 static PyObject *owrap_setPreviousDesktop(OpenboxWrap *self, PyObject *args)
104 {
105 gboolean wrap = TRUE;
106 guint d;
107
108 CHECK_OWRAP(self, "setPreviousDesktop");
109 if (!PyArg_ParseTuple(args, "|i:setPreviousDesktop", &wrap))
110 return NULL;
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);
116 Py_INCREF(Py_None);
117 return Py_None;
118 }
119
120 static PyObject *owrap_numDesktops(OpenboxWrap *self, PyObject *args)
121 {
122 CHECK_OWRAP(self, "numDesktops");
123 if (!PyArg_ParseTuple(args, ":numDesktops"))
124 return NULL;
125 return PyInt_FromLong(screen_num_desktops);
126 }
127
128 static PyObject *owrap_setNumDesktops(OpenboxWrap *self, PyObject *args)
129 {
130 int desktops;
131
132 CHECK_OWRAP(self, "setNumDesktops");
133 if (!PyArg_ParseTuple(args, "i:setNumDesktops", &desktops))
134 return NULL;
135 if (desktops <= 0) {
136 PyErr_SetString(PyExc_ValueError, "invalid number of desktops");
137 return NULL;
138 }
139 screen_set_num_desktops(desktops);
140 Py_INCREF(Py_None);
141 return Py_None;
142 }
143
144 static PyObject *owrap_desktopNames(OpenboxWrap *self, PyObject *args)
145 {
146 PyObject *tuple;
147 int i, s;
148
149 CHECK_OWRAP(self, "desktopNames");
150 if (!PyArg_ParseTuple(args, ":desktopNames"))
151 return NULL;
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));
156 return tuple;
157 }
158
159 static PyObject *owrap_setDesktopNames(OpenboxWrap *self, PyObject *args)
160 {
161 PyObject *seq;
162 int i, s;
163 GPtrArray *data;
164
165 CHECK_OWRAP(self, "setDesktopNames");
166 if (!PyArg_ParseTuple(args, "O:setDesktopNames", &seq))
167 return NULL;
168 if (!PySequence_Check(seq))
169 PyErr_SetString(PyExc_TypeError, "expected a sequence");
170 return NULL;
171
172 s = PySequence_Size(seq);
173 for (i = 0; i < s; ++i) {
174 PyObject *item;
175 gboolean check;
176 item = PySequence_GetItem(seq, i); /* new */
177 check = PyString_Check(item);
178 Py_DECREF(item);
179 if (!check) {
180 PyErr_SetString(PyExc_TypeError, "expected a sequence of strings");
181 return NULL;
182 }
183 }
184
185 data = g_ptr_array_sized_new(s);
186 for (i = 0; i < s; ++i) {
187 PyObject *item;
188 item = PySequence_GetItem(seq, i); /* new */
189 g_ptr_array_index(data, i) = PyString_AsString(item); /* borrowed */
190 Py_DECREF(item);
191 }
192
193 PROP_SETSA(ob_root, net_desktop_names, utf8, data);
194 g_ptr_array_free(data, TRUE);
195
196 Py_INCREF(Py_None);
197 return Py_None;
198 }
199
200 static PyObject *owrap_showingDesktop(OpenboxWrap *self, PyObject *args)
201 {
202 CHECK_OWRAP(self, "showingDesktop");
203 if (!PyArg_ParseTuple(args, ":showingDesktop"))
204 return NULL;
205 return PyInt_FromLong(!!screen_showing_desktop);
206 }
207
208 static PyObject *owrap_setShowingDesktop(OpenboxWrap *self, PyObject *args)
209 {
210 int show;
211
212 CHECK_OWRAP(self, "setShowingDesktop");
213 if (!PyArg_ParseTuple(args, "i:setShowingDesktop", &show))
214 return NULL;
215 screen_show_desktop(show);
216 Py_INCREF(Py_None);
217 return Py_None;
218 }
219
220 static PyObject *owrap_screenArea(OpenboxWrap *self, PyObject *args)
221 {
222 int desktop;
223 Rect *area;
224 PyObject *tuple;
225
226 CHECK_OWRAP(self, "screenArea");
227 if (!PyArg_ParseTuple(args, "i:screenArea", &desktop))
228 return NULL;
229
230 area = screen_area(desktop);
231 if (area == NULL) {
232 PyErr_SetString(PyExc_ValueError, "invalid desktop");
233 return NULL;
234 }
235
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));
241 return tuple;
242 }
243
244 static PyObject *owrap_screenStrut(OpenboxWrap *self, PyObject *args)
245 {
246 int desktop;
247 Strut *strut;
248 PyObject *tuple;
249
250 CHECK_OWRAP(self, "screenStrut");
251 if (!PyArg_ParseTuple(args, "i:screenStrut", &desktop))
252 return NULL;
253
254 strut = screen_strut(desktop);
255 if (strut == NULL) {
256 PyErr_SetString(PyExc_ValueError, "invalid desktop");
257 return NULL;
258 }
259
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));
265 return tuple;
266 }
267
268 static PyObject *owrap_physicalSize(OpenboxWrap *self, PyObject *args)
269 {
270 PyObject *tuple;
271
272 CHECK_OWRAP(self, "physicalSize");
273 if (!PyArg_ParseTuple(args, ":physicalSize"))
274 return NULL;
275
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));
279 return tuple;
280 }
281
282 static PyObject *owrap_screenNumber(OpenboxWrap *self, PyObject *args)
283 {
284 CHECK_OWRAP(self, "screenNumber");
285 if (!PyArg_ParseTuple(args, ":screenNumber"))
286 return NULL;
287 return PyInt_FromLong(ob_screen);
288 }
289
290 static PyObject *owrap_rootWindow(OpenboxWrap *self, PyObject *args)
291 {
292 CHECK_OWRAP(self, "rootWindow");
293 if (!PyArg_ParseTuple(args, ":rootWindow"))
294 return NULL;
295 return PyInt_FromLong(ob_root);
296 }
297
298 static PyObject *owrap_clientList(OpenboxWrap *self, PyObject *args)
299 {
300 CHECK_OWRAP(self, "clientList");
301 if (!PyArg_ParseTuple(args, ":clientList"))
302 return NULL;
303 Py_INCREF(self->client_list);
304 return self->client_list;
305 }
306
307 #define METH(n, d) {#n, (PyCFunction)owrap_##n, METH_VARARGS, #d}
308
309 static PyMethodDef OpenboxWrapMethods[] = {
310 METH(shutdown,
311 "Causes Openbox to shutdown and exit."),
312 METH(restart,
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 "
316 "restart itself."),
317 METH(state,
318 "Returns Openbox's current state, this will be one of the State "
319 "constants."),
320 METH(desktop,
321 "Returns the number of the currently visible desktop. This will be "
322 "in the range of [0, numDesktops())."),
323 METH(setDesktop,
324 "Sets the specified desktop as the visible desktop."),
325 METH(setNextDesktop,
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."),
331 METH(numDesktops,
332 "Returns the number of desktops available."),
333 METH(desktopNames,
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."),
339 METH(showingDesktop,
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."),
346 METH(screenArea,
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()."),
350 METH(screenStrut,
351 "Returns the combined strut which has been reserved by all "
352 "applications on the desktops."),
353 METH(physicalSize,
354 "Returns the physical size of the display device (in pixels)."),
355 METH(screenNumber,
356 "Returns the number of the screen on which Openbox is running."),
357 METH(rootWindow,
358 "Return the window id of the root window."),
359 METH(clientList,
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 }
363 };
364
365 /***************************************************************************
366
367 Type methods/struct
368
369 ***************************************************************************/
370
371 /*static PyObject *owrap_getattr(OpenboxWrap *self, char *name)
372 {
373 CHECK_OWRAP(self, "getattr");
374 return Py_FindMethod(OpenboxWrapAttributeMethods, (PyObject*)self, name);
375 }*/
376
377 static void owrap_dealloc(OpenboxWrap *self)
378 {
379 PyObject_Del((PyObject*) self);
380 }
381
382 static PyTypeObject OpenboxWrapType = {
383 PyObject_HEAD_INIT(NULL)
384 0,
385 "Openbox",
386 sizeof(OpenboxWrap),
387 0,
388 (destructor) owrap_dealloc, /*tp_dealloc*/
389 0, /*tp_print*/
390 0, /*tp_getattr*/
391 0, /*tp_setattr*/
392 0, /*tp_compare*/
393 0, /*tp_repr*/
394 0, /*tp_as_number*/
395 0, /*tp_as_sequence*/
396 0, /*tp_as_mapping*/
397 0, /*tp_hash */
398 };
399
400 /***************************************************************************
401
402 Define the type 'OpenboxState'
403
404 ***************************************************************************/
405
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' " \
411 "object"); \
412 return NULL; \
413 } \
414 }
415
416 staticforward PyTypeObject OpenboxStateType;
417
418 typedef struct OpenboxState {
419 PyObject_HEAD
420 } OpenboxState;
421
422 static void ostate_dealloc(PyObject *self)
423 {
424 PyObject_Del(self);
425 }
426
427 static PyObject *ostate_getattr(OpenboxState *self, char *name)
428 {
429 struct S { char *name; int val; };
430 struct S s[] = {
431 { "Starting", State_Starting },
432 { "Running", State_Running },
433 { "Exiting", State_Exiting },
434 { NULL, 0 } };
435 int i;
436
437 CHECK_OSTATE(self, "__getattr__");
438
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");
443 return NULL;
444 }
445
446 static PyTypeObject OpenboxStateType = {
447 PyObject_HEAD_INIT(NULL)
448 0,
449 "State",
450 sizeof(OpenboxState),
451 0,
452 (destructor) ostate_dealloc, /*tp_dealloc*/
453 0, /*tp_print*/
454 (getattrfunc) ostate_getattr, /*tp_getattr*/
455 0, /*tp_setattr*/
456 0, /*tp_compare*/
457 0, /*tp_repr*/
458 0, /*tp_as_number*/
459 0, /*tp_as_sequence*/
460 0, /*tp_as_mapping*/
461 0, /*tp_hash */
462 };
463
464 /***************************************************************************
465
466 External methods
467
468 ***************************************************************************/
469
470 void openboxwrap_startup()
471 {
472 PyObject *ob, *obdict, *state;
473
474 OpenboxWrapType.ob_type = &PyType_Type;
475 OpenboxWrapType.tp_methods = OpenboxWrapMethods;
476 PyType_Ready(&OpenboxWrapType);
477
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);
483
484 /* add an Openbox instance to the ob module */
485 openboxwrap_obj = PyObject_New(OpenboxWrap, &OpenboxWrapType);
486 openboxwrap_obj->client_list = PyList_New(0);
487
488 PyDict_SetItemString(obdict, "Openbox", (PyObject*) openboxwrap_obj);
489
490 /* add an instance of OpenboxState */
491 state = (PyObject*) PyObject_New(OpenboxState, &OpenboxStateType);
492 PyDict_SetItemString(obdict, "State", state);
493 Py_DECREF(state);
494
495 Py_DECREF(ob);
496 }
497
498 void openboxwrap_shutdown()
499 {
500 Py_DECREF(openboxwrap_obj->client_list);
501 Py_DECREF(openboxwrap_obj);
502 }
This page took 0.057475 seconds and 4 git commands to generate.