Aurore
A Switch-like interface for your app, on every screen
Loading...
Searching...
No Matches
headless_platform.hpp
Go to the documentation of this file.
1/*
2 Copyright 2026 JigSawFr
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17#pragma once
18
19// The test harness' platform: no window, no display. OpenGL draws into an
20// offscreen framebuffer of a context made with EGL without any surface
21// (Mesa's surfaceless platform: no X server needed), or of a hidden GLFW
22// window where EGL is missing (macOS, Windows) or AURORE_HEADLESS_GLFW=1.
23// Inputs come from the harness only; battery, network, clipboard, browser
24// and keyboard are stand-ins, so screens look the same on every machine.
25
26#include <aurore/platforms/desktop/desktop_platform.hpp>
27
28#include <atomic>
29#include <optional>
30#include <set>
31#include <string>
32#include <vector>
33
34namespace aurore
35{
36
38{
39 public:
40 HeadlessVideoContext(int width, int height);
42
43 NVGcontext* getNVGContext() override { return nvgContext; }
44 void clear(NVGcolor color) override;
45 void beginFrame() override;
46 void endFrame() override;
47 void setSwapInterval(int interval) override { }
48 void resetState() override;
49 double getScaleFactor() override { return 1.0; }
50 bool readPixels(std::vector<unsigned char>* rgba, int* width, int* height) override;
51
52 // A new framebuffer size (the window resized)
53 void resize(int width, int height);
54
55 bool isValid() const { return nvgContext != nullptr; }
56
57 private:
58 bool createContext();
59 void createFramebuffer();
60 void destroyFramebuffer();
61
62 int width, height;
63 NVGcontext* nvgContext = nullptr;
64 unsigned framebuffer = 0, colorBuffer = 0, depthStencilBuffer = 0;
65 void* eglDisplay = nullptr;
66 void* eglContext = nullptr;
67 void* glfwWindow = nullptr;
68};
69
71{
72 public:
73 short getControllersConnectedCount() override { return 1; }
75 void updateControllerState(ControllerState* state, int controller) override;
77 void updateTouchStates(std::vector<RawTouchState>* states) override;
78 void updateMouseStates(RawMouseState* state) override;
79 void sendRumble(unsigned short controller, unsigned short lowFreqMotor, unsigned short highFreqMotor) override { }
80
81 void setButton(ControllerButton button, bool pressed);
82 void setAxis(ControllerAxis axis, float value);
83 void setKey(AuroreKeyboardScancode key, bool pressed);
84 void setTouch(int fingerId, bool pressed, Point position);
85 void setMouse(Point position, bool leftButton);
86 void scroll(Point offset);
87
88 private:
89 bool buttons[_BUTTON_MAX] = {};
90 float axes[_AXES_MAX] = {};
91 std::set<AuroreKeyboardScancode> keys;
92 std::vector<RawTouchState> touches;
93 RawMouseState mouse;
94 ButtonLatch leftLatch;
95};
96
97// Answers the keyboard with the text the harness was given, at once
99{
100 public:
101 bool openForText(std::function<void(std::string)> f, std::string headerText = "",
102 std::string subText = "", int maxStringLength = 32, std::string initialText = "",
103 int kbdDisableBitmask = KeyboardKeyDisableBitmask::KEYBOARD_DISABLE_NONE) override;
104 bool openForNumber(std::function<void(long)> f, std::string headerText = "",
105 std::string subText = "", int maxStringLength = 18, std::string initialText = "",
106 std::string leftButton = "", std::string rightButton = "",
107 int kbdDisableBitmask = KeyboardKeyDisableBitmask::KEYBOARD_DISABLE_NONE) override;
108
109 // The next keyboard opened gets `text` (once); none: it is cancelled
110 std::optional<std::string> nextText;
111 // The header of the last keyboard opened
112 std::string lastHeader;
113};
114
115class HeadlessPlatform : public DesktopPlatform
116{
117 public:
118 HeadlessPlatform(int width, int height, std::string locale, ThemeVariant theme);
120
121 std::string getName() override { return "Headless"; }
122 void createWindow(std::string title, uint32_t width, uint32_t height, float windowXPos, float windowYPos) override;
123 void setWindowSize(uint32_t width, uint32_t height) override;
124 bool mainLoopIteration() override { return !closeRequested; }
125
126 AudioPlayer* getAudioPlayer() override { return &audioPlayer; }
127 VideoContext* getVideoContext() override { return videoContext; }
128 InputManager* getInputManager() override { return &inputManager; }
129 ImeManager* getImeManager() override { return &headlessImeManager; }
130
131 bool canShowBatteryLevel() override { return showStatus; }
132 bool canShowWirelessLevel() override { return showStatus; }
133 int getBatteryLevel() override { return batteryLevel; }
134 bool isBatteryCharging() override { return false; }
135 bool hasWirelessConnection() override { return false; }
136 int getWirelessLevel() override { return 0; }
137 bool hasEthernetConnection() override { return true; }
138 std::string getIpAddress() override { return "127.0.0.1"; }
139 std::string getDnsServer() override { return "127.0.0.1"; }
140 void disableScreenDimming(bool disable, const std::string& reason, const std::string& app) override { screenDimmingOff = disable; }
141 bool isScreenDimmingDisabled() override { return screenDimmingOff; }
142 void openBrowser(std::string url) override { openedUrls.push_back(url); }
143 void pasteToClipboard(const std::string& text) override { clipboard = text; }
144 std::string pasteFromClipboard() override { return clipboard; }
145
146 HeadlessInputManager* getHeadlessInput() { return &inputManager; }
147 HeadlessImeManager* getHeadlessIme() { return &headlessImeManager; }
148 HeadlessVideoContext* getHeadlessVideo() { return videoContext; }
149
150 // Ends the main loop on its next iteration
151 void requestClose() { closeRequested = true; }
152
153 // The links openBrowser() was asked to open
154 std::vector<std::string> openedUrls;
155
156 // The battery and Wi-Fi widgets shown (the widgets made after it is set)
157 bool showStatus = false;
158 // What getBatteryLevel() says (read on the task thread)
159 std::atomic<int> batteryLevel { 100 };
160
161 private:
162 int width, height;
163 NullAudioPlayer audioPlayer;
164 HeadlessVideoContext* videoContext = nullptr;
165 HeadlessInputManager inputManager;
166 HeadlessImeManager headlessImeManager;
167 std::string clipboard;
168 bool screenDimmingOff = false;
169 bool closeRequested = false;
170};
171
172} // namespace aurore
Definition video.hpp:30
Definition audio.hpp:45
Definition headless_platform.hpp:99
bool openForNumber(std::function< void(long)> f, std::string headerText="", std::string subText="", int maxStringLength=18, std::string initialText="", std::string leftButton="", std::string rightButton="", int kbdDisableBitmask=KeyboardKeyDisableBitmask::KEYBOARD_DISABLE_NONE) override
bool openForText(std::function< void(std::string)> f, std::string headerText="", std::string subText="", int maxStringLength=32, std::string initialText="", int kbdDisableBitmask=KeyboardKeyDisableBitmask::KEYBOARD_DISABLE_NONE) override
std::optional< std::string > nextText
Definition headless_platform.hpp:110
std::string lastHeader
Definition headless_platform.hpp:112
Definition headless_platform.hpp:71
void updateUnifiedControllerState(ControllerState *state) override
short getControllersConnectedCount() override
Definition headless_platform.hpp:73
void updateControllerState(ControllerState *state, int controller) override
void setKey(AuroreKeyboardScancode key, bool pressed)
void setTouch(int fingerId, bool pressed, Point position)
bool getKeyboardKeyState(AuroreKeyboardScancode key) override
void setAxis(ControllerAxis axis, float value)
void scroll(Point offset)
void updateMouseStates(RawMouseState *state) override
void setButton(ControllerButton button, bool pressed)
void sendRumble(unsigned short controller, unsigned short lowFreqMotor, unsigned short highFreqMotor) override
Definition headless_platform.hpp:79
void updateTouchStates(std::vector< RawTouchState > *states) override
void setMouse(Point position, bool leftButton)
Definition headless_platform.hpp:116
int getWirelessLevel() override
Definition headless_platform.hpp:136
void createWindow(std::string title, uint32_t width, uint32_t height, float windowXPos, float windowYPos) override
void requestClose()
Definition headless_platform.hpp:151
bool showStatus
Definition headless_platform.hpp:157
bool hasWirelessConnection() override
Definition headless_platform.hpp:135
InputManager * getInputManager() override
Definition headless_platform.hpp:128
std::string getDnsServer() override
Definition headless_platform.hpp:139
int getBatteryLevel() override
Definition headless_platform.hpp:133
AudioPlayer * getAudioPlayer() override
Definition headless_platform.hpp:126
std::string pasteFromClipboard() override
Definition headless_platform.hpp:144
std::string getName() override
Definition headless_platform.hpp:121
std::string getIpAddress() override
Definition headless_platform.hpp:138
VideoContext * getVideoContext() override
Definition headless_platform.hpp:127
HeadlessPlatform(int width, int height, std::string locale, ThemeVariant theme)
bool canShowBatteryLevel() override
Definition headless_platform.hpp:131
std::atomic< int > batteryLevel
Definition headless_platform.hpp:159
bool canShowWirelessLevel() override
Definition headless_platform.hpp:132
void setWindowSize(uint32_t width, uint32_t height) override
bool isScreenDimmingDisabled() override
Definition headless_platform.hpp:141
std::vector< std::string > openedUrls
Definition headless_platform.hpp:154
HeadlessInputManager * getHeadlessInput()
Definition headless_platform.hpp:146
void openBrowser(std::string url) override
Definition headless_platform.hpp:142
bool mainLoopIteration() override
Definition headless_platform.hpp:124
bool hasEthernetConnection() override
Definition headless_platform.hpp:137
ImeManager * getImeManager() override
Definition headless_platform.hpp:129
bool isBatteryCharging() override
Definition headless_platform.hpp:134
void pasteToClipboard(const std::string &text) override
Definition headless_platform.hpp:143
HeadlessImeManager * getHeadlessIme()
Definition headless_platform.hpp:147
HeadlessVideoContext * getHeadlessVideo()
Definition headless_platform.hpp:148
void disableScreenDimming(bool disable, const std::string &reason, const std::string &app) override
Definition headless_platform.hpp:140
Definition headless_platform.hpp:38
HeadlessVideoContext(int width, int height)
NVGcontext * getNVGContext() override
Definition headless_platform.hpp:43
void setSwapInterval(int interval) override
Definition headless_platform.hpp:47
bool readPixels(std::vector< unsigned char > *rgba, int *width, int *height) override
void resize(int width, int height)
double getScaleFactor() override
Definition headless_platform.hpp:49
void clear(NVGcolor color) override
bool isValid() const
Definition headless_platform.hpp:55
Definition ime.hpp:41
Definition input.hpp:334
Definition audio.hpp:70
Definition actions.hpp:25
AuroreKeyboardScancode
Definition input.hpp:44
ThemeVariant
The two sets of colours every theme has: light and dark.
Definition theme.hpp:37
@ KEYBOARD_DISABLE_NONE
Definition ime.hpp:29
ControllerButton
Definition input.hpp:179
@ _BUTTON_MAX
Definition input.hpp:209
ControllerAxis
Definition input.hpp:214
@ _AXES_MAX
Definition input.hpp:224
Definition text.hpp:13
Definition input.hpp:251
Definition geometry.hpp:26
Definition input.hpp:286