776bdb2b5f83bd0bf8b3866e20f437e5fef7b8ba
[mikachu/openbox.git] / wrap / ob_callback.i
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 %module ob_callback
4
5 %include "std_string.i"
6
7 %{
8 /*
9   Calls a python callback for the MouseCallback function type
10  */
11 static void PythonMouseCallback(ob::MouseData *data, void *pyfunc)
12 {
13   PyObject *arglist, *pdata, *result;
14
15   pdata = SWIG_NewPointerObj((void *) data, SWIGTYPE_p_ob__MouseData, 0);
16   arglist = Py_BuildValue("(O)", pdata);
17   Py_DECREF(pdata);
18
19   // call the callback
20   result = PyEval_CallObject((PyObject*)pyfunc, arglist);
21   if (!result || PyErr_Occurred()) {
22     // an exception occured in the script, display it
23     PyErr_Print();
24   }
25
26   Py_XDECREF(result);
27   Py_DECREF(arglist);
28 }
29
30 /*
31   Calls a python callback for the KeyCallback function type
32  */
33 static void PythonKeyCallback(ob::KeyData *data, void *pyfunc)
34 {
35   PyObject *arglist, *pdata, *result;
36
37   pdata = SWIG_NewPointerObj((void *) data, SWIGTYPE_p_ob__KeyData, 0);
38   arglist = Py_BuildValue("(O)", pdata);
39   Py_DECREF(pdata);
40
41   // call the callback
42   result = PyEval_CallObject((PyObject*)pyfunc, arglist);
43   if (!result || PyErr_Occurred()) {
44     // an exception occured in the script, display it
45     PyErr_Print();
46   }
47
48   Py_XDECREF(result);
49   Py_DECREF(arglist);
50 }
51
52 /*
53   Calls a python callback for the EventCallback function type
54  */
55 static void PythonEventCallback(ob::EventData *data, void *pyfunc)
56 {
57   PyObject *arglist, *pdata, *result;
58
59   pdata = SWIG_NewPointerObj((void *) data, SWIGTYPE_p_ob__EventData, 0);
60   arglist = Py_BuildValue("(O)", pdata);
61   Py_DECREF(pdata);
62
63   // call the callback
64   result = PyEval_CallObject((PyObject*)pyfunc, arglist);
65   if (!result || PyErr_Occurred()) {
66     // an exception occured in the script, display it
67     PyErr_Print();
68   }
69
70   Py_XDECREF(result);
71   Py_DECREF(arglist);
72 }
73 %}
74
75 // for all of these, PyErr_SetString is called before they return a false!
76 %exception mbind {
77   $action
78   if (!result) return NULL;
79 }
80 %exception kbind {
81   $action
82   if (!result) return NULL;
83 }
84 %exception ebind {
85   $action
86   if (!result) return NULL;
87 }
88 %exception kgrab {
89   $action
90   if (!result) return NULL;
91 }
92 %exception mgrab {
93   $action
94   if (!result) return NULL;
95 }
96
97 // Grab a Python function object as a Python object.
98 %typemap(python,in) PyObject *func {
99   if (!PyCallable_Check($input)) {
100     PyErr_SetString(PyExc_TypeError, "Excepting a callable object.");
101     return NULL;
102   }
103   $1 = $input;
104 }
105
106 %inline %{
107 #include "bindings.hh"
108   
109 bool mbind(const std::string &button, ob::MouseContext::MC context,
110            ob::MouseAction::MA action, PyObject *func)
111 {
112   if(context < 0 || context >= ob::MouseContext::NUM_MOUSE_CONTEXT) {
113     PyErr_SetString(PyExc_ValueError, "Invalid MouseContext");
114     return false;
115   }
116   if(action < 0 || action >= ob::MouseAction::NUM_MOUSE_ACTION) {
117     PyErr_SetString(PyExc_ValueError, "Invalid MouseAction");
118     return false;
119   }
120   
121   if (!ob::openbox->bindings()->addButton(button, context,
122                                           action, PythonMouseCallback, func)) {
123     PyErr_SetString(PyExc_RuntimeError,"Unable to add binding.");
124     return false;
125   }
126   Py_INCREF(func); // the func is never decreffed... XXX
127   return true;
128 }
129
130 bool ebind(ob::EventAction::EA action, PyObject *func)
131 {
132   if(action < 0 || action >= ob::EventAction::NUM_EVENT_ACTION) {
133     PyErr_SetString(PyExc_ValueError, "Invalid EventAction");
134     return false;
135   }
136
137   if (!ob::openbox->bindings()->addEvent(action, PythonEventCallback, func)) {
138     PyErr_SetString(PyExc_RuntimeError,"Unable to add binding.");
139     return false;
140   }
141   Py_INCREF(func); // the func is never decreffed... XXX
142   return true;
143 }
144
145 bool kgrab(int screen, PyObject *func)
146 {
147   if (!ob::openbox->bindings()->grabKeyboard(screen,
148                                              PythonKeyCallback, func)) {
149     PyErr_SetString(PyExc_RuntimeError,"Unable to grab keybaord.");
150     return false;
151   }
152   Py_INCREF(func); // the func is never decreffed... XXX
153   return true;
154 }
155
156 void kungrab()
157 {
158   ob::openbox->bindings()->ungrabKeyboard();
159 }
160
161 bool mgrab(int screen)
162 {
163   if (!ob::openbox->bindings()->grabPointer(screen)) {
164     PyErr_SetString(PyExc_RuntimeError,"Unable to grab pointer.");
165     return false;
166   }
167   return true;
168 }
169
170 void mungrab()
171 {
172   ob::openbox->bindings()->ungrabPointer();
173 }
174
175 bool kbind(PyObject *keylist, ob::KeyContext::KC context, PyObject *func)
176 {
177   if (!PyList_Check(keylist)) {
178     PyErr_SetString(PyExc_TypeError, "Invalid keylist. Not a list.");
179     return false;
180   }
181   if(context < 0 || context >= ob::KeyContext::NUM_KEY_CONTEXT) {
182     PyErr_SetString(PyExc_ValueError, "Invalid KeyContext");
183     return false;
184   }
185
186   ob::Bindings::StringVect vectkeylist;
187   for (int i = 0, end = PyList_Size(keylist); i < end; ++i) {
188     PyObject *str = PyList_GetItem(keylist, i);
189     if (!PyString_Check(str)) {
190       PyErr_SetString(PyExc_TypeError,
191                      "Invalid keylist. It must contain only strings.");
192       return false;
193     }
194     vectkeylist.push_back(PyString_AsString(str));
195   }
196
197   (void)context; // XXX use this sometime!
198   if (!ob::openbox->bindings()->addKey(vectkeylist, PythonKeyCallback, func)) {
199     PyErr_SetString(PyExc_RuntimeError,"Unable to add binding.");
200     return false;
201   }
202   Py_INCREF(func); // the func is never decreffed... XXX
203   return true;
204 }
205
206 %};