summaryrefslogblamecommitdiffstats
path: root/src/input/inputEvent.h
blob: 4e132ebc2ed5e10ef7f3195a2ddfb30693578fb9 (plain) (tree)



















                                                                               
                                              
                  
 




                   











                                                                       








                                                                         


                       


                                                                                              
 
       
                                                                                                           


         
                                                                                                          






                    

                                      
 






                                                                                                                                   
                                                                     
 






                                                                                                    
 






                                                                                                    
 



                                                               
                                                           
         
                                                                         
         
 



                                



                                                                                              



                                





                                                                                                                                    



                                       


                                                                           
                
 
                                            

                                   





                                                                      
                            
         
                             

         


                                                                      
                            
         
                             

         











                                                                         
                             
         
                              

         


                                                 

                               
                                       

         


                                                     

                             
                                          

         


                                                      

                              
                                           

         


                                                       

                              
                                           

         


                                                                       

                            
                                         

         


                                                                         

                              
                                           

         



                                                      
                                     
         

                                           

         




                                                                
                                   
         

                                           

         


                                                     
                              
         

                                            

         


                                                     
                              
         

                                            

         


























                                                                                     
                                                 




                                                                      
                                                 











                                         
                                                         


                 



                                                                      
                                                 













                                         
                                                         


                 


                                                                
                                
         
                                                                                                                                  

         
                





                                                                                           

  








                                                                   

                                   




                                                                                
                                                                                                            



                                                                                 



                                   


                      



                                                                                                                 
 


                                                                        




                                                     



                                                                                            


                                                                           
                          
/*
 # 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/
 # --------------------------------------------------------------------------
 # inputEvent.h:
 #  - Definition of an input event
 # --------------------------------------------------------------------------
 */

#ifndef INPUTEVENT_H_
#define INPUTEVENT_H_

#include <cassert>
#include <QCoreApplication> // for translation
#include <QString>

struct QDataStream;
struct QString;
struct QMouseEvent;
struct QKeyEvent;

/**
 * The inputEvent class represents a single input event.
 * An input event is any of:
 * - Pressing or releasing a keyboard key,
 * - Moving the mouse pointer,
 * - Pressing or releasing a mouse button,
 * - Special system events like "reboot".
 *
 * Events are described by the \ref type(), \ref code()
 * and \ref value(). Possible values for \ref type() are given by
 * the \c ET_* constants, and for \ref code() by the \c EC_* constants.
 */
class InputEvent
{
private:
	friend QDataStream& operator<<(QDataStream&, InputEvent const&);
	friend QDataStream& operator>>(QDataStream&, InputEvent&);

	friend void eventToString(InputEvent const& evt, QString& str);
	friend bool eventFromString(QString const& str, InputEvent& evt);

	quint16 _type;
	quint16 _code;
	quint32 _value;

	// InputEvents are immutable. Prohibit assignment:
	InputEvent& operator=(InputEvent const&); // There intentionally is no implementation.

public:
	InputEvent(quint16 type, quint16 code, quint32 value = 0) : _type(type), _code(code), _value(value)
	{
	}

	InputEvent(InputEvent const& other) : _type(other._type), _code(other._code), _value(other._value)
	{
	}

	InputEvent()
	{
	}

	/** \name Factory Functions */
	/* @{ */

	/**
	 * Generates an event for a mouse button press or release.
	 * \param button The button that caused this event, as defined by \ref Qt::MouseButton.
	 * \param buttons The buttons that were pressed at the moment the event was generated, as defined by \ref Qt::MouseButtons.
	 *   If the event is a button press, this includes the pressed button. If it is a button release,
	 *   it does not include the pressed button.
	 */
	static InputEvent mousePressRelease(int button, int buttons);

	/**
	 * Generates an event for a keyboard press.
	 * \param key The key code that generated this event, as defined by \ref Qt::Key.
	 * \param mods The modificator keys that were pressed at the moment the event was generated,
	 *   as defined by \ref Qt::KeyboardModifiers.
	 */
	static InputEvent keyboardPress(int key, int mods);

	/**
	 * Generates an event for a keyboard release.
	 * \param key The key code that generated this event, as defined by \ref Qt::Key.
	 * \param mods The modificator keys that were pressed at the moment the event was generated,
	 *   as defined by \ref Qt::KeyboardModifiers.
	 */
	static InputEvent keyboardRelease(int key, int mods);

	/**
	 * Generates an event for a mouse pointer movement.
	 * \param x,y X and Y coordinates of the mouse pointer.
	 */
	static InputEvent mouseMotion(quint16 x, quint16 y)
	{
		return InputEvent(ET_POINTER, 0, ((quint32)x << 16) | y);
	}

	/* @} */

	/** \name Event Types */
	/* @{ */
	static const quint16 ET_KEY = 0; /**< The event is related to the keyboard */
	static const quint16 ET_BUTTON = 1; /**< The event is related to a mouse button */
	static const quint16 ET_POINTER = 2; /**< The event is related to the mouse pointer */
	static const quint16 ET_SPECIAL = 3; /**< The event is a special system event */
	/* @} */

	/** \name Event Codes */
	/* @{ */
	static const quint16 EC_PRESS = 0; /**< The event is a press (keyboard or mouse button) */
	static const quint16 EC_RELEASE = 1; /**< The event is a release (keyboard or mouse button) */
	static const quint16 EC_REBOOT = 2; /**< The event is a request to reboot (special system event) */
	static const quint16 EC_SYSRQ = 3; /**< The event is a request to perform a Magic-SysRq function (special system event) */
	static const quint16 EC_KILL_X = 4; /**< The event is a request to kill the X Server (special system event) */
	static const quint16 EC_SAY_HELLO = 5; /**< The event is a request to write a line to the log file (special system event) */
	/* @} */

	/** \name Mouse Button Flags */
	/* @{ */
	static const quint16 EB_LEFT = 1; /**< The left mouse button */
	static const quint16 EB_MIDDLE = 2; /**< The middle mouse button */
	static const quint16 EB_RIGHT = 4; /**< The right mouse button */
	/* @} */

	static const quint32 MODIFIER_MASK =
			0x7e000000;

	/** \name Event Decoding Functions */
	/* @{ */

	/**
	 * Return the event type, as defined by the \c ET_* constants.
	 */
	quint16 type() const
	{
		return _type;
	}

	/**
	 * Return the event code, as defined by the \c EC_* constants.
	 */
	quint16 code() const
	{
		return _code;
	}

	/**
	 * Return the value associated with the event. The interpretation
	 * differs according to event type and code:
	 * - If the event type is \c ET_KEY, the value specifies which
	 *   key and modifiers were pressed.
	 * - If the event type is \c ET_BUTTON, the value specifies which
	 *   buttons were pressed and which button generated the event.
	 * - If the event type is \c ET_POINTER, the value specifies the
	 *   screen coordinates the mouse has moved to.
	 * - If the event type is \c ET_SPECIAL, the interpretation
	 *   depends on the event code.
	 */
	quint32 value() const
	{
		return _value;
	}

	/**
	 * True if the event is a keyboard event.
	 */
	bool isKeyboard() const
	{
		return _type == ET_KEY;
	}

	/**
	 * True if the event is a mouse button event.
	 */
	bool isButton() const
	{
		return _type == ET_BUTTON;
	}

	/**
	 * True if the event is a mouse pointer event.
	 */
	bool isPointer() const
	{
		return _type == ET_POINTER;
	}

	/**
	 * True if the event is a special system event.
	 */
	bool isSpecial() const
	{
		return _type == ET_SPECIAL;
	}

	/**
	 * True if the event is a keyboard or mouse button press event.
	 */
	bool isPress() const
	{
		return _code == EC_PRESS;
	}

	/**
	 * True if the event is a keyboard or mouse button release event.
	 */
	bool isRelease() const
	{
		return _code == EC_RELEASE;
	}

	/**
	 * The mouse button that generated this event.
	 * \return one of the \c EB_* constants.
	 */
	quint16 pressedButton() const
	{
		assert(_type == ET_BUTTON);
		return (_value >> 16);
	}

	/**
	 * The mouse buttons that were pressed at the moment the
	 * event was generated.
	 * \return a bitwise or of \c EB_* constants.
	 */
	quint16 heldButtons() const
	{
		assert(_type == ET_BUTTON);
		return (_value & 0xffff);
	}

	/**
	 * The X coordinate the pointer was moved to.
	 */
	quint16 xCoord() const
	{
		assert(_type == ET_POINTER);
		return (_value >> 16);
	}

	/**
	 * The Y coordinate the pointer was moved to.
	 */
	quint16 yCoord() const
	{
		assert(_type == ET_POINTER);
		return (_value & 0xffff);
	}

	/**
	 * The key that generated the event, as defined by \ref Qt::Key.
	 */
	quint32 qtKeysym() const
	{
		return _value & ~MODIFIER_MASK;
	}

	/**
	 * The modifier keys that were pressed at the moment the event was generated,
	 * as defined by \ref Qt::KeyboardModifiers.
	 */
	quint32 qtModifiers() const
	{
		return _value & MODIFIER_MASK;
	}
	/* @} */


	/** \name Conversion Functions */
	/* @{ */

	/**
	 * Converts mouse buttons from the bit flags defined by \ref Qt::MouseButton
	 * to their internal representation as defined in \ref "Mouse Button Flags".
	 * \returns A bitwise or of \c EB_* values.
	 */
	static quint16 mouseButtonsFromQt(int b);

	/**
	 * Converts an event type as given by the \c ET_* constants to
	 * a string.
	 */
	static QString typeToString(quint16 type)
	{
		switch(type)
		{
		case ET_BUTTON:
			return "BUTTON";
		case ET_KEY:
			return "KEY";
		case ET_POINTER:
			return "POINTER";
		case ET_SPECIAL:
			return "SPECIAL";
		default:
			return QString::number(type, 16);
		}
	}

	/**
	 * Converts an event code as given by the \c EC_* constants to
	 * a string.
	 */
	static QString codeToString(quint16 code)
	{
		switch(code)
		{
		case EC_PRESS:
			return "PRESS";
		case EC_RELEASE:
			return "RELEASE";
		case EC_SYSRQ:
			return "SYSRQ";
		case EC_REBOOT:
			return "REBOOT";
		case EC_KILL_X:
			return "KILL_X";
		default:
			return QString::number(code, 16);
		}
	}

	/**
	 * Convert the event to a human-readable representation.
	 */
	QString toString() const
	{
		return QString("%1:%2:%3").arg(typeToString(_type)).arg(codeToString(_code)).arg(_value, 8, 16, QLatin1Char('0'));
	}

	/* @} */

	// We want to enable InputEvent as a translation context, so we fake the tr method:
	static QString tr(const char* string)
	{
		return QCoreApplication::translate("InputEvent", string);
	}
};

/**
 * The SpecialInputEventDescription class provides a human-readable
 * name for special system events.
 *
 * To use the translations of these descriptions in your program,
 * you need to link to the \c libpvsinput library and
 * use the \ref USE_PVSINPUT_TRANSLATIONS macro in your
 * \c main function.
 */
struct SpecialInputEventDescription
{
	/**
	 * Initialize an instance of the SpecialInputEventDescription class.
	 * This is only meant to be called from describeSpecialEvents().
	 * If you need to add more special event descriptions, do so from there.
	 */
	SpecialInputEventDescription(quint16 type, quint16 code, quint32 value, QString const& description_)
		: type(type), code(code), value(value), description(description_)
	{
	}

	/** \name InputEvent fields
	 * \see InputEvent
	 */
	/* @{ */
	quint16 type;
	quint16 code;
	quint32 value;
	/* @} */

	QString description; /**< Human-readable description for a special input event. Can be translated via the
	 	 	 	 	 	 	  InputEvent::tr(char const*) method. */

	/**
	 * Returns an \ref InputEvent corresponding to this description.
	 */
	InputEvent toEvent() const
	{
		return InputEvent(type, code, value);
	}

	/**
	 * Returns a \ref QList of all known special system events with their human-readable
	 * description.
	 */
	static QList<SpecialInputEventDescription> describeSpecialEvents();
};

#endif /* INPUTEVENT_H_ */