From: Felix Domke Date: Mon, 21 Mar 2005 21:52:48 +0000 (+0000) Subject: - added missing actions (sorry) X-Git-Tag: 2.6.0~5921 X-Git-Url: https://git.cweiske.de/enigma2.git/commitdiff_plain/95ac56f69ddb6de8e260c8e55aff68d1df0b452c?hp=3af66122574386a2856e83ba9c5d73d27a6f3710 - added missing actions (sorry) --- diff --git a/lib/actions/Makefile.am b/lib/actions/Makefile.am new file mode 100644 index 00000000..cdaf2a70 --- /dev/null +++ b/lib/actions/Makefile.am @@ -0,0 +1,13 @@ +INCLUDES = \ + -I$(top_srcdir)/include + +noinst_LIBRARIES = libenigma_actions.a + +libenigma_actions_a_SOURCES = \ + action.cpp + +action.cpp: actionids.h + +actionids.h: + python ./parseactions.py include ../gui/*.h > actionids.h + python ./parseactions.py parse ../gui/*.h >> actionids.h diff --git a/lib/actions/action.cpp b/lib/actions/action.cpp new file mode 100644 index 00000000..c538bd48 --- /dev/null +++ b/lib/actions/action.cpp @@ -0,0 +1,178 @@ +#include +#include +#include +#include + +/* + + THIS CODE SUCKS. + +we need: + - contexts that aren't compared as strings, + - maybe a lookup "device,key,flags" -> actions? (lazy validation, on bindAction) + - devices as ids + - seperate native from python keys? (currently, if an action wasn't found, it's ignored.) + +Sorry. I spent 3 days on thinking how this could be made better, and it just DID NOT WORKED OUT. + +If you have a better idea, please tell me. + + */ + +DEFINE_REF(eActionMap); + +eActionMap *eActionMap::instance; + +eActionMap::eActionMap() +{ + instance = this; +} + +eActionMap::~eActionMap() +{ + instance = 0; +} + +RESULT eActionMap::getInstance(ePtr &ptr) +{ + ptr = instance; + if (!ptr) + return -1; + return 0; +} + +#if 0 +void eActionMap::getInstance(eActionMap **ptr) +{ + *ptr = instance; +} +#endif + +void eActionMap::bindAction(const std::string &context, int priority, int id, eWidget *widget) +{ + eActionBinding bnd; + + bnd.m_context = context; + bnd.m_widget = widget; + bnd.m_fnc = 0; + bnd.m_id = id; + m_bindings.insert(std::pair(priority, bnd)); +} + +void eActionMap::bindAction(const std::string &context, int priority, PyObject *function) +{ + eActionBinding bnd; + + bnd.m_context = context; + bnd.m_widget = 0; + Py_INCREF(function); + bnd.m_fnc = function; + m_bindings.insert(std::pair(priority, bnd)); +} + +void eActionMap::unbindAction(eWidget *widget, int id) +{ + for (std::multimap::iterator i(m_bindings.begin()); i != m_bindings.end(); ++i) + if ((i->second.m_widget == widget) && (i->second.m_id == id)) + { + m_bindings.erase(i); + return; + } +} + +void eActionMap::unbindAction(const std::string &context, PyObject *function) +{ + for (std::multimap::iterator i(m_bindings.begin()); i != m_bindings.end(); ++i) + { + if (i->second.m_fnc && (PyObject_Compare(i->second.m_fnc, function) == 0)) + { + Py_DECREF(i->second.m_fnc); + m_bindings.erase(i); + return; + } + } + eFatal("unbindAction with illegal python reference"); +} + + +void eActionMap::bindKey(const std::string &device, int key, int flags, const std::string &context, const std::string &action) +{ + // first, search the actionlist table + unsigned int i; + for (i=0; i(context, bind)); + return; + } + } + + // we didn't find the action, so it must be a pythonAction + ePythonKeyBinding bind; + + bind.m_device = 0; + bind.m_key = key; + bind.m_flags = flags; + bind.m_action = action; + m_python_keys.insert(std::pair(context, bind)); +} + +void eActionMap::keyPressed(int device, int key, int flags) +{ + /* iterate active contexts. */ + for (std::multimap::const_iterator c(m_bindings.begin()); c != m_bindings.end();) + { + std::multimap::const_iterator i = c; + ++c; + /* is this a native context? */ + if (i->second.m_widget) + { + std::multimap::const_iterator + k = m_native_keys.lower_bound(i->second.m_context), + e = m_native_keys.upper_bound(i->second.m_context); + + for (; k != e; ++k) + { + if ( + // (k->second.m_device == m_device) && + (k->second.m_key == key) && + ((k->second.m_flags & flags)==flags)) + { + if (i->second.m_widget->event(eWidget::evtAction, 0, (void*)k->second.m_action)) + return; + } + } + } else if (i->second.m_fnc) + { + std::multimap::const_iterator + k = m_python_keys.lower_bound(i->second.m_context), + e = m_python_keys.upper_bound(i->second.m_context); + + for (; k != e;) + { + if ( + // (k->second.m_device == m_device) && + (k->second.m_key == key) && + ((k->second.m_flags & flags)==flags)) + { + PyObject *pArgs = PyTuple_New(2); + PyTuple_SetItem(pArgs, 0, PyString_FromString(k->first.c_str())); + PyTuple_SetItem(pArgs, 1, PyString_FromString(k->second.m_action.c_str())); + ++k; + ePython::call(i->second.m_fnc, pArgs); + Py_DECREF(pArgs); + } else + ++k; + } + } + } +} + +eAutoInitPtr init_eActionMap(eAutoInitNumbers::actions, "eActionMap"); diff --git a/lib/actions/action.h b/lib/actions/action.h new file mode 100644 index 00000000..63a2f349 --- /dev/null +++ b/lib/actions/action.h @@ -0,0 +1,79 @@ +#ifndef __lib_driver_action_h +#define __lib_driver_action_h + +#include + + /* avoid warnigs :) */ +#include +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112L +#include +#include +#include +#include + +class eWidget; + +class eActionMap: public iObject +{ +DECLARE_REF(eActionMap); +public: +#ifndef SWIG + eActionMap(); + ~eActionMap(); + void bindAction(const std::string &context, int priority, int id, eWidget *widget); + void unbindAction(eWidget *widget, int id); +#endif + + void bindAction(const std::string &context, int priority, PyObject *function); + void unbindAction(const std::string &context, PyObject *function); + + void bindKey(const std::string &device, int key, int flags, const std::string &context, const std::string &action); + + void keyPressed(int device, int key, int flags); + + static RESULT getInstance(ePtr &ptr); +#ifndef SWIG +private: + static eActionMap *instance; + struct eActionBinding + { +// eActionContext *m_context; + std::string m_context; // FIXME + + PyObject *m_fnc; + + eWidget *m_widget; + int m_id; + }; + + std::multimap m_bindings; + + friend struct compare_string_keybind_native; + struct eNativeKeyBinding + { + int m_device; + int m_key; + int m_flags; + +// eActionContext *m_context; + int m_action; + }; + + std::multimap m_native_keys; + + friend struct compare_string_keybind_python; + struct ePythonKeyBinding + { + int m_device; + int m_key; + int m_flags; + + std::string m_action; + }; + + std::multimap m_python_keys; +#endif +}; + +#endif diff --git a/lib/actions/actionids.h b/lib/actions/actionids.h new file mode 100644 index 00000000..e69de29b diff --git a/lib/actions/parseactions.py b/lib/actions/parseactions.py new file mode 100644 index 00000000..683febd9 --- /dev/null +++ b/lib/actions/parseactions.py @@ -0,0 +1,114 @@ +# takes a header file, outputs action ids + +import token, tokenize, os, sys, string + +def filter(g): + while 1: + t = g.next() + if t[1] == "/*": + while g.next()[1] != "*/": + pass + continue + if t[1] == "//": + while g.next()[1] != "\n": + pass + continue + + if t[1] != "\n": +# print t + yield t[1] + +def do_file(f, mode): + tokens = filter(tokenize.generate_tokens(open(f, 'r').readline)) + + sys.stderr.write("parsing %s\n" % f) + + state = 0 + + classstate = 0 + + firsthit = 1 + + while 1: + try: + t = tokens.next() + except: + break + + if t == "class": + classname = tokens.next() + classstate = state + + if t == "{": + state = state + 1 + + if t == "}": + state = state - 1 + + if t == "enum" and state == classstate + 1: + actionname = tokens.next() + + if actionname[-7:] == "Actions": + if tokens.next() != "{": + try: + print classname + except: + pass + + try: + print actionname + except: + pass + + raise "action enum must be simple." + + counter = 0 + + while 1: + + t = tokens.next() + + if t == "=": + tokens.next() + t = tokens.next() + + if t == "}": + break + + if counter: + if t != ",": + raise "no comma" + t = tokens.next() + + if firsthit: + + if mode == "include": + # hack hack hack!! + print "#include " + else: + print "\t// " + f + + firsthit = 0 + + if mode == "parse": + print "{\"" + actionname + "\", \"" + t + "\", " + string.join((classname, t), "::") + "}," + + + counter = counter + 1 + +mode = sys.argv[1] + +if mode == "parse": + print """ + /* generated by parseactions.py - do not modify! */ +struct eActionList +{ + const char *m_context, *m_action; + int m_id; +} actions[]={""" + +for x in sys.argv[2:]: + do_file(x, mode) + +if mode == "parse": + print "};"