diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp index 97fc843c6a6..e29d9c3da50 100644 --- a/backends/events/default/default-events.cpp +++ b/backends/events/default/default-events.cpp @@ -305,6 +305,10 @@ void DefaultEventManager::purgeMouseEvents() { case Common::EVENT_WHEELDOWN: case Common::EVENT_MBUTTONDOWN: case Common::EVENT_MBUTTONUP: + case Common::EVENT_X1BUTTONDOWN: + case Common::EVENT_X1BUTTONUP: + case Common::EVENT_X2BUTTONDOWN: + case Common::EVENT_X2BUTTONUP: case Common::EVENT_MOUSEMOVE: // do nothing break; diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp index 9e14ee6af96..1f6e56b6604 100644 --- a/backends/events/sdl/sdl-events.cpp +++ b/backends/events/sdl/sdl-events.cpp @@ -819,6 +819,14 @@ bool SdlEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) #if defined(SDL_BUTTON_MIDDLE) else if (ev.button.button == SDL_BUTTON_MIDDLE) event.type = Common::EVENT_MBUTTONDOWN; +#endif +#if defined(SDL_BUTTON_X1) + else if (ev.button.button == SDL_BUTTON_X1) + event.type = Common::EVENT_X1BUTTONDOWN; +#endif +#if defined(SDL_BUTTON_X2) + else if (ev.button.button == SDL_BUTTON_X2) + event.type = Common::EVENT_X2BUTTONDOWN; #endif else return false; @@ -838,6 +846,14 @@ bool SdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) { #if defined(SDL_BUTTON_MIDDLE) else if (ev.button.button == SDL_BUTTON_MIDDLE) event.type = Common::EVENT_MBUTTONUP; +#endif +#if defined(SDL_BUTTON_X1) + else if (ev.button.button == SDL_BUTTON_X1) + event.type = Common::EVENT_X1BUTTONUP; +#endif +#if defined(SDL_BUTTON_X2) + else if (ev.button.button == SDL_BUTTON_X2) + event.type = Common::EVENT_X2BUTTONUP; #endif else return false; diff --git a/backends/keymapper/action.h b/backends/keymapper/action.h index d4aef5496db..a8e46e8d9c0 100644 --- a/backends/keymapper/action.h +++ b/backends/keymapper/action.h @@ -100,6 +100,14 @@ public: setEvent(EVENT_WHEELDOWN); } + void setX1ClickEvent() { + setEvent(EVENT_X1BUTTONDOWN); + } + + void setX2ClickEvent() { + setEvent(EVENT_X2BUTTONDOWN); + } + /** * Add a default input mapping for the action * diff --git a/backends/keymapper/hardware-input.cpp b/backends/keymapper/hardware-input.cpp index 543c8507125..45e448ec5aa 100644 --- a/backends/keymapper/hardware-input.cpp +++ b/backends/keymapper/hardware-input.cpp @@ -231,12 +231,14 @@ const ModifierTableEntry defaultModifiers[] = { }; const HardwareInputTableEntry defaultMouseButtons[] = { - { "MOUSE_LEFT", MOUSE_BUTTON_LEFT, _s("Left Mouse Button") }, - { "MOUSE_RIGHT", MOUSE_BUTTON_RIGHT, _s("Right Mouse Button") }, - { "MOUSE_MIDDLE", MOUSE_BUTTON_MIDDLE, _s("Middle Mouse Button") }, - { "MOUSE_WHEEL_UP", MOUSE_WHEEL_UP, _s("Mouse Wheel Up") }, - { "MOUSE_WHEEL_DOWN", MOUSE_WHEEL_DOWN, _s("Mouse Wheel Down") }, - { nullptr, 0, nullptr } + { "MOUSE_LEFT", MOUSE_BUTTON_LEFT, _s("Left Mouse Button") }, + { "MOUSE_RIGHT", MOUSE_BUTTON_RIGHT, _s("Right Mouse Button") }, + { "MOUSE_MIDDLE", MOUSE_BUTTON_MIDDLE, _s("Middle Mouse Button") }, + { "MOUSE_WHEEL_UP", MOUSE_WHEEL_UP, _s("Mouse Wheel Up") }, + { "MOUSE_WHEEL_DOWN", MOUSE_WHEEL_DOWN, _s("Mouse Wheel Down") }, + { "MOUSE_X1", MOUSE_BUTTON_X1, _s("X1 Mouse Button") }, + { "MOUSE_X2", MOUSE_BUTTON_X2, _s("X2 Mouse Button") }, + { nullptr, 0, nullptr } }; const HardwareInputTableEntry defaultJoystickButtons[] = { @@ -442,6 +444,14 @@ HardwareInput MouseHardwareInputSet::findHardwareInput(const Event &event) const case Common::EVENT_WHEELDOWN: button = MOUSE_WHEEL_DOWN; break; + case EVENT_X1BUTTONDOWN: + case EVENT_X1BUTTONUP: + button = MOUSE_BUTTON_X1; + break; + case EVENT_X2BUTTONDOWN: + case EVENT_X2BUTTONUP: + button = MOUSE_BUTTON_X2; + break; default: button = -1; break; diff --git a/backends/keymapper/input-watcher.cpp b/backends/keymapper/input-watcher.cpp index c1dc6d39258..9a57c8876ea 100644 --- a/backends/keymapper/input-watcher.cpp +++ b/backends/keymapper/input-watcher.cpp @@ -63,6 +63,8 @@ bool InputWatcher::notifyEvent(const Event &event) { case EVENT_LBUTTONDOWN: case EVENT_RBUTTONDOWN: case EVENT_MBUTTONDOWN: + case EVENT_X1BUTTONDOWN: + case EVENT_X2BUTTONDOWN: return true; case EVENT_KEYUP: case EVENT_JOYBUTTON_UP: @@ -72,6 +74,8 @@ bool InputWatcher::notifyEvent(const Event &event) { case EVENT_MBUTTONUP: case EVENT_WHEELUP: case EVENT_WHEELDOWN: + case EVENT_X1BUTTONUP: + case EVENT_X2BUTTONUP: case EVENT_CUSTOM_BACKEND_HARDWARE: _hwInput = _keymapper->findHardwareInput(event); if (_hwInput.type != kHardwareInputTypeInvalid) { diff --git a/backends/keymapper/keymap.cpp b/backends/keymapper/keymap.cpp index 55ca9e7c960..409aff6a2c5 100644 --- a/backends/keymapper/keymap.cpp +++ b/backends/keymapper/keymap.cpp @@ -155,6 +155,16 @@ Keymap::ActionArray Keymap::getMappedActions(const Event &event) const { HardwareInput hardwareInput = HardwareInput::createMouse("", MOUSE_WHEEL_DOWN, ""); return _hwActionMap[hardwareInput]; } + case EVENT_X1BUTTONDOWN: + case EVENT_X1BUTTONUP: { + HardwareInput hardwareInput = HardwareInput::createMouse("", MOUSE_BUTTON_X1, ""); + return _hwActionMap[hardwareInput]; + } + case EVENT_X2BUTTONDOWN: + case EVENT_X2BUTTONUP: { + HardwareInput hardwareInput = HardwareInput::createMouse("", MOUSE_BUTTON_X2, ""); + return _hwActionMap[hardwareInput]; + } case EVENT_JOYBUTTON_DOWN: case EVENT_JOYBUTTON_UP: { HardwareInput hardwareInput = HardwareInput::createJoystickButton("", event.joystick.button, ""); diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp index 7f7f90bd9db..869c7969f86 100644 --- a/backends/keymapper/keymapper.cpp +++ b/backends/keymapper/keymapper.cpp @@ -248,6 +248,8 @@ Keymapper::IncomingEventType Keymapper::convertToIncomingEventType(const Event & || ev.type == EVENT_LBUTTONDOWN || ev.type == EVENT_RBUTTONDOWN || ev.type == EVENT_MBUTTONDOWN + || ev.type == EVENT_X1BUTTONDOWN + || ev.type == EVENT_X2BUTTONDOWN || ev.type == EVENT_JOYBUTTON_DOWN) { return kIncomingEventStart; } else { @@ -264,6 +266,10 @@ bool Keymapper::isMouseEvent(const Event &event) { || event.type == EVENT_MBUTTONUP || event.type == EVENT_WHEELDOWN || event.type == EVENT_WHEELUP + || event.type == EVENT_X1BUTTONDOWN + || event.type == EVENT_X1BUTTONUP + || event.type == EVENT_X2BUTTONDOWN + || event.type == EVENT_X2BUTTONUP || event.type == EVENT_MOUSEMOVE; } @@ -324,6 +330,12 @@ EventType Keymapper::convertStartToEnd(EventType type) { case EVENT_MBUTTONDOWN: result = EVENT_MBUTTONUP; break; + case EVENT_X1BUTTONDOWN: + result = EVENT_X1BUTTONUP; + break; + case EVENT_X2BUTTONDOWN: + result = EVENT_X2BUTTONUP; + break; case EVENT_JOYBUTTON_DOWN: result = EVENT_JOYBUTTON_UP; break; diff --git a/common/events.h b/common/events.h index 4346f083c23..d7a39d52d4f 100644 --- a/common/events.h +++ b/common/events.h @@ -92,7 +92,18 @@ enum EventType { EVENT_CLIPBOARD_UPDATE = 27, EVENT_CUSTOM_BACKEND_HARDWARE = 28, - EVENT_DEBUGGER = 29 + EVENT_DEBUGGER = 29, + + /** + * Additional mouse events, details in Event::mouse. + * + * Note that X1 and X2 are usually back and forward, however + * this can't be guaranteed on all platforms. + */ + EVENT_X1BUTTONDOWN = 30, + EVENT_X1BUTTONUP = 31, + EVENT_X2BUTTONDOWN = 32, + EVENT_X2BUTTONUP = 33 }; const int16 JOYAXIS_MIN = -32768; @@ -157,8 +168,10 @@ enum MouseButton { MOUSE_BUTTON_LEFT = 0, MOUSE_BUTTON_RIGHT = 1, MOUSE_BUTTON_MIDDLE = 2, - MOUSE_WHEEL_UP = 3, - MOUSE_WHEEL_DOWN = 4 + MOUSE_WHEEL_UP = 3, + MOUSE_WHEEL_DOWN = 4, + MOUSE_BUTTON_X1 = 5, + MOUSE_BUTTON_X2 = 6 }; typedef uint32 CustomEventType; diff --git a/common/recorderfile.cpp b/common/recorderfile.cpp index efdc342de7d..e74c013e2d8 100644 --- a/common/recorderfile.cpp +++ b/common/recorderfile.cpp @@ -382,6 +382,10 @@ void PlaybackFile::readEvent(RecorderEvent& event) { case EVENT_WHEELDOWN: case EVENT_MBUTTONDOWN: case EVENT_MBUTTONUP: + case EVENT_X1BUTTONDOWN: + case EVENT_X1BUTTONUP: + case EVENT_X2BUTTONDOWN: + case EVENT_X2BUTTONUP: event.time = _tmpPlaybackFile.readUint32LE(); event.mouse.x = _tmpPlaybackFile.readSint16LE(); event.mouse.y = _tmpPlaybackFile.readSint16LE(); @@ -537,6 +541,10 @@ void PlaybackFile::writeEvent(const RecorderEvent &event) { case EVENT_WHEELDOWN: case EVENT_MBUTTONDOWN: case EVENT_MBUTTONUP: + case EVENT_X1BUTTONDOWN: + case EVENT_X1BUTTONUP: + case EVENT_X2BUTTONDOWN: + case EVENT_X2BUTTONUP: _tmpRecordFile.writeUint32LE(event.time); _tmpRecordFile.writeSint16LE(event.mouse.x); _tmpRecordFile.writeSint16LE(event.mouse.y); diff --git a/engines/testbed/events.cpp b/engines/testbed/events.cpp index 3e1b6adf9ef..4b3ca8b8a27 100644 --- a/engines/testbed/events.cpp +++ b/engines/testbed/events.cpp @@ -142,17 +142,21 @@ TestExitStatus EventTests::mouseEvents() { Common::EventManager *eventMan = g_system->getEventManager(); - Common::Point pt(0, 30); + Common::Point pt(0, 25); Common::Rect rectInfo = Testsuite::writeOnScreen("Generate mouse events make L/R/M button clicks, move wheel", pt); pt.y += 15; Testsuite::writeOnScreen("Press X to exit", pt); - pt.y = 70; + pt.y = 55; Common::Rect rectLB = Testsuite::writeOnScreen("Left-button click : Not tested", pt); pt.y += 15; Common::Rect rectRB = Testsuite::writeOnScreen("Right-button click : Not tested", pt); pt.y += 15; Common::Rect rectMB = Testsuite::writeOnScreen("Middle-button click : Not tested", pt); pt.y += 15; + Common::Rect rectX1B = Testsuite::writeOnScreen("X1-button click : Not tested", pt); + pt.y += 15; + Common::Rect rectX2B = Testsuite::writeOnScreen("X2-button click : Not tested", pt); + pt.y += 15; Common::Rect rectWheel = Testsuite::writeOnScreen("Wheel Movements : Not tested", pt); @@ -195,6 +199,14 @@ TestExitStatus EventTests::mouseEvents() { Testsuite::clearScreen(rectInfo); Testsuite::writeOnScreen("Mouse middle-button pressed ", Common::Point(rectInfo.left, rectInfo.top)); break; + case Common::EVENT_X1BUTTONDOWN: + Testsuite::clearScreen(rectInfo); + Testsuite::writeOnScreen("Mouse X1-button pressed ", Common::Point(rectInfo.left, rectInfo.top)); + break; + case Common::EVENT_X2BUTTONDOWN: + Testsuite::clearScreen(rectInfo); + Testsuite::writeOnScreen("Mouse X2-button pressed ", Common::Point(rectInfo.left, rectInfo.top)); + break; case Common::EVENT_LBUTTONUP: Testsuite::clearScreen(rectInfo); if (finishZone.contains(eventMan->getMousePos())) { @@ -218,6 +230,16 @@ TestExitStatus EventTests::mouseEvents() { Testsuite::writeOnScreen("Mouse middle-button released ", Common::Point(rectInfo.left, rectInfo.top)); Testsuite::writeOnScreen("Middle-button clicks : Done!", Common::Point(rectMB.left, rectMB.top)); break; + case Common::EVENT_X1BUTTONUP: + Testsuite::clearScreen(rectInfo); + Testsuite::writeOnScreen("Mouse X1-button released ", Common::Point(rectInfo.left, rectInfo.top)); + Testsuite::writeOnScreen("X1-button clicks : Done!", Common::Point(rectX1B.left, rectX1B.top)); + break; + case Common::EVENT_X2BUTTONUP: + Testsuite::clearScreen(rectInfo); + Testsuite::writeOnScreen("Mouse X2-button released ", Common::Point(rectInfo.left, rectInfo.top)); + Testsuite::writeOnScreen("X2-button clicks : Done!", Common::Point(rectX2B.left, rectX2B.top)); + break; case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_x) { Testsuite::clearScreen(rectInfo);