screen.displays() returns a list(?) of displays.
[screen-lua.git] / src / python.c
blob5f549401849f1697fa599c2956c90087f008d6aa
1 /* Python scripting support
3 * Copyright (c) 2009 Sadrul Habib Chowdhury (sadrul@users.sf.net)
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program (see the file COPYING); if not, write to the
17 * Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
20 ****************************************************************
22 #include <sys/types.h>
24 #include "config.h"
25 #include "screen.h"
26 #include "script.h"
27 #include <sys/stat.h>
28 #include <unistd.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
34 #include "extern.h"
35 #include "logfile.h"
37 #include <Python.h>
38 #include <structmember.h>
40 extern struct win *windows;
41 extern struct display *display, *displays;
43 static PyObject * SPy_Get(PyObject *obj, void *closure);
44 static PyObject * SPy_Set(PyObject *obj, PyObject *value, void *closure);
46 typedef struct
48 char *name;
49 char *doc;
51 int type;
52 size_t offset1;
53 size_t offset2;
54 PyObject * (*conv)(void *);
55 } SPyClosure;
57 #define REGISTER_TYPE(type, Type, closures) \
58 static int \
59 register_##type(PyObject *module) \
60 { \
61 static PyGetSetDef getsets[sizeof(closures)]; \
62 int i, count = sizeof(closures); \
63 for (i = 0; i < count; i++) \
64 { \
65 getsets[i].name = closures[i].name; \
66 getsets[i].doc = closures[i].doc; \
67 getsets[i].closure = &closures[i]; \
68 getsets[i].get = SPy_Get; \
69 getsets[i].set = SPy_Set; \
70 } \
71 PyType##Type.tp_getset = getsets; \
72 PyType_Ready(&PyType##Type); \
73 Py_INCREF(&PyType##Type); \
74 PyModule_AddObject(module, #Type, (PyObject *)&PyType##Type); \
75 return 1; \
78 #define DEFINE_TYPE(str, Type) \
79 typedef struct \
80 { \
81 PyObject_HEAD \
82 str *_obj; \
83 } Py##Type; \
85 static PyTypeObject PyType##Type = \
86 { \
87 PyObject_HEAD_INIT(NULL) \
88 .ob_size = 0, \
89 .tp_name = "screen." #Type, \
90 .tp_basicsize = sizeof(Py##Type), \
91 .tp_flags = Py_TPFLAGS_DEFAULT, \
92 .tp_doc = #Type " object", \
93 .tp_methods = NULL, \
94 .tp_getset = NULL, \
95 }; \
97 static PyObject * \
98 PyObject_From##Type(str *_obj) \
99 { \
100 Py##Type *obj = PyType##Type.tp_alloc(&PyType##Type, 0); \
101 obj->_obj = _obj; \
102 return (PyObject *)obj; \
105 static PyObject *
106 PyString_FromStringSafe(const char *str)
108 if (str)
109 return PyString_FromString(str);
110 Py_INCREF(Py_None);
111 return Py_None;
114 /** Window {{{ */
115 DEFINE_TYPE(struct win, Window)
117 #define SPY_CLOSURE(name, doc, type, member, func) \
118 {name, doc, type, offsetof(PyWindow, _obj), offsetof(struct win, member), func}
119 static SPyClosure wclosures[] =
121 SPY_CLOSURE("title", "Window title", T_STRING, w_title, NULL),
122 SPY_CLOSURE("number", "Window number", T_INT, w_number, NULL),
123 SPY_CLOSURE("dir", "Window directory", T_STRING, w_dir, NULL),
124 SPY_CLOSURE("tty", "TTY belonging to the window", T_STRING_INPLACE, w_tty, NULL),
125 SPY_CLOSURE("group", "The group the window belongs to", T_OBJECT_EX, w_group, PyObject_FromWindow),
126 SPY_CLOSURE("pid", "Window pid", T_INT, w_pid, NULL),
127 {NULL}
129 REGISTER_TYPE(window, Window, wclosures)
130 #undef SPY_CLOSURE
132 /** }}} */
134 /** Display {{{ */
135 DEFINE_TYPE(struct display, Display)
137 #define SPY_CLOSURE(name, doc, type, member, func) \
138 {name, doc, type, offsetof(PyDisplay, _obj), offsetof(struct display, member), func}
139 static SPyClosure dclosures[] =
141 SPY_CLOSURE("tty", "Display TTY", T_STRING_INPLACE, d_usertty, NULL),
142 SPY_CLOSURE("term", "Display Term", T_STRING_INPLACE, d_termname, NULL),
143 SPY_CLOSURE("fore", "Foreground window of the display", T_OBJECT_EX, d_fore, PyObject_FromWindow),
144 SPY_CLOSURE("width", "Display width", T_INT, d_width, NULL),
145 SPY_CLOSURE("height", "Display height", T_INT, d_height, NULL),
146 {NULL}
148 REGISTER_TYPE(display, Display, dclosures)
149 #undef SPY_CLOSURE
150 /** }}} */
152 static PyObject *
153 SPy_Get(PyObject *obj, void *closure)
155 SPyClosure *sc = closure;
156 char **first = (char *)obj + sc->offset1;
157 char **second = (char *)*first + sc->offset2;
158 PyObject *(*cb)(void *) = sc->conv;
159 void *data = *second;
161 if (!cb)
163 switch (sc->type)
165 case T_STRING:
166 cb = PyString_FromStringSafe;
167 data = *second;
168 break;
169 case T_STRING_INPLACE:
170 cb = PyString_FromStringSafe;
171 data = second;
172 break;
173 case T_INT:
174 cb = PyInt_FromLong;
175 data = *second;
176 break;
179 return cb(data);
182 static PyObject *
183 SPy_Set(PyObject *obj, PyObject *value, void *closure)
185 return NULL;
188 static PyObject *
189 screen_display(PyObject *self)
191 if (!display)
193 Py_INCREF(Py_None);
194 return Py_None;
196 return PyObject_FromDisplay(display);
199 static PyObject *
200 screen_displays(PyObject *self)
202 struct display *d = displays;
203 int count = 0;
204 for (; d; d = d->d_next)
205 ++count;
206 PyObject *tuple = PyTuple_New(count);
208 for (d = displays, count = 0; d; d = d->d_next, ++count)
209 PyTuple_SetItem(tuple, count, PyObject_FromDisplay(d));
211 return tuple;
214 static PyObject *
215 screen_windows(PyObject *self)
217 struct win *w = windows;
218 int count = 0;
219 for (; w; w = w->w_next)
220 ++count;
221 PyObject *tuple = PyTuple_New(count);
223 for (w = windows, count = 0; w; w = w->w_next, ++count)
224 PyTuple_SetItem(tuple, count, PyObject_FromWindow(w));
226 return tuple;
229 const PyMethodDef py_methods[] = {
230 {"display", (PyCFunction)screen_display, METH_NOARGS, NULL},
231 {"displays", (PyCFunction)screen_displays, METH_NOARGS, NULL},
232 {"windows", (PyCFunction)screen_windows, METH_NOARGS, NULL},
233 {NULL, NULL, 0, NULL}
236 static int
237 SPyInit(void)
239 PyObject *m;
241 Py_Initialize();
243 m = Py_InitModule3 ("screen", py_methods, NULL);
244 register_window(m);
245 register_display(m);
247 return 0;
250 static int
251 SPyFinit(void)
253 Py_Finalize();
254 return 0;
257 static int
258 SPySource(const char *file, int async)
260 FILE *f = fopen(file, "rb");
261 int ret = PyRun_SimpleFile(f, file);
262 fclose(f);
264 if (ret == 0)
265 return 1; /* Success */
267 if (PyErr_Occurred())
269 PyErr_Print();
270 return 0;
273 return 1;
276 struct binding py_binding =
278 "python",
281 SPyInit,
282 SPyFinit,
284 SPySource,