1 | //============================================================================ |
2 | // |
3 | // SSSS tt lll lll |
4 | // SS SS tt ll ll |
5 | // SS tttttt eeee ll ll aaaa |
6 | // SSSS tt ee ee ll ll aa |
7 | // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" |
8 | // SS SS tt ee ll ll aa aa |
9 | // SSSS ttt eeeee llll llll aaaaa |
10 | // |
11 | // Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony |
12 | // and the Stella Team |
13 | // |
14 | // See the file "License.txt" for information on usage and redistribution of |
15 | // this file, and for a DISCLAIMER OF ALL WARRANTIES. |
16 | //============================================================================ |
17 | |
18 | #ifndef PHYSICAL_KEYBOARD_HANDLER_HXX |
19 | #define PHYSICAL_KEYBOARD_HANDLER_HXX |
20 | |
21 | #include <map> |
22 | |
23 | class OSystem; |
24 | class EventHandler; |
25 | |
26 | #include "bspf.hxx" |
27 | #include "Event.hxx" |
28 | #include "EventHandlerConstants.hxx" |
29 | #include "KeyMap.hxx" |
30 | |
31 | /** |
32 | This class handles all physical keyboard-related operations in Stella. |
33 | |
34 | It is responsible for getting/setting events associated with keyboard |
35 | actions. |
36 | |
37 | Essentially, this class is an extension of the EventHandler class, but |
38 | handling only keyboard-specific functionality. |
39 | |
40 | @author Stephen Anthony, Thomas Jentzsch |
41 | */ |
42 | class PhysicalKeyboardHandler |
43 | { |
44 | public: |
45 | |
46 | PhysicalKeyboardHandler(OSystem& system, EventHandler& handler); |
47 | |
48 | void setDefaultMapping(Event::Type type, EventMode mode, bool updateDefaults = false); |
49 | |
50 | /** define mappings for current controllers */ |
51 | void defineControllerMappings(const Controller::Type type, Controller::Jack port); |
52 | /** enable mappings for emulation mode */ |
53 | void enableEmulationMappings(); |
54 | |
55 | void eraseMapping(Event::Type event, EventMode mode); |
56 | void saveMapping(); |
57 | |
58 | string getMappingDesc(Event::Type event, EventMode mode) const { |
59 | return myKeyMap.getEventMappingDesc(event, getEventMode(event, mode)); |
60 | } |
61 | |
62 | /** Bind a physical keyboard event to a virtual event/action. */ |
63 | bool addMapping(Event::Type event, EventMode mode, StellaKey key, StellaMod mod); |
64 | |
65 | /** Handle a physical keyboard event. */ |
66 | void handleEvent(StellaKey key, StellaMod mod, bool pressed, bool repeated); |
67 | |
68 | Event::Type eventForKey(EventMode mode, StellaKey key, StellaMod mod) const { |
69 | return myKeyMap.get(mode, key, mod); |
70 | } |
71 | |
72 | #ifdef BSPF_UNIX |
73 | /** See comments on 'myAltKeyCounter' for more information. */ |
74 | uInt8& altKeyCount() { return myAltKeyCounter; } |
75 | #endif |
76 | |
77 | /** See comments on KeyMap.myModEnabled for more information. */ |
78 | bool& useModKeys() { return myKeyMap.enableMod(); } |
79 | |
80 | private: |
81 | |
82 | // Structure used for action menu items |
83 | struct EventMapping { |
84 | Event::Type event; |
85 | StellaKey key; |
86 | int mod = KBDM_NONE; |
87 | }; |
88 | using EventMappingArray = std::vector<EventMapping>; |
89 | |
90 | void setDefaultKey(EventMapping map, Event::Type event = Event::NoType, |
91 | EventMode mode = EventMode::kEmulationMode, bool updateDefaults = false); |
92 | |
93 | /** returns the event's controller mode */ |
94 | EventMode getEventMode(const Event::Type event, const EventMode mode) const; |
95 | /** Checks event type. */ |
96 | bool isJoystickEvent(const Event::Type event) const; |
97 | bool isPaddleEvent(const Event::Type event) const; |
98 | bool isKeypadEvent(const Event::Type event) const; |
99 | bool isCommonEvent(const Event::Type event) const; |
100 | |
101 | void enableCommonMappings(); |
102 | |
103 | void enableMappings(const Event::EventSet events, EventMode mode); |
104 | void enableMapping(const Event::Type event, EventMode mode); |
105 | |
106 | OSystem& myOSystem; |
107 | EventHandler& myHandler; |
108 | |
109 | // Hashmap of key events |
110 | KeyMap myKeyMap; |
111 | |
112 | EventMode myLeftMode; |
113 | EventMode myRightMode; |
114 | |
115 | #ifdef BSPF_UNIX |
116 | // Sometimes key combos with the Alt key become 'stuck' after the |
117 | // window changes state, and we want to ignore that event |
118 | // For example, press Alt-Tab and then upon re-entering the window, |
119 | // the app receives 'tab'; obviously the 'tab' shouldn't be happening |
120 | // So we keep track of the cases that matter (for now, Alt-Tab) |
121 | // and swallow the event afterwards |
122 | // Basically, the initial event sets the variable to 1, and upon |
123 | // returning to the app (ie, receiving EVENT_WINDOW_FOCUS_GAINED), |
124 | // the count is updated to 2, but only if it was already updated to 1 |
125 | // TODO - This may be a bug in SDL, and might be removed in the future |
126 | // It only seems to be an issue in Linux |
127 | uInt8 myAltKeyCounter; |
128 | #endif |
129 | |
130 | // Controller menu and common emulation mappings |
131 | static EventMappingArray DefaultMenuMapping; |
132 | static EventMappingArray DefaultCommonMapping; |
133 | // Controller specific mappings |
134 | static EventMappingArray DefaultJoystickMapping; |
135 | static EventMappingArray DefaultPaddleMapping; |
136 | static EventMappingArray DefaultKeypadMapping; |
137 | static EventMappingArray CompuMateMapping; |
138 | }; |
139 | |
140 | #endif |
141 | |