root/mwmmodule.c

Revision 1, 10.2 KB (checked in by root, 3 years ago)

Initial commit

Line 
1#include "Python.h"
2#include <stdio.h>
3#include <pthread.h>
4#include <stdlib.h>
5#include "evilwm.h"
6
7struct cargs
8{
9  int (*mainf)(int argc, char**argv);
10  int argc;
11  char **argv;
12};
13
14void* main_runner(void* _args)
15{
16  struct cargs *args = (struct cargs*)_args;
17  args->mainf(args->argc, args->argv);
18  free(args);
19  return NULL;
20}
21
22PyObject* run(PyObject *_, PyObject *pyargs)
23{
24  int sz;
25  int i;
26  pthread_t t;
27
28  PyEval_InitThreads();
29
30  struct cargs *args = malloc(sizeof(struct cargs));
31  args->mainf = wm_main;
32
33  if(!PyTuple_Check(pyargs)) return PyExc_TypeError;
34
35  sz = PyTuple_Size(pyargs);
36  for(i = 0; i < sz; ++i)
37    if(!PyString_Check(PyTuple_GetItem(pyargs, i)))
38      return PyExc_TypeError;
39
40  args->argc = sz + 1;
41  args->argv = malloc(args->argc * sizeof(char *));
42 
43  args->argv[0] = "m@rcell.wm";
44  for(i = 1; i < args->argc; ++i) {
45    const char *str = PyString_AsString(PyTuple_GetItem(pyargs, i - 1));
46    args->argv[i] = malloc(strlen(str + 1));
47    strcpy(args->argv[i], str);
48  }
49
50  pthread_create(&t, NULL, main_runner, args);
51  Py_RETURN_NONE;
52}
53
54;;;;
55
56typedef struct {
57  PyObject_HEAD
58  Client *cli;
59  char *name;
60} ClientObject;
61
62void Client_dtor(ClientObject *o)
63{
64  //  puts("tu i tamo stogod se i obrise");
65  free(o->name);
66  o->ob_type->tp_free((PyObject*)o);
67}
68
69int client_is_valid(Client *c)
70{
71  Client *it;
72  for (it = head_client; it; it = it->next)
73    if(it == c) return 1;
74  return 0;
75}
76
77PyObject *Client_hide(ClientObject *self)
78{
79  if(!client_is_valid(self->cli)) Py_RETURN_NONE;
80  hide(self->cli);
81  Py_RETURN_NONE;
82}
83
84PyObject *Client_show(ClientObject *self)
85{
86  if(!client_is_valid(self->cli)) Py_RETURN_NONE;
87  unhide(self->cli, RAISE);
88  Py_RETURN_NONE;
89}
90
91PyObject *Client_focus(ClientObject *self)
92{
93  if(!client_is_valid(self->cli)) Py_RETURN_NONE;
94  select_client(self->cli);
95  Py_RETURN_NONE;
96}
97
98PyObject *Client_kill(ClientObject *self)
99{
100  if(!client_is_valid(self->cli)) Py_RETURN_NONE;
101  send_wm_delete(self->cli, 1);
102  Py_RETURN_NONE;
103}
104
105
106PyObject *Client_foo(ClientObject *self)
107{
108  //if(!client_is_valid(self->cli)) Py_RETURN_NONE;
109  printf("get attro: %x\n", ((PyObject*)self)->ob_type->tp_getattro);
110  puts("bar");
111  Py_RETURN_NONE;
112}
113
114PyObject *Client_grab_mask(ClientObject *self)
115{
116  if(!client_is_valid(self->cli)) Py_RETURN_NONE;
117  grab_button(self->cli->parent, grabmask2, AnyButton);
118  Py_RETURN_NONE;
119}
120
121PyObject *Client_grab_all(ClientObject *self)
122{
123  if(!client_is_valid(self->cli)) Py_RETURN_NONE;
124  grab_button(self->cli->parent, AnyModifier, AnyButton);
125  Py_RETURN_NONE;
126}
127
128
129static PyMethodDef Client_methods [] = {
130  {"hide", (PyCFunction)Client_hide, METH_NOARGS, "Hide the client"},
131  {"show", (PyCFunction)Client_show, METH_NOARGS, "Show the client"},
132  {"focus", (PyCFunction)Client_focus, METH_NOARGS, "Show the client"},
133  {"kill", (PyCFunction)Client_kill, METH_NOARGS, "Kill the client"},
134  {"set_grab_button_mask", (PyCFunction)Client_grab_mask, METH_NOARGS, "Kill the client"},
135  {"unset_grab_button_mask", (PyCFunction)Client_grab_all, METH_NOARGS, "Kill the client"}, //todo: remove fun, just add different args
136  {"foo", (PyCFunction)Client_foo, METH_NOARGS, "foobar the client"},
137  {NULL}
138};
139
140PyObject *Client_get_name(ClientObject *self, void *_)
141{return PyString_FromString(self->name);}
142
143#define CLIENT_GET_INT(attr) \
144static PyObject *Client_get_ ## attr(ClientObject *self, void *_) \
145{return PyInt_FromLong(self -> cli -> attr);}
146
147#define CLIENT_SET_INT(attr) \
148static int Client_set_ ## attr(ClientObject *self, PyObject *val, void *_) \
149{ \
150  Client *c = self -> cli; \
151  c -> attr = PyInt_AsLong(val); \
152  XLockDisplay(dpy); \
153  moveresize(c); \
154  XUnlockDisplay(dpy); \
155  return 0; \
156}
157
158CLIENT_GET_INT(x)
159CLIENT_GET_INT(y)
160CLIENT_GET_INT(width)
161CLIENT_GET_INT(height)
162
163CLIENT_SET_INT(x)
164CLIENT_SET_INT(y)
165CLIENT_SET_INT(width)
166CLIENT_SET_INT(height)
167
168static PyGetSetDef Client_getset[] = {
169  {"x", (getter)Client_get_x, (setter)Client_set_x, "x coord", NULL},
170  {"y", (getter)Client_get_y, (setter)Client_set_y, "y coord", NULL},
171  {"width", (getter)Client_get_width, (setter)Client_set_width, "width", NULL},
172  {"height", (getter)Client_get_height, (setter)Client_set_height, "height", NULL},
173  {"name", (getter)Client_get_name, NULL, "name", NULL},
174  {NULL}
175};
176
177PyObject *Client_getattro(PyObject *self, PyObject *attr)
178{
179  PyObject* attrval = PyObject_GenericGetAttr(self, attr);
180  if(!PyErr_ExceptionMatches(PyExc_AttributeError)) return attrval;
181  PyErr_Clear(); 
182  attrval = PyDict_GetItem(((ClientObject*)self)->cli->dict, attr);
183  if(!attrval) PyErr_SetString(PyExc_AttributeError, "err!");
184  return attrval;
185}
186
187int Client_setattro(PyObject *self, PyObject *attr, PyObject *val)
188{
189  int ret = PyObject_GenericSetAttr(self, attr, val);
190  if(!PyErr_ExceptionMatches(PyExc_AttributeError)) return ret;
191  PyErr_Clear();
192  return PyDict_SetItem(((ClientObject*)self)->cli->dict, attr, val);
193}
194
195static PyTypeObject mwm_ClientType = {
196    PyObject_HEAD_INIT(NULL)
197    0,                         /*ob_size*/
198    "mwm.Client",              /*tp_name*/
199    sizeof(ClientObject),  /*tp_basicsize*/
200    0,                         /*tp_itemsize*/
201    (destructor)Client_dtor,   /*tp_dealloc*/
202    0,                         /*tp_print*/
203    0,                         /*tp_getattr*/
204    0,                         /*tp_setattr*/
205    0,                         /*tp_compare*/
206    0,                         /*tp_repr*/
207    0,                         /*tp_as_number*/
208    0,                         /*tp_as_sequence*/
209    0,                         /*tp_as_mapping*/
210    0,                         /*tp_hash */
211    0,                         /*tp_call*/
212    0,                         /*tp_str*/
213    Client_getattro,           /*tp_getattro*/
214    Client_setattro,           /*tp_setattro*/
215    0,                         /*tp_as_buffer*/
216    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
217    "WM client",               /* tp_doc */
218    0,                         /* tp_traverse */
219    0,                         /* tp_clear */
220    0,                         /* tp_richcompare */
221    0,                         /* tp_weaklistoffset */
222    0,                         /* tp_iter */
223    0,                         /* tp_iternext */
224    Client_methods,            /* tp_methods */
225    0,                         /* tp_members */
226    Client_getset,             /* tp_getset */
227    0,                         /* tp_base */
228    0,                         /* tp_dict */
229    0,                         /* tp_descr_get */
230    0,                         /* tp_descr_set */
231    0,                         /* tp_dictoffset */
232    0,                         /* tp_init */
233    0,                         /* tp_alloc */
234    0,                         /* tp_new */
235};
236
237
238void set_name(ClientObject *o, const char *name)
239{
240  int len = strlen(name);
241  o->name = malloc(len + 1);
242  strcpy(o->name, name);
243}
244
245PyObject* Client_ctor(Client*c)
246{
247  ClientObject *o = (ClientObject*)mwm_ClientType.tp_alloc(&mwm_ClientType, 0);
248  PyObject *pyo = (PyObject*)(o);
249  o->cli = c;
250 
251  XTextProperty tp;
252  if (!XGetWMName(dpy, c->window, &tp)) {
253    set_name(o, "(no name)");
254  } else if (tp.nitems > 0) {
255    int count = 0, i, ret;
256    char **list = NULL;
257    ret = XmbTextPropertyToTextList(dpy, &tp, &list, &count);
258    if((ret == Success || ret > 0) && list != NULL) {
259      for(i=0; i<count; i++)
260        set_name(o, list[i]);
261      XFreeStringList(list);
262    } else {
263      set_name(o, tp.value);
264    }
265  }
266
267  //Py_INCREF(pyo); -- todo: not sure
268  return pyo;
269}
270
271PyObject* list(PyObject*_, PyObject*__)
272{
273  Client *c;
274  PyObject *lst = PyList_New(0);
275
276  for (c = head_client; c; c = c->next)
277    PyList_Append(lst, Client_ctor(c));
278
279  return lst;
280}
281
282PyObject* get_focused(PyObject*_, PyObject*__)
283{
284  if(!current) Py_RETURN_NONE;
285  Client_ctor(current);
286}
287;;;
288
289#define HOOK_HANDLE(name) \
290PyObject * name ## _hook = NULL;                                      \
291PyObject* set_ ## name ## _hook(PyObject *_,  PyObject* pyargs)       \
292{                                                                     \
293  if(!PyTuple_Check(pyargs)) return PyExc_TypeError;                  \
294  if(PyTuple_Size(pyargs) != 1) return PyExc_TypeError;               \
295  PyObject* hook = PyTuple_GetItem(pyargs, 0);                        \
296  PyObject *ret = name ## _hook;                                      \
297  if(!PyCallable_Check(hook)) return PyExc_TypeError;                 \
298                                                                      \
299  Py_INCREF(hook);                                                    \
300  name ## _hook = hook;                                               \
301                                                                      \
302  if(ret) return ret;                                                 \
303  Py_RETURN_NONE;                                                     \
304}                                                                     \
305PyObject* run_ ## name ## _hook(Client *c)                            \
306{                                                                     \
307  PyObject *ret;                                                      \
308  if(!name ## _hook) return NULL;                                     \
309  PyGILState_STATE s = PyGILState_Ensure();                           \
310  PyObject *arg = PyTuple_New(1);                                     \
311  PyTuple_SetItem(arg, 0,  Client_ctor(c));                           \
312  ret = PyObject_CallObject(name ## _hook, arg);                      \
313  Py_DECREF(arg);                                                     \
314  PyGILState_Release(s);                                              \
315  return ret;                                                         \
316}
317
318HOOK_HANDLE(geometry);
319HOOK_HANDLE(drag_start);
320HOOK_HANDLE(drag_end);
321HOOK_HANDLE(sweep_start);
322HOOK_HANDLE(sweep_end);
323HOOK_HANDLE(mouse_enter);
324HOOK_HANDLE(mouse_leave);
325HOOK_HANDLE(mouse_button1);
326HOOK_HANDLE(mouse_button2);
327HOOK_HANDLE(mouse_button3);
328
329;;;
330
331#define HOOK_EXPOSE(sname, hname) \
332  {#sname, set_ ## hname ## _hook, METH_VARARGS}
333
334PyObject* set_key_hook(PyObject *_,  PyObject* pyargs); //todo: remove
335PyMODINIT_FUNC initmwm(void)
336{
337  static PyMethodDef mtds[] = {
338    HOOK_EXPOSE(set_post_geometry_hook, geometry),
339    HOOK_EXPOSE(set_drag_start_hook, drag_start),
340    HOOK_EXPOSE(set_drag_end_hook, drag_end),
341    HOOK_EXPOSE(set_sweep_start_hook, sweep_start),
342    HOOK_EXPOSE(set_sweep_end_hook, sweep_end),
343    HOOK_EXPOSE(set_mouse_enter_hook, mouse_enter),
344    HOOK_EXPOSE(set_mouse_leave_hook, mouse_leave),
345    HOOK_EXPOSE(set_mouse_button1_hook, mouse_button1),
346    HOOK_EXPOSE(set_mouse_button2_hook, mouse_button2),
347    HOOK_EXPOSE(set_mouse_button3_hook, mouse_button3),
348
349    HOOK_EXPOSE(set_key, key), //todo: remove
350    //    {"set_post_geometry_hook", set_post_geometry_hook, METH_VARARGS},
351    {"list",  list,  METH_VARARGS},
352    {"run",  run,  METH_VARARGS},
353    {"grab_keys", grab_keys, METH_VARARGS},
354    {"focused", get_focused, METH_VARARGS},
355    {NULL, NULL, 0,  NULL}};
356
357    PyObject* m;
358
359    mwm_ClientType.tp_new = PyType_GenericNew;
360    if (PyType_Ready(&mwm_ClientType) < 0)
361        return;
362
363    m = Py_InitModule("mwm", mtds);
364
365    Py_INCREF(&mwm_ClientType);
366    PyModule_AddObject(m, "Client", (PyObject*)&mwm_ClientType);
367}
Note: See TracBrowser for help on using the browser.