1 /* GemRB - Infinity Engine Emulator 2 * Copyright (C) 2003 The GemRB Project 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 * 18 * 19 */ 20 21 /** 22 * @file EventMgr.h 23 * Declares EventMgr, class distributing events from input devices to GUI windows 24 * @author The GemRB Project 25 */ 26 27 28 #ifndef EVENTMGR_H 29 #define EVENTMGR_H 30 31 #include "exports.h" 32 #include "ie_types.h" 33 34 #include "Callback.h" 35 #include "Region.h" 36 #include "System/String.h" 37 38 #include <bitset> 39 #include <climits> 40 #include <cstdint> 41 #include <list> 42 #include <map> 43 #include <vector> 44 45 namespace GemRB { 46 47 class Control; 48 class Window; 49 50 #define GEM_LEFT 0x81 51 #define GEM_RIGHT 0x82 52 #define GEM_UP 0x83 53 #define GEM_DOWN 0x84 54 #define GEM_DELETE 0x85 55 #define GEM_RETURN 0x86 56 #define GEM_BACKSP 0x87 57 #define GEM_TAB 0x88 58 #define GEM_ALT 0x89 59 #define GEM_HOME 0x8a 60 #define GEM_END 0x8b 61 #define GEM_ESCAPE 0x8c 62 #define GEM_PGUP 0x8d 63 #define GEM_PGDOWN 0x8e 64 #define GEM_GRAB 0x8f 65 66 // 0x90 - 0x9f reserved for function keys (1-16) 67 #define GEM_FUNCTIONX(x) \ 68 (0x8F + x) 69 70 #define GEM_MOD_SHIFT 1 71 #define GEM_MOD_CTRL 2 72 #define GEM_MOD_ALT 4 73 74 // Mouse buttons 75 #define GEM_MB_ACTION 1 76 #define GEM_MB_MIDDLE 2 77 #define GEM_MB_MENU 4 78 79 #define FINGER_MAX 5 80 81 enum InputAxis : int8_t { 82 AXIS_INVALID = -1, 83 AXIS_LEFT_X, 84 AXIS_LEFT_Y, 85 AXIS_RIGHT_X, 86 AXIS_RIGHT_Y 87 }; 88 89 enum ControllerButton : int8_t { 90 CONTROLLER_INVALID = -1, 91 CONTROLLER_BUTTON_A, 92 CONTROLLER_BUTTON_B, 93 CONTROLLER_BUTTON_X, 94 CONTROLLER_BUTTON_Y, 95 CONTROLLER_BUTTON_BACK, 96 CONTROLLER_BUTTON_GUIDE, 97 CONTROLLER_BUTTON_START, 98 CONTROLLER_BUTTON_LEFTSTICK, 99 CONTROLLER_BUTTON_RIGHTSTICK, 100 CONTROLLER_BUTTON_LEFTSHOULDER, 101 CONTROLLER_BUTTON_RIGHTSHOULDER, 102 CONTROLLER_BUTTON_DPAD_UP, 103 CONTROLLER_BUTTON_DPAD_DOWN, 104 CONTROLLER_BUTTON_DPAD_LEFT, 105 CONTROLLER_BUTTON_DPAD_RIGHT 106 }; 107 108 typedef unsigned char EventButton; 109 typedef unsigned short KeyboardKey; 110 typedef unsigned short ButtonMask; 111 112 struct EventBase { 113 unsigned short repeats; // number of times this event has been repeated (within the repeat time interval) 114 }; 115 116 struct ScreenEvent : public EventBase { 117 // cant use Point due to non trival constructor 118 int x,y; // mouse position at time of event 119 int deltaX, deltaY; // the vector of motion/scroll 120 PosScreenEvent121 Point Pos() const { return Point(x,y); } DeltaScreenEvent122 Point Delta() const { return Point(deltaX, deltaY); } 123 }; 124 125 struct GEM_EXPORT MouseEvent : public ScreenEvent { 126 ButtonMask buttonStates; 127 EventButton button; 128 ButtonStateMouseEvent129 bool ButtonState(unsigned short btn) const { 130 return buttonStates & btn; 131 } 132 }; 133 134 struct GEM_EXPORT KeyboardEvent : public EventBase { 135 KeyboardKey keycode; // raw keycode 136 KeyboardKey character; // the translated character 137 }; 138 139 struct GEM_EXPORT TextEvent : public EventBase { 140 String text; // activate the soft keyboard and disable hot keys until next (non TextEvent) event 141 }; 142 143 struct GEM_EXPORT ControllerEvent : public EventBase { 144 InputAxis axis; 145 float axisPct; 146 int axisDelta; 147 ButtonMask buttonStates; 148 EventButton button; 149 }; 150 151 struct GEM_EXPORT TouchEvent : public ScreenEvent { 152 struct Finger : public ScreenEvent { 153 uint64_t id; 154 }; 155 156 Finger fingers[FINGER_MAX]; 157 158 int numFingers; 159 float pressure; 160 }; 161 162 struct GEM_EXPORT GestureEvent : public TouchEvent { 163 float dTheta; 164 float dDist; 165 }; 166 167 struct GEM_EXPORT Event { 168 enum EventType { 169 MouseMove = 0, 170 MouseUp, 171 MouseDown, 172 MouseScroll, 173 174 KeyUp, 175 KeyDown, 176 177 TouchGesture, 178 TouchUp, 179 TouchDown, 180 181 TextInput, // clipboard or faux event sent to signal the soft keyboard+temp disable hotkeys 182 183 ControllerAxis, 184 ControllerButtonUp, 185 ControllerButtonDown 186 187 // leaving off types for unused events 188 }; 189 190 enum EventTypeMask { 191 NoEventsMask = 0U, 192 193 MouseMoveMask = 1 << MouseMove, 194 MouseUpMask = 1 << MouseUp, 195 MouseDownMask = 1 << MouseDown, 196 MouseScrollMask = 1 << MouseScroll, 197 198 AllMouseMask = MouseMoveMask | MouseUpMask | MouseDownMask | MouseScrollMask, 199 200 KeyUpMask = 1 << KeyUp, 201 KeyDownMask = 1 << KeyDown, 202 203 AllKeyMask = KeyUpMask | KeyDownMask, 204 205 TouchGestureMask = 1 << TouchGesture, 206 TouchUpMask = 1 << TouchUp, 207 TouchDownMask = 1 << TouchDown, 208 209 AllTouchMask = TouchGestureMask | TouchUpMask | TouchDownMask, 210 211 TextInputMask = 1 << TextInput, 212 213 ControllerAxisMask = 1 << ControllerAxis, 214 ControllerButtonUpMask = 1 << ControllerButtonUp, 215 ControllerButtonDownMask = 1 << ControllerButtonDown, 216 217 AllControllerMask = ControllerAxisMask | ControllerButtonUpMask | ControllerButtonDownMask, 218 219 AllEventsMask = 0xffffffffU 220 }; 221 EventMaskFromTypeEvent222 static EventTypeMask EventMaskFromType (EventType type) { return static_cast<EventTypeMask>(1U << type); }; 223 224 union { 225 MouseEvent mouse; 226 ControllerEvent controller; 227 KeyboardEvent keyboard; 228 TouchEvent touch; 229 GestureEvent gesture; 230 }; 231 232 TextEvent text; // text is nontrivial so it stands alone (until C++11 is allowed) 233 234 typedef unsigned short EventMods; 235 236 EventType type; 237 unsigned long time; 238 EventMods mod; // modifier keys held during the event 239 bool isScreen; // event coresponsds to location on screen 240 }; 241 242 MouseEvent MouseEventFromTouch(const TouchEvent& te, bool down); 243 MouseEvent MouseEventFromController(const ControllerEvent& ce, bool down); 244 KeyboardEvent KeyEventFromController(const ControllerEvent& ce); 245 246 /** 247 * @class EventMgr 248 * Class distributing events from input devices to GUI windows. 249 * The events are pumped into instance of this class from a Video driver plugin 250 */ 251 252 class GEM_EXPORT EventMgr { 253 public: 254 typedef std::bitset<sizeof(short) * CHAR_BIT> buttonbits; 255 using EventCallback = Callback<bool, const Event&>; 256 typedef size_t TapMonitorId; 257 258 static constexpr int mouseClickRadius = 5; // radius for reapeat click events 259 static constexpr int mouseDragRadius = 10; // radius for drag events 260 261 static unsigned long DCDelay; 262 static unsigned long DPDelay; 263 static bool TouchInputEnabled; 264 265 static Event CreateMouseBtnEvent(const Point& pos, EventButton btn, bool down, int mod = 0); 266 static Event CreateMouseMotionEvent(const Point& pos, int mod = 0); 267 static Event CreateMouseWheelEvent(const Point& vec, int mod = 0); 268 269 static Event CreateKeyEvent(KeyboardKey key, bool down, int mod = 0); 270 271 static Event CreateTouchEvent(const TouchEvent::Finger fingers[], int numFingers, bool down, float pressure = 0.0); 272 static Event CreateTouchGesture(const TouchEvent& touch, float rotation, float pinch); 273 274 static Event CreateTextEvent(const char* text); 275 static Event CreateTextEvent(const String& text); 276 277 static Event CreateControllerAxisEvent(InputAxis axis, int delta, float pct); 278 static Event CreateControllerButtonEvent(EventButton btn, bool down); 279 280 static bool RegisterHotKeyCallback(EventCallback, KeyboardKey key, short mod = 0); 281 static void UnRegisterHotKeyCallback(EventCallback, KeyboardKey key, short mod = 0); 282 static TapMonitorId RegisterEventMonitor(EventCallback, Event::EventTypeMask mask = Event::AllEventsMask); 283 static void UnRegisterEventMonitor(TapMonitorId monitor); 284 285 private: 286 // FIXME: this shouldnt really be static... but im not sure we want direct access to the EventMgr instance... 287 // currently the delays are static so it makes sense for now that the HotKeys are... 288 // map combination of keyboard key and modifier keys to a callback 289 typedef std::map<TapMonitorId, std::pair<Event::EventTypeMask, EventCallback> > EventTaps; 290 typedef std::map<int, std::list<EventCallback> > KeyMap; 291 292 static EventTaps Taps; 293 static KeyMap HotKeys; 294 295 static buttonbits mouseButtonFlags; 296 static buttonbits modKeys; 297 static Point mousePos; 298 299 static std::map<uint64_t, TouchEvent::Finger> fingerStates; 300 301 static buttonbits controllerButtonStates; 302 303 public: 304 void DispatchEvent(Event&& e); 305 306 static bool ModState(unsigned short mod); 307 308 static bool MouseButtonState(EventButton btn); 309 static bool MouseDown(); MousePos()310 static Point MousePos() { return mousePos; } 311 FingerState(uint64_t id)312 static const TouchEvent::Finger* FingerState(uint64_t id) { return (fingerStates.count(id)) ? &fingerStates[id] : NULL; }; 313 static bool FingerDown(); NumFingersDown()314 static ieByte NumFingersDown() { return fingerStates.size(); }; 315 316 static bool ControllerButtonState(EventButton btn); 317 }; 318 319 } 320 321 #endif // ! EVENTMGR_H 322