4 #include "clientwrap.h"
9 * Define the type 'EventData'
13 #define IS_EVENTDATA(v) ((v)->ob_type == &EventDataType)
14 #define CHECK_EVENTDATA(self, funcname) { \
15 if (!IS_EVENTDATA(self)) { \
16 PyErr_SetString(PyExc_TypeError, \
17 "descriptor '" funcname "' requires an 'EventData' " \
23 staticforward PyTypeObject EventDataType;
25 static PyObject *eventdata_type(EventData *self, PyObject *args)
27 CHECK_EVENTDATA(self, "type");
28 if (!PyArg_ParseTuple(args, ":type"))
30 return PyInt_FromLong(self->type);
33 static PyObject *eventdata_time(EventData *self, PyObject *args)
35 CHECK_EVENTDATA(self, "time");
36 if (!PyArg_ParseTuple(args, ":time"))
38 return PyInt_FromLong(event_lasttime);
41 static PyObject *eventdata_context(EventData *self, PyObject *args)
43 CHECK_EVENTDATA(self, "context");
44 if (!PyArg_ParseTuple(args, ":context"))
46 return PyString_FromString(self->context);
49 static PyObject *eventdata_client(EventData *self, PyObject *args)
51 CHECK_EVENTDATA(self, "client");
52 if (!PyArg_ParseTuple(args, ":client"))
54 if (self->client == NULL) {
58 return clientwrap_new(self->client);
62 static PyObject *eventdata_keycode(EventData *self, PyObject *args)
64 CHECK_EVENTDATA(self, "keycode");
65 if (!PyArg_ParseTuple(args, ":keycode"))
72 PyErr_SetString(PyExc_TypeError,
73 "The EventData object is not a Key event");
76 return PyInt_FromLong(self->details.key->keycode);
79 static PyObject *eventdata_modifiers(EventData *self, PyObject *args)
81 CHECK_EVENTDATA(self, "key");
82 if (!PyArg_ParseTuple(args, ":key"))
92 PyErr_SetString(PyExc_TypeError,
93 "The EventData object is not a Key or Pointer event");
96 return PyInt_FromLong(self->details.key->modifiers);
99 static PyObject *eventdata_keyName(EventData *self, PyObject *args)
105 CHECK_EVENTDATA(self, "keyName");
106 if (!PyArg_ParseTuple(args, ":keyName"))
108 switch (self->type) {
113 PyErr_SetString(PyExc_TypeError,
114 "The EventData object is not a Key event");
118 if (self->details.key->keylist != NULL) {
119 tuple = PyTuple_New(g_list_length(self->details.key->keylist));
120 for (i = 0, it = self->details.key->keylist; it != NULL;
122 PyTuple_SET_ITEM(tuple, i, PyString_FromString(it->data));
125 GString *str = g_string_sized_new(0);
128 if (self->details.key->modifiers & ControlMask)
129 g_string_append(str, "C-");
130 if (self->details.key->modifiers & ShiftMask)
131 g_string_append(str, "S-");
132 if (self->details.key->modifiers & Mod1Mask)
133 g_string_append(str, "Mod1-");
134 if (self->details.key->modifiers & Mod2Mask)
135 g_string_append(str, "Mod2-");
136 if (self->details.key->modifiers & Mod3Mask)
137 g_string_append(str, "Mod3-");
138 if (self->details.key->modifiers & Mod4Mask)
139 g_string_append(str, "Mod4-");
140 if (self->details.key->modifiers & Mod5Mask)
141 g_string_append(str, "Mod5-");
143 sym = XKeycodeToKeysym(ob_display, self->details.key->keycode, 0);
145 g_string_append(str, "NoSymbol");
147 char *name = XKeysymToString(sym);
150 g_string_append(str, name);
153 tuple = PyTuple_New(1);
154 PyTuple_SET_ITEM(tuple, 0, PyString_FromString(str->str));
155 g_string_free(str, TRUE);
161 static PyObject *eventdata_button(EventData *self, PyObject *args)
163 CHECK_EVENTDATA(self, "button");
164 if (!PyArg_ParseTuple(args, ":button"))
166 switch (self->type) {
168 case Pointer_Release:
172 PyErr_SetString(PyExc_TypeError,
173 "The EventData object is not a Pointer event");
176 return PyInt_FromLong(self->details.pointer->button);
179 static PyObject *eventdata_buttonName(EventData *self, PyObject *args)
181 CHECK_EVENTDATA(self, "buttonName");
182 if (!PyArg_ParseTuple(args, ":buttonName"))
184 switch (self->type) {
186 case Pointer_Release:
190 PyErr_SetString(PyExc_TypeError,
191 "The EventData object is not a Pointer event");
195 if (self->details.pointer->name != NULL) {
196 return PyString_FromString(self->details.pointer->name);
199 GString *str = g_string_sized_new(0);
201 if (self->details.pointer->modifiers & ControlMask)
202 g_string_append(str, "C-");
203 if (self->details.pointer->modifiers & ShiftMask)
204 g_string_append(str, "S-");
205 if (self->details.pointer->modifiers & Mod1Mask)
206 g_string_append(str, "Mod1-");
207 if (self->details.pointer->modifiers & Mod2Mask)
208 g_string_append(str, "Mod2-");
209 if (self->details.pointer->modifiers & Mod3Mask)
210 g_string_append(str, "Mod3-");
211 if (self->details.pointer->modifiers & Mod4Mask)
212 g_string_append(str, "Mod4-");
213 if (self->details.pointer->modifiers & Mod5Mask)
214 g_string_append(str, "Mod5-");
216 g_string_append_printf(str, "%d", self->details.pointer->button);
218 pystr = PyString_FromString(str->str);
220 g_string_free(str, TRUE);
226 static PyObject *eventdata_position(EventData *self, PyObject *args)
230 CHECK_EVENTDATA(self, "position");
231 if (!PyArg_ParseTuple(args, ":position"))
233 switch (self->type) {
235 case Pointer_Release:
239 PyErr_SetString(PyExc_TypeError,
240 "The EventData object is not a Pointer event");
243 tuple = PyTuple_New(2);
244 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->details.pointer->xroot));
245 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->details.pointer->yroot));
249 static PyMethodDef EventDataAttributeMethods[] = {
250 {"type", (PyCFunction)eventdata_type, METH_VARARGS,
251 "data.type() -- Return the event type"},
252 {"context", (PyCFunction)eventdata_context, METH_VARARGS,
253 "data.context() -- Return the context for the event. If it is "
254 "\"client\", then data.client() can be used to find out the "
256 {"client", (PyCFunction)eventdata_client, METH_VARARGS,
257 "data.client() -- Return the client for the event. This may be None if "
258 "there is no client, even if data.context() gives Context_Client."},
259 {"time", (PyCFunction)eventdata_time, METH_VARARGS,
260 "data.time() -- Return the time at which the last X event occured with "
261 "a timestamp. Should be the time at which this event, or the event that "
262 "caused this event to occur happened."},
263 {"modifiers", (PyCFunction)eventdata_modifiers, METH_VARARGS,
264 "data.modifiers() -- Return the modifier keymask that was pressed "
265 "when the event occured. A bitmask of ShiftMask, LockMask, ControlMask, "
266 "Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask. Cannot be used "
267 "when the data.type() is not a Key_* or Pointer_* event type."},
268 {"keycode", (PyCFunction)eventdata_keycode, METH_VARARGS,
269 "data.keycode() -- Return the keycode for the key which generated the "
270 "event. Cannot be used when the data.type() is not a Key_* event type."},
271 {"keyName", (PyCFunction)eventdata_keyName, METH_VARARGS,
272 "data.keyName() -- Return a tuple of the string names of the key which "
273 "generated the event. Cannot be used when the data.type() is not a Key_* "
276 {"button", (PyCFunction)eventdata_button, METH_VARARGS,
277 "data.button() -- Return the pointer button which generated the event. "
278 "Cannot be used when the data.type() is not a Pointer_* event type."},
279 {"buttonName", (PyCFunction)eventdata_keyName, METH_VARARGS,
280 "data.buttonName() -- Return the name of the button which generated the "
281 "event. Cannot be used when the data.type() is not a Pointer_* event "
283 {"position", (PyCFunction)eventdata_position, METH_VARARGS,
284 "data.position() -- Returns the current position of the pointer on the "
285 "root window when the event was generated. Gives the position in a tuple "
286 "with a format of (x, y). Cannot be used when the data.type() is not a "
287 "Pointer_* event type."},
288 { NULL, NULL, 0, NULL }
291 static void data_dealloc(EventData *self)
296 case Logical_EnterWindow:
297 case Logical_LeaveWindow:
298 case Logical_NewWindow:
299 case Logical_CloseWindow:
300 case Logical_Startup:
301 case Logical_Shutdown:
302 case Logical_RequestActivate:
303 case Logical_WindowShow:
304 case Logical_WindowHide:
307 case Logical_UrgentWindow:
308 g_free(self->details.logical);
311 case Pointer_Release:
313 if (self->details.pointer->name != NULL)
314 g_free(self->details.pointer->name);
315 g_free(self->details.pointer);
319 for (it = self->details.key->keylist; it != NULL; it = it->next)
321 g_list_free(self->details.key->keylist);
322 g_free(self->details.key);
325 g_assert_not_reached();
327 PyObject_Del((PyObject*) self);
330 static PyObject *eventdata_getattr(EventData *self, char *name)
332 return Py_FindMethod(EventDataAttributeMethods, (PyObject*)self, name);
335 static PyTypeObject EventDataType = {
336 PyObject_HEAD_INIT(NULL)
341 (destructor) data_dealloc, /*tp_dealloc*/
343 (getattrfunc) eventdata_getattr, /*tp_getattr*/
348 0, /*tp_as_sequence*/
355 void eventdata_startup()
357 EventDataType.ob_type = &PyType_Type;
358 PyType_Ready(&EventDataType);
361 void eventdata_shutdown()
365 void eventdata_free(EventData *data)
370 EventData *eventdata_new_logical(EventType type, GQuark context,
371 struct Client *client)
375 g_assert(type < Pointer_Press);
377 data = PyObject_New(EventData, &EventDataType);
379 data->context = g_quark_to_string(context);
380 data->client = client;
381 data->details.logical = g_new(LogicalEvent, 1);
385 EventData *eventdata_new_pointer(EventType type, GQuark context,
386 struct Client *client, guint modifiers,
387 guint button, char *name,
388 int xroot, int yroot)
392 g_assert(type >= Pointer_Press && type < Key_Press);
394 data = PyObject_New(EventData, &EventDataType);
396 data->context = g_quark_to_string(context);
397 data->client = client;
398 data->details.pointer = g_new(PointerEvent, 1);
399 data->details.pointer->modifiers = modifiers;
400 data->details.pointer->button = button;
401 data->details.pointer->name = name == NULL ? name : g_strdup(name);
402 data->details.pointer->xroot = xroot;
403 data->details.pointer->yroot = yroot;
407 EventData *eventdata_new_key(EventType type, GQuark context,
408 struct Client *client, guint modifiers,
409 guint keycode, GList *keylist)
412 GList *mykeylist, *it;
414 g_assert(type >= Key_Press);
416 data = PyObject_New(EventData, &EventDataType);
418 data->context = g_quark_to_string(context);
419 data->client = client;
420 data->details.key = g_new(KeyEvent, 1);
422 /* make a copy of the keylist.
423 If the user were to clear the key bindings, then the keylist given here
424 would no longer point at valid memory.*/
425 mykeylist = g_list_copy(keylist); /* shallow copy */
426 for (it = mykeylist; it != NULL; it = it->next) /* deep copy */
427 it->data = g_strdup(it->data);
429 data->details.key->keylist = mykeylist;
430 data->details.key->keycode = keycode;
431 data->details.key->modifiers = modifiers;