diff --git a/doc/user/lua-plugins.rst b/doc/user/lua-plugins.rst index dcd254a4..3e5b84c3 100644 --- a/doc/user/lua-plugins.rst +++ b/doc/user/lua-plugins.rst @@ -604,24 +604,6 @@ methods will be noops. Disconnect the existing callback (if any) for the given event name. See ``EvdevDevice:connect()`` for a list of supported names. -.. function:: EvdevDevice:inject_frame(frame) - - .. warning:: This function is only available from inside a timer callback. - - Inject an :ref:`evdev frame ` into the event stream - for this device. This emulates that same event frame being sent by the kernel - immediately with the current time. - - Assuming three plugins P1, P2 and P3, if P2 injects a frame the frame is - seen by P1, P2 and P3. - - This is rarely the right API to use. Injecting frames at the lowest level - may make other plugins behave unexpectedly. Use ``prepend_frame`` or - ``append_frame`` instead. - - .. warning:: The injected frame will be seen by all plugins, including the - injecting frame. Ensure a guard is in place to prevent recursion. - .. function:: EvdevDevice:prepend_frame(frame) Prepend an :ref:`evdev frame ` for this device diff --git a/src/libinput-plugin-lua.c b/src/libinput-plugin-lua.c index 4ed8dc55..20ddc22e 100644 --- a/src/libinput-plugin-lua.c +++ b/src/libinput-plugin-lua.c @@ -116,7 +116,6 @@ struct libinput_lua_plugin { struct libinput_plugin_timer *timer; bool in_timer_func; - struct list timer_injected_events; }; static struct libinput_lua_plugin * @@ -566,12 +565,6 @@ libinputplugin_gc(lua_State *L) return 0; } -struct timer_injected_event { - struct list link; - struct evdev_frame *frame; - int device_refid; -}; - static void plugin_timer_func(struct libinput_plugin *libinput_plugin, uint64_t now, void *data) { @@ -581,28 +574,7 @@ plugin_timer_func(struct libinput_plugin *libinput_plugin, uint64_t now, void *d lua_rawgeti(L, LUA_REGISTRYINDEX, plugin->timer_expired_refid); lua_pushinteger(L, now); - /* To allow for injecting events */ - plugin->in_timer_func = true; libinput_lua_pcall(plugin, 1, 0); - plugin->in_timer_func = false; - - struct timer_injected_event *injected_event; - list_for_each_safe(injected_event, &plugin->timer_injected_events, link) { - EvdevDevice *device; - list_for_each(device, &plugin->evdev_devices, link) { - if (device->refid == injected_event->device_refid) { - libinput_plugin_inject_evdev_frame( - plugin->parent, - device->device, - injected_event->frame); - break; - } - } - - list_remove(&injected_event->link); - evdev_frame_unref(injected_event->frame); - free(injected_event); - } } static int @@ -951,36 +923,6 @@ evdevdevice_frame(lua_State *L, struct libinput_lua_plugin *plugin, EvdevDevice return frame; } -static int -evdevdevice_inject_frame(lua_State *L) -{ - EvdevDevice *device = luaL_checkudata(L, 1, EVDEV_DEVICE_METATABLE); - luaL_argcheck(L, device != NULL, 1, EVDEV_DEVICE_METATABLE " expected"); - - luaL_checktype(L, 2, LUA_TTABLE); - - /* No refid means we got removed, so quietly - * drop any disconnect call */ - if (device->refid == LUA_NOREF) - return 0; - - struct libinput_lua_plugin *plugin = lua_get_libinput_lua_plugin(L); - if (!plugin->in_timer_func) { - return luaL_error(L, "Injecting events only possible in a timer func"); - } - _unref_(evdev_frame) *frame = evdevdevice_frame(L, plugin, device); - - /* Lua is unhappy if we inject an event which calls into our lua state - * immediately so we need to queue this for later when we're out of the timer - * func */ - struct timer_injected_event *event = zalloc(sizeof(*event)); - event->device_refid = device->refid; - event->frame = steal(&frame); - list_insert(&plugin->timer_injected_events, &event->link); - - return 0; -} - static int evdevdevice_prepend_frame(lua_State *L) { @@ -1089,7 +1031,6 @@ static const struct luaL_Reg evdevdevice_vtable[] = { { "set_absinfo", evdevdevice_set_absinfo }, { "connect", evdevdevice_connect }, { "disconnect", evdevdevice_disconnect }, - { "inject_frame", evdevdevice_inject_frame }, { "prepend_frame", evdevdevice_prepend_frame }, { "append_frame", evdevdevice_append_frame }, { "disable_feature", evdevdevice_disable_feature }, @@ -1355,7 +1296,6 @@ libinput_lua_plugin_new_from_path(struct libinput *libinput, const char *path) plugin->device_new_refid = LUA_NOREF; plugin->timer_expired_refid = LUA_NOREF; list_init(&plugin->evdev_devices); - list_init(&plugin->timer_injected_events); _cleanup_(lua_closep) lua_State *L = libinput_lua_plugin_init_lua(libinput, plugin); diff --git a/test/test-plugins-lua.c b/test/test-plugins-lua.c index 9b771cc8..32dbe4b1 100644 --- a/test/test-plugins-lua.c +++ b/test/test-plugins-lua.c @@ -929,164 +929,6 @@ START_TEST(lua_ignore_unsupported_codes) } END_TEST -START_TEST(lua_inject_frame) -{ - bool in_timer = litest_test_param_get_bool(test_env->params, "in_timer"); - _destroy_(tmpdir) *tmpdir = tmpdir_create(NULL); - - /* Plugin 1 swaps left to right */ - const char *lua1 = - "libinput:register({1})\n" - "function frame_handler(device, frame, timestamp)\n" - " for _, e in ipairs(frame) do\n" - " if e.usage == evdev.BTN_LEFT then\n" - " e.usage = evdev.BTN_RIGHT\n" - " end\n" - " end\n" - " return frame\n" - "end\n" - "libinput:connect(\"new-evdev-device\", function(device)\n" - " device:connect(\"evdev-frame\", frame_handler)\n" - "end)\n"; - - /* Plugin 2 injects a left button if a middle button is pressed */ - _autofree_ char *lua2 = strdup_printf( - "libinput:register({1})\n" - "mydev = nil\n" - "function frame_handler(device, frame, timestamp)\n" - " for _, e in ipairs(frame) do\n" - " if e.usage == evdev.BTN_SIDE then\n" - " e.usage = evdev.BTN_EXTRA\n" - " end\n" - " if e.usage == evdev.BTN_MIDDLE then\n" - " log.debug(\"Injecting frame BTN_LEFT value \" .. e.value)\n" - " %sdevice:inject_frame({{ usage = evdev.BTN_LEFT, value = e.value }})\n" - " %slibinput:timer_set_relative(200000)\n" /* commented out - if !in_timer */ - " end\n" - " end\n" - " return frame\n" - "end\n" - "function timer_expired(t)\n" - " log.debug(\"Injecting timer BTN_LEFT\")\n" - " mydev:inject_frame({{ usage = evdev.BTN_LEFT, value = 1 }})\n" - "end\n" - "libinput:connect(\"new-evdev-device\", function(device)\n" - " mydev = device\n" - " device:connect(\"evdev-frame\", frame_handler)\n" - "end)\n" - "libinput:connect(\"timer-expired\", timer_expired)\n", - in_timer ? "-- " : "", - in_timer ? "" : "-- "); - - _autofree_ char *p1 = litest_write_plugin(tmpdir->path, lua1); - _autofree_ char *p2 = litest_write_plugin(tmpdir->path, lua2); - _litest_context_destroy_ struct libinput *li = - litest_create_context_with_plugindir(tmpdir->path); - libinput_plugin_system_load_plugins(li, LIBINPUT_PLUGIN_SYSTEM_FLAG_NONE); - litest_drain_events(li); - - _destroy_(litest_device) *device = litest_add_device(li, LITEST_CYBORG_RAT); - litest_drain_events(li); - litest_dispatch(li); - - litest_log_group("P1 should swap left to right") { - litest_button_click_debounced(device, li, BTN_LEFT, 1); - litest_button_click_debounced(device, li, BTN_LEFT, 0); - litest_dispatch(li); - - litest_assert_button_event(li, - BTN_RIGHT, - LIBINPUT_BUTTON_STATE_PRESSED); - litest_assert_button_event(li, - BTN_RIGHT, - LIBINPUT_BUTTON_STATE_RELEASED); - litest_drain_events(li); - } - - litest_log_group("P1/P2 should leave BTN_EXTRA untouched") { - litest_button_click_debounced(device, li, BTN_EXTRA, 1); - litest_button_click_debounced(device, li, BTN_EXTRA, 0); - litest_dispatch(li); - - /* This might be a false positive */ - litest_assert_button_event(li, - BTN_EXTRA, - LIBINPUT_BUTTON_STATE_PRESSED); - litest_assert_button_event(li, - BTN_EXTRA, - LIBINPUT_BUTTON_STATE_RELEASED); - } - - litest_log_group("P2 should map BTN_SIDE to BTN_EXTRA") { - litest_button_click_debounced(device, li, BTN_SIDE, 1); - litest_button_click_debounced(device, li, BTN_SIDE, 0); - litest_dispatch(li); - litest_timeout_debounce(li); - litest_dispatch(li); - - litest_assert_button_event(li, - BTN_EXTRA, - LIBINPUT_BUTTON_STATE_PRESSED); - litest_assert_button_event(li, - BTN_EXTRA, - LIBINPUT_BUTTON_STATE_RELEASED); - } - - if (in_timer) { - litest_log_group( - "P2 should inject left on middle via timer, P1 changes that left to right in timer") { - litest_button_click_debounced(device, li, BTN_MIDDLE, 1); - litest_dispatch(li); - - litest_assert_button_event(li, - BTN_MIDDLE, - LIBINPUT_BUTTON_STATE_PRESSED); - litest_assert_button_event(li, - BTN_RIGHT, - LIBINPUT_BUTTON_STATE_PRESSED); - - litest_button_click_debounced(device, li, BTN_MIDDLE, 0); - litest_dispatch(li); - litest_assert_button_event(li, - BTN_MIDDLE, - LIBINPUT_BUTTON_STATE_RELEASED); - /* We only inject BTN_RIGHT down, so the second inject should - * get filtered */ - litest_assert_empty_queue(li); - } - } else { - litest_log_group("P2 tries to inject during frame, gets unloaded") { - litest_set_log_handler_bug(li); - litest_button_click_debounced(device, li, BTN_MIDDLE, 1); - litest_restore_log_handler(li); - litest_button_click_debounced(device, li, BTN_MIDDLE, 0); - litest_dispatch(li); - - litest_assert_button_event(li, - BTN_MIDDLE, - LIBINPUT_BUTTON_STATE_PRESSED); - litest_assert_button_event(li, - BTN_MIDDLE, - LIBINPUT_BUTTON_STATE_RELEASED); - } - - litest_log_group("P2 is unloaded, expect BTN_SIDE") { - litest_button_click_debounced(device, li, BTN_SIDE, 1); - litest_button_click_debounced(device, li, BTN_SIDE, 0); - litest_dispatch(li); - - litest_assert_button_event(li, - BTN_SIDE, - LIBINPUT_BUTTON_STATE_PRESSED); - litest_assert_button_event(li, - BTN_SIDE, - LIBINPUT_BUTTON_STATE_RELEASED); - } - } -} -END_TEST - enum when { DEVICE_NEW, FIRST_FRAME, @@ -1268,10 +1110,6 @@ TEST_COLLECTION(lua) litest_add_parametrized_no_device(lua_append_prepend_frame, params); } - litest_with_parameters(params, "in_timer", 'b') { - litest_add_parametrized_no_device(lua_inject_frame, params); - } - litest_with_parameters(params, "when", 'I', 2, litest_named_i32(DEVICE_NEW), litest_named_i32(FIRST_FRAME)) {