diff options
Diffstat (limited to 'src/input/inputEventHandler.h')
| -rw-r--r-- | src/input/inputEventHandler.h | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/src/input/inputEventHandler.h b/src/input/inputEventHandler.h new file mode 100644 index 0000000..52e3338 --- /dev/null +++ b/src/input/inputEventHandler.h @@ -0,0 +1,295 @@ +/* + # Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg + # + # This program is free software distributed under the GPL version 2. + # See http://openslx.org/COPYING + # + # If you have any feedback please consult http://openslx.org/feedback and + # send your suggestions, praise, or complaints to feedback@openslx.org + # + # General information about OpenSLX can be found at http://openslx.org/ + # -------------------------------------------------------------------------- + # inputEventHandler.h: + # - Common definitions for input event handlers + # -------------------------------------------------------------------------- + */ + +#ifndef INPUTEVENTHANDLER_H_ +#define INPUTEVENTHANDLER_H_ + +#include <QtGlobal> +#include <QtDebug> +#include <QList> +#include <QString> +#include <QCoreApplication> +#include <boost/mpl/contains.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/vector.hpp> +#include <src/input/inputEvent.h> + +#define HANDLER_TYPE_DONT_CARE 0xffff +#define HANDLER_CODE_DONT_CARE 0xffff +#define HANDLER_VALUE_DONT_CARE 0xffffffff + +class InputEventContext +{ +public: + virtual pid_t getSenderPid() const = 0; + virtual uid_t getSenderUid() const = 0; + virtual gid_t getSenderGid() const = 0; +}; + +struct SpecialInputEventDescription +{ + SpecialInputEventDescription(QString const& d, quint16 t, quint16 c, quint32 v = 0) + : descriptionString(d), evtType(t), evtCode(c), evtValue(v) + { + } + + QString descriptionString; + quint16 evtType; + quint16 evtCode; + quint32 evtValue; + + InputEvent toEvent() const + { + return InputEvent(evtType, evtCode, evtValue); + } +}; + +template<quint16 Type = HANDLER_TYPE_DONT_CARE, + quint16 Code = HANDLER_CODE_DONT_CARE, + quint32 Value = HANDLER_VALUE_DONT_CARE> +class DefaultInputEventHandler { +protected: + static QString tr(char const* string) + { + return QCoreApplication::translate("InputEventHandler", string); + } + +public: + virtual bool matches(InputEvent const& evt, InputEventContext const*) { + if(Type != HANDLER_TYPE_DONT_CARE) { + if(evt.type() != Type) + return false; + } + if(Code != HANDLER_CODE_DONT_CARE) { + if(evt.code() != Code) + return false; + } + if(Value != HANDLER_VALUE_DONT_CARE) { + if(evt.value() != Value) + return false; + } + return true; + } + + virtual void initialize() + { + } + + virtual void handle(InputEvent const& evt, InputEventContext const*) = 0; + + static void describeInto(QList<SpecialInputEventDescription>& description) + { + } +}; + +namespace policy { + +enum SecurityFlags { + SEC_FREE_FOR_ALL, + SEC_PHYSICAL_OR_PRIVILEGED +}; + +bool allowPhysicalSeat(InputEvent const& evt, InputEventContext const* ctx); +bool allowPrivilegedUser(InputEvent const& evt, InputEventContext const* ctx); + +struct SecurityAllowAny +{ + bool allow(InputEvent const& evt, InputEventContext const* ctx) + { + return true; + } +}; + +struct SecurityAllowPhysicalOrPrivileged +{ + bool allow(InputEvent const& evt, InputEventContext const* ctx) + { + if(allowPhysicalSeat(evt, ctx)) + return true; + else if(allowPrivilegedUser(evt, ctx)) + return true; + return false; + } +}; + +struct UnixLike; +struct Linux; +struct Windows; + +#if defined(__linux) +typedef boost::mpl::vector2<UnixLike,Linux>::type Systems; +#elif defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__) +typedef boost::mpl::vector1<Windows>::type Systems; +#else +# error "Porting is needed!" +#endif + +struct SystemEnabled; +struct SystemDisabled; + +template<typename System> +struct RequireSystem +{ + typedef typename boost::mpl::contains<Systems, System>::type enabled_type; + static const bool enabled = enabled_type::value; +}; + +struct RequireNoSystem +{ + typedef boost::mpl::bool_<true>::type enabled_type; + static const bool enabled = enabled_type::value; +}; + +} + +template<bool Enabled, typename Delegate, typename SecurityPolicy> +class HandlerHelper +{ +public: + bool handle(InputEvent const& evt, InputEventContext const* context = 0) { + if(!securityPolicy.allow(evt, context)) + { + std::string evtStr = evt.toString(); + qWarning("Input Event %s has been denied by security policy", evtStr.c_str()); + return true; + } + if(delegate.matches(evt, context)) { + delegate.handle(evt, context); + return true; + } else { + return false; + } + } + + void initialize() + { + delegate.initialize(); + } + + static void describeInto(QList<SpecialInputEventDescription>& list) + { + Delegate::describeInto(list); + } + +private: + Delegate delegate; + SecurityPolicy securityPolicy; +}; + +template<typename Delegate, typename SecurityPolicy> +class HandlerHelper<false, Delegate, SecurityPolicy> +{ +public: + bool handle(InputEvent const& evt, InputEventContext const* context = 0) { + return false; + } + + void initialize() + { + } + + static void describeInto(QList<SpecialInputEventDescription>&) + { + } +}; + +template<typename Delegate, typename SystemPolicy = policy::RequireNoSystem, typename SecurityPolicy = void> +struct Handler : public HandlerHelper<SystemPolicy::enabled, Delegate, SecurityPolicy> +{ +}; + +template<typename DefaultSecurityPolicy, typename HandlerType> +struct ApplyDefaultSecurityPolicy +{ + typedef HandlerType type; +}; + +template<typename DefaultSecurityPolicy, typename Delegate, typename SystemPolicy> +struct ApplyDefaultSecurityPolicy<DefaultSecurityPolicy, Handler<Delegate, SystemPolicy, void> > +{ + typedef Handler<Delegate, SystemPolicy, DefaultSecurityPolicy> type; +}; + +template<typename DefaultSecurityPolicy, typename Begin, typename End> +struct InputEventHandlerChainHelper +{ +private: + typedef typename boost::mpl::next<Begin>::type next_iterator_type; + typedef InputEventHandlerChainHelper<DefaultSecurityPolicy, next_iterator_type, End> next_in_chain; + + typedef typename boost::mpl::deref<Begin>::type handler_entry_type; + typedef typename ApplyDefaultSecurityPolicy<DefaultSecurityPolicy, handler_entry_type>::type handler_type; + + handler_type _handler; + next_in_chain _next; + +public: + void handle(InputEvent const& evt, InputEventContext const* context = 0) { + if(!_handler.handle(evt, context)) { + _next.handle(evt, context); + } + } + + void initialize() { + _handler.initialize(); + _next.initialize(); + } + + static void describeInto(QList<SpecialInputEventDescription>& list) + { + handler_type::describeInto(list); + next_in_chain::describeInto(list); + } + + static QList<SpecialInputEventDescription> describe() + { + QList<SpecialInputEventDescription> list; + describeInto(list); + return list; + } +}; + +template<typename DefaultSecurityPolicy, typename End> +struct InputEventHandlerChainHelper<DefaultSecurityPolicy, End, End> +{ + void handle(InputEvent const&, InputEventContext const* context = 0) { + // do nothing + } + + void initialize() { + // do nothing + } + + static void describeInto(QList<SpecialInputEventDescription>&) + { + // do nothing + } + + static QList<SpecialInputEventDescription> describe() + { + return QList<SpecialInputEventDescription>(); + } +}; + +template<typename DefaultSecurityPolicy, typename Collection> +struct InputEventHandlerChain : + public InputEventHandlerChainHelper<DefaultSecurityPolicy, + typename boost::mpl::begin<Collection>::type, + typename boost::mpl::end<Collection>::type> +{ +}; + +#endif /* INPUTEVENTHANDLER_H_ */ |
