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)
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>
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
);
54 PyObject
* (*conv
)(void *);
57 #define REGISTER_TYPE(type, Type, closures) \
59 register_##type(PyObject *module) \
61 static PyGetSetDef getsets[sizeof(closures)]; \
62 int i, count = sizeof(closures); \
63 for (i = 0; i < count; i++) \
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; \
71 PyType##Type.tp_getset = getsets; \
72 PyType_Ready(&PyType##Type); \
73 Py_INCREF(&PyType##Type); \
74 PyModule_AddObject(module, #Type, (PyObject *)&PyType##Type); \
78 #define DEFINE_TYPE(str, Type) \
85 static PyTypeObject PyType##Type = \
87 PyObject_HEAD_INIT(NULL) \
89 .tp_name = "screen." #Type, \
90 .tp_basicsize = sizeof(Py##Type), \
91 .tp_flags = Py_TPFLAGS_DEFAULT, \
92 .tp_doc = #Type " object", \
98 PyObject_From##Type(str *_obj) \
100 Py##Type *obj = PyType##Type.tp_alloc(&PyType##Type, 0); \
102 return (PyObject *)obj; \
106 PyString_FromStringSafe(const char *str
)
109 return PyString_FromString(str
);
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
),
129 REGISTER_TYPE(window
, Window
, wclosures
)
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
),
148 REGISTER_TYPE(display
, Display
, dclosures
)
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
;
166 cb
= PyString_FromStringSafe
;
169 case T_STRING_INPLACE
:
170 cb
= PyString_FromStringSafe
;
183 SPy_Set(PyObject
*obj
, PyObject
*value
, void *closure
)
189 screen_display(PyObject
*self
)
196 return PyObject_FromDisplay(display
);
200 screen_displays(PyObject
*self
)
202 struct display
*d
= displays
;
204 for (; d
; d
= d
->d_next
)
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
));
215 screen_windows(PyObject
*self
)
217 struct win
*w
= windows
;
219 for (; w
; w
= w
->w_next
)
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
));
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
}
243 m
= Py_InitModule3 ("screen", py_methods
, NULL
);
258 SPySource(const char *file
, int async
)
260 FILE *f
= fopen(file
, "rb");
261 int ret
= PyRun_SimpleFile(f
, file
);
265 return 1; /* Success */
267 if (PyErr_Occurred())
276 struct binding py_binding
=