#include "cell.h" #include #include "sdl.h" void SDL_Event_free(JSRuntime *rt, SDL_Event *e) { free(e); } QJSCLASS(SDL_Event,) // Internal keymod function for input module static JSValue js_keymod(JSContext *js) { SDL_Keymod modstate = SDL_GetModState(); JS_FRAME(js); JS_LOCAL(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)); JS_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); JS_FRAME(js); JS_LOCAL(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)); JS_RETURN(m); ) // Event processing functions 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 JSValue js_vec2(JSContext *js, double x, double y) { JS_FRAME(js); JS_LOCAL(arr, JS_NewArray(js)); JS_SetPropertyNumber(js, arr, 0, number2js(js, x)); JS_SetPropertyNumber(js, arr, 1, number2js(js, y)); JS_RETURN(arr); } static JSValue event2js(JSContext *js, const SDL_Event *e) { JS_FRAME(js); JS_LOCAL(obj, JS_NewObject(js)); JSValue tmp; tmp = JS_NewString(js, event_type_to_string(e->type)); JS_SetPropertyStr(js, obj, "type", tmp); JS_SetPropertyStr(js, obj, "timestamp", number2js(js, (double)e->common.timestamp)); switch (e->type) { case SDL_EVENT_AUDIO_DEVICE_ADDED: case SDL_EVENT_AUDIO_DEVICE_REMOVED: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->adevice.which)); JS_SetPropertyStr(js, obj, "recording", JS_NewBool(js, e->adevice.recording)); break; case SDL_EVENT_DISPLAY_ORIENTATION: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->display.displayID)); JS_SetPropertyStr(js, obj, "orientation", number2js(js, (double)e->display.data1)); JS_SetPropertyStr(js, obj, "data2", number2js(js, (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: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->display.displayID)); JS_SetPropertyStr(js, obj, "data1", number2js(js, (double)e->display.data1)); JS_SetPropertyStr(js, obj, "data2", number2js(js, (double)e->display.data2)); break; case SDL_EVENT_MOUSE_MOTION: JS_SetPropertyStr(js, obj, "window", number2js(js, (double)e->motion.windowID)); JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->motion.which)); JS_SetPropertyStr(js, obj, "state", number2js(js, (double)e->motion.state)); tmp = js_vec2(js, (double)e->motion.x, (double)e->motion.y); JS_SetPropertyStr(js, obj, "pos", tmp); tmp = js_vec2(js, (double)e->motion.xrel, (double)e->motion.yrel); JS_SetPropertyStr(js, obj, "d_pos", tmp); break; case SDL_EVENT_MOUSE_WHEEL: JS_SetPropertyStr(js, obj, "window", number2js(js, (double)e->wheel.windowID)); JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->wheel.which)); tmp = js_vec2(js, (double)e->wheel.x, (double)e->wheel.y); JS_SetPropertyStr(js, obj, "scroll", tmp); tmp = js_vec2(js, (double)e->wheel.mouse_x, (double)e->wheel.mouse_y); JS_SetPropertyStr(js, obj, "pos", tmp); break; case SDL_EVENT_MOUSE_BUTTON_UP: case SDL_EVENT_MOUSE_BUTTON_DOWN: JS_SetPropertyStr(js, obj, "window", number2js(js, (double)e->button.windowID)); JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->button.which)); JS_SetPropertyStr(js, obj, "down", JS_NewBool(js, e->button.down)); tmp = JS_NewString(js, mouse_button_to_string(e->button.button)); JS_SetPropertyStr(js, obj, "button", tmp); JS_SetPropertyStr(js, obj, "clicks", number2js(js, (double)e->button.clicks)); tmp = js_vec2(js, (double)e->button.x, (double)e->button.y); JS_SetPropertyStr(js, obj, "pos", tmp); break; case SDL_EVENT_SENSOR_UPDATE: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->sensor.which)); JS_SetPropertyStr(js, obj, "sensor_timestamp", number2js(js, (double)e->sensor.sensor_timestamp)); break; case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_UP: JS_SetPropertyStr(js, obj, "window", number2js(js, (double)e->key.windowID)); JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->key.which)); JS_SetPropertyStr(js, obj, "down", JS_NewBool(js, e->key.down)); JS_SetPropertyStr(js, obj, "repeat", JS_NewBool(js, e->key.repeat)); JS_SetPropertyStr(js, obj, "key", number2js(js, (double)e->key.key)); JS_SetPropertyStr(js, obj, "scancode", number2js(js, (double)e->key.scancode)); JS_SetPropertyStr(js, obj, "mod", number2js(js, (double)e->key.mod)); break; case SDL_EVENT_FINGER_MOTION: case SDL_EVENT_FINGER_DOWN: case SDL_EVENT_FINGER_UP: JS_SetPropertyStr(js, obj, "touch", number2js(js, (double)e->tfinger.touchID)); JS_SetPropertyStr(js, obj, "finger", number2js(js, (double)e->tfinger.fingerID)); tmp = js_vec2(js, (double)e->tfinger.x, (double)e->tfinger.y); JS_SetPropertyStr(js, obj, "pos", tmp); tmp = js_vec2(js, (double)e->tfinger.dx, (double)e->tfinger.dy); JS_SetPropertyStr(js, obj, "d_pos", tmp); JS_SetPropertyStr(js, obj, "pressure", number2js(js, (double)e->tfinger.pressure)); JS_SetPropertyStr(js, obj, "window", number2js(js, (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: JS_SetPropertyStr(js, obj, "window", number2js(js, (double)e->drop.windowID)); tmp = js_vec2(js, (double)e->drop.x, (double)e->drop.y); JS_SetPropertyStr(js, obj, "pos", tmp); tmp = JS_NewString(js, e->drop.data ? e->drop.data : ""); JS_SetPropertyStr(js, obj, "data", tmp); tmp = JS_NewString(js, e->drop.source ? e->drop.source : ""); JS_SetPropertyStr(js, obj, "source", tmp); break; case SDL_EVENT_TEXT_INPUT: JS_SetPropertyStr(js, obj, "window", number2js(js, (double)e->text.windowID)); tmp = JS_NewString(js, e->text.text); JS_SetPropertyStr(js, obj, "text", tmp); JS_SetPropertyStr(js, obj, "mod", number2js(js, 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: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->cdevice.which)); break; case SDL_EVENT_CLIPBOARD_UPDATE: JS_SetPropertyStr(js, obj, "owner", JS_NewBool(js, e->clipboard.owner)); break; case SDL_EVENT_WINDOW_EXPOSED: case SDL_EVENT_WINDOW_FOCUS_GAINED: case SDL_EVENT_WINDOW_FOCUS_LOST: case SDL_EVENT_WINDOW_CLOSE_REQUESTED: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->window.windowID)); break; case SDL_EVENT_WINDOW_SHOWN: case SDL_EVENT_WINDOW_HIDDEN: 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_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: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->window.windowID)); JS_SetPropertyStr(js, obj, "data1", number2js(js, (double)e->window.data1)); JS_SetPropertyStr(js, obj, "data2", number2js(js, (double)e->window.data2)); break; case SDL_EVENT_WINDOW_SAFE_AREA_CHANGED: { SDL_Window *window = SDL_GetWindowFromID(e->window.windowID); SDL_Rect safe_area = {0, 0, 0, 0}; if (window && SDL_GetWindowSafeArea(window, &safe_area)) { JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->window.windowID)); JS_SetPropertyStr(js, obj, "x", number2js(js, (double)safe_area.x)); JS_SetPropertyStr(js, obj, "y", number2js(js, (double)safe_area.y)); JS_SetPropertyStr(js, obj, "width", number2js(js, (double)safe_area.w)); JS_SetPropertyStr(js, obj, "height", number2js(js, (double)safe_area.h)); } else { JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->window.windowID)); JS_SetPropertyStr(js, obj, "data1", number2js(js, (double)e->window.data1)); JS_SetPropertyStr(js, obj, "data2", number2js(js, (double)e->window.data2)); } break; } case SDL_EVENT_WINDOW_MOVED: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->window.windowID)); JS_SetPropertyStr(js, obj, "x", number2js(js, (double)e->window.data1)); JS_SetPropertyStr(js, obj, "y", number2js(js, (double)e->window.data2)); break; case SDL_EVENT_WINDOW_RESIZED: case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: case SDL_EVENT_WINDOW_METAL_VIEW_RESIZED: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->window.windowID)); JS_SetPropertyStr(js, obj, "width", number2js(js, (double)e->window.data1)); JS_SetPropertyStr(js, obj, "height", number2js(js, (double)e->window.data2)); break; case SDL_EVENT_WINDOW_DISPLAY_CHANGED: case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->window.windowID)); JS_SetPropertyStr(js, obj, "display_index", number2js(js, (double)e->window.data1)); JS_SetPropertyStr(js, obj, "data2", number2js(js, (double)e->window.data2)); break; case SDL_EVENT_JOYSTICK_ADDED: case SDL_EVENT_JOYSTICK_REMOVED: case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->jdevice.which)); break; case SDL_EVENT_JOYSTICK_AXIS_MOTION: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->jaxis.which)); JS_SetPropertyStr(js, obj, "axis", number2js(js, (double)e->jaxis.axis)); JS_SetPropertyStr(js, obj, "value", number2js(js, (double)e->jaxis.value)); break; case SDL_EVENT_JOYSTICK_BALL_MOTION: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->jball.which)); JS_SetPropertyStr(js, obj, "ball", number2js(js, (double)e->jball.ball)); tmp = js_vec2(js, (double)e->jball.xrel, (double)e->jball.yrel); JS_SetPropertyStr(js, obj, "rel", tmp); break; case SDL_EVENT_JOYSTICK_BUTTON_DOWN: case SDL_EVENT_JOYSTICK_BUTTON_UP: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->jbutton.which)); JS_SetPropertyStr(js, obj, "button", number2js(js, (double)e->jbutton.button)); JS_SetPropertyStr(js, obj, "down", JS_NewBool(js, e->jbutton.down)); 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: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->gdevice.which)); break; case SDL_EVENT_GAMEPAD_AXIS_MOTION: { JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->gaxis.which)); tmp = JS_NewString(js, SDL_GetGamepadStringForAxis(e->gaxis.axis)); JS_SetPropertyStr(js, obj, "axis", tmp); double normalized_value = (double)e->gaxis.value / 32767.0; JS_SetPropertyStr(js, obj, "value", number2js(js, normalized_value)); break; } case SDL_EVENT_GAMEPAD_BUTTON_DOWN: case SDL_EVENT_GAMEPAD_BUTTON_UP: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->gbutton.which)); tmp = JS_NewString(js, SDL_GetGamepadStringForButton(e->gbutton.button)); JS_SetPropertyStr(js, obj, "button", tmp); JS_SetPropertyStr(js, obj, "down", JS_NewBool(js, e->gbutton.down)); break; case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN: case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION: case SDL_EVENT_GAMEPAD_TOUCHPAD_UP: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->gtouchpad.which)); JS_SetPropertyStr(js, obj, "touchpad", number2js(js, (double)e->gtouchpad.touchpad)); JS_SetPropertyStr(js, obj, "finger", number2js(js, (double)e->gtouchpad.finger)); tmp = js_vec2(js, (double)e->gtouchpad.x, (double)e->gtouchpad.y); JS_SetPropertyStr(js, obj, "pos", tmp); JS_SetPropertyStr(js, obj, "pressure", number2js(js, (double)e->gtouchpad.pressure)); break; case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: JS_SetPropertyStr(js, obj, "which", number2js(js, (double)e->gsensor.which)); JS_SetPropertyStr(js, obj, "sensor", number2js(js, (double)e->gsensor.sensor)); JS_SetPropertyStr(js, obj, "sensor_timestamp", number2js(js, (double)e->gsensor.sensor_timestamp)); break; case SDL_EVENT_USER: JS_SetPropertyStr(js, obj, "cb", number2js(js, (double)(uintptr_t)e->user.data1)); break; } JS_RETURN(obj); } // Get all events directly from SDL event queue JSC_CCALL(input_get_events, JS_FRAME(js); JS_LOCAL(events_array, JS_NewArray(js)); SDL_Event event; int event_count = 0; while (SDL_PollEvent(&event)) { SDL_Event *e = (SDL_Event *)malloc(sizeof(SDL_Event)); memcpy(e, &event, sizeof(SDL_Event)); JS_SetPropertyNumber(js, events_array, event_count, SDL_Event2js(js, e)); event_count++; } JS_RETURN(events_array); ) JSC_CCALL(input_objectify, SDL_Event *e = js2SDL_Event(js, argv[0]); if (!e) return JS_ThrowTypeError(js, "Expected SDL_Event object"); return event2js(js, e); ) JSC_CCALL(input_gamepad_id_to_type, int id = js2number(js, argv[0]); return JS_NewString(js, SDL_GetGamepadStringForType(SDL_GetGamepadTypeForID(id))); ) 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), MIST_FUNC_DEF(input, objectify, 1), MIST_FUNC_DEF(input, gamepad_id_to_type, 1), }; CELL_USE_INIT( QJSCLASSPREP_NO_FUNCS(SDL_Event); JS_FRAME(js); JS_LOCAL(mod, JS_NewObject(js)); JS_SetPropertyFunctionList(js, mod, js_input_funcs, countof(js_input_funcs)); JS_RETURN(mod); )