Unwrap SDL_Event
Some checks failed
checkrefs / lfscheck (push) Has been cancelled
checkrefs / checkrefs (push) Has been cancelled
lint / cppcheck (push) Has been cancelled
lint / copyright (push) Has been cancelled
lint / jenkinsfiles (push) Has been cancelled
pre-commit / build (push) Has been cancelled

Since C++11 a C typedef'ed union can be forward declared, so the wrapper
is no longer needed.

While at it switch signatures to refs and convert C style casts.

Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
This commit is contained in:
Ralph Sennhauser 2026-05-18 21:11:00 +02:00
parent 34ab0f3938
commit a0bb103390
No known key found for this signature in database
38 changed files with 370 additions and 411 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -42,6 +42,7 @@
#include "simulation2/components/ICmpRangeManager.h" #include "simulation2/components/ICmpRangeManager.h"
#include "simulation2/system/Component.h" #include "simulation2/system/Component.h"
#include <SDL_events.h>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <functional> #include <functional>
@ -654,13 +655,13 @@ void CCameraController::FocusHeight(bool smooth)
m_PosY.Add(diff); m_PosY.Add(diff);
} }
InReaction CCameraController::HandleEvent(const SDL_Event_* ev) InReaction CCameraController::HandleEvent(const SDL_Event& ev)
{ {
switch (ev->ev.type) switch (ev.type)
{ {
case SDL_HOTKEYPRESS: case SDL_HOTKEYPRESS:
{ {
std::string hotkey = static_cast<const char*>(ev->ev.user.data1); std::string hotkey = static_cast<const char*>(ev.user.data1);
if (hotkey == "camera.reset") if (hotkey == "camera.reset")
{ {
ResetCameraAngleZoom(); ResetCameraAngleZoom();
@ -676,7 +677,7 @@ InReaction CCameraController::HandleEvent(const SDL_Event_* ev)
case SDL_HOTKEYDOWN: case SDL_HOTKEYDOWN:
{ {
std::string hotkey = static_cast<const char*>(ev->ev.user.data1); std::string hotkey = static_cast<const char*>(ev.user.data1);
// Mouse wheel must be treated using events instead of polling, // Mouse wheel must be treated using events instead of polling,
// because SDL auto-generates a sequence of mousedown/mouseup events // because SDL auto-generates a sequence of mousedown/mouseup events

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -30,6 +30,7 @@ class CCamera;
class CConfigDBHook; class CConfigDBHook;
class CMatrix3D; class CMatrix3D;
class CVector3D; class CVector3D;
union SDL_Event;
class CCameraController : public ICameraController class CCameraController : public ICameraController
{ {
@ -40,7 +41,7 @@ public:
void LoadConfig() override; void LoadConfig() override;
InReaction HandleEvent(const SDL_Event_* ev) override; InReaction HandleEvent(const SDL_Event& ev) override;
CVector3D GetCameraPivot() const override; CVector3D GetCameraPivot() const override;
CVector3D GetCameraPosition() const override; CVector3D GetCameraPosition() const override;

View file

@ -53,6 +53,7 @@
#include "renderer/WaterManager.h" #include "renderer/WaterManager.h"
#include "simulation2/Simulation2.h" #include "simulation2/Simulation2.h"
#include <SDL_events.h>
#include <memory> #include <memory>
#include <string> #include <string>
@ -350,7 +351,7 @@ entity_id_t CGameView::GetFollowedEntity()
return m->CameraController->GetFollowedEntity(); return m->CameraController->GetFollowedEntity();
} }
InReaction game_view_handler(const SDL_Event_* ev) InReaction game_view_handler(const SDL_Event& ev)
{ {
// put any events that must be processed even if inactive here // put any events that must be processed even if inactive here
if (!g_app_has_focus || !g_Game || !g_Game->IsGameStarted() || g_Game->GetView()->GetCinema()->IsPlaying()) if (!g_app_has_focus || !g_Game || !g_Game->IsGameStarted() || g_Game->GetView()->GetCinema()->IsPlaying())
@ -361,13 +362,13 @@ InReaction game_view_handler(const SDL_Event_* ev)
return pView->HandleEvent(ev); return pView->HandleEvent(ev);
} }
InReaction CGameView::HandleEvent(const SDL_Event_* ev) InReaction CGameView::HandleEvent(const SDL_Event& ev)
{ {
switch(ev->ev.type) switch(ev.type)
{ {
case SDL_HOTKEYPRESS: case SDL_HOTKEYPRESS:
{ {
std::string hotkey = static_cast<const char*>(ev->ev.user.data1); std::string hotkey = static_cast<const char*>(ev.user.data1);
CSceneRenderer& sceneRenderer = g_Renderer.GetSceneRenderer(); CSceneRenderer& sceneRenderer = g_Renderer.GetSceneRenderer();
if (hotkey == "wireframe") if (hotkey == "wireframe")
{ {

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -31,8 +31,8 @@ class CObjectManager;
class CVector3D; class CVector3D;
namespace Renderer::Backend { class IDevice; } namespace Renderer::Backend { class IDevice; }
namespace Renderer::Backend { class IDeviceCommandContext; } namespace Renderer::Backend { class IDeviceCommandContext; }
struct SDL_Event_;
struct SViewPort; struct SViewPort;
union SDL_Event;
class CGameView : private Scene class CGameView : private Scene
{ {
@ -58,7 +58,7 @@ public:
void Render(Renderer::Backend::IDeviceCommandContext* deviceCommandContext); void Render(Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
void RenderOverlays(Renderer::Backend::IDeviceCommandContext* deviceCommandContext); void RenderOverlays(Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
InReaction HandleEvent(const SDL_Event_* ev); InReaction HandleEvent(const SDL_Event& ev);
CVector3D GetCameraPivot() const; CVector3D GetCameraPivot() const;
CVector3D GetCameraPosition() const; CVector3D GetCameraPosition() const;
@ -98,6 +98,6 @@ private:
CGameViewImpl* m; CGameViewImpl* m;
}; };
extern InReaction game_view_handler(const SDL_Event_* ev); extern InReaction game_view_handler(const SDL_Event& ev);
#endif // INCLUDED_GAMEVIEW #endif // INCLUDED_GAMEVIEW

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -24,8 +24,8 @@
class CCamera; class CCamera;
class CVector3D; class CVector3D;
struct SDL_Event_;
struct SViewPort; struct SViewPort;
union SDL_Event;
/** /**
* @interface ICameraController defines a camera controller interface. The camera object * @interface ICameraController defines a camera controller interface. The camera object
@ -43,7 +43,7 @@ public:
virtual void LoadConfig() = 0; virtual void LoadConfig() = 0;
virtual InReaction HandleEvent(const SDL_Event_* ev) = 0; virtual InReaction HandleEvent(const SDL_Event& ev) = 0;
virtual CVector3D GetCameraPivot() const = 0; virtual CVector3D GetCameraPivot() const = 0;
virtual CVector3D GetCameraPosition() const = 0; virtual CVector3D GetCameraPosition() const = 0;

View file

@ -111,15 +111,15 @@ CGUI::~CGUI()
g_NetClient->Unregister(m_ScriptInterface.get()); g_NetClient->Unregister(m_ScriptInterface.get());
} }
InReaction CGUI::HandleEvent(const SDL_Event_* ev) InReaction CGUI::HandleEvent(const SDL_Event& ev)
{ {
InReaction ret = IN_PASS; InReaction ret = IN_PASS;
if (ev->ev.type == SDL_HOTKEYDOWN || ev->ev.type == SDL_HOTKEYPRESS || ev->ev.type == SDL_HOTKEYUP) if (ev.type == SDL_HOTKEYDOWN || ev.type == SDL_HOTKEYPRESS || ev.type == SDL_HOTKEYUP)
{ {
const char* hotkey = static_cast<const char*>(ev->ev.user.data1); const char* hotkey = static_cast<const char*>(ev.user.data1);
const CStr& eventName = ev->ev.type == SDL_HOTKEYPRESS ? EventNamePress : ev->ev.type == SDL_HOTKEYDOWN ? EventNameKeyDown : EventNameRelease; const CStr& eventName = ev.type == SDL_HOTKEYPRESS ? EventNamePress : ev.type == SDL_HOTKEYDOWN ? EventNameKeyDown : EventNameRelease;
if (m_GlobalHotkeys.find(hotkey) != m_GlobalHotkeys.end() && m_GlobalHotkeys[hotkey].find(eventName) != m_GlobalHotkeys[hotkey].end()) if (m_GlobalHotkeys.find(hotkey) != m_GlobalHotkeys.end() && m_GlobalHotkeys[hotkey].find(eventName) != m_GlobalHotkeys[hotkey].end())
{ {
@ -138,35 +138,35 @@ InReaction CGUI::HandleEvent(const SDL_Event_* ev)
{ {
if (!obj->IsEnabled()) if (!obj->IsEnabled())
continue; continue;
if (ev->ev.type == SDL_HOTKEYPRESS) if (ev.type == SDL_HOTKEYPRESS)
ret = obj->SendEvent(GUIM_PRESSED, EventNamePress); ret = obj->SendEvent(GUIM_PRESSED, EventNamePress);
else if (ev->ev.type == SDL_HOTKEYDOWN) else if (ev.type == SDL_HOTKEYDOWN)
ret = obj->SendEvent(GUIM_KEYDOWN, EventNameKeyDown); ret = obj->SendEvent(GUIM_KEYDOWN, EventNameKeyDown);
else else
ret = obj->SendEvent(GUIM_RELEASED, EventNameRelease); ret = obj->SendEvent(GUIM_RELEASED, EventNameRelease);
} }
} }
else if (ev->ev.type == SDL_MOUSEMOTION) else if (ev.type == SDL_MOUSEMOTION)
{ {
// Yes the mouse position is stored as float to avoid // Yes the mouse position is stored as float to avoid
// constant conversions when operating in a // constant conversions when operating in a
// float-based environment. // float-based environment.
m_MousePos = CVector2D((float)ev->ev.motion.x / g_VideoMode.GetScale(), (float)ev->ev.motion.y / g_VideoMode.GetScale()); m_MousePos = CVector2D(static_cast<float>(ev.motion.x) / g_VideoMode.GetScale(), static_cast<float>(ev.motion.y) / g_VideoMode.GetScale());
SGUIMessage msg(GUIM_MOUSE_MOTION); SGUIMessage msg(GUIM_MOUSE_MOTION);
m_BaseObject->RecurseObject(&IGUIObject::IsHiddenOrGhostOrOutOfBoundaries, &IGUIObject::HandleMessage, msg); m_BaseObject->RecurseObject(&IGUIObject::IsHiddenOrGhostOrOutOfBoundaries, &IGUIObject::HandleMessage, msg);
} }
// Update m_MouseButtons. (BUTTONUP is handled later.) // Update m_MouseButtons. (BUTTONUP is handled later.)
else if (ev->ev.type == SDL_MOUSEBUTTONDOWN) else if (ev.type == SDL_MOUSEBUTTONDOWN)
{ {
switch (ev->ev.button.button) switch (ev.button.button)
{ {
case SDL_BUTTON_LEFT: case SDL_BUTTON_LEFT:
case SDL_BUTTON_RIGHT: case SDL_BUTTON_RIGHT:
case SDL_BUTTON_MIDDLE: case SDL_BUTTON_MIDDLE:
m_MouseButtons |= Bit<unsigned int>(ev->ev.button.button); m_MouseButtons |= Bit<unsigned int>(ev.button.button);
break; break;
default: default:
break; break;
@ -175,9 +175,9 @@ InReaction CGUI::HandleEvent(const SDL_Event_* ev)
// Update m_MousePos (for delayed mouse button events) // Update m_MousePos (for delayed mouse button events)
CVector2D oldMousePos = m_MousePos; CVector2D oldMousePos = m_MousePos;
if (ev->ev.type == SDL_MOUSEBUTTONDOWN || ev->ev.type == SDL_MOUSEBUTTONUP) if (ev.type == SDL_MOUSEBUTTONDOWN || ev.type == SDL_MOUSEBUTTONUP)
{ {
m_MousePos = CVector2D((float)ev->ev.button.x / g_VideoMode.GetScale(), (float)ev->ev.button.y / g_VideoMode.GetScale()); m_MousePos = CVector2D(static_cast<float>(ev.button.x) / g_VideoMode.GetScale(), static_cast<float>(ev.button.y) / g_VideoMode.GetScale());
} }
// Allow the focused object to pre-empt regular GUI events. // Allow the focused object to pre-empt regular GUI events.
@ -195,9 +195,9 @@ InReaction CGUI::HandleEvent(const SDL_Event_* ev)
// update their own data and send messages accordingly // update their own data and send messages accordingly
m_BaseObject->RecurseObject(&IGUIObject::IsHiddenOrGhostOrOutOfBoundaries, &IGUIObject::UpdateMouseOver, static_cast<IGUIObject* const&>(pNearest)); m_BaseObject->RecurseObject(&IGUIObject::IsHiddenOrGhostOrOutOfBoundaries, &IGUIObject::UpdateMouseOver, static_cast<IGUIObject* const&>(pNearest));
if (ev->ev.type == SDL_MOUSEBUTTONDOWN) if (ev.type == SDL_MOUSEBUTTONDOWN)
{ {
switch (ev->ev.button.button) switch (ev.button.button)
{ {
case SDL_BUTTON_LEFT: case SDL_BUTTON_LEFT:
// Focus the clicked object (or focus none if nothing clicked on) // Focus the clicked object (or focus none if nothing clicked on)
@ -216,21 +216,21 @@ InReaction CGUI::HandleEvent(const SDL_Event_* ev)
break; break;
} }
} }
else if (ev->ev.type == SDL_MOUSEWHEEL && pNearest) else if (ev.type == SDL_MOUSEWHEEL && pNearest)
{ {
if (ev->ev.wheel.y < 0) if (ev.wheel.y < 0)
ret = pNearest->SendMouseEvent(GUIM_MOUSE_WHEEL_DOWN, EventNameMouseWheelDown); ret = pNearest->SendMouseEvent(GUIM_MOUSE_WHEEL_DOWN, EventNameMouseWheelDown);
else if (ev->ev.wheel.y > 0) else if (ev.wheel.y > 0)
ret = pNearest->SendMouseEvent(GUIM_MOUSE_WHEEL_UP, EventNameMouseWheelUp); ret = pNearest->SendMouseEvent(GUIM_MOUSE_WHEEL_UP, EventNameMouseWheelUp);
if (ev->ev.wheel.x < 0) if (ev.wheel.x < 0)
ret = pNearest->SendMouseEvent(GUIM_MOUSE_WHEEL_LEFT, EventNameMouseWheelLeft); ret = pNearest->SendMouseEvent(GUIM_MOUSE_WHEEL_LEFT, EventNameMouseWheelLeft);
else if (ev->ev.wheel.x > 0) else if (ev.wheel.x > 0)
ret = pNearest->SendMouseEvent(GUIM_MOUSE_WHEEL_RIGHT, EventNameMouseWheelRight); ret = pNearest->SendMouseEvent(GUIM_MOUSE_WHEEL_RIGHT, EventNameMouseWheelRight);
} }
else if (ev->ev.type == SDL_MOUSEBUTTONUP) else if (ev.type == SDL_MOUSEBUTTONUP)
{ {
switch (ev->ev.button.button) switch (ev.button.button)
{ {
case SDL_BUTTON_LEFT: case SDL_BUTTON_LEFT:
if (pNearest) if (pNearest)
@ -267,14 +267,14 @@ InReaction CGUI::HandleEvent(const SDL_Event_* ev)
// BUTTONUP's effect on m_MouseButtons is handled after // BUTTONUP's effect on m_MouseButtons is handled after
// everything else, so that e.g. 'press' handlers (activated // everything else, so that e.g. 'press' handlers (activated
// on button up) see which mouse button had been pressed. // on button up) see which mouse button had been pressed.
if (ev->ev.type == SDL_MOUSEBUTTONUP) if (ev.type == SDL_MOUSEBUTTONUP)
{ {
switch (ev->ev.button.button) switch (ev.button.button)
{ {
case SDL_BUTTON_LEFT: case SDL_BUTTON_LEFT:
case SDL_BUTTON_RIGHT: case SDL_BUTTON_RIGHT:
case SDL_BUTTON_MIDDLE: case SDL_BUTTON_MIDDLE:
m_MouseButtons &= ~Bit<unsigned int>(ev->ev.button.button); m_MouseButtons &= ~Bit<unsigned int>(ev.button.button);
break; break;
default: default:
break; break;
@ -282,15 +282,15 @@ InReaction CGUI::HandleEvent(const SDL_Event_* ev)
} }
// Restore m_MousePos (for delayed mouse button events) // Restore m_MousePos (for delayed mouse button events)
if (ev->ev.type == SDL_MOUSEBUTTONDOWN || ev->ev.type == SDL_MOUSEBUTTONUP) if (ev.type == SDL_MOUSEBUTTONDOWN || ev.type == SDL_MOUSEBUTTONUP)
m_MousePos = oldMousePos; m_MousePos = oldMousePos;
// Let GUI items handle keys after everything else, e.g. for input boxes. // Let GUI items handle keys after everything else, e.g. for input boxes.
if (ret == IN_PASS && GetFocusedObject()) if (ret == IN_PASS && GetFocusedObject())
{ {
if (ev->ev.type == SDL_KEYUP || ev->ev.type == SDL_KEYDOWN || if (ev.type == SDL_KEYUP || ev.type == SDL_KEYDOWN ||
ev->ev.type == SDL_HOTKEYUP || ev->ev.type == SDL_HOTKEYDOWN || ev.type == SDL_HOTKEYUP || ev.type == SDL_HOTKEYDOWN ||
ev->ev.type == SDL_TEXTINPUT || ev->ev.type == SDL_TEXTEDITING) ev.type == SDL_TEXTINPUT || ev.type == SDL_TEXTEDITING)
ret = GetFocusedObject()->ManuallyHandleKeys(ev); ret = GetFocusedObject()->ManuallyHandleKeys(ev);
// else will return IN_PASS because we never used the button. // else will return IN_PASS because we never used the button.
} }

View file

@ -67,8 +67,8 @@ class XMBElement;
namespace JS { class HandleValueArray; } namespace JS { class HandleValueArray; }
namespace JS { class Value; } namespace JS { class Value; }
namespace js { class BaseProxyHandler; } namespace js { class BaseProxyHandler; }
struct SDL_Event_;
struct SGUIImageEffects; struct SGUIImageEffects;
union SDL_Event;
extern const double SELECT_DBLCLICK_RATE; extern const double SELECT_DBLCLICK_RATE;
@ -132,11 +132,11 @@ public:
void DrawSprite(const CGUISpriteInstance& Sprite, CCanvas2D& canvas, const CRect& Rect, const CRect& Clipping = CRect()); void DrawSprite(const CGUISpriteInstance& Sprite, CCanvas2D& canvas, const CRect& Rect, const CRect& Clipping = CRect());
/** /**
* The replacement of Process(), handles an SDL_Event_ * The replacement of Process(), handles an SDL_Event
* *
* @param ev SDL Event, like mouse/keyboard input * @param ev SDL Event, like mouse/keyboard input
*/ */
InReaction HandleEvent(const SDL_Event_* ev); InReaction HandleEvent(const SDL_Event& ev);
/** /**
* Load a GUI XML file into the GUI. * Load a GUI XML file into the GUI.

View file

@ -44,6 +44,7 @@
#include "scriptinterface/StructuredClone.h" #include "scriptinterface/StructuredClone.h"
#include "simulation2/system/Component.h" #include "simulation2/system/Component.h"
#include <SDL_events.h>
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
#include <js/Equality.h> #include <js/Equality.h>
@ -81,7 +82,7 @@ CGUIManager* g_GUI = nullptr;
// called from main loop when (input) events are received. // called from main loop when (input) events are received.
// event is passed to other handlers if false is returned. // event is passed to other handlers if false is returned.
// trampoline: we don't want to make the HandleEvent implementation static // trampoline: we don't want to make the HandleEvent implementation static
InReaction gui_handler(const SDL_Event_* ev) InReaction gui_handler(const SDL_Event& ev)
{ {
if (!g_GUI) if (!g_GUI)
return IN_PASS; return IN_PASS;
@ -370,7 +371,7 @@ Status CGUIManager::ReloadAllPages()
return INFO::OK; return INFO::OK;
} }
InReaction CGUIManager::HandleEvent(const SDL_Event_* ev) InReaction CGUIManager::HandleEvent(const SDL_Event& ev)
{ {
// We want scripts to have access to the raw input events, so they can do complex // We want scripts to have access to the raw input events, so they can do complex
// processing when necessary (e.g. for unit selection and camera movement). // processing when necessary (e.g. for unit selection and camera movement).
@ -386,7 +387,7 @@ InReaction CGUIManager::HandleEvent(const SDL_Event_* ev)
ScriptRequest rq(*top()->GetScriptInterface()); ScriptRequest rq(*top()->GetScriptInterface());
JS::RootedValue global(rq.cx, rq.globalValue()); JS::RootedValue global(rq.cx, rq.globalValue());
if (ScriptFunction::Call(rq, global, "handleInputBeforeGui", handled, *ev, top()->FindObjectUnderMouse())) if (ScriptFunction::Call(rq, global, "handleInputBeforeGui", handled, ev, top()->FindObjectUnderMouse()))
if (handled) if (handled)
return IN_HANDLED; return IN_HANDLED;
} }
@ -404,7 +405,7 @@ InReaction CGUIManager::HandleEvent(const SDL_Event_* ev)
JS::RootedValue global(rq.cx, rq.globalValue()); JS::RootedValue global(rq.cx, rq.globalValue());
PROFILE("handleInputAfterGui"); PROFILE("handleInputAfterGui");
if (ScriptFunction::Call(rq, global, "handleInputAfterGui", handled, *ev)) if (ScriptFunction::Call(rq, global, "handleInputAfterGui", handled, ev))
if (handled) if (handled)
return IN_HANDLED; return IN_HANDLED;
} }

View file

@ -43,7 +43,7 @@ class ScriptContext;
namespace JS { class HandleValueArray; } namespace JS { class HandleValueArray; }
namespace JS { class Value; } namespace JS { class Value; }
namespace PS { template <typename T, size_t N> class StaticVector; } namespace PS { template <typename T, size_t N> class StaticVector; }
struct SDL_Event_; union SDL_Event;
/** /**
* External interface to the GUI system. * External interface to the GUI system.
@ -99,7 +99,7 @@ public:
/** /**
* Pass input events to the currently active GUI page. * Pass input events to the currently active GUI page.
*/ */
InReaction HandleEvent(const SDL_Event_* ev); InReaction HandleEvent(const SDL_Event& ev);
/** /**
* See CGUI::SendEventToAll; applies to the currently active page. * See CGUI::SendEventToAll; applies to the currently active page.
@ -242,6 +242,6 @@ private:
extern CGUIManager* g_GUI; extern CGUIManager* g_GUI;
extern InReaction gui_handler(const SDL_Event_* ev); extern InReaction gui_handler(const SDL_Event& ev);
#endif // INCLUDED_GUIMANAGER #endif // INCLUDED_GUIMANAGER

View file

@ -49,7 +49,7 @@ class JSTracer;
class XMBData; class XMBData;
class XMBElement; class XMBElement;
namespace JS { class HandleValueArray; } namespace JS { class HandleValueArray; }
struct SDL_Event_; union SDL_Event;
#define GUI_OBJECT(obj) \ #define GUI_OBJECT(obj) \
public: \ public: \
@ -285,17 +285,17 @@ protected:
virtual void Draw(CCanvas2D& canvas) = 0; virtual void Draw(CCanvas2D& canvas) = 0;
/** /**
* Some objects need to be able to pre-emptively process SDL_Event_. * Some objects need to be able to pre-emptively process SDL_Event.
* *
* Only the object with focus will have this function called. * Only the object with focus will have this function called.
* *
* Returns either IN_PASS or IN_HANDLED. If IN_HANDLED, then * Returns either IN_PASS or IN_HANDLED. If IN_HANDLED, then
* the event won't be passed on and processed by other handlers. * the event won't be passed on and processed by other handlers.
*/ */
virtual InReaction PreemptEvent(const SDL_Event_*) { return IN_PASS; } virtual InReaction PreemptEvent(const SDL_Event&) { return IN_PASS; }
/** /**
* Some objects need to handle the text-related SDL_Event_ manually. * Some objects need to handle the text-related SDL_Event manually.
* For instance the input box. * For instance the input box.
* *
* Only the object with focus will have this function called. * Only the object with focus will have this function called.
@ -304,7 +304,7 @@ protected:
* the key won't be passed on and processed by other handlers. * the key won't be passed on and processed by other handlers.
* This is used for keys that the GUI uses. * This is used for keys that the GUI uses.
*/ */
virtual InReaction ManuallyHandleKeys(const SDL_Event_*) { return IN_PASS; } virtual InReaction ManuallyHandleKeys(const SDL_Event&) { return IN_PASS; }
/** /**
* Applies the given style to the object. * Applies the given style to the object.

View file

@ -272,14 +272,14 @@ void CDropDown::HandleMessage(SGUIMessage& Message)
SetupText(); SetupText();
} }
InReaction CDropDown::ManuallyHandleKeys(const SDL_Event_* ev) InReaction CDropDown::ManuallyHandleKeys(const SDL_Event& ev)
{ {
InReaction result = IN_PASS; InReaction result = IN_PASS;
bool update_highlight = false; bool update_highlight = false;
if (ev->ev.type == SDL_KEYDOWN) if (ev.type == SDL_KEYDOWN)
{ {
int szChar = ev->ev.key.keysym.sym; int szChar = ev.key.keysym.sym;
switch (szChar) switch (szChar)
{ {

View file

@ -42,6 +42,7 @@ GUI Object - Drop Down (list)
#include <string> #include <string>
class CGUI; class CGUI;
union SDL_Event;
/** /**
* Drop Down * Drop Down
@ -67,7 +68,7 @@ public:
/** /**
* Handle events manually to catch keyboard inputting. * Handle events manually to catch keyboard inputting.
*/ */
virtual InReaction ManuallyHandleKeys(const SDL_Event_* ev); virtual InReaction ManuallyHandleKeys(const SDL_Event& ev);
/** /**
* Draws the Button * Draws the Button

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -105,9 +105,9 @@ void CHotkeyPicker::HandleMessage(SGUIMessage& Message)
} }
} }
InReaction CHotkeyPicker::PreemptEvent(const SDL_Event_* ev) InReaction CHotkeyPicker::PreemptEvent(const SDL_Event& ev)
{ {
switch (ev->ev.type) switch (ev.type)
{ {
// Handle the same mouse events that hotkeys handle // Handle the same mouse events that hotkeys handle
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
@ -116,27 +116,27 @@ InReaction CHotkeyPicker::PreemptEvent(const SDL_Event_* ev)
{ {
SDL_Scancode scancode; SDL_Scancode scancode;
if (ev->ev.type != SDL_MOUSEWHEEL) if (ev.type != SDL_MOUSEWHEEL)
{ {
// Wait a little bit -> this gets triggered when clicking on a button, // Wait a little bit -> this gets triggered when clicking on a button,
// but after the button click is processed, thus immediately triggering... // but after the button click is processed, thus immediately triggering...
if (timer_Time()-m_LastKeyChange < 0.2) if (timer_Time()-m_LastKeyChange < 0.2)
return IN_HANDLED; return IN_HANDLED;
// This is from hotkeyHandler - not sure what it does in all honesty. // This is from hotkeyHandler - not sure what it does in all honesty.
if(ev->ev.button.button >= SDL_BUTTON_X1) if(ev.button.button >= SDL_BUTTON_X1)
scancode = static_cast<SDL_Scancode>(MOUSE_BASE + (int)ev->ev.button.button + 2); scancode = static_cast<SDL_Scancode>(MOUSE_BASE + static_cast<int>(ev.button.button) + 2);
else else
scancode = static_cast<SDL_Scancode>(MOUSE_BASE + (int)ev->ev.button.button); scancode = static_cast<SDL_Scancode>(MOUSE_BASE + static_cast<int>(ev.button.button));
} }
else else
{ {
if (ev->ev.wheel.y > 0) if (ev.wheel.y > 0)
scancode = static_cast<SDL_Scancode>(MOUSE_WHEELUP); scancode = static_cast<SDL_Scancode>(MOUSE_WHEELUP);
else if (ev->ev.wheel.y < 0) else if (ev.wheel.y < 0)
scancode = static_cast<SDL_Scancode>(MOUSE_WHEELDOWN); scancode = static_cast<SDL_Scancode>(MOUSE_WHEELDOWN);
else if (ev->ev.wheel.x > 0) else if (ev.wheel.x > 0)
scancode = static_cast<SDL_Scancode>(MOUSE_X2); scancode = static_cast<SDL_Scancode>(MOUSE_X2);
else if (ev->ev.wheel.x < 0) else if (ev.wheel.x < 0)
scancode = static_cast<SDL_Scancode>(MOUSE_X1); scancode = static_cast<SDL_Scancode>(MOUSE_X1);
else else
return IN_HANDLED; return IN_HANDLED;
@ -153,7 +153,7 @@ InReaction CHotkeyPicker::PreemptEvent(const SDL_Event_* ev)
case SDL_KEYDOWN: case SDL_KEYDOWN:
case SDL_KEYUP: case SDL_KEYUP:
{ {
SDL_Scancode scancode = ev->ev.key.keysym.scancode; SDL_Scancode scancode = ev.key.keysym.scancode;
// Don't handle caps-lock, it doesn't really work in-game and it's a weird hotkey. // Don't handle caps-lock, it doesn't really work in-game and it's a weird hotkey.
if (scancode == SDL_SCANCODE_CAPSLOCK) if (scancode == SDL_SCANCODE_CAPSLOCK)
@ -168,7 +168,7 @@ InReaction CHotkeyPicker::PreemptEvent(const SDL_Event_* ev)
else if (scancode == SDL_SCANCODE_LGUI || scancode == SDL_SCANCODE_RGUI) else if (scancode == SDL_SCANCODE_LGUI || scancode == SDL_SCANCODE_RGUI)
scancode = static_cast<SDL_Scancode>(UNIFIED_SUPER); scancode = static_cast<SDL_Scancode>(UNIFIED_SUPER);
if (ev->ev.type == SDL_KEYDOWN) if (ev.type == SDL_KEYDOWN)
{ {
std::vector<Key>::const_iterator it = \ std::vector<Key>::const_iterator it = \
std::find_if(m_KeysPressed.begin(), m_KeysPressed.end(), [&scancode](Key& k) { return k.code == scancode; }); std::find_if(m_KeysPressed.begin(), m_KeysPressed.end(), [&scancode](Key& k) { return k.code == scancode; });

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -27,6 +27,7 @@
#include <vector> #include <vector>
class CGUI; class CGUI;
union SDL_Event;
/** /**
* When in focus, returns all currently pressed keys. * When in focus, returns all currently pressed keys.
@ -52,7 +53,7 @@ public:
virtual void HandleMessage(SGUIMessage& Message); virtual void HandleMessage(SGUIMessage& Message);
// Pre-empt events: this is our sole purpose. // Pre-empt events: this is our sole purpose.
virtual InReaction PreemptEvent(const SDL_Event_* ev); virtual InReaction PreemptEvent(const SDL_Event& ev);
struct Key struct Key
{ {

View file

@ -113,7 +113,7 @@ void CInput::ClearComposedText()
m_iComposedPos = 0; m_iComposedPos = 0;
} }
InReaction CInput::ManuallyHandleKeys(const SDL_Event_* ev) InReaction CInput::ManuallyHandleKeys(const SDL_Event& ev)
{ {
ENSURE(m_iBufferPos != -1); ENSURE(m_iBufferPos != -1);
@ -121,7 +121,7 @@ InReaction CInput::ManuallyHandleKeys(const SDL_Event_* ev)
// (Messages don't currently need to be sent) // (Messages don't currently need to be sent)
CStrW& caption = m_Caption.GetMutable(); CStrW& caption = m_Caption.GetMutable();
switch (ev->ev.type) switch (ev.type)
{ {
case SDL_HOTKEYDOWN: case SDL_HOTKEYDOWN:
{ {
@ -138,7 +138,7 @@ InReaction CInput::ManuallyHandleKeys(const SDL_Event_* ev)
return IN_PASS; return IN_PASS;
// Text has been committed, either single key presses or through an IME // Text has been committed, either single key presses or through an IME
std::wstring text = wstring_from_utf8(ev->ev.text.text); std::wstring text = wstring_from_utf8(ev.text.text);
// Check max length // Check max length
if (m_MaxLength != 0 && caption.length() + text.length() > static_cast<size_t>(m_MaxLength)) if (m_MaxLength != 0 && caption.length() + text.length() > static_cast<size_t>(m_MaxLength))
@ -178,7 +178,7 @@ InReaction CInput::ManuallyHandleKeys(const SDL_Event_* ev)
// Text is being composed with an IME // Text is being composed with an IME
// TODO: indicate this by e.g. underlining the uncommitted text // TODO: indicate this by e.g. underlining the uncommitted text
const char* rawText = ev->ev.edit.text; const char* rawText = ev.edit.text;
int rawLength = strlen(rawText); int rawLength = strlen(rawText);
std::wstring wtext = wstring_from_utf8(rawText); std::wstring wtext = wstring_from_utf8(rawText);
@ -196,7 +196,7 @@ InReaction CInput::ManuallyHandleKeys(const SDL_Event_* ev)
ClearComposedText(); ClearComposedText();
} }
m_ComposingText = ev->ev.edit.start != 0 || rawLength != 0; m_ComposingText = ev.edit.start != 0 || rawLength != 0;
if (m_ComposingText) if (m_ComposingText)
{ {
caption.insert(m_iInsertPos, wtext); caption.insert(m_iInsertPos, wtext);
@ -204,7 +204,7 @@ InReaction CInput::ManuallyHandleKeys(const SDL_Event_* ev)
// The text buffer is limited to SDL_TEXTEDITINGEVENT_TEXT_SIZE bytes, yet start // The text buffer is limited to SDL_TEXTEDITINGEVENT_TEXT_SIZE bytes, yet start
// increases without limit, so don't let it advance beyond the composed text length // increases without limit, so don't let it advance beyond the composed text length
m_iComposedLength = wtext.length(); m_iComposedLength = wtext.length();
m_iComposedPos = ev->ev.edit.start < m_iComposedLength ? ev->ev.edit.start : m_iComposedLength; m_iComposedPos = ev.edit.start < m_iComposedLength ? ev.edit.start : m_iComposedLength;
m_iBufferPos = m_iInsertPos + m_iComposedPos; m_iBufferPos = m_iInsertPos + m_iComposedPos;
// TODO: composed text selection - what does ev.edit.length do? // TODO: composed text selection - what does ev.edit.length do?
@ -225,7 +225,7 @@ InReaction CInput::ManuallyHandleKeys(const SDL_Event_* ev)
// Since the GUI framework doesn't handle to set settings // Since the GUI framework doesn't handle to set settings
// in Unicode (CStrW), we'll simply retrieve the actual // in Unicode (CStrW), we'll simply retrieve the actual
// pointer and edit that. // pointer and edit that.
SDL_Keycode keyCode = ev->ev.key.keysym.sym; SDL_Keycode keyCode = ev.key.keysym.sym;
// We have a probably printable key - we should return HANDLED so it can't trigger hotkeys. // We have a probably printable key - we should return HANDLED so it can't trigger hotkeys.
// However, if Ctrl/Meta modifiers are active, just pass it through instead, // However, if Ctrl/Meta modifiers are active, just pass it through instead,
@ -242,7 +242,7 @@ InReaction CInput::ManuallyHandleKeys(const SDL_Event_* ev)
if (m_ComposingText) if (m_ComposingText)
return IN_HANDLED; return IN_HANDLED;
if (ev->ev.type == SDL_KEYDOWN) if (ev.type == SDL_KEYDOWN)
{ {
ManuallyImmutableHandleKeyDownEvent(keyCode); ManuallyImmutableHandleKeyDownEvent(keyCode);
ManuallyMutableHandleKeyDownEvent(keyCode); ManuallyMutableHandleKeyDownEvent(keyCode);
@ -619,11 +619,11 @@ void CInput::SetupGeneratedPlaceholderText()
m_GeneratedPlaceholderTextValid = true; m_GeneratedPlaceholderTextValid = true;
} }
InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event_* ev) InReaction CInput::ManuallyHandleHotkeyEvent(const SDL_Event& ev)
{ {
bool shiftKeyPressed = g_scancodes[SDL_SCANCODE_LSHIFT] || g_scancodes[SDL_SCANCODE_RSHIFT]; bool shiftKeyPressed = g_scancodes[SDL_SCANCODE_LSHIFT] || g_scancodes[SDL_SCANCODE_RSHIFT];
std::string hotkey = static_cast<const char*>(ev->ev.user.data1); std::string hotkey = static_cast<const char*>(ev.user.data1);
// Get direct access to silently mutate m_Caption. // Get direct access to silently mutate m_Caption.
// (Messages don't currently need to be sent) // (Messages don't currently need to be sent)
@ -1161,12 +1161,12 @@ void CInput::HandleMessage(SGUIMessage& Message)
if (m_ComposingText) if (m_ComposingText)
{ {
// Simulate a final text editing event to clear the composition // Simulate a final text editing event to clear the composition
SDL_Event_ evt; SDL_Event ev{};
evt.ev.type = SDL_TEXTEDITING; ev.type = SDL_TEXTEDITING;
evt.ev.edit.length = 0; ev.edit.length = 0;
evt.ev.edit.start = 0; ev.edit.start = 0;
evt.ev.edit.text[0] = 0; ev.edit.text[0] = '\0';
ManuallyHandleKeys(&evt); ManuallyHandleKeys(ev);
} }
SDL_StopTextInput(); SDL_StopTextInput();

View file

@ -36,7 +36,7 @@
class CCanvas2D; class CCanvas2D;
class CGUI; class CGUI;
struct SDL_Event_; union SDL_Event;
/** /**
* Text field where you can input and edit the text. * Text field where you can input and edit the text.
@ -80,7 +80,7 @@ protected:
/** /**
* Handle events manually to catch keyboard inputting. * Handle events manually to catch keyboard inputting.
*/ */
virtual InReaction ManuallyHandleKeys(const SDL_Event_* ev); virtual InReaction ManuallyHandleKeys(const SDL_Event& ev);
/** /**
* Handle events manually to catch keys which change the text. * Handle events manually to catch keys which change the text.
@ -95,7 +95,7 @@ protected:
/** /**
* Handle hotkey events (called by ManuallyHandleKeys) * Handle hotkey events (called by ManuallyHandleKeys)
*/ */
virtual InReaction ManuallyHandleHotkeyEvent(const SDL_Event_* ev); virtual InReaction ManuallyHandleHotkeyEvent(const SDL_Event& ev);
/** /**
* @see IGUIObject#HandleSizeChanged() * @see IGUIObject#HandleSizeChanged()

View file

@ -260,13 +260,13 @@ void CList::HandleMessage(SGUIMessage& Message)
IGUITextOwner::HandleMessage(Message); IGUITextOwner::HandleMessage(Message);
} }
InReaction CList::ManuallyHandleKeys(const SDL_Event_* ev) InReaction CList::ManuallyHandleKeys(const SDL_Event& ev)
{ {
InReaction result = IN_PASS; InReaction result = IN_PASS;
if (ev->ev.type == SDL_KEYDOWN) if (ev.type == SDL_KEYDOWN)
{ {
int szChar = ev->ev.key.keysym.sym; int szChar = ev.key.keysym.sym;
switch (szChar) switch (szChar)
{ {

View file

@ -35,6 +35,7 @@
class CCanvas2D; class CCanvas2D;
class CGUI; class CGUI;
class CGUIString; class CGUIString;
union SDL_Event;
/** /**
* Create a list of elements, where one can be selected * Create a list of elements, where one can be selected
@ -88,7 +89,7 @@ protected:
/** /**
* Handle events manually to catch keyboard inputting. * Handle events manually to catch keyboard inputting.
*/ */
virtual InReaction ManuallyHandleKeys(const SDL_Event_* ev); virtual InReaction ManuallyHandleKeys(const SDL_Event& ev);
/** /**
* Draws the List box * Draws the List box

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -55,11 +55,11 @@ struct CColor;
// ignore JS_SetProperty return value, because errors should be impossible // ignore JS_SetProperty return value, because errors should be impossible
// and we can't do anything useful in the case of errors anyway // and we can't do anything useful in the case of errors anyway
template<> void Script::ToJSVal<SDL_Event_>(const ScriptRequest& rq, JS::MutableHandleValue ret, SDL_Event_ const& val) template<> void Script::ToJSVal<SDL_Event>(const ScriptRequest& rq, JS::MutableHandleValue ret, SDL_Event const& ev)
{ {
const char* typeName; const char* typeName;
switch (val.ev.type) switch (ev.type)
{ {
case SDL_WINDOWEVENT: typeName = "windowevent"; break; case SDL_WINDOWEVENT: typeName = "windowevent"; break;
case SDL_KEYDOWN: typeName = "keydown"; break; case SDL_KEYDOWN: typeName = "keydown"; break;
@ -85,13 +85,13 @@ template<> void Script::ToJSVal<SDL_Event_>(const ScriptRequest& rq, JS::Mutable
SET(obj, "type", typeName); SET(obj, "type", typeName);
switch (val.ev.type) switch (ev.type)
{ {
case SDL_KEYDOWN: case SDL_KEYDOWN:
case SDL_KEYUP: case SDL_KEYUP:
{ {
// SET(obj, "which", (int)val.ev.key.which); // (not in wsdl.h) // SET(obj, "which", static_cast<int>(ev.key.which)); // (not in wsdl.h)
// SET(obj, "state", (int)val.ev.key.state); // (not in wsdl.h) // SET(obj, "state", static_cast<int>(ev.key.state)); // (not in wsdl.h)
JS::RootedObject keysym(rq.cx, JS_NewPlainObject(rq.cx)); JS::RootedObject keysym(rq.cx, JS_NewPlainObject(rq.cx));
if (!keysym) if (!keysym)
@ -102,9 +102,9 @@ template<> void Script::ToJSVal<SDL_Event_>(const ScriptRequest& rq, JS::Mutable
JS::RootedValue keysymVal(rq.cx, JS::ObjectValue(*keysym)); JS::RootedValue keysymVal(rq.cx, JS::ObjectValue(*keysym));
JS_SetProperty(rq.cx, obj, "keysym", keysymVal); JS_SetProperty(rq.cx, obj, "keysym", keysymVal);
// SET(keysym, "scancode", (int)val.ev.key.keysym.scancode); // (not in wsdl.h) // SET(keysym, "scancode", static_cast<int>(ev.key.keysym.scancode)); // (not in wsdl.h)
SET(keysym, "sym", (int)val.ev.key.keysym.sym); SET(keysym, "sym", static_cast<int>(ev.key.keysym.sym));
// SET(keysym, "mod", (int)val.ev.key.keysym.mod); // (not in wsdl.h) // SET(keysym, "mod", static_cast<int>(ev.key.keysym.mod)); // (not in wsdl.h)
{ {
SET(keysym, "unicode", JS::UndefinedHandleValue); SET(keysym, "unicode", JS::UndefinedHandleValue);
} }
@ -115,23 +115,23 @@ template<> void Script::ToJSVal<SDL_Event_>(const ScriptRequest& rq, JS::Mutable
} }
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
{ {
// SET(obj, "which", (int)val.ev.motion.which); // (not in wsdl.h) // SET(obj, "which", static_cast<int>(ev.motion.which)); // (not in wsdl.h)
// SET(obj, "state", (int)val.ev.motion.state); // (not in wsdl.h) // SET(obj, "state", static_cast<int>(ev.motion.state)); // (not in wsdl.h)
SET(obj, "x", (int)val.ev.motion.x); SET(obj, "x", static_cast<int>(ev.motion.x));
SET(obj, "y", (int)val.ev.motion.y); SET(obj, "y", static_cast<int>(ev.motion.y));
// SET(obj, "xrel", (int)val.ev.motion.xrel); // (not in wsdl.h) // SET(obj, "xrel", static_cast<int>(ev.motion.xrel)); // (not in wsdl.h)
// SET(obj, "yrel", (int)val.ev.motion.yrel); // (not in wsdl.h) // SET(obj, "yrel", static_cast<int>(ev.motion.yrel)); // (not in wsdl.h)
break; break;
} }
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
{ {
// SET(obj, "which", (int)val.ev.button.which); // (not in wsdl.h) // SET(obj, "which", static_cast<int>(ev.button.which)); // (not in wsdl.h)
SET(obj, "button", (int)val.ev.button.button); SET(obj, "button", static_cast<int>(ev.button.button));
SET(obj, "state", (int)val.ev.button.state); SET(obj, "state", static_cast<int>(ev.button.state));
SET(obj, "x", (int)val.ev.button.x); SET(obj, "x", static_cast<int>(ev.button.x));
SET(obj, "y", (int)val.ev.button.y); SET(obj, "y", static_cast<int>(ev.button.y));
SET(obj, "clicks", (int)val.ev.button.clicks); SET(obj, "clicks", static_cast<int>(ev.button.clicks));
break; break;
} }
case SDL_HOTKEYPRESS: case SDL_HOTKEYPRESS:
@ -140,7 +140,7 @@ template<> void Script::ToJSVal<SDL_Event_>(const ScriptRequest& rq, JS::Mutable
case SDL_HOTKEYPRESS_SILENT: case SDL_HOTKEYPRESS_SILENT:
case SDL_HOTKEYUP_SILENT: case SDL_HOTKEYUP_SILENT:
{ {
SET(obj, "hotkey", static_cast<const char*>(val.ev.user.data1)); SET(obj, "hotkey", static_cast<const char*>(ev.user.data1));
break; break;
} }
} }

View file

@ -160,17 +160,17 @@ public:
g_GUI->OpenChildPage(L"hotkey/page_hotkey.xml", data); g_GUI->OpenChildPage(L"hotkey/page_hotkey.xml", data);
// Press 'a'. // Press 'a'.
SDL_Event_ hotkeyNotification; SDL_Event hotkeyNotification;
hotkeyNotification.ev.type = SDL_KEYDOWN; hotkeyNotification.type = SDL_KEYDOWN;
hotkeyNotification.ev.key.keysym.scancode = SDL_SCANCODE_A; hotkeyNotification.key.keysym.scancode = SDL_SCANCODE_A;
hotkeyNotification.ev.key.repeat = 0; hotkeyNotification.key.repeat = 0;
// Init input and poll the event. // Init input and poll the event.
InitInput(); InitInput();
in_push_priority_event(&hotkeyNotification); in_push_priority_event(hotkeyNotification);
SDL_Event_ ev; SDL_Event ev;
while (in_poll_event(&ev)) while (in_poll_event(ev))
in_dispatch_event(&ev); in_dispatch_event(ev);
const ScriptInterface& pageScriptInterface = *(g_GUI->GetActiveGUI()->GetScriptInterface()); const ScriptInterface& pageScriptInterface = *(g_GUI->GetActiveGUI()->GetScriptInterface());
ScriptRequest prq(pageScriptInterface); ScriptRequest prq(pageScriptInterface);
@ -190,10 +190,10 @@ public:
TS_ASSERT_EQUALS(hotkey_pressed_value, true); TS_ASSERT_EQUALS(hotkey_pressed_value, true);
// We are listening to KeyDown events, so repeat shouldn't matter. // We are listening to KeyDown events, so repeat shouldn't matter.
hotkeyNotification.ev.key.repeat = 1; hotkeyNotification.key.repeat = 1;
in_push_priority_event(&hotkeyNotification); in_push_priority_event(hotkeyNotification);
while (in_poll_event(&ev)) while (in_poll_event(ev))
in_dispatch_event(&ev); in_dispatch_event(ev);
hotkey_pressed_value = false; hotkey_pressed_value = false;
Script::GetProperty(prq, global, "state_before", &js_hotkey_pressed_value); Script::GetProperty(prq, global, "state_before", &js_hotkey_pressed_value);
@ -205,10 +205,10 @@ public:
Script::FromJSVal(prq, js_hotkey_pressed_value, hotkey_pressed_value); Script::FromJSVal(prq, js_hotkey_pressed_value, hotkey_pressed_value);
TS_ASSERT_EQUALS(hotkey_pressed_value, true); TS_ASSERT_EQUALS(hotkey_pressed_value, true);
hotkeyNotification.ev.type = SDL_KEYUP; hotkeyNotification.type = SDL_KEYUP;
in_push_priority_event(&hotkeyNotification); in_push_priority_event(hotkeyNotification);
while (in_poll_event(&ev)) while (in_poll_event(ev))
in_dispatch_event(&ev); in_dispatch_event(ev);
hotkey_pressed_value = true; hotkey_pressed_value = true;
Script::GetProperty(prq, global, "state_before", &js_hotkey_pressed_value); Script::GetProperty(prq, global, "state_before", &js_hotkey_pressed_value);

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
@ -28,7 +28,6 @@
#define INCLUDED_SDL #define INCLUDED_SDL
#include "lib/config2.h" #include "lib/config2.h"
#include "lib/external_libraries/libsdl_fwd.h"
# include <SDL.h> # include <SDL.h>
# include <SDL_thread.h> # include <SDL_thread.h>
@ -43,12 +42,6 @@
// another header that toggles between wsdl and SDL_endian.h. // another header that toggles between wsdl and SDL_endian.h.
# include <SDL_endian.h> # include <SDL_endian.h>
// complete definition of our forward-declared SDL_Event (see sdl_fwd.h)
struct SDL_Event_
{
SDL_Event ev;
};
// Returns a windowing subsystem used for the window. // Returns a windowing subsystem used for the window.
const char* GetSDLSubsystem(SDL_Window* window); const char* GetSDLSubsystem(SDL_Window* window);

View file

@ -1,41 +0,0 @@
/* Copyright (C) 2010 Wildfire Games.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* forward declaration of SDL_Event
*/
#ifndef INCLUDED_SDL_FWD
#define INCLUDED_SDL_FWD
// 2006-08-26 SDL is dragged into 6 of our 7 static library components.
// it must be specified in each of their "extern_libs" so that the
// include path is set and <SDL.h> can be found.
//
// obviously this is bad, so we work around the root cause. mostly only
// SDL_Event is needed. unfortunately it cannot be forward-declared,
// because it is a union (regrettable design mistake).
// we fix this by wrapping it in a struct, which can safely be
// forward-declared and used for SDL_Event_* parameters.
struct SDL_Event_;
#endif // #ifndef INCLUDED_SDL_FWD

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
@ -40,7 +40,7 @@ const size_t MAX_HANDLERS = 10;
static InHandler handler_stack[MAX_HANDLERS]; static InHandler handler_stack[MAX_HANDLERS];
static size_t handler_stack_top = 0; static size_t handler_stack_top = 0;
static std::list<SDL_Event_> priority_events; static std::list<SDL_Event> priority_events;
void in_add_handler(InHandler handler) void in_add_handler(InHandler handler)
{ {
@ -58,11 +58,11 @@ void in_reset_handlers()
} }
// send ev to each handler until one returns IN_HANDLED // send ev to each handler until one returns IN_HANDLED
void in_dispatch_event(const SDL_Event_* ev) void in_dispatch_event(const SDL_Event& ev)
{ {
for(int i = (int)handler_stack_top-1; i >= 0; i--) for(int i = (int)handler_stack_top-1; i >= 0; i--)
{ {
ENSURE(handler_stack[i] && ev); ENSURE(handler_stack[i]);
InReaction ret = handler_stack[i](ev); InReaction ret = handler_stack[i](ev);
// .. done, return // .. done, return
if(ret == IN_HANDLED) if(ret == IN_HANDLED)
@ -76,22 +76,22 @@ void in_dispatch_event(const SDL_Event_* ev)
} }
} }
void in_push_priority_event(const SDL_Event_* event) void in_push_priority_event(const SDL_Event& event)
{ {
priority_events.push_back(*event); priority_events.push_back(event);
} }
int in_poll_priority_event(SDL_Event_* event) int in_poll_priority_event(SDL_Event& event)
{ {
if (priority_events.empty()) if (priority_events.empty())
return 0; return 0;
*event = priority_events.front(); event = priority_events.front();
priority_events.pop_front(); priority_events.pop_front();
return 1; return 1;
} }
int in_poll_event(SDL_Event_* event) int in_poll_event(SDL_Event& event)
{ {
return in_poll_priority_event(event) ? 1 : SDL_PollEvent(&event->ev); return in_poll_priority_event(event) ? 1 : SDL_PollEvent(&event);
} }

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
@ -27,7 +27,7 @@
#ifndef INCLUDED_INPUT #ifndef INCLUDED_INPUT
#define INCLUDED_INPUT #define INCLUDED_INPUT
struct SDL_Event_; union SDL_Event;
// input handler return values. // input handler return values.
enum InReaction enum InReaction
@ -42,7 +42,7 @@ enum InReaction
IN_HANDLED = 2 IN_HANDLED = 2
}; };
typedef InReaction (*InHandler)(const SDL_Event_*); typedef InReaction (*InHandler)(const SDL_Event&);
// register an input handler, which will receive all subsequent events first. // register an input handler, which will receive all subsequent events first.
// events are passed to other handlers if handler returns IN_PASS. // events are passed to other handlers if handler returns IN_PASS.
@ -52,19 +52,19 @@ extern void in_add_handler(InHandler handler);
extern void in_reset_handlers(); extern void in_reset_handlers();
// send event to each handler (newest first) until one returns true // send event to each handler (newest first) until one returns true
extern void in_dispatch_event(const SDL_Event_* event); extern void in_dispatch_event(const SDL_Event& event);
// push an event onto the back of a high-priority queue - the new event will // push an event onto the back of a high-priority queue - the new event will
// be returned by in_poll_event before any standard SDL events // be returned by in_poll_event before any standard SDL events
extern void in_push_priority_event(const SDL_Event_* event); extern void in_push_priority_event(const SDL_Event& event);
// reads events that were pushed by in_push_priority_event // reads events that were pushed by in_push_priority_event
// returns 1 if an event was read, 0 otherwise. // returns 1 if an event was read, 0 otherwise.
extern int in_poll_priority_event(SDL_Event_* event); extern int in_poll_priority_event(SDL_Event& event);
// reads events that were pushed by in_push_priority_event, or, if there are // reads events that were pushed by in_push_priority_event, or, if there are
// no high-priority events) reads from the SDL event queue with SDL_PollEvent. // no high-priority events) reads from the SDL event queue with SDL_PollEvent.
// returns 1 if an event was read, 0 otherwise. // returns 1 if an event was read, 0 otherwise.
extern int in_poll_event(SDL_Event_* event); extern int in_poll_event(SDL_Event& event);
#endif // #ifndef INCLUDED_INPUT #endif // #ifndef INCLUDED_INPUT

View file

@ -195,19 +195,19 @@ void RestartEngine()
} }
// main app message handler // main app message handler
static InReaction MainInputHandler(const SDL_Event_* ev) static InReaction MainInputHandler(const SDL_Event& ev)
{ {
switch(ev->ev.type) switch(ev.type)
{ {
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:
switch(ev->ev.window.event) switch(ev.window.event)
{ {
case SDL_WINDOWEVENT_RESIZED: case SDL_WINDOWEVENT_RESIZED:
g_ResizedW = ev->ev.window.data1; g_ResizedW = ev.window.data1;
g_ResizedH = ev->ev.window.data2; g_ResizedH = ev.window.data2;
break; break;
case SDL_WINDOWEVENT_MOVED: case SDL_WINDOWEVENT_MOVED:
g_VideoMode.UpdatePosition(ev->ev.window.data1, ev->ev.window.data2); g_VideoMode.UpdatePosition(ev.window.data1, ev.window.data2);
} }
break; break;
@ -217,7 +217,7 @@ static InReaction MainInputHandler(const SDL_Event_* ev)
case SDL_DROPFILE: case SDL_DROPFILE:
{ {
char* dropped_filedir = ev->ev.drop.file; char* dropped_filedir = ev.drop.file;
const Paths paths(g_CmdLineArgs); const Paths paths(g_CmdLineArgs);
CModInstaller installer(paths.UserData() / "mods", paths.Cache()); CModInstaller installer(paths.UserData() / "mods", paths.Cache());
installer.Install(std::string(dropped_filedir), g_ScriptContext, true); installer.Install(std::string(dropped_filedir), g_ScriptContext, true);
@ -235,7 +235,7 @@ static InReaction MainInputHandler(const SDL_Event_* ev)
} }
case SDL_HOTKEYPRESS: case SDL_HOTKEYPRESS:
std::string hotkey = static_cast<const char*>(ev->ev.user.data1); std::string hotkey = static_cast<const char*>(ev.user.data1);
if (hotkey == "exit") if (hotkey == "exit")
{ {
QuitEngine(EXIT_SUCCESS); QuitEngine(EXIT_SUCCESS);
@ -281,8 +281,8 @@ static void PumpEvents()
PROFILE3("dispatch events"); PROFILE3("dispatch events");
SDL_Event_ ev; SDL_Event ev{};
while (in_poll_event(&ev)) while (in_poll_event(ev))
{ {
PROFILE2("event"); PROFILE2("event");
if (g_GUI) if (g_GUI)
@ -292,7 +292,7 @@ static void PumpEvents()
std::string data = Script::StringifyJSON(rq, &tmpVal); std::string data = Script::StringifyJSON(rq, &tmpVal);
PROFILE2_ATTR("%s", data.c_str()); PROFILE2_ATTR("%s", data.c_str());
} }
in_dispatch_event(&ev); in_dispatch_event(ev);
} }
g_TouchInput.Frame(); g_TouchInput.Frame();

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -692,14 +692,14 @@ static bool isUnprintableChar(SDL_Keysym key)
} }
} }
InReaction conInputHandler(const SDL_Event_* ev) InReaction conInputHandler(const SDL_Event& ev)
{ {
if (!g_Console) if (!g_Console)
return IN_PASS; return IN_PASS;
if (static_cast<int>(ev->ev.type) == SDL_HOTKEYPRESS) if (static_cast<int>(ev.type) == SDL_HOTKEYPRESS)
{ {
std::string hotkey = static_cast<const char*>(ev->ev.user.data1); std::string hotkey = static_cast<const char*>(ev.user.data1);
if (hotkey == "console.toggle") if (hotkey == "console.toggle")
{ {
@ -734,23 +734,23 @@ InReaction conInputHandler(const SDL_Event_* ev)
// In SDL2, we no longer get Unicode wchars via SDL_Keysym // In SDL2, we no longer get Unicode wchars via SDL_Keysym
// we use text input events instead and they provide UTF-8 chars // we use text input events instead and they provide UTF-8 chars
if (ev->ev.type == SDL_TEXTINPUT) if (ev.type == SDL_TEXTINPUT)
{ {
// TODO: this could be more efficient with an interface to insert UTF-8 strings directly // TODO: this could be more efficient with an interface to insert UTF-8 strings directly
std::wstring wstr = wstring_from_utf8(ev->ev.text.text); std::wstring wstr = wstring_from_utf8(ev.text.text);
for (size_t i = 0; i < wstr.length(); ++i) for (size_t i = 0; i < wstr.length(); ++i)
g_Console->InsertChar(0, wstr[i]); g_Console->InsertChar(0, wstr[i]);
return IN_HANDLED; return IN_HANDLED;
} }
// TODO: text editing events for IME support // TODO: text editing events for IME support
if (ev->ev.type != SDL_KEYDOWN && ev->ev.type != SDL_KEYUP) if (ev.type != SDL_KEYDOWN && ev.type != SDL_KEYUP)
return IN_PASS; return IN_PASS;
int sym = ev->ev.key.keysym.sym; int sym = ev.key.keysym.sym;
// Stop unprintable characters (ctrl+, alt+ and escape). // Stop unprintable characters (ctrl+, alt+ and escape).
if (ev->ev.type == SDL_KEYDOWN && isUnprintableChar(ev->ev.key.keysym) && if (ev.type == SDL_KEYDOWN && isUnprintableChar(ev.key.keysym) &&
!HotkeyIsPressed("console.toggle")) !HotkeyIsPressed("console.toggle"))
{ {
g_Console->InsertChar(sym, 0); g_Console->InsertChar(sym, 0);

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -34,7 +34,7 @@
class CCanvas2D; class CCanvas2D;
class CTextRenderer; class CTextRenderer;
struct SDL_Event_; union SDL_Event;
/** /**
* In-game console. * In-game console.
@ -137,6 +137,6 @@ private:
extern CConsole* g_Console; extern CConsole* g_Console;
extern InReaction conInputHandler(const SDL_Event_* ev); extern InReaction conInputHandler(const SDL_Event& ev);
#endif // INCLUDED_CCONSOLE #endif // INCLUDED_CCONSOLE

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -40,14 +40,14 @@ bool g_mouse_buttons[MOUSE_LAST - MOUSE_BASE] = {0};
PIFrequencyFilter g_frequencyFilter; PIFrequencyFilter g_frequencyFilter;
// updates the state of the above; never swallows messages. // updates the state of the above; never swallows messages.
InReaction GlobalsInputHandler(const SDL_Event_* ev) InReaction GlobalsInputHandler(const SDL_Event& ev)
{ {
size_t c; size_t c;
switch(ev->ev.type) switch(ev.type)
{ {
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:
switch(ev->ev.window.event) switch(ev.window.event)
{ {
case SDL_WINDOWEVENT_MINIMIZED: case SDL_WINDOWEVENT_MINIMIZED:
g_app_minimized = true; g_app_minimized = true;
@ -72,15 +72,15 @@ InReaction GlobalsInputHandler(const SDL_Event_* ev)
return IN_PASS; return IN_PASS;
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
g_mouse_x = ev->ev.motion.x; g_mouse_x = ev.motion.x;
g_mouse_y = ev->ev.motion.y; g_mouse_y = ev.motion.y;
return IN_PASS; return IN_PASS;
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
c = ev->ev.button.button; c = ev.button.button;
if(c < ARRAY_SIZE(g_mouse_buttons)) if(c < ARRAY_SIZE(g_mouse_buttons))
g_mouse_buttons[c] = (ev->ev.type == SDL_MOUSEBUTTONDOWN); g_mouse_buttons[c] = (ev.type == SDL_MOUSEBUTTONDOWN);
else else
{ {
// don't complain: just ignore people with too many mouse buttons // don't complain: just ignore people with too many mouse buttons
@ -90,7 +90,7 @@ InReaction GlobalsInputHandler(const SDL_Event_* ev)
case SDL_KEYDOWN: case SDL_KEYDOWN:
case SDL_KEYUP: case SDL_KEYUP:
g_scancodes[ev->ev.key.keysym.scancode] = (ev->ev.type == SDL_KEYDOWN); g_scancodes[ev.key.keysym.scancode] = (ev.type == SDL_KEYDOWN);
return IN_PASS; return IN_PASS;
default: default:

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -25,7 +25,7 @@
#include <cstdint> #include <cstdint>
#include <unordered_map> #include <unordered_map>
struct SDL_Event_; union SDL_Event;
// thin abstraction layer on top of SDL. // thin abstraction layer on top of SDL.
// game code should use it instead of SDL_GetMouseState etc. because // game code should use it instead of SDL_GetMouseState etc. because
@ -59,7 +59,7 @@ extern std::unordered_map<int32_t, bool> g_scancodes;
*/ */
extern bool g_mouse_buttons[MOUSE_LAST - MOUSE_BASE]; extern bool g_mouse_buttons[MOUSE_LAST - MOUSE_BASE];
extern InReaction GlobalsInputHandler(const SDL_Event_* ev); extern InReaction GlobalsInputHandler(const SDL_Event& ev);
extern PIFrequencyFilter g_frequencyFilter; extern PIFrequencyFilter g_frequencyFilter;

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -71,7 +71,7 @@ namespace {
// Stores the 'specificity' of the newly pressed hotkeys. // Stores the 'specificity' of the newly pressed hotkeys.
size_t closestMapMatch = 0; size_t closestMapMatch = 0;
// This is merely used to ensure consistency in EventWillFireHotkey. // This is merely used to ensure consistency in EventWillFireHotkey.
const SDL_Event_* currentEvent; const SDL_Event* currentEvent;
// List of currently pressed hotkeys. This is used to quickly reset hotkeys. // List of currently pressed hotkeys. This is used to quickly reset hotkeys.
// This is an unsorted vector because there will generally be very few elements, // This is an unsorted vector because there will generally be very few elements,
@ -174,16 +174,16 @@ bool isPressed(const SKey& key)
return false; return false;
} }
InReaction HotkeyStateChange(const SDL_Event_* ev) InReaction HotkeyStateChange(const SDL_Event& ev)
{ {
if (ev->ev.type == SDL_HOTKEYPRESS || ev->ev.type == SDL_HOTKEYPRESS_SILENT) if (ev.type == SDL_HOTKEYPRESS || ev.type == SDL_HOTKEYPRESS_SILENT)
g_HotkeyStatus[static_cast<const char*>(ev->ev.user.data1)] = true; g_HotkeyStatus[static_cast<const char*>(ev.user.data1)] = true;
else if (ev->ev.type == SDL_HOTKEYUP || ev->ev.type == SDL_HOTKEYUP_SILENT) else if (ev.type == SDL_HOTKEYUP || ev.type == SDL_HOTKEYUP_SILENT)
g_HotkeyStatus[static_cast<const char*>(ev->ev.user.data1)] = false; g_HotkeyStatus[static_cast<const char*>(ev.user.data1)] = false;
return IN_PASS; return IN_PASS;
} }
InReaction HotkeyInputPrepHandler(const SDL_Event_* ev) InReaction HotkeyInputPrepHandler(const SDL_Event& ev)
{ {
int scancode = SDL_SCANCODE_UNKNOWN; int scancode = SDL_SCANCODE_UNKNOWN;
@ -191,40 +191,40 @@ InReaction HotkeyInputPrepHandler(const SDL_Event_* ev)
newPressedHotkeys.clear(); newPressedHotkeys.clear();
currentEvent = nullptr; currentEvent = nullptr;
switch(ev->ev.type) switch(ev.type)
{ {
case SDL_KEYDOWN: case SDL_KEYDOWN:
case SDL_KEYUP: case SDL_KEYUP:
scancode = ev->ev.key.keysym.scancode; scancode = ev.key.keysym.scancode;
break; break;
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
// Mousewheel events are no longer buttons, but we want to maintain the order // Mousewheel events are no longer buttons, but we want to maintain the order
// expected by g_mouse_buttons for compatibility // expected by g_mouse_buttons for compatibility
if (ev->ev.button.button >= SDL_BUTTON_X1) if (ev.button.button >= SDL_BUTTON_X1)
scancode = MOUSE_BASE + (int)ev->ev.button.button + 2; scancode = MOUSE_BASE + static_cast<int>(ev.button.button) + 2;
else else
scancode = MOUSE_BASE + (int)ev->ev.button.button; scancode = MOUSE_BASE + static_cast<int>(ev.button.button);
break; break;
case SDL_MOUSEWHEEL: case SDL_MOUSEWHEEL:
if (ev->ev.wheel.y > 0) if (ev.wheel.y > 0)
{ {
scancode = MOUSE_WHEELUP; scancode = MOUSE_WHEELUP;
break; break;
} }
else if (ev->ev.wheel.y < 0) else if (ev.wheel.y < 0)
{ {
scancode = MOUSE_WHEELDOWN; scancode = MOUSE_WHEELDOWN;
break; break;
} }
else if (ev->ev.wheel.x > 0) else if (ev.wheel.x > 0)
{ {
scancode = MOUSE_X2; scancode = MOUSE_X2;
break; break;
} }
else if (ev->ev.wheel.x < 0) else if (ev.wheel.x < 0)
{ {
scancode = MOUSE_X1; scancode = MOUSE_X1;
break; break;
@ -240,41 +240,41 @@ InReaction HotkeyInputPrepHandler(const SDL_Event_* ev)
// Create phantom 'unified-modifier' events when left- or right- modifier keys are pressed // Create phantom 'unified-modifier' events when left- or right- modifier keys are pressed
// Just send them to this handler; don't let the imaginary event codes leak back to real SDL. // Just send them to this handler; don't let the imaginary event codes leak back to real SDL.
SDL_Event_ phantom; SDL_Event phantom{};
phantom.ev.type = ((ev->ev.type == SDL_KEYDOWN) || (ev->ev.type == SDL_MOUSEBUTTONDOWN)) ? SDL_KEYDOWN : SDL_KEYUP; phantom.type = ((ev.type == SDL_KEYDOWN) || (ev.type == SDL_MOUSEBUTTONDOWN)) ? SDL_KEYDOWN : SDL_KEYUP;
if (phantom.ev.type == SDL_KEYDOWN) if (phantom.type == SDL_KEYDOWN)
phantom.ev.key.repeat = ev->ev.type == SDL_KEYDOWN ? ev->ev.key.repeat : 0; phantom.key.repeat = ev.type == SDL_KEYDOWN ? ev.key.repeat : 0;
if (scancode == SDL_SCANCODE_LSHIFT || scancode == SDL_SCANCODE_RSHIFT) if (scancode == SDL_SCANCODE_LSHIFT || scancode == SDL_SCANCODE_RSHIFT)
{ {
phantom.ev.key.keysym.scancode = static_cast<SDL_Scancode>(UNIFIED_SHIFT); phantom.key.keysym.scancode = static_cast<SDL_Scancode>(UNIFIED_SHIFT);
unified[0] = (phantom.ev.type == SDL_KEYDOWN); unified[0] = (phantom.type == SDL_KEYDOWN);
return HotkeyInputPrepHandler(&phantom); return HotkeyInputPrepHandler(phantom);
} }
else if (scancode == SDL_SCANCODE_LCTRL || scancode == SDL_SCANCODE_RCTRL) else if (scancode == SDL_SCANCODE_LCTRL || scancode == SDL_SCANCODE_RCTRL)
{ {
phantom.ev.key.keysym.scancode = static_cast<SDL_Scancode>(UNIFIED_CTRL); phantom.key.keysym.scancode = static_cast<SDL_Scancode>(UNIFIED_CTRL);
unified[1] = (phantom.ev.type == SDL_KEYDOWN); unified[1] = (phantom.type == SDL_KEYDOWN);
return HotkeyInputPrepHandler(&phantom); return HotkeyInputPrepHandler(phantom);
} }
else if (scancode == SDL_SCANCODE_LALT || scancode == SDL_SCANCODE_RALT) else if (scancode == SDL_SCANCODE_LALT || scancode == SDL_SCANCODE_RALT)
{ {
phantom.ev.key.keysym.scancode = static_cast<SDL_Scancode>(UNIFIED_ALT); phantom.key.keysym.scancode = static_cast<SDL_Scancode>(UNIFIED_ALT);
unified[2] = (phantom.ev.type == SDL_KEYDOWN); unified[2] = (phantom.type == SDL_KEYDOWN);
return HotkeyInputPrepHandler(&phantom); return HotkeyInputPrepHandler(phantom);
} }
else if (scancode == SDL_SCANCODE_LGUI || scancode == SDL_SCANCODE_RGUI) else if (scancode == SDL_SCANCODE_LGUI || scancode == SDL_SCANCODE_RGUI)
{ {
phantom.ev.key.keysym.scancode = static_cast<SDL_Scancode>(UNIFIED_SUPER); phantom.key.keysym.scancode = static_cast<SDL_Scancode>(UNIFIED_SUPER);
unified[3] = (phantom.ev.type == SDL_KEYDOWN); unified[3] = (phantom.type == SDL_KEYDOWN);
return HotkeyInputPrepHandler(&phantom); return HotkeyInputPrepHandler(phantom);
} }
// Check whether we have any hotkeys registered that include this scancode. // Check whether we have any hotkeys registered that include this scancode.
if (g_HotkeyMap.find(scancode) == g_HotkeyMap.end()) if (g_HotkeyMap.find(scancode) == g_HotkeyMap.end())
return IN_PASS; return IN_PASS;
currentEvent = ev; currentEvent = &ev;
/** /**
* Hotkey behaviour spec (see also tests): * Hotkey behaviour spec (see also tests):
@ -299,9 +299,9 @@ InReaction HotkeyInputPrepHandler(const SDL_Event_* ev)
* ...Yes, this is all surprisingly complex. * ...Yes, this is all surprisingly complex.
*/ */
bool isReleasedKey = ev->ev.type == SDL_KEYUP || ev->ev.type == SDL_MOUSEBUTTONUP; bool isReleasedKey = ev.type == SDL_KEYUP || ev.type == SDL_MOUSEBUTTONUP;
// Wheel events are pressed & released in the same go. // Wheel events are pressed & released in the same go.
bool isInstantaneous = ev->ev.type == SDL_MOUSEWHEEL; bool isInstantaneous = ev.type == SDL_MOUSEWHEEL;
if (!isInstantaneous) if (!isInstantaneous)
{ {
@ -359,12 +359,12 @@ InReaction HotkeyInputPrepHandler(const SDL_Event_* ev)
return IN_PASS; return IN_PASS;
} }
InReaction HotkeyInputActualHandler(const SDL_Event_* ev) InReaction HotkeyInputActualHandler(const SDL_Event& ev)
{ {
if (!currentEvent) if (!currentEvent)
return IN_PASS; return IN_PASS;
bool isInstantaneous = ev->ev.type == SDL_MOUSEWHEEL; bool isInstantaneous = ev.type == SDL_MOUSEWHEEL;
// TODO: it's probably possible to break hotkeys somewhat if the "Up" event that would release a hotkey is handled // TODO: it's probably possible to break hotkeys somewhat if the "Up" event that would release a hotkey is handled
// by a priori handler - it might be safer to do that in the 'Prep' phase. // by a priori handler - it might be safer to do that in the 'Prep' phase.
@ -424,12 +424,12 @@ InReaction HotkeyInputActualHandler(const SDL_Event_* ev)
for (const PressedHotkey& hotkey : isInstantaneous ? newPressedHotkeys : pressedHotkeys) for (const PressedHotkey& hotkey : isInstantaneous ? newPressedHotkeys : pressedHotkeys)
{ {
// Send a KeyPress event when a hotkey is pressed initially and on mouseButton and mouseWheel events. // Send a KeyPress event when a hotkey is pressed initially and on mouseButton and mouseWheel events.
if (ev->ev.type != SDL_KEYDOWN || ev->ev.key.repeat == 0) if (ev.type != SDL_KEYDOWN || ev.key.repeat == 0)
{ {
SDL_Event_ hotkeyPressNotification; SDL_Event hotkeyPressNotification{};
hotkeyPressNotification.ev.type = hotkey.retriggered ? SDL_HOTKEYPRESS_SILENT : SDL_HOTKEYPRESS; hotkeyPressNotification.type = hotkey.retriggered ? SDL_HOTKEYPRESS_SILENT : SDL_HOTKEYPRESS;
hotkeyPressNotification.ev.user.data1 = const_cast<char*>(hotkey.mapping->name.c_str()); hotkeyPressNotification.user.data1 = const_cast<char*>(hotkey.mapping->name.c_str());
in_push_priority_event(&hotkeyPressNotification); in_push_priority_event(hotkeyPressNotification);
} }
// Send a HotkeyDown event on every key, mouseButton and mouseWheel event. // Send a HotkeyDown event on every key, mouseButton and mouseWheel event.
@ -439,12 +439,12 @@ InReaction HotkeyInputActualHandler(const SDL_Event_* ev)
// (It might be better to check for HotkeyIsPressed, however). // (It might be better to check for HotkeyIsPressed, however).
// For keys the event is repeated depending on hardware and OS configured interval. // For keys the event is repeated depending on hardware and OS configured interval.
// On linux, modifier keys (shift, alt, ctrl) are not repeated, see https://github.com/SFML/SFML/issues/122. // On linux, modifier keys (shift, alt, ctrl) are not repeated, see https://github.com/SFML/SFML/issues/122.
if (ev->ev.key.repeat == 0 && hotkey.retriggered) if (ev.key.repeat == 0 && hotkey.retriggered)
continue; continue;
SDL_Event_ hotkeyDownNotification; SDL_Event hotkeyDownNotification{};
hotkeyDownNotification.ev.type = SDL_HOTKEYDOWN; hotkeyDownNotification.type = SDL_HOTKEYDOWN;
hotkeyDownNotification.ev.user.data1 = const_cast<char*>(hotkey.mapping->name.c_str()); hotkeyDownNotification.user.data1 = const_cast<char*>(hotkey.mapping->name.c_str());
in_push_priority_event(&hotkeyDownNotification); in_push_priority_event(hotkeyDownNotification);
} }
// Release instantaneous events (e.g. mouse wheel) right away. // Release instantaneous events (e.g. mouse wheel) right away.
@ -454,19 +454,19 @@ InReaction HotkeyInputActualHandler(const SDL_Event_* ev)
for (const ReleasedHotkey& hotkey : releasedHotkeys) for (const ReleasedHotkey& hotkey : releasedHotkeys)
{ {
SDL_Event_ hotkeyNotification; SDL_Event hotkeyNotification{};
hotkeyNotification.ev.type = hotkey.wasRetriggered ? SDL_HOTKEYUP_SILENT : SDL_HOTKEYUP; hotkeyNotification.type = hotkey.wasRetriggered ? SDL_HOTKEYUP_SILENT : SDL_HOTKEYUP;
hotkeyNotification.ev.user.data1 = const_cast<char*>(hotkey.name); hotkeyNotification.user.data1 = const_cast<char*>(hotkey.name);
in_push_priority_event(&hotkeyNotification); in_push_priority_event(hotkeyNotification);
} }
return IN_PASS; return IN_PASS;
} }
bool EventWillFireHotkey(const SDL_Event_* ev, const CStr& keyname) bool EventWillFireHotkey(const SDL_Event& ev, const CStr& keyname)
{ {
// Sanity check of sort. This parameter mostly exists because it looks right from the caller's perspective. // Sanity check of sort. This parameter mostly exists because it looks right from the caller's perspective.
if (ev != currentEvent || !currentEvent) if (&ev != currentEvent || !currentEvent)
return false; return false;
return std::find_if(newPressedHotkeys.begin(), newPressedHotkeys.end(), return std::find_if(newPressedHotkeys.begin(), newPressedHotkeys.end(),
@ -478,10 +478,10 @@ void ResetActiveHotkeys()
newPressedHotkeys.clear(); newPressedHotkeys.clear();
for (const PressedHotkey& hotkey : pressedHotkeys) for (const PressedHotkey& hotkey : pressedHotkeys)
{ {
SDL_Event_ hotkeyNotification; SDL_Event hotkeyNotification;
hotkeyNotification.ev.type = hotkey.retriggered ? SDL_HOTKEYUP_SILENT : SDL_HOTKEYUP; hotkeyNotification.type = hotkey.retriggered ? SDL_HOTKEYUP_SILENT : SDL_HOTKEYUP;
hotkeyNotification.ev.user.data1 = const_cast<char*>(hotkey.mapping->name.c_str()); hotkeyNotification.user.data1 = const_cast<char*>(hotkey.mapping->name.c_str());
in_push_priority_event(&hotkeyNotification); in_push_priority_event(hotkeyNotification);
} }
pressedHotkeys.clear(); pressedHotkeys.clear();
activeScancodes.clear(); activeScancodes.clear();

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -39,7 +39,7 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
struct SDL_Event_; union SDL_Event;
// SDL_Scancode is an enum, we'll use an explicit int to avoid including SDL in this header. // SDL_Scancode is an enum, we'll use an explicit int to avoid including SDL in this header.
using SDL_Scancode_ = int; using SDL_Scancode_ = int;
@ -85,22 +85,22 @@ extern void UnloadHotkeys();
/** /**
* Updates g_HotkeyMap. * Updates g_HotkeyMap.
*/ */
extern InReaction HotkeyStateChange(const SDL_Event_* ev); extern InReaction HotkeyStateChange(const SDL_Event& ev);
/** /**
* Detects hotkeys that should fire. This allows using EventWillFireHotkey, * Detects hotkeys that should fire. This allows using EventWillFireHotkey,
* (and then possibly preventing those hotkeys from firing by handling the event). * (and then possibly preventing those hotkeys from firing by handling the event).
*/ */
extern InReaction HotkeyInputPrepHandler(const SDL_Event_* ev); extern InReaction HotkeyInputPrepHandler(const SDL_Event& ev);
/** /**
* Actually fires hotkeys. * Actually fires hotkeys.
*/ */
extern InReaction HotkeyInputActualHandler(const SDL_Event_* ev); extern InReaction HotkeyInputActualHandler(const SDL_Event& ev);
/** /**
* @return whether the event @param ev will fire the hotkey @param keyname. * @return whether the event @param ev will fire the hotkey @param keyname.
*/ */
extern bool EventWillFireHotkey(const SDL_Event_* ev, const CStr& keyname); extern bool EventWillFireHotkey(const SDL_Event& ev, const CStr& keyname);
/** /**
* Resets all currently active hotkeys (and clears in-flight hotkeys). * Resets all currently active hotkeys (and clears in-flight hotkeys).

View file

@ -271,16 +271,16 @@ void CProfileViewer::RenderProfile(CCanvas2D& canvas)
// Handle input // Handle input
InReaction CProfileViewer::Input(const SDL_Event_* ev) InReaction CProfileViewer::Input(const SDL_Event& ev)
{ {
switch(ev->ev.type) switch(ev.type)
{ {
case SDL_KEYDOWN: case SDL_KEYDOWN:
{ {
if (!m->profileVisible) if (!m->profileVisible)
break; break;
int k = ev->ev.key.keysym.sym; int k = ev.key.keysym.sym;
if (k >= SDLK_0 && k <= SDLK_9) if (k >= SDLK_0 && k <= SDLK_9)
{ {
m->NavigateTree(k - SDLK_0); m->NavigateTree(k - SDLK_0);
@ -289,7 +289,7 @@ InReaction CProfileViewer::Input(const SDL_Event_* ev)
break; break;
} }
case SDL_HOTKEYPRESS: case SDL_HOTKEYPRESS:
std::string hotkey = static_cast<const char*>(ev->ev.user.data1); std::string hotkey = static_cast<const char*>(ev.user.data1);
if( hotkey == "profile.toggle" ) if( hotkey == "profile.toggle" )
{ {
@ -334,7 +334,7 @@ InReaction CProfileViewer::Input(const SDL_Event_* ev)
return( IN_PASS ); return( IN_PASS );
} }
InReaction CProfileViewer::InputThunk(const SDL_Event_* ev) InReaction CProfileViewer::InputThunk(const SDL_Event& ev)
{ {
if (CProfileViewer::IsInitialised()) if (CProfileViewer::IsInitialised())
return g_ProfileViewer.Input(ev); return g_ProfileViewer.Input(ev);

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -30,7 +30,7 @@
#include <vector> #include <vector>
class CCanvas2D; class CCanvas2D;
struct SDL_Event_; union SDL_Event;
/** /**
* Struct ProfileColumn: Describes one column of an AbstractProfileTable. * Struct ProfileColumn: Describes one column of an AbstractProfileTable.
@ -156,7 +156,7 @@ public:
* @return IN_PASS or IN_HANDLED depending on whether the event relates * @return IN_PASS or IN_HANDLED depending on whether the event relates
* to the profiling display. * to the profiling display.
*/ */
InReaction Input(const SDL_Event_* ev); InReaction Input(const SDL_Event& ev);
/** /**
* AddRootTable: Add a new profile table as a root table (i.e. the * AddRootTable: Add a new profile table as a root table (i.e. the
@ -178,7 +178,7 @@ public:
* This allows our input handler to be installed via in_add_handler * This allows our input handler to be installed via in_add_handler
* like a normal, global function input handler. * like a normal, global function input handler.
*/ */
static InReaction InputThunk(const SDL_Event_* ev); static InReaction InputThunk(const SDL_Event& ev);
/** /**
* SaveToFile: Save the current profiler data (for all profile tables) * SaveToFile: Save the current profiler data (for all profile tables)

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -95,18 +95,18 @@ void CTouchInput::OnFingerUp(int id, int x, int y)
{ {
m_State = STATE_INACTIVE; m_State = STATE_INACTIVE;
SDL_Event_ ev; SDL_Event ev;
ev.ev.button.button = SDL_BUTTON_LEFT; ev.button.button = SDL_BUTTON_LEFT;
ev.ev.button.x = m_Pos[0].X; ev.button.x = m_Pos[0].X;
ev.ev.button.y = m_Pos[0].Y; ev.button.y = m_Pos[0].Y;
ev.ev.type = SDL_MOUSEBUTTONDOWN; ev.type = SDL_MOUSEBUTTONDOWN;
ev.ev.button.state = SDL_PRESSED; ev.button.state = SDL_PRESSED;
SDL_PushEvent(&ev.ev); SDL_PushEvent(&ev);
ev.ev.type = SDL_MOUSEBUTTONUP; ev.type = SDL_MOUSEBUTTONUP;
ev.ev.button.state = SDL_RELEASED; ev.button.state = SDL_RELEASED;
SDL_PushEvent(&ev.ev); SDL_PushEvent(&ev);
} }
else if (m_State == STATE_ZOOMING && id == 1) else if (m_State == STATE_ZOOMING && id == 1)
{ {
@ -172,44 +172,44 @@ void CTouchInput::Frame()
{ {
m_State = STATE_INACTIVE; m_State = STATE_INACTIVE;
SDL_Event_ ev; SDL_Event ev;
ev.ev.button.button = SDL_BUTTON_RIGHT; ev.button.button = SDL_BUTTON_RIGHT;
ev.ev.button.x = m_Pos[0].X; ev.button.x = m_Pos[0].X;
ev.ev.button.y = m_Pos[0].Y; ev.button.y = m_Pos[0].Y;
ev.ev.type = SDL_MOUSEBUTTONDOWN; ev.type = SDL_MOUSEBUTTONDOWN;
ev.ev.button.state = SDL_PRESSED; ev.button.state = SDL_PRESSED;
SDL_PushEvent(&ev.ev); SDL_PushEvent(&ev);
ev.ev.type = SDL_MOUSEBUTTONUP; ev.type = SDL_MOUSEBUTTONUP;
ev.ev.button.state = SDL_RELEASED; ev.button.state = SDL_RELEASED;
SDL_PushEvent(&ev.ev); SDL_PushEvent(&ev);
} }
} }
InReaction CTouchInput::HandleEvent([[maybe_unused]] const SDL_Event_* ev) InReaction CTouchInput::HandleEvent([[maybe_unused]] const SDL_Event& ev)
{ {
if (!IsEnabled()) if (!IsEnabled())
return IN_PASS; return IN_PASS;
#if EMULATE_FINGERS_WITH_MOUSE #if EMULATE_FINGERS_WITH_MOUSE
switch(ev->ev.type) switch(ev.type)
{ {
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
{ {
int button; int button;
if (ev->ev.button.button == SDL_BUTTON_LEFT) if (ev.button.button == SDL_BUTTON_LEFT)
button = 0; button = 0;
else if (ev->ev.button.button == SDL_BUTTON_RIGHT) else if (ev.button.button == SDL_BUTTON_RIGHT)
button = 1; button = 1;
else else
return IN_PASS; return IN_PASS;
m_MouseEmulateDownPos[button] = CVector2D(ev->ev.button.x, ev->ev.button.y); m_MouseEmulateDownPos[button] = CVector2D(ev.button.x, ev.button.y);
if (m_MouseEmulateState[button] == MOUSE_INACTIVE) if (m_MouseEmulateState[button] == MOUSE_INACTIVE)
{ {
m_MouseEmulateState[button] = MOUSE_ACTIVATING; m_MouseEmulateState[button] = MOUSE_ACTIVATING;
OnFingerDown(button, ev->ev.button.x, ev->ev.button.y); OnFingerDown(button, ev.button.x, ev.button.y);
} }
else if (m_MouseEmulateState[button] == MOUSE_ACTIVE_UP) else if (m_MouseEmulateState[button] == MOUSE_ACTIVE_UP)
{ {
@ -221,9 +221,9 @@ InReaction CTouchInput::HandleEvent([[maybe_unused]] const SDL_Event_* ev)
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
{ {
int button; int button;
if (ev->ev.button.button == SDL_BUTTON_LEFT) if (ev.button.button == SDL_BUTTON_LEFT)
button = 0; button = 0;
else if (ev->ev.button.button == SDL_BUTTON_RIGHT) else if (ev.button.button == SDL_BUTTON_RIGHT)
button = 1; button = 1;
else else
return IN_PASS; return IN_PASS;
@ -234,11 +234,11 @@ InReaction CTouchInput::HandleEvent([[maybe_unused]] const SDL_Event_* ev)
} }
else if (m_MouseEmulateState[button] == MOUSE_ACTIVE_DOWN) else if (m_MouseEmulateState[button] == MOUSE_ACTIVE_DOWN)
{ {
float dist = (m_MouseEmulateDownPos[button] - CVector2D(ev->ev.button.x, ev->ev.button.y)).Length(); float dist = (m_MouseEmulateDownPos[button] - CVector2D(ev.button.x, ev.button.y)).Length();
if (dist <= 2) if (dist <= 2)
{ {
m_MouseEmulateState[button] = MOUSE_INACTIVE; m_MouseEmulateState[button] = MOUSE_INACTIVE;
OnFingerUp(button, ev->ev.button.x, ev->ev.button.y); OnFingerUp(button, ev.button.x, ev.button.y);
} }
else else
{ {
@ -254,7 +254,7 @@ InReaction CTouchInput::HandleEvent([[maybe_unused]] const SDL_Event_* ev)
{ {
if (m_MouseEmulateState[i] == MOUSE_ACTIVE_DOWN) if (m_MouseEmulateState[i] == MOUSE_ACTIVE_DOWN)
{ {
OnFingerMotion(i, ev->ev.motion.x, ev->ev.motion.y); OnFingerMotion(i, ev.motion.x, ev.motion.y);
} }
} }
return IN_HANDLED; return IN_HANDLED;
@ -262,7 +262,7 @@ InReaction CTouchInput::HandleEvent([[maybe_unused]] const SDL_Event_* ev)
} }
#endif #endif
switch(ev->ev.type) switch(ev.type)
{ {
case SDL_FINGERDOWN: case SDL_FINGERDOWN:
case SDL_FINGERUP: case SDL_FINGERUP:
@ -270,18 +270,18 @@ InReaction CTouchInput::HandleEvent([[maybe_unused]] const SDL_Event_* ev)
{ {
// Map finger events onto the mouse, for basic testing // Map finger events onto the mouse, for basic testing
debug_printf("finger %s tid=%" PRId64 " fid=%" PRId64 " x=%f y=%f dx=%f dy=%f p=%f\n", debug_printf("finger %s tid=%" PRId64 " fid=%" PRId64 " x=%f y=%f dx=%f dy=%f p=%f\n",
ev->ev.type == SDL_FINGERDOWN ? "down" : ev.type == SDL_FINGERDOWN ? "down" :
ev->ev.type == SDL_FINGERUP ? "up" : ev.type == SDL_FINGERUP ? "up" :
ev->ev.type == SDL_FINGERMOTION ? "motion" : "?", ev.type == SDL_FINGERMOTION ? "motion" : "?",
ev->ev.tfinger.touchId, ev->ev.tfinger.fingerId, ev.tfinger.touchId, ev.tfinger.fingerId,
ev->ev.tfinger.x, ev->ev.tfinger.y, ev->ev.tfinger.dx, ev->ev.tfinger.dy, ev->ev.tfinger.pressure); ev.tfinger.x, ev.tfinger.y, ev.tfinger.dx, ev.tfinger.dy, ev.tfinger.pressure);
if (ev->ev.type == SDL_FINGERDOWN) if (ev.type == SDL_FINGERDOWN)
OnFingerDown(ev->ev.tfinger.fingerId, g_xres * ev->ev.tfinger.x, g_yres * ev->ev.tfinger.y); OnFingerDown(ev.tfinger.fingerId, g_xres * ev.tfinger.x, g_yres * ev.tfinger.y);
else if (ev->ev.type == SDL_FINGERUP) else if (ev.type == SDL_FINGERUP)
OnFingerUp(ev->ev.tfinger.fingerId, g_xres * ev->ev.tfinger.x, g_yres * ev->ev.tfinger.y); OnFingerUp(ev.tfinger.fingerId, g_xres * ev.tfinger.x, g_yres * ev.tfinger.y);
else if (ev->ev.type == SDL_FINGERMOTION) else if (ev.type == SDL_FINGERMOTION)
OnFingerMotion(ev->ev.tfinger.fingerId, g_xres * ev->ev.tfinger.x, g_yres * ev->ev.tfinger.y); OnFingerMotion(ev.tfinger.fingerId, g_xres * ev.tfinger.x, g_yres * ev.tfinger.y);
return IN_HANDLED; return IN_HANDLED;
} }
} }
@ -291,7 +291,7 @@ InReaction CTouchInput::HandleEvent([[maybe_unused]] const SDL_Event_* ev)
CTouchInput g_TouchInput; CTouchInput g_TouchInput;
InReaction touch_input_handler(const SDL_Event_* ev) InReaction touch_input_handler(const SDL_Event& ev)
{ {
return g_TouchInput.HandleEvent(ev); return g_TouchInput.HandleEvent(ev);
} }

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -24,7 +24,7 @@
#include <cstddef> #include <cstddef>
struct SDL_Event_; union SDL_Event;
/** /**
* Maps touch events (e.g. on Android touchscreen devices) onto mouse events * Maps touch events (e.g. on Android touchscreen devices) onto mouse events
@ -41,7 +41,7 @@ public:
*/ */
bool IsEnabled(); bool IsEnabled();
InReaction HandleEvent(const SDL_Event_* ev); InReaction HandleEvent(const SDL_Event& ev);
/** /**
* Should be called once per frame to perform updates. * Should be called once per frame to perform updates.
@ -90,6 +90,6 @@ private:
extern CTouchInput g_TouchInput; extern CTouchInput g_TouchInput;
extern InReaction touch_input_handler(const SDL_Event_* ev); extern InReaction touch_input_handler(const SDL_Event& ev);
#endif // INCLUDED_TOUCHINPUT #endif // INCLUDED_TOUCHINPUT

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
@ -52,20 +52,20 @@ private:
void fakeInput(const char* key, bool keyDown) void fakeInput(const char* key, bool keyDown)
{ {
SDL_Event_ ev; SDL_Event ev;
ev.ev.type = keyDown ? SDL_KEYDOWN : SDL_KEYUP; ev.type = keyDown ? SDL_KEYDOWN : SDL_KEYUP;
ev.ev.key.repeat = 0; ev.key.repeat = 0;
ev.ev.key.keysym.scancode = SDL_GetScancodeFromName(key); ev.key.keysym.scancode = SDL_GetScancodeFromName(key);
GlobalsInputHandler(&ev); GlobalsInputHandler(ev);
HotkeyInputPrepHandler(&ev); HotkeyInputPrepHandler(ev);
HotkeyInputActualHandler(&ev); HotkeyInputActualHandler(ev);
hotkeyPress = false; hotkeyPress = false;
hotkeyUp = false; hotkeyUp = false;
while(in_poll_priority_event(&ev)) while(in_poll_priority_event(ev))
{ {
hotkeyUp |= ev.ev.type == SDL_HOTKEYUP; hotkeyUp |= ev.type == SDL_HOTKEYUP;
hotkeyPress |= ev.ev.type == SDL_HOTKEYPRESS; hotkeyPress |= ev.type == SDL_HOTKEYPRESS;
HotkeyStateChange(&ev); HotkeyStateChange(ev);
} }
} }

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -254,9 +254,9 @@ QUERYHANDLER(RenderLoop)
RendererIncrementalLoad(); RendererIncrementalLoad();
// Pump SDL events (e.g. hotkeys) // Pump SDL events (e.g. hotkeys)
SDL_Event_ ev; SDL_Event ev{};
while (in_poll_priority_event(&ev)) while (in_poll_priority_event(ev))
in_dispatch_event(&ev); in_dispatch_event(ev);
if (g_GUI) if (g_GUI)
g_GUI->TickObjects(); g_GUI->TickObjects();

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2025 Wildfire Games. /* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -110,36 +110,36 @@ MESSAGEHANDLER(GuiSwitchPage)
MESSAGEHANDLER(GuiMouseButtonEvent) MESSAGEHANDLER(GuiMouseButtonEvent)
{ {
SDL_Event_ ev = { { 0 } }; SDL_Event ev{};
ev.ev.type = msg->pressed ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP; ev.type = msg->pressed ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP;
ev.ev.button.button = msg->button; ev.button.button = msg->button;
ev.ev.button.state = msg->pressed ? SDL_PRESSED : SDL_RELEASED; ev.button.state = msg->pressed ? SDL_PRESSED : SDL_RELEASED;
ev.ev.button.clicks = msg->clicks; ev.button.clicks = msg->clicks;
float x, y; float x, y;
msg->pos->GetScreenSpace(x, y); msg->pos->GetScreenSpace(x, y);
ev.ev.button.x = static_cast<u16>(Clamp<int>(x, 0, g_xres)); ev.button.x = static_cast<u16>(Clamp<int>(x, 0, g_xres));
ev.ev.button.y = static_cast<u16>(Clamp<int>(y, 0, g_yres)); ev.button.y = static_cast<u16>(Clamp<int>(y, 0, g_yres));
in_dispatch_event(&ev); in_dispatch_event(ev);
} }
MESSAGEHANDLER(GuiMouseMotionEvent) MESSAGEHANDLER(GuiMouseMotionEvent)
{ {
SDL_Event_ ev = { { 0 } }; SDL_Event ev{};
ev.ev.type = SDL_MOUSEMOTION; ev.type = SDL_MOUSEMOTION;
float x, y; float x, y;
msg->pos->GetScreenSpace(x, y); msg->pos->GetScreenSpace(x, y);
ev.ev.motion.x = static_cast<u16>(Clamp<int>(x, 0, g_xres)); ev.motion.x = static_cast<u16>(Clamp<int>(x, 0, g_xres));
ev.ev.motion.y = static_cast<u16>(Clamp<int>(y, 0, g_yres)); ev.motion.y = static_cast<u16>(Clamp<int>(y, 0, g_yres));
in_dispatch_event(&ev); in_dispatch_event(ev);
} }
MESSAGEHANDLER(GuiKeyEvent) MESSAGEHANDLER(GuiKeyEvent)
{ {
SDL_Event_ ev = { { 0 } }; SDL_Event ev{};
ev.ev.type = msg->pressed ? SDL_KEYDOWN : SDL_KEYUP; ev.type = msg->pressed ? SDL_KEYDOWN : SDL_KEYUP;
ev.ev.key.keysym.sym = (SDL_Keycode)(int)msg->sdlkey; ev.key.keysym.sym = static_cast<SDL_Keycode>(static_cast<int>(msg->sdlkey));
ev.ev.key.keysym.scancode = SDL_GetScancodeFromKey((SDL_Keycode)(int)msg->sdlkey); ev.key.keysym.scancode = SDL_GetScancodeFromKey(static_cast<SDL_Keycode>(static_cast<int>(msg->sdlkey)));
in_dispatch_event(&ev); in_dispatch_event(ev);
} }
MESSAGEHANDLER(GuiCharEvent) MESSAGEHANDLER(GuiCharEvent)
@ -147,18 +147,18 @@ MESSAGEHANDLER(GuiCharEvent)
// Simulate special 'text input' events in the SDL // Simulate special 'text input' events in the SDL
// This isn't quite compatible with WXWidget's handling, // This isn't quite compatible with WXWidget's handling,
// so to avoid trouble we only send 'letter-like' ASCII input. // so to avoid trouble we only send 'letter-like' ASCII input.
SDL_Event_ ev = { { 0 } }; SDL_Event ev{};
ev.ev.type = SDL_TEXTEDITING; ev.type = SDL_TEXTEDITING;
ev.ev.text.type = SDL_TEXTEDITING; ev.text.type = SDL_TEXTEDITING;
ev.ev.text.text[0] = (char)msg->sdlkey; ev.text.text[0] = static_cast<char>(msg->sdlkey);
ev.ev.text.text[1] = (char)0; ev.text.text[1] = '\0';
in_dispatch_event(&ev); in_dispatch_event(ev);
ev.ev.type = SDL_TEXTINPUT; ev.type = SDL_TEXTINPUT;
ev.ev.text.type = SDL_TEXTINPUT; ev.text.type = SDL_TEXTINPUT;
ev.ev.text.text[0] = (char)msg->sdlkey; ev.text.text[0] = static_cast<char>(msg->sdlkey);
ev.ev.text.text[1] = (char)0; ev.text.text[1] = '\0';
in_dispatch_event(&ev); in_dispatch_event(ev);
} }
} // namespace AtlasMessage } // namespace AtlasMessage