#include "qjs_sdl_input.h" #include "jsffi.h" #include "qjs_macros.h" #include "cell.h" #include "qjs_blob.h" #include "stb_ds.h" #include "qjs_actor.h" #include "qjs_wota.h" #include // Internal keymod function for input module static JSValue js_keymod(JSContext *js) { SDL_Keymod modstate = SDL_GetModState(); JSValue ret = JS_NewObject(js); if (SDL_KMOD_CTRL & modstate) JS_SetPropertyStr(js,ret,"ctrl", JS_NewBool(js,1)); if (SDL_KMOD_SHIFT & modstate) JS_SetPropertyStr(js,ret,"shift", JS_NewBool(js,1)); if (SDL_KMOD_ALT & modstate) JS_SetPropertyStr(js,ret,"alt", JS_NewBool(js,1)); if (SDL_KMOD_GUI & modstate) JS_SetPropertyStr(js,ret,"super", JS_NewBool(js,1)); if (SDL_KMOD_NUM & modstate) JS_SetPropertyStr(js,ret,"numlock", JS_NewBool(js,1)); if (SDL_KMOD_CAPS & modstate) JS_SetPropertyStr(js,ret,"caps", JS_NewBool(js,1)); if (SDL_KMOD_SCROLL & modstate) JS_SetPropertyStr(js,ret,"scrolllock", JS_NewBool(js,1)); if (SDL_KMOD_MODE & modstate) JS_SetPropertyStr(js,ret,"mode", JS_NewBool(js,1)); return ret; } // INPUT FUNCTIONS JSC_CCALL(input_mouse_lock, SDL_CaptureMouse(JS_ToBool(js,argv[0]))) JSC_CCALL(input_mouse_show, if (JS_ToBool(js,argv[0])) SDL_ShowCursor(); else SDL_HideCursor(); ) JSC_CCALL(input_keyname, return JS_NewString(js, SDL_GetKeyName(js2number(js,argv[0]))); ) JSC_CCALL(input_keymod, return js_keymod(js); ) JSC_CCALL(input_mousestate, float x,y; SDL_MouseButtonFlags flags = SDL_GetMouseState(&x,&y); JSValue m = JS_NewObject(js); JS_SetPropertyStr(js,m,"x", number2js(js,x)); JS_SetPropertyStr(js,m,"y", number2js(js,y)); if (flags & SDL_BUTTON_LMASK) JS_SetPropertyStr(js, m, "left", JS_NewBool(js, 1)); if (flags & SDL_BUTTON_MMASK) JS_SetPropertyStr(js, m, "middle", JS_NewBool(js, 1)); if (flags & SDL_BUTTON_RMASK) JS_SetPropertyStr(js, m, "right", JS_NewBool(js, 1)); if (flags & SDL_BUTTON_X1MASK) JS_SetPropertyStr(js, m, "x1", JS_NewBool(js, 1)); if (flags & SDL_BUTTON_X2MASK) JS_SetPropertyStr(js, m, "x2", JS_NewBool(js, 1)); return m; ) // Event processing functions (moved from cell.c) const char* event_type_to_string(Uint32 event_type) { switch (event_type) { // Application events case SDL_EVENT_QUIT: return "quit"; case SDL_EVENT_TERMINATING: return "terminating"; case SDL_EVENT_LOW_MEMORY: return "low_memory"; case SDL_EVENT_WILL_ENTER_BACKGROUND: return "will_enter_background"; case SDL_EVENT_DID_ENTER_BACKGROUND: return "did_enter_background"; case SDL_EVENT_WILL_ENTER_FOREGROUND: return "will_enter_foreground"; case SDL_EVENT_DID_ENTER_FOREGROUND: return "did_enter_foreground"; case SDL_EVENT_LOCALE_CHANGED: return "locale_changed"; case SDL_EVENT_SYSTEM_THEME_CHANGED: return "system_theme_changed"; // Display events case SDL_EVENT_DISPLAY_ORIENTATION: return "display_orientation"; case SDL_EVENT_DISPLAY_ADDED: return "display_added"; case SDL_EVENT_DISPLAY_REMOVED: return "display_removed"; case SDL_EVENT_DISPLAY_MOVED: return "display_moved"; case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED: return "display_desktop_mode_changed"; case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED: return "display_current_mode_changed"; case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED: return "display_content_scale_changed"; // Window events case SDL_EVENT_WINDOW_SHOWN: return "window_shown"; case SDL_EVENT_WINDOW_HIDDEN: return "window_hidden"; case SDL_EVENT_WINDOW_EXPOSED: return "window_exposed"; case SDL_EVENT_WINDOW_MOVED: return "window_moved"; case SDL_EVENT_WINDOW_RESIZED: return "window_resized"; case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: return "window_pixel_size_changed"; case SDL_EVENT_WINDOW_METAL_VIEW_RESIZED: return "window_metal_view_resized"; case SDL_EVENT_WINDOW_MINIMIZED: return "window_minimized"; case SDL_EVENT_WINDOW_MAXIMIZED: return "window_maximized"; case SDL_EVENT_WINDOW_RESTORED: return "window_restored"; case SDL_EVENT_WINDOW_MOUSE_ENTER: return "window_mouse_enter"; case SDL_EVENT_WINDOW_MOUSE_LEAVE: return "window_mouse_leave"; case SDL_EVENT_WINDOW_FOCUS_GAINED: return "window_focus_gained"; case SDL_EVENT_WINDOW_FOCUS_LOST: return "window_focus_lost"; case SDL_EVENT_WINDOW_CLOSE_REQUESTED: return "window_close_requested"; case SDL_EVENT_WINDOW_HIT_TEST: return "window_hit_test"; case SDL_EVENT_WINDOW_ICCPROF_CHANGED: return "window_iccprof_changed"; case SDL_EVENT_WINDOW_DISPLAY_CHANGED: return "window_display_changed"; case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: return "window_display_scale_changed"; case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED: return "window_safe_area_changed"; case SDL_EVENT_WINDOW_OCCLUDED: return "window_occluded"; case SDL_EVENT_WINDOW_ENTER_FULLSCREEN: return "window_enter_fullscreen"; case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN: return "window_leave_fullscreen"; case SDL_EVENT_WINDOW_DESTROYED: return "window_destroyed"; case SDL_EVENT_WINDOW_HDR_STATE_CHANGED: return "window_hdr_state_changed"; // Keyboard events case SDL_EVENT_KEY_DOWN: return "key_down"; case SDL_EVENT_KEY_UP: return "key_up"; case SDL_EVENT_TEXT_EDITING: return "text_editing"; case SDL_EVENT_TEXT_INPUT: return "text_input"; case SDL_EVENT_KEYMAP_CHANGED: return "keymap_changed"; case SDL_EVENT_KEYBOARD_ADDED: return "keyboard_added"; case SDL_EVENT_KEYBOARD_REMOVED: return "keyboard_removed"; case SDL_EVENT_TEXT_EDITING_CANDIDATES: return "text_editing_candidates"; // Mouse events case SDL_EVENT_MOUSE_MOTION: return "mouse_motion"; case SDL_EVENT_MOUSE_BUTTON_DOWN: return "mouse_button_down"; case SDL_EVENT_MOUSE_BUTTON_UP: return "mouse_button_up"; case SDL_EVENT_MOUSE_WHEEL: return "mouse_wheel"; case SDL_EVENT_MOUSE_ADDED: return "mouse_added"; case SDL_EVENT_MOUSE_REMOVED: return "mouse_removed"; // Joystick events case SDL_EVENT_JOYSTICK_AXIS_MOTION: return "joystick_axis_motion"; case SDL_EVENT_JOYSTICK_BALL_MOTION: return "joystick_ball_motion"; case SDL_EVENT_JOYSTICK_HAT_MOTION: return "joystick_hat_motion"; case SDL_EVENT_JOYSTICK_BUTTON_DOWN: return "joystick_button_down"; case SDL_EVENT_JOYSTICK_BUTTON_UP: return "joystick_button_up"; case SDL_EVENT_JOYSTICK_ADDED: return "joystick_added"; case SDL_EVENT_JOYSTICK_REMOVED: return "joystick_removed"; case SDL_EVENT_JOYSTICK_BATTERY_UPDATED: return "joystick_battery_updated"; case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE: return "joystick_update_complete"; // Gamepad events case SDL_EVENT_GAMEPAD_AXIS_MOTION: return "gamepad_axis_motion"; case SDL_EVENT_GAMEPAD_BUTTON_DOWN: return "gamepad_button_down"; case SDL_EVENT_GAMEPAD_BUTTON_UP: return "gamepad_button_up"; case SDL_EVENT_GAMEPAD_ADDED: return "gamepad_added"; case SDL_EVENT_GAMEPAD_REMOVED: return "gamepad_removed"; case SDL_EVENT_GAMEPAD_REMAPPED: return "gamepad_remapped"; case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN: return "gamepad_touchpad_down"; case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION: return "gamepad_touchpad_motion"; case SDL_EVENT_GAMEPAD_TOUCHPAD_UP: return "gamepad_touchpad_up"; case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: return "gamepad_sensor_update"; case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE: return "gamepad_update_complete"; case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED: return "gamepad_steam_handle_updated"; // Touch events case SDL_EVENT_FINGER_DOWN: return "finger_down"; case SDL_EVENT_FINGER_UP: return "finger_up"; case SDL_EVENT_FINGER_MOTION: return "finger_motion"; // Clipboard events case SDL_EVENT_CLIPBOARD_UPDATE: return "clipboard_update"; // Drag and drop events case SDL_EVENT_DROP_FILE: return "drop_file"; case SDL_EVENT_DROP_TEXT: return "drop_text"; case SDL_EVENT_DROP_BEGIN: return "drop_begin"; case SDL_EVENT_DROP_COMPLETE: return "drop_complete"; case SDL_EVENT_DROP_POSITION: return "drop_position"; // Audio device events case SDL_EVENT_AUDIO_DEVICE_ADDED: return "audio_device_added"; case SDL_EVENT_AUDIO_DEVICE_REMOVED: return "audio_device_removed"; case SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED: return "audio_device_format_changed"; // Sensor events case SDL_EVENT_SENSOR_UPDATE: return "sensor_update"; // Pen events case SDL_EVENT_PEN_PROXIMITY_IN: return "pen_proximity_in"; case SDL_EVENT_PEN_PROXIMITY_OUT: return "pen_proximity_out"; case SDL_EVENT_PEN_DOWN: return "pen_down"; case SDL_EVENT_PEN_UP: return "pen_up"; case SDL_EVENT_PEN_BUTTON_DOWN: return "pen_button_down"; case SDL_EVENT_PEN_BUTTON_UP: return "pen_button_up"; case SDL_EVENT_PEN_MOTION: return "pen_motion"; case SDL_EVENT_PEN_AXIS: return "pen_axis"; // Camera events case SDL_EVENT_CAMERA_DEVICE_ADDED: return "camera_device_added"; case SDL_EVENT_CAMERA_DEVICE_REMOVED: return "camera_device_removed"; case SDL_EVENT_CAMERA_DEVICE_APPROVED: return "camera_device_approved"; case SDL_EVENT_CAMERA_DEVICE_DENIED: return "camera_device_denied"; // Render events case SDL_EVENT_RENDER_TARGETS_RESET: return "render_targets_reset"; case SDL_EVENT_RENDER_DEVICE_RESET: return "render_device_reset"; case SDL_EVENT_RENDER_DEVICE_LOST: return "render_device_lost"; // User event (assuming it should be included) case SDL_EVENT_USER: return "user"; default: return "unknown"; } } const char* mouse_button_to_string(int mouse) { switch (mouse) { case SDL_BUTTON_LEFT: return "left"; case SDL_BUTTON_MIDDLE: return "middle"; case SDL_BUTTON_RIGHT: return "right"; case SDL_BUTTON_X1: return "x1"; case SDL_BUTTON_X2: return "x2"; default: return "left"; } } static void wota_write_vec2(WotaBuffer *wb, double x, double y) { // We'll store as WOTA_ARR of length 2, then two numbers wota_write_array(wb, 2); wota_write_number(wb, x); wota_write_number(wb, y); } static int event2wota_count_props(const SDL_Event *event) { // We always store at least "type" and "timestamp". int count = 2; switch (event->type) { case SDL_EVENT_AUDIO_DEVICE_ADDED: case SDL_EVENT_AUDIO_DEVICE_REMOVED: count += 2; // which, recording break; case SDL_EVENT_DISPLAY_ORIENTATION: case SDL_EVENT_DISPLAY_ADDED: case SDL_EVENT_DISPLAY_REMOVED: case SDL_EVENT_DISPLAY_MOVED: case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED: case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED: case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED: count += 3; // which, orientation/data1, data2 break; case SDL_EVENT_MOUSE_MOTION: count += 5; break; case SDL_EVENT_MOUSE_WHEEL: // window, which, scroll, mouse => 4 extra count += 4; break; case SDL_EVENT_MOUSE_BUTTON_UP: case SDL_EVENT_MOUSE_BUTTON_DOWN: // window, which, down, button, clicks, mouse => 6 extra count += 6; break; case SDL_EVENT_SENSOR_UPDATE: // which, sensor_timestamp => 2 extra count += 2; break; case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_UP: // window, which, down, repeat, key, scancode, mod => 7 extra count += 7; break; case SDL_EVENT_FINGER_MOTION: case SDL_EVENT_FINGER_DOWN: case SDL_EVENT_FINGER_UP: // touch, finger, pos, d_pos, pressure, window => 6 extra count += 6; break; case SDL_EVENT_DROP_BEGIN: case SDL_EVENT_DROP_FILE: case SDL_EVENT_DROP_TEXT: case SDL_EVENT_DROP_COMPLETE: case SDL_EVENT_DROP_POSITION: // window, pos, data, source => 4 extra count += 4; break; case SDL_EVENT_TEXT_INPUT: // window, text, mod => 3 extra count += 3; break; case SDL_EVENT_CAMERA_DEVICE_APPROVED: case SDL_EVENT_CAMERA_DEVICE_REMOVED: case SDL_EVENT_CAMERA_DEVICE_ADDED: case SDL_EVENT_CAMERA_DEVICE_DENIED: // which => 1 extra count += 1; break; case SDL_EVENT_CLIPBOARD_UPDATE: // owner => 1 extra count += 1; break; /* Window events (just group them all together) */ case SDL_EVENT_WINDOW_SHOWN: case SDL_EVENT_WINDOW_HIDDEN: case SDL_EVENT_WINDOW_EXPOSED: case SDL_EVENT_WINDOW_MOVED: case SDL_EVENT_WINDOW_RESIZED: case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: case SDL_EVENT_WINDOW_METAL_VIEW_RESIZED: case SDL_EVENT_WINDOW_MINIMIZED: case SDL_EVENT_WINDOW_MAXIMIZED: case SDL_EVENT_WINDOW_RESTORED: case SDL_EVENT_WINDOW_MOUSE_ENTER: case SDL_EVENT_WINDOW_MOUSE_LEAVE: case SDL_EVENT_WINDOW_FOCUS_GAINED: case SDL_EVENT_WINDOW_FOCUS_LOST: case SDL_EVENT_WINDOW_CLOSE_REQUESTED: case SDL_EVENT_WINDOW_HIT_TEST: case SDL_EVENT_WINDOW_ICCPROF_CHANGED: case SDL_EVENT_WINDOW_DISPLAY_CHANGED: case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED: case SDL_EVENT_WINDOW_OCCLUDED: case SDL_EVENT_WINDOW_ENTER_FULLSCREEN: case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN: case SDL_EVENT_WINDOW_DESTROYED: case SDL_EVENT_WINDOW_HDR_STATE_CHANGED: // which, x/width/display_index, y/height => 3 extra count += 3; break; case SDL_EVENT_JOYSTICK_ADDED: case SDL_EVENT_JOYSTICK_REMOVED: case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE: // which => 1 extra count += 1; break; case SDL_EVENT_JOYSTICK_AXIS_MOTION: // which, axis, value => 3 extra count += 3; break; case SDL_EVENT_JOYSTICK_BALL_MOTION: // which, ball, rel => 3 extra count += 3; break; case SDL_EVENT_JOYSTICK_BUTTON_DOWN: case SDL_EVENT_JOYSTICK_BUTTON_UP: // which, button, down => 3 extra count += 3; break; case SDL_EVENT_GAMEPAD_ADDED: case SDL_EVENT_GAMEPAD_REMOVED: case SDL_EVENT_GAMEPAD_REMAPPED: case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE: case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED: // which => 1 extra count += 1; break; case SDL_EVENT_GAMEPAD_AXIS_MOTION: // which, axis, value => 3 extra count += 3; break; case SDL_EVENT_GAMEPAD_BUTTON_DOWN: case SDL_EVENT_GAMEPAD_BUTTON_UP: // which, button, down => 3 extra count += 3; break; case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN: case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION: case SDL_EVENT_GAMEPAD_TOUCHPAD_UP: // which, touchpad, finger, pos, pressure => 5 extra count += 5; break; case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: // which, sensor, sensor_timestamp => 3 extra count += 3; break; case SDL_EVENT_USER: // cb => 1 extra count += 1; break; } return count; } static void event2wota_write(WotaBuffer *wb, const SDL_Event *e, int c) { wota_write_record(wb, (unsigned long long)c); wota_write_text(wb, "type"); wota_write_text(wb, event_type_to_string(e->type)); wota_write_text(wb, "timestamp"); wota_write_number(wb, (double)e->common.timestamp); switch(e->type) { case SDL_EVENT_AUDIO_DEVICE_ADDED: case SDL_EVENT_AUDIO_DEVICE_REMOVED: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->adevice.which); wota_write_text(wb, "recording"); wota_write_sym(wb, e->adevice.recording ? WOTA_TRUE : WOTA_FALSE); break; case SDL_EVENT_DISPLAY_ORIENTATION: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->display.displayID); wota_write_text(wb, "orientation"); wota_write_number(wb, (double)e->display.data1); wota_write_text(wb, "data2"); wota_write_number(wb, (double)e->display.data2); break; case SDL_EVENT_DISPLAY_ADDED: case SDL_EVENT_DISPLAY_REMOVED: case SDL_EVENT_DISPLAY_MOVED: case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED: case SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED: case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->display.displayID); wota_write_text(wb, "data1"); wota_write_number(wb, (double)e->display.data1); wota_write_text(wb, "data2"); wota_write_number(wb, (double)e->display.data2); break; case SDL_EVENT_MOUSE_MOTION: wota_write_text(wb, "window"); wota_write_number(wb, (double)e->motion.windowID); wota_write_text(wb, "which"); wota_write_number(wb, (double)e->motion.which); wota_write_text(wb, "state"); wota_write_number(wb, (double)e->motion.state); wota_write_text(wb, "pos"); wota_write_vec2(wb, (double)e->motion.x, (double)e->motion.y); wota_write_text(wb, "d_pos"); wota_write_vec2(wb, (double)e->motion.xrel, (double)e->motion.yrel); break; case SDL_EVENT_MOUSE_WHEEL: wota_write_text(wb, "window"); wota_write_number(wb, (double)e->wheel.windowID); wota_write_text(wb, "which"); wota_write_number(wb, (double)e->wheel.which); wota_write_text(wb, "scroll"); wota_write_vec2(wb, (double)e->wheel.x, (double)e->wheel.y); wota_write_text(wb, "pos"); wota_write_vec2(wb, (double)e->wheel.mouse_x, (double)e->wheel.mouse_y); break; case SDL_EVENT_MOUSE_BUTTON_UP: case SDL_EVENT_MOUSE_BUTTON_DOWN: wota_write_text(wb, "window"); wota_write_number(wb, (double)e->button.windowID); wota_write_text(wb, "which"); wota_write_number(wb, (double)e->button.which); wota_write_text(wb, "down"); wota_write_sym(wb, e->button.down ? WOTA_TRUE : WOTA_FALSE); wota_write_text(wb, "button"); wota_write_text(wb, mouse_button_to_string(e->button.button)); wota_write_text(wb, "clicks"); wota_write_number(wb, (double)e->button.clicks); wota_write_text(wb, "pos"); wota_write_vec2(wb, (double)e->button.x, (double)e->button.y); break; case SDL_EVENT_SENSOR_UPDATE: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->sensor.which); wota_write_text(wb, "sensor_timestamp"); wota_write_number(wb, (double)e->sensor.sensor_timestamp); break; case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_UP: wota_write_text(wb, "window"); wota_write_number(wb, (double)e->key.windowID); wota_write_text(wb, "which"); wota_write_number(wb, (double)e->key.which); wota_write_text(wb, "down"); wota_write_sym(wb, e->key.down ? WOTA_TRUE : WOTA_FALSE); wota_write_text(wb, "repeat"); wota_write_sym(wb, e->key.repeat ? WOTA_TRUE : WOTA_FALSE); wota_write_text(wb, "key"); wota_write_number(wb, (double)e->key.key); wota_write_text(wb, "scancode"); wota_write_number(wb, (double)e->key.scancode); wota_write_text(wb, "mod"); wota_write_number(wb, 0); break; case SDL_EVENT_FINGER_MOTION: case SDL_EVENT_FINGER_DOWN: case SDL_EVENT_FINGER_UP: wota_write_text(wb, "touch"); wota_write_number(wb, (double)e->tfinger.touchID); wota_write_text(wb, "finger"); wota_write_number(wb, (double)e->tfinger.fingerID); wota_write_text(wb, "pos"); wota_write_vec2(wb, (double)e->tfinger.x, (double)e->tfinger.y); wota_write_text(wb, "d_pos"); wota_write_vec2(wb, (double)e->tfinger.dx, (double)e->tfinger.dy); wota_write_text(wb, "pressure"); wota_write_number(wb, (double)e->tfinger.pressure); wota_write_text(wb, "window"); wota_write_number(wb, (double)e->key.windowID); break; case SDL_EVENT_DROP_BEGIN: case SDL_EVENT_DROP_FILE: case SDL_EVENT_DROP_TEXT: case SDL_EVENT_DROP_COMPLETE: case SDL_EVENT_DROP_POSITION: wota_write_text(wb, "window"); wota_write_number(wb, (double)e->drop.windowID); wota_write_text(wb, "pos"); wota_write_vec2(wb, (double)e->drop.x, (double)e->drop.y); wota_write_text(wb, "data"); wota_write_text(wb, e->drop.data ? e->drop.data : ""); wota_write_text(wb, "source"); wota_write_text(wb, e->drop.source ? e->drop.source : ""); break; case SDL_EVENT_TEXT_INPUT: wota_write_text(wb, "window"); wota_write_number(wb, (double)e->text.windowID); wota_write_text(wb, "text"); wota_write_text(wb, e->text.text); wota_write_text(wb, "mod"); wota_write_number(wb, 0); break; case SDL_EVENT_CAMERA_DEVICE_APPROVED: case SDL_EVENT_CAMERA_DEVICE_REMOVED: case SDL_EVENT_CAMERA_DEVICE_ADDED: case SDL_EVENT_CAMERA_DEVICE_DENIED: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->cdevice.which); break; case SDL_EVENT_CLIPBOARD_UPDATE: wota_write_text(wb, "owner"); wota_write_sym(wb, e->clipboard.owner ? WOTA_TRUE : WOTA_FALSE); break; case SDL_EVENT_WINDOW_SHOWN: case SDL_EVENT_WINDOW_HIDDEN: case SDL_EVENT_WINDOW_EXPOSED: case SDL_EVENT_WINDOW_MINIMIZED: case SDL_EVENT_WINDOW_MAXIMIZED: case SDL_EVENT_WINDOW_RESTORED: case SDL_EVENT_WINDOW_MOUSE_ENTER: case SDL_EVENT_WINDOW_MOUSE_LEAVE: case SDL_EVENT_WINDOW_FOCUS_GAINED: case SDL_EVENT_WINDOW_FOCUS_LOST: case SDL_EVENT_WINDOW_CLOSE_REQUESTED: case SDL_EVENT_WINDOW_HIT_TEST: case SDL_EVENT_WINDOW_ICCPROF_CHANGED: case SDL_EVENT_WINDOW_OCCLUDED: case SDL_EVENT_WINDOW_ENTER_FULLSCREEN: case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN: case SDL_EVENT_WINDOW_DESTROYED: case SDL_EVENT_WINDOW_HDR_STATE_CHANGED: case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->window.windowID); wota_write_text(wb, "data1"); wota_write_number(wb, (double)e->window.data1); wota_write_text(wb, "data2"); wota_write_number(wb, (double)e->window.data2); break; case SDL_EVENT_WINDOW_MOVED: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->window.windowID); wota_write_text(wb, "x"); wota_write_number(wb, (double)e->window.data1); wota_write_text(wb, "y"); wota_write_number(wb, (double)e->window.data2); break; case SDL_EVENT_WINDOW_RESIZED: case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: case SDL_EVENT_WINDOW_METAL_VIEW_RESIZED: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->window.windowID); wota_write_text(wb, "width"); wota_write_number(wb, (double)e->window.data1); wota_write_text(wb, "height"); wota_write_number(wb, (double)e->window.data2); break; case SDL_EVENT_WINDOW_DISPLAY_CHANGED: case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->window.windowID); wota_write_text(wb, "display_index"); wota_write_number(wb, (double)e->window.data1); wota_write_text(wb, "data2"); wota_write_number(wb, (double)e->window.data2); break; case SDL_EVENT_JOYSTICK_ADDED: case SDL_EVENT_JOYSTICK_REMOVED: case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->jdevice.which); break; case SDL_EVENT_JOYSTICK_AXIS_MOTION: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->jaxis.which); wota_write_text(wb, "axis"); wota_write_number(wb, (double)e->jaxis.axis); wota_write_text(wb, "value"); wota_write_number(wb, (double)e->jaxis.value); break; case SDL_EVENT_JOYSTICK_BALL_MOTION: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->jball.which); wota_write_text(wb, "ball"); wota_write_number(wb, (double)e->jball.ball); wota_write_text(wb, "rel"); wota_write_vec2(wb, (double)e->jball.xrel, (double)e->jball.yrel); break; case SDL_EVENT_JOYSTICK_BUTTON_DOWN: case SDL_EVENT_JOYSTICK_BUTTON_UP: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->jbutton.which); wota_write_text(wb, "button"); wota_write_number(wb, (double)e->jbutton.button); wota_write_text(wb, "down"); wota_write_sym(wb, e->jbutton.down ? WOTA_TRUE : WOTA_FALSE); break; case SDL_EVENT_GAMEPAD_ADDED: case SDL_EVENT_GAMEPAD_REMOVED: case SDL_EVENT_GAMEPAD_REMAPPED: case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE: case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->gdevice.which); break; case SDL_EVENT_GAMEPAD_AXIS_MOTION: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->gaxis.which); wota_write_text(wb, "axis"); wota_write_number(wb, (double)e->gaxis.axis); wota_write_text(wb, "value"); wota_write_number(wb, (double)e->gaxis.value); break; case SDL_EVENT_GAMEPAD_BUTTON_DOWN: case SDL_EVENT_GAMEPAD_BUTTON_UP: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->gbutton.which); wota_write_text(wb, "button"); wota_write_number(wb, (double)e->gbutton.button); wota_write_text(wb, "down"); wota_write_sym(wb, e->gbutton.down ? WOTA_TRUE : WOTA_FALSE); break; case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN: case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION: case SDL_EVENT_GAMEPAD_TOUCHPAD_UP: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->gtouchpad.which); wota_write_text(wb, "touchpad"); wota_write_number(wb, (double)e->gtouchpad.touchpad); wota_write_text(wb, "finger"); wota_write_number(wb, (double)e->gtouchpad.finger); wota_write_text(wb, "pos"); wota_write_vec2(wb, (double)e->gtouchpad.x, (double)e->gtouchpad.y); wota_write_text(wb, "pressure"); wota_write_number(wb, (double)e->gtouchpad.pressure); break; case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: wota_write_text(wb, "which"); wota_write_number(wb, (double)e->gsensor.which); wota_write_text(wb, "sensor"); wota_write_number(wb, (double)e->gsensor.sensor); wota_write_text(wb, "sensor_timestamp"); wota_write_number(wb, (double)e->gsensor.sensor_timestamp); break; case SDL_EVENT_USER: wota_write_text(wb, "cb"); wota_write_number(wb, (double)(uintptr_t)e->user.data1); break; } } static WotaBuffer event2wota(const SDL_Event *event) { WotaBuffer wb; wota_buffer_init(&wb, 8); int n = event2wota_count_props(event); event2wota_write(&wb, event, n); return wb; } // Get all events directly from SDL event queue JSC_CCALL(input_get_events, JSValue events_array = JS_NewArray(js); SDL_Event event; int event_count = 0; while (SDL_PollEvent(&event)) { WotaBuffer wb = event2wota(&event); JSValue event_obj = wota2value(js, wb.data); JS_SetPropertyUint32(js, events_array, event_count, event_obj); wota_buffer_free(&wb); event_count++; } return events_array; ) static const JSCFunctionListEntry js_input_funcs[] = { MIST_FUNC_DEF(input, mouse_show, 1), MIST_FUNC_DEF(input, mouse_lock, 1), MIST_FUNC_DEF(input, keyname, 1), MIST_FUNC_DEF(input, keymod, 0), MIST_FUNC_DEF(input, mousestate, 0), MIST_FUNC_DEF(input, get_events, 0), }; JSValue js_input_use(JSContext *js) { JSValue mod = JS_NewObject(js); JS_SetPropertyFunctionList(js,mod,js_input_funcs,countof(js_input_funcs)); return mod; }