diff options
| author | Dana Jansens <danakj@orodu.net> | 2003-03-16 21:11:39 +0000 |
|---|---|---|
| committer | Dana Jansens <danakj@orodu.net> | 2003-03-16 21:11:39 +0000 |
| commit | f8a47de5ec444c452093371e3db16857eb39a490 (patch) | |
| tree | 31db2567842d98232775f9980f7a8d2586c0ac71 /c/eventdata.c | |
| parent | 8ba0586bcbdc7fe9648f1063812126d71a041670 (diff) | |
merge the C branch into HEAD
Diffstat (limited to 'c/eventdata.c')
| -rw-r--r-- | c/eventdata.c | 433 |
1 files changed, 433 insertions, 0 deletions
diff --git a/c/eventdata.c b/c/eventdata.c new file mode 100644 index 00000000..e3bf15e1 --- /dev/null +++ b/c/eventdata.c @@ -0,0 +1,433 @@ +#include "eventdata.h" +#include "openbox.h" +#include "event.h" +#include "clientwrap.h" +#include <X11/Xlib.h> + +/* + * + * Define the type 'EventData' + * + */ + +#define IS_EVENTDATA(v) ((v)->ob_type == &EventDataType) +#define CHECK_EVENTDATA(self, funcname) { \ + if (!IS_EVENTDATA(self)) { \ + PyErr_SetString(PyExc_TypeError, \ + "descriptor '" funcname "' requires an 'EventData' " \ + "object"); \ + return NULL; \ + } \ +} + +staticforward PyTypeObject EventDataType; + +static PyObject *eventdata_type(EventData *self, PyObject *args) +{ + CHECK_EVENTDATA(self, "type"); + if (!PyArg_ParseTuple(args, ":type")) + return NULL; + return PyInt_FromLong(self->type); +} + +static PyObject *eventdata_time(EventData *self, PyObject *args) +{ + CHECK_EVENTDATA(self, "time"); + if (!PyArg_ParseTuple(args, ":time")) + return NULL; + return PyInt_FromLong(event_lasttime); +} + +static PyObject *eventdata_context(EventData *self, PyObject *args) +{ + CHECK_EVENTDATA(self, "context"); + if (!PyArg_ParseTuple(args, ":context")) + return NULL; + return PyString_FromString(self->context); +} + +static PyObject *eventdata_client(EventData *self, PyObject *args) +{ + CHECK_EVENTDATA(self, "client"); + if (!PyArg_ParseTuple(args, ":client")) + return NULL; + if (self->client == NULL) { + Py_INCREF(Py_None); + return Py_None; + } else { + return clientwrap_new(self->client); + } +} + +static PyObject *eventdata_keycode(EventData *self, PyObject *args) +{ + CHECK_EVENTDATA(self, "keycode"); + if (!PyArg_ParseTuple(args, ":keycode")) + return NULL; + switch (self->type) { + case Key_Press: + case Key_Release: + break; + default: + PyErr_SetString(PyExc_TypeError, + "The EventData object is not a Key event"); + return NULL; + } + return PyInt_FromLong(self->details.key->keycode); +} + +static PyObject *eventdata_modifiers(EventData *self, PyObject *args) +{ + CHECK_EVENTDATA(self, "key"); + if (!PyArg_ParseTuple(args, ":key")) + return NULL; + switch (self->type) { + case Key_Press: + case Key_Release: + case Pointer_Press: + case Pointer_Release: + case Pointer_Motion: + break; + default: + PyErr_SetString(PyExc_TypeError, + "The EventData object is not a Key or Pointer event"); + return NULL; + } + return PyInt_FromLong(self->details.key->modifiers); +} + +static PyObject *eventdata_keyName(EventData *self, PyObject *args) +{ + GList *it; + PyObject *tuple; + int i; + + CHECK_EVENTDATA(self, "keyName"); + if (!PyArg_ParseTuple(args, ":keyName")) + return NULL; + switch (self->type) { + case Key_Press: + case Key_Release: + break; + default: + PyErr_SetString(PyExc_TypeError, + "The EventData object is not a Key event"); + return NULL; + } + + if (self->details.key->keylist != NULL) { + tuple = PyTuple_New(g_list_length(self->details.key->keylist)); + for (i = 0, it = self->details.key->keylist; it != NULL; + it = it->next, ++i) + PyTuple_SET_ITEM(tuple, i, PyString_FromString(it->data)); + return tuple; + } else { + GString *str = g_string_sized_new(0); + KeySym sym; + + if (self->details.key->modifiers & ControlMask) + g_string_append(str, "C-"); + if (self->details.key->modifiers & ShiftMask) + g_string_append(str, "S-"); + if (self->details.key->modifiers & Mod1Mask) + g_string_append(str, "Mod1-"); + if (self->details.key->modifiers & Mod2Mask) + g_string_append(str, "Mod2-"); + if (self->details.key->modifiers & Mod3Mask) + g_string_append(str, "Mod3-"); + if (self->details.key->modifiers & Mod4Mask) + g_string_append(str, "Mod4-"); + if (self->details.key->modifiers & Mod5Mask) + g_string_append(str, "Mod5-"); + + sym = XKeycodeToKeysym(ob_display, self->details.key->keycode, 0); + if (sym == NoSymbol) + g_string_append(str, "NoSymbol"); + else { + char *name = XKeysymToString(sym); + if (name == NULL) + name = "Undefined"; + g_string_append(str, name); + } + + tuple = PyTuple_New(1); + PyTuple_SET_ITEM(tuple, 0, PyString_FromString(str->str)); + g_string_free(str, TRUE); + + return tuple; + } +} + +static PyObject *eventdata_button(EventData *self, PyObject *args) +{ + CHECK_EVENTDATA(self, "button"); + if (!PyArg_ParseTuple(args, ":button")) + return NULL; + switch (self->type) { + case Pointer_Press: + case Pointer_Release: + case Pointer_Motion: + break; + default: + PyErr_SetString(PyExc_TypeError, + "The EventData object is not a Pointer event"); + return NULL; + } + return PyInt_FromLong(self->details.pointer->button); +} + +static PyObject *eventdata_buttonName(EventData *self, PyObject *args) +{ + CHECK_EVENTDATA(self, "buttonName"); + if (!PyArg_ParseTuple(args, ":buttonName")) + return NULL; + switch (self->type) { + case Pointer_Press: + case Pointer_Release: + case Pointer_Motion: + break; + default: + PyErr_SetString(PyExc_TypeError, + "The EventData object is not a Pointer event"); + return NULL; + } + + if (self->details.pointer->name != NULL) { + return PyString_FromString(self->details.pointer->name); + } else { + PyObject *pystr; + GString *str = g_string_sized_new(0); + + if (self->details.pointer->modifiers & ControlMask) + g_string_append(str, "C-"); + if (self->details.pointer->modifiers & ShiftMask) + g_string_append(str, "S-"); + if (self->details.pointer->modifiers & Mod1Mask) + g_string_append(str, "Mod1-"); + if (self->details.pointer->modifiers & Mod2Mask) + g_string_append(str, "Mod2-"); + if (self->details.pointer->modifiers & Mod3Mask) + g_string_append(str, "Mod3-"); + if (self->details.pointer->modifiers & Mod4Mask) + g_string_append(str, "Mod4-"); + if (self->details.pointer->modifiers & Mod5Mask) + g_string_append(str, "Mod5-"); + + g_string_append_printf(str, "%d", self->details.pointer->button); + + pystr = PyString_FromString(str->str); + + g_string_free(str, TRUE); + + return pystr; + } +} + +static PyObject *eventdata_position(EventData *self, PyObject *args) +{ + PyObject *tuple; + + CHECK_EVENTDATA(self, "position"); + if (!PyArg_ParseTuple(args, ":position")) + return NULL; + switch (self->type) { + case Pointer_Press: + case Pointer_Release: + case Pointer_Motion: + break; + default: + PyErr_SetString(PyExc_TypeError, + "The EventData object is not a Pointer event"); + return NULL; + } + tuple = PyTuple_New(2); + PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(self->details.pointer->xroot)); + PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(self->details.pointer->yroot)); + return tuple; +} + +static PyMethodDef EventDataAttributeMethods[] = { + {"type", (PyCFunction)eventdata_type, METH_VARARGS, + "data.type() -- Return the event type"}, + {"context", (PyCFunction)eventdata_context, METH_VARARGS, + "data.context() -- Return the context for the event. If it is " + "\"client\", then data.client() can be used to find out the " + "client."}, + {"client", (PyCFunction)eventdata_client, METH_VARARGS, + "data.client() -- Return the client for the event. This may be None if " + "there is no client, even if data.context() gives Context_Client."}, + {"time", (PyCFunction)eventdata_time, METH_VARARGS, + "data.time() -- Return the time at which the last X event occured with " + "a timestamp. Should be the time at which this event, or the event that " + "caused this event to occur happened."}, + {"modifiers", (PyCFunction)eventdata_modifiers, METH_VARARGS, + "data.modifiers() -- Return the modifier keymask that was pressed " + "when the event occured. A bitmask of ShiftMask, LockMask, ControlMask, " + "Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask. Cannot be used " + "when the data.type() is not a Key_* or Pointer_* event type."}, + {"keycode", (PyCFunction)eventdata_keycode, METH_VARARGS, + "data.keycode() -- Return the keycode for the key which generated the " + "event. Cannot be used when the data.type() is not a Key_* event type."}, + {"keyName", (PyCFunction)eventdata_keyName, METH_VARARGS, + "data.keyName() -- Return a tuple of the string names of the key which " + "generated the event. Cannot be used when the data.type() is not a Key_* " + "event " + "type."}, + {"button", (PyCFunction)eventdata_button, METH_VARARGS, + "data.button() -- Return the pointer button which generated the event. " + "Cannot be used when the data.type() is not a Pointer_* event type."}, + {"buttonName", (PyCFunction)eventdata_keyName, METH_VARARGS, + "data.buttonName() -- Return the name of the button which generated the " + "event. Cannot be used when the data.type() is not a Pointer_* event " + "type."}, + {"position", (PyCFunction)eventdata_position, METH_VARARGS, + "data.position() -- Returns the current position of the pointer on the " + "root window when the event was generated. Gives the position in a tuple " + "with a format of (x, y). Cannot be used when the data.type() is not a " + "Pointer_* event type."}, + { NULL, NULL, 0, NULL } +}; + +static void data_dealloc(EventData *self) +{ + GList *it; + + switch(self->type) { + case Logical_EnterWindow: + case Logical_LeaveWindow: + case Logical_NewWindow: + case Logical_CloseWindow: + case Logical_Startup: + case Logical_Shutdown: + case Logical_RequestActivate: + case Logical_WindowShow: + case Logical_WindowHide: + case Logical_Focus: + case Logical_Bell: + case Logical_UrgentWindow: + g_free(self->details.logical); + break; + case Pointer_Press: + case Pointer_Release: + case Pointer_Motion: + if (self->details.pointer->name != NULL) + g_free(self->details.pointer->name); + g_free(self->details.pointer); + break; + case Key_Press: + case Key_Release: + for (it = self->details.key->keylist; it != NULL; it = it->next) + g_free(it->data); + g_list_free(self->details.key->keylist); + g_free(self->details.key); + break; + default: + g_assert_not_reached(); + } + PyObject_Del((PyObject*) self); +} + +static PyObject *eventdata_getattr(EventData *self, char *name) +{ + return Py_FindMethod(EventDataAttributeMethods, (PyObject*)self, name); +} + +static PyTypeObject EventDataType = { + PyObject_HEAD_INIT(NULL) + 0, + "EventData", + sizeof(EventData), + 0, + (destructor) data_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + (getattrfunc) eventdata_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ +}; + + + +void eventdata_startup() +{ + EventDataType.ob_type = &PyType_Type; + PyType_Ready(&EventDataType); +} + +void eventdata_shutdown() +{ +} + +void eventdata_free(EventData *data) +{ + Py_DECREF(data); +} + +EventData *eventdata_new_logical(EventType type, GQuark context, + struct Client *client) +{ + EventData *data; + + g_assert(type < Pointer_Press); + + data = PyObject_New(EventData, &EventDataType); + data->type = type; + data->context = g_quark_to_string(context); + data->client = client; + data->details.logical = g_new(LogicalEvent, 1); + return data; +} + +EventData *eventdata_new_pointer(EventType type, GQuark context, + struct Client *client, guint modifiers, + guint button, char *name, + int xroot, int yroot) +{ + EventData *data; + + g_assert(type >= Pointer_Press && type < Key_Press); + + data = PyObject_New(EventData, &EventDataType); + data->type = type; + data->context = g_quark_to_string(context); + data->client = client; + data->details.pointer = g_new(PointerEvent, 1); + data->details.pointer->modifiers = modifiers; + data->details.pointer->button = button; + data->details.pointer->name = name == NULL ? name : g_strdup(name); + data->details.pointer->xroot = xroot; + data->details.pointer->yroot = yroot; + return data; +} + +EventData *eventdata_new_key(EventType type, GQuark context, + struct Client *client, guint modifiers, + guint keycode, GList *keylist) +{ + EventData *data; + GList *mykeylist, *it; + + g_assert(type >= Key_Press); + + data = PyObject_New(EventData, &EventDataType); + data->type = type; + data->context = g_quark_to_string(context); + data->client = client; + data->details.key = g_new(KeyEvent, 1); + + /* make a copy of the keylist. + If the user were to clear the key bindings, then the keylist given here + would no longer point at valid memory.*/ + mykeylist = g_list_copy(keylist); /* shallow copy */ + for (it = mykeylist; it != NULL; it = it->next) /* deep copy */ + it->data = g_strdup(it->data); + + data->details.key->keylist = mykeylist; + data->details.key->keycode = keycode; + data->details.key->modifiers = modifiers; + return data; +} |
