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