+
+bool Bindings::addEvent(EventAction action, PyObject *callback)
+{
+ if (action < 0 || action >= NUM_EVENTS) {
+ return false;
+ }
+#ifdef XKB
+ if (action == EventBell && _eventlist[action].empty())
+ XkbSelectEvents(otk::Display::display, XkbUseCoreKbd,
+ XkbBellNotifyMask, XkbBellNotifyMask);
+#endif // XKB
+ _eventlist[action].push_back(callback);
+ Py_INCREF(callback);
+ return true;
+}
+
+bool Bindings::removeEvent(EventAction action, PyObject *callback)
+{
+ if (action < 0 || action >= NUM_EVENTS) {
+ return false;
+ }
+
+ CallbackList::iterator it = std::find(_eventlist[action].begin(),
+ _eventlist[action].end(),
+ callback);
+ if (it != _eventlist[action].end()) {
+ Py_XDECREF(*it);
+ _eventlist[action].erase(it);
+#ifdef XKB
+ if (action == EventBell && _eventlist[action].empty())
+ XkbSelectEvents(otk::Display::display, XkbUseCoreKbd,
+ XkbBellNotifyMask, 0);
+#endif // XKB
+ return true;
+ }
+ return false;
+}
+
+void Bindings::removeAllEvents()
+{
+ for (int i = 0; i < NUM_EVENTS; ++i) {
+ while (!_eventlist[i].empty()) {
+ Py_XDECREF(_eventlist[i].front());
+ _eventlist[i].pop_front();
+ }
+ }
+}
+
+void Bindings::fireEvent(EventData *data)
+{
+ CallbackList::iterator c_it, c_end = _eventlist[data->action].end();
+ for (c_it = _eventlist[data->action].begin(); c_it != c_end; ++c_it)
+ python_callback(*c_it, data);
+}
+