Skip to content

Commit cc8ec6c

Browse files
authored
Handle global mouse state for Emscripten (#12669)
1 parent 53d0532 commit cc8ec6c

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

src/video/emscripten/SDL_emscriptenmouse.c

+60
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,26 @@ static bool Emscripten_SetRelativeMouseMode(bool enabled)
196196
return false;
197197
}
198198

199+
static SDL_MouseButtonFlags Emscripten_GetGlobalMouseState(float *x, float *y)
200+
{
201+
*x = MAIN_THREAD_EM_ASM_DOUBLE({
202+
return Module['SDL3']['mouse_x'];
203+
});
204+
*y = MAIN_THREAD_EM_ASM_DOUBLE({
205+
return Module['SDL3']['mouse_y'];
206+
});
207+
SDL_MouseButtonFlags flags = 0;
208+
for (int i = 0; i < 5; ++i) {
209+
const bool button_down = MAIN_THREAD_EM_ASM_INT({
210+
return Module['SDL3']['mouse_buttons'][$0];
211+
}, i);
212+
if (button_down) {
213+
flags |= 1 << i;
214+
}
215+
}
216+
return flags;
217+
}
218+
199219
void Emscripten_InitMouse(void)
200220
{
201221
SDL_Mouse *mouse = SDL_GetMouse();
@@ -206,6 +226,46 @@ void Emscripten_InitMouse(void)
206226
mouse->CreateSystemCursor = Emscripten_CreateSystemCursor;
207227
mouse->SetRelativeMouseMode = Emscripten_SetRelativeMouseMode;
208228

229+
// Add event listeners to track mouse events on the document
230+
MAIN_THREAD_EM_ASM({
231+
if (!Module['SDL3']) {
232+
Module['SDL3'] = {};
233+
}
234+
var SDL3 = Module['SDL3'];
235+
SDL3['mouse_x'] = 0;
236+
SDL3['mouse_y'] = 0;
237+
/*
238+
Based on https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
239+
Possible value for button in the event object is [0, 5)
240+
NOTE: Some browsers do not allow handling the forwards and backwards buttons
241+
*/
242+
SDL3['mouse_buttons'] = [];
243+
for (var i = 0; i < 5; ++i) {
244+
SDL3['mouse_buttons'][i] = false;
245+
}
246+
document.addEventListener('mousemove', function(e) {
247+
// Reacquire from object in case it changed for some reason
248+
var SDL3 = Module['SDL3'];
249+
SDL3['mouse_x'] = e.clientX;
250+
SDL3['mouse_y'] = e.clientY;
251+
});
252+
document.addEventListener('mousedown', function(e) {
253+
// Reacquire from object in case it changed for some reason
254+
var SDL3 = Module['SDL3'];
255+
if (0 <= e.button && e.button < SDL3['mouse_buttons'].length) {
256+
SDL3['mouse_buttons'][e.button] = true;
257+
}
258+
});
259+
document.addEventListener('mouseup', function(e) {
260+
// Reacquire from object in case it changed for some reason
261+
var SDL3 = Module['SDL3'];
262+
if (0 <= e.button && e.button < SDL3['mouse_buttons'].length) {
263+
SDL3['mouse_buttons'][e.button] = false;
264+
}
265+
});
266+
});
267+
mouse->GetGlobalMouseState = Emscripten_GetGlobalMouseState;
268+
209269
SDL_SetDefaultCursor(Emscripten_CreateDefaultCursor());
210270
}
211271

test/testmouse.c

+6
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ static void loop(void *arg)
117117
struct mouse_loop_data *loop_data = (struct mouse_loop_data *)arg;
118118
SDL_Event event;
119119
SDL_Renderer *renderer = loop_data->renderer;
120+
float fx, fy;
121+
SDL_MouseButtonFlags flags;
120122

121123
/* Check for events */
122124
while (SDL_PollEvent(&event)) {
@@ -265,6 +267,10 @@ static void loop(void *arg)
265267
DrawObject(renderer, active);
266268
}
267269

270+
flags = SDL_GetGlobalMouseState(&fx, &fy);
271+
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
272+
SDL_RenderDebugTextFormat(renderer, 0, 0, "Global Mouse State: x=%f y=%f flags=%" SDL_PRIu32, fx, fy, flags);
273+
268274
SDL_RenderPresent(renderer);
269275

270276
#ifdef SDL_PLATFORM_EMSCRIPTEN

0 commit comments

Comments
 (0)