diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c06e6d87..4aa00fd82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,13 @@ * convey tui/tpack state in resize events * target\_anchorhint added for informing clients about positioning and hierarchy * video\_displaymode expose eotf / coordinates for primaries and contents light levels + * open\_nonblock can now adopt an existing iostream into a target vid + * input\_remap\_translation overloaded form for serializing backing keymap ## Core * respect border attribute in text rasteriser * added frame\_id to external events that pairs with shmif-SIGVID signals + * optional tracy build for profiling (-DENABLE\_TRACY) ## Tui * nbio asynch type confusion fix (function becomes pcall:userdata) diff --git a/doc/input_remap_translation.lua b/doc/input_remap_translation.lua index 1bbf59f3c..ecca45769 100644 --- a/doc/input_remap_translation.lua +++ b/doc/input_remap_translation.lua @@ -1,7 +1,8 @@ -- input_remap_translation -- @short: Reset or modify platform level keyboard translation -- @inargs: number:devid, number:action, string:arg_1, ... --- @outargs: bool:ok, string:reason +-- @inargs: number:devid, number:action, bool:extract, string:arg_1, ... +-- @outargs: bool:ok, string:reason or nbiotbl -- @longdescr: For some low level platforms it makes sense modifying input -- translation before the inputs are processed and forwarded onwards and forego -- patchin in the scripting layer. The main case where this has caused problems @@ -17,12 +18,19 @@ -- The *action* can be one out of: -- TRANSLATION_CLEAR, TRANSLATION_SET and TRANSLATION_REMAP. -- TRANSLATION_CLEAR is to revert as close to as the initial state as possible. --- TRANSLATION_MAP is to set/override a complete map. +-- TRANSLATION_SET is to set/override a complete map. -- TRANSLATION_REMAP is to add a specific remapping. -- -- The set of string arguments following the action will be raw-forwarded to -- the input platform and is thus platform dependent. -- +-- It is also possible to get a readable representation of the platform input +-- map through the *extract* parameter form. With TRANSLATION_SET this will +-- just give you the map based on the spec as an iostream (see +-- ref:open_nonblock). With TRANSLATION_REMAP this will instead provide the +-- current active map. No local modifications will be made with the *extract* +-- form. +-- -- The constant API_ENGINE_BUILD can be used to obtain which input platform -- is currently in use, which mutates the interpretation and effect of the -- various actions. diff --git a/doc/open_nonblock.lua b/doc/open_nonblock.lua index 2e2b53ca0..a03ad4eb8 100644 --- a/doc/open_nonblock.lua +++ b/doc/open_nonblock.lua @@ -1,24 +1,32 @@ -- open_nonblock -- @short: Open a file in read or write mode for non-blocking I/O. --- @inargs: string:res --- @inargs: string:res, bool:write -- @inargs: vid:res -- @inargs: vid:res, bool:write -- @inargs: vid:res, bool:write, string:identifier=stream +-- @inargs: vid:res, bool:write, string:identifier=stream, blocktbl +-- @inargs: string:res +-- @inargs: string:res, bool:write -- @outargs: blocktbl -- @longdescr: Create or open the resource indicated by *res* in (default) -- read-mode or (if *mode* is provided, write mode) --- If *res* is a vid connected to a frameserver, a streaming fifo session will --- be set up over the connection along with the corresponding _BCHUNK events. +-- +-- If *res* is a vid connected to a frameserver, either a streaming fifo +-- session will be set up over the connection along with the corresponding +-- _BCHUNK events or an pre-existing nonblock-io stream will be redirected to +-- said client and the backing descriptor closed locally. +-- -- The *identifier* argument can then be used to specify some client announced -- type identifier, or one of the reserved "stdin", "stdout", "stderr". +-- -- If *res* is a string, the initial character determines if it creates a -- FIFO (<) or a SOCKET (=). Unless a namespace is explicitly set and the -- namespace is marked as valid for IPC, FIFOs and SOCKETs will be created -- in the RESOURCE_APPL_TEMP namespace. +-- -- If the string starts with a valid namespace identifier and separator -- (alphanum:/) the identifier will first be matched to a user defined -- namespace (see ref:list_namespaces). +-- -- If successful, FIFOs and normal resources return a table wih a close -- operation (which is activated on garbage collection unless called in -- beforehand) and a read or write function depending on the mode that diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bc6d5c1db..7c98b9030 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -511,6 +511,18 @@ elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") message(FATAL_ERROR "${CL_RED}Unsupported OS(${CMAKE_SYSTEM_NAME}) detected, abandon ship!${CL_RST}") endif() +# XKB might be necessary to deal with nested clients of all platform types +# and near necessary for wayland and x11 clients. +pkg_check_modules(XKB QUIET xkbcommon) +if (XKB_FOUND) + amsg("${CL_YEL}xkb keyboard: \t${CL_GRN}libxkbcommon${CL_RST}") + list(APPEND ARCAN_DEFINITIONS HAVE_XKBCOMMON) + list(APPEND ARCAN_LIBRARIES ${XKB_LINK_LIBRARIES}) + list(APPEND INCLUDE_DIRS ${XKB_INCLUDE_DIRS}) +else() + amsg("${CL_YEL}xkb keyboard: \t${CL_RED}no libxkbcommon${CL_RST}") +endif() + if (CLIENT_LIBRARY_BUILD OR BUILD_PRESET STREQUAL "client") set(AGP_PLATFORM "stub") else() diff --git a/src/engine/alt/nbio.c b/src/engine/alt/nbio.c index 881e117b8..b39982832 100644 --- a/src/engine/alt/nbio.c +++ b/src/engine/alt/nbio.c @@ -865,26 +865,42 @@ static int opennonblock_tgt(lua_State* L, bool wr) if (vobj->feed.state.tag != ARCAN_TAG_FRAMESERV) arcan_fatal("open_nonblock(tgt), target must be a valid frameserver."); +/* overloaded form: + * open_nonblock(vid, r | w, type, nbio_ud) + * + * This takes an existing userdata, extracts the descriptor and sends to the + * target, while disassociating the descriptor from the argument source. + */ + const char* type = luaL_optstring(L, 3, "stream"); + struct arcan_event ev = { + .category = EVENT_TARGET, + .tgt.kind = wr ? TARGET_COMMAND_BCHUNK_IN : TARGET_COMMAND_BCHUNK_OUT + }; + snprintf(ev.tgt.message, COUNT_OF(ev.tgt.message), "%s", type); + if (lua_type(L, 4) == LUA_TUSERDATA){ + struct nonblock_io** ibb = luaL_checkudata(L, 4, "nonblockIO"); + struct nonblock_io* ib = *ibb; + + if (ib->fd > 0){ + platform_fsrv_pushfd(fsrv, &ev, ib->fd); + close(ib->fd); + ib->fd = -1; + } + + return 0; + } + +/* WRITE mode = 'INPUT' in the client space */ int outp[2]; if (-1 == pipe(outp)){ arcan_warning("open_nonblock(tgt), pipe-pair creation failed: %d\n", errno); return 0; } - - const char* type = luaL_optstring(L, 3, "stream"); - -/* WRITE mode = 'INPUT' in the client space */ int dst = wr ? outp[0] : outp[1]; int src = wr ? outp[1] : outp[0]; /* in any scenario where this would fail, "blocking" behavior is acceptable */ alt_nbio_nonblock_cloexec(src, true); - struct arcan_event ev = { - .category = EVENT_TARGET, - .tgt.kind = wr ? TARGET_COMMAND_BCHUNK_IN : TARGET_COMMAND_BCHUNK_OUT - }; - snprintf(ev.tgt.message, COUNT_OF(ev.tgt.message), "%s", type); - if (ARCAN_OK != platform_fsrv_pushfd(fsrv, &ev, dst)){ close(dst); close(src); diff --git a/src/engine/arcan_lua.c b/src/engine/arcan_lua.c index 0248cfb9d..17522d44c 100644 --- a/src/engine/arcan_lua.c +++ b/src/engine/arcan_lua.c @@ -6414,6 +6414,14 @@ static int inputremaptranslation(lua_State* ctx) LUA_TRACE("input_remap_translation") int devid = luaL_checknumber(ctx, 1); int act = luaL_checknumber(ctx, 2); + bool getmap = false; + int ofs = 2; + +/* set if we want an iostream to the current (remap) or a desired one */ + if (lua_type(ctx, 3) == LUA_TBOOLEAN || lua_type(ctx, 3) == LUA_TNUMBER){ + getmap = luaL_checkbnumber(ctx, 3); + ofs++; + } if ( act != EVENT_TRANSLATION_CLEAR && @@ -6423,14 +6431,30 @@ static int inputremaptranslation(lua_State* ctx) } int ttop = lua_gettop(ctx); - const char* arr[ttop-2]; - for (size_t i = 0; i < ttop - 2; i++){ - arr[i] = luaL_checkstring(ctx, i+3); + const char* arr[ttop]; + + if (ttop - ofs > 0){ + for (size_t i = 0; i < ttop - ofs; i++){ + arr[i] = luaL_checkstring(ctx, i+ofs+1); + } + arr[ttop-ofs] = NULL; } - arr[ttop-2] = NULL; const char* err = ""; - bool res = platform_event_translation(devid, act, arr, &err); + + if (getmap){ + int mode = EVENT_TRANSLATION_SERIALIZE_CURRENT; + if (act == EVENT_TRANSLATION_SET) + mode = EVENT_TRANSLATION_SERIALIZE_SPEC; + + int fd = platform_event_translation(devid, mode, arr, &err); + struct nonblock_io* dst; + alt_nbio_import(ctx, fd, mode, &dst, NULL); + lua_pushstring(ctx, err); + LUA_ETRACE("input_remap_translation", NULL, 2); + } + + int res = platform_event_translation(devid, act, arr, &err); lua_pushboolean(ctx, res); lua_pushstring(ctx, err); @@ -7275,8 +7299,7 @@ static int arcantargethint(lua_State* ctx) if (lua_type(ctx, tblind) != LUA_TTABLE) luaL_typerror(ctx, tblind, "expected argument table"); -/* LABELHINT (labelhint: label, initial, descr, vsym, subv) */ - if (strcmp(msg, "input_label") == 0){ + else if (strcmp(msg, "input_label") == 0){ struct arcan_event ev = { .category = EVENT_EXTERNAL, .ext = EVENT_EXTERNAL_LABELHINT, diff --git a/src/platform/arcan/video.c b/src/platform/arcan/video.c index 8fb7e87d6..e8b62c0fb 100644 --- a/src/platform/arcan/video.c +++ b/src/platform/arcan/video.c @@ -32,6 +32,7 @@ #include #include #include +#include extern jmp_buf arcanmain_recover_state; @@ -75,7 +76,6 @@ extern jmp_buf arcanmain_recover_state; #include "../egl-dri/egl_gbm_helper.h" static struct egl_env agp_eglenv; - #endif #ifdef _DEBUG @@ -84,6 +84,12 @@ static struct egl_env agp_eglenv; #define DEBUG 0 #endif +#ifdef HAVE_XKBCOMMON +#include +#include +#include +#endif + #define debug_print(fmt, ...) \ do { if (DEBUG) arcan_warning("%lld:%s:%d:%s(): " fmt "\n",\ arcan_timemillis(), "platform-arcan:", __LINE__, __func__,##__VA_ARGS__); } while (0) @@ -132,6 +138,7 @@ struct display { struct agp_vstore* vstore; float ppcm; int id; + map_region keymap; /* only used for first display */ uint8_t subseg_alloc; @@ -420,11 +427,92 @@ int platform_video_cardhandle(int cardn, int* method, size_t* msz, uint8_t** dbu return -1; } -bool platform_event_translation(int devid, +static char* names_to_keymap_str(const char** arg, const char** err) +{ +#ifdef HAVE_XKBCOMMON +/* setup / fill out pref. */ + struct xkb_context* xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + struct xkb_rule_names names = {0}; + names.layout = arg[0]; + if (names.layout) + names.model = arg[1]; + if (names.model) + names.variant = arg[2]; + if (names.variant) + names.options = arg[3]; + +/* compile / convert */ + struct xkb_keymap* kmap = + xkb_keymap_new_from_names(xkb_context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!kmap){ + *err = "couldn't compile map"; + xkb_context_unref(xkb_context); + return NULL; + } + char* map = xkb_map_get_as_string(kmap); + if (!map){ + *err = "export failed"; + xkb_keymap_unref(kmap); + xkb_context_unref(xkb_context); + return NULL; + } + +/* export / cleanup */ + char* res = strdup(map); + if (!res){ + *err = "map copy failed"; + } + else + *err = ""; + + xkb_keymap_unref(kmap); + xkb_context_unref(xkb_context); + return res; +#else + *err = "no xkb support"; + return NULL; +#endif +} + +int platform_event_translation(int devid, int action, const char** names, const char** err) { +/* + * The serialize and remap can have meaning here as we might have native + * wayland / x11 clients that need the map client side and we are running + * inside another arcan that has it. + * + * If we get a BCHUNK event with 'xkb' type, the shared / cached 'current' + * is forwarded, and if not we build and set according to the shared helper + */ + if ((devid == -1 || devid == 0) && disp[0].keymap.ptr){ + switch (action){ + case EVENT_TRANSLATION_SET:{ + char* newmap = names_to_keymap_str(names, err); + if (!newmap){ + return -1; + } + arcan_release_map(disp[0].keymap); + disp[0].keymap.ptr = newmap; + disp[0].keymap.sz = strlen(newmap); + return 0; + } + break; + case EVENT_TRANSLATION_SERIALIZE_SPEC:{ + char* newmap = names_to_keymap_str(names, err); + int fd = arcan_strbuf_tempfile(newmap, strlen(newmap), err); + free(newmap); + return fd; + } + case EVENT_TRANSLATION_SERIALIZE_CURRENT:{ + return arcan_strbuf_tempfile(disp[0].keymap.ptr, disp[0].keymap.sz, err); + } + break; + } + } + *err = "Not Supported"; - return false; + return -1; } int platform_event_device_request(int space, const char* path) @@ -1193,7 +1281,7 @@ static bool scan_subseg(arcan_tgtevent* ev, bool ok) * return true if the segment has expired */ extern struct arcan_luactx* main_lua_context; -static bool event_process_disp(arcan_evctx* ctx, struct display* d, size_t i) +static bool event_process_disp(arcan_evctx* ctx, struct display* d, size_t did) { if (!d->conn.addr) return true; @@ -1367,8 +1455,18 @@ static bool event_process_disp(arcan_evctx* ctx, struct display* d, size_t i) return true; /* it's not safe here */ break; + case TARGET_COMMAND_BCHUNK_IN: + if (strcmp(ev.tgt.message, "xkb") == 0){ + data_source ds = {.fd = ev.tgt.ioevs[0].iv}; + arcan_release_map(d->keymap); +/* setting to write means that the fd won't be cached and the whole resource + * will be read in one go and copied, so no need to dup and keep a fd */ + d->keymap = arcan_map_resource(&ds, true); + } + +/* fallthrough to default is intended */ default: - if (i == 0){ + if (did == 0){ arcan_lwa_subseg_ev(main_lua_context, ARCAN_VIDEO_WORLDID, 0, &ev); } break; diff --git a/src/platform/cmake/CMakeLists.BSD b/src/platform/cmake/CMakeLists.BSD index d59a7167a..b839efc11 100644 --- a/src/platform/cmake/CMakeLists.BSD +++ b/src/platform/cmake/CMakeLists.BSD @@ -44,6 +44,7 @@ list(APPEND ARCAN_PLATFORM ${PLATFORM_PATH}/launch.c ${PLATFORM_PATH}/config.c ${PLATFORM_PATH}/random.c + ${PLATFORM_PATH}/tempfile.c ${PLATFORM_PATH}/prodthrd.c ) set(LWA_PLATFORM ${ARCAN_PLATFORM}) diff --git a/src/platform/cmake/CMakeLists.Darwin b/src/platform/cmake/CMakeLists.Darwin index e84bb175f..d5d9ab5f0 100644 --- a/src/platform/cmake/CMakeLists.Darwin +++ b/src/platform/cmake/CMakeLists.Darwin @@ -102,6 +102,7 @@ set(ARCAN_PLATFORM ${PLATFORM_PATH}/launch.c ${PLATFORM_PATH}/config.c ${PLATFORM_PATH}/random.c + ${PLATFORM_PATH}/tempfile.c ${PLATFORM_PATH}/fsrv_guard.c ) diff --git a/src/platform/cmake/CMakeLists.Linux b/src/platform/cmake/CMakeLists.Linux index 9be1e239e..aadf92998 100644 --- a/src/platform/cmake/CMakeLists.Linux +++ b/src/platform/cmake/CMakeLists.Linux @@ -69,6 +69,7 @@ set(ARCAN_PLATFORM ${PLATFORM_PATH}/launch.c ${PLATFORM_PATH}/config.c ${PLATFORM_PATH}/random.c + ${PLATFORM_PATH}/tempfile.c ${PLATFORM_PATH}/../stub/setproctitle.c ${PLATFORM_PATH}/prodthrd.c ) diff --git a/src/platform/cmake/CMakeLists.Video b/src/platform/cmake/CMakeLists.Video index 084747b2a..39882aa71 100644 --- a/src/platform/cmake/CMakeLists.Video +++ b/src/platform/cmake/CMakeLists.Video @@ -147,16 +147,3 @@ if (NOT ENABLE_LWA) set(LWA_PLATFORM_STR "stub") endif() -if (INPUT_PLATFORM STREQUAL "evdev") - pkg_check_modules(XKB QUIET xkbcommon) - if (XKB_FOUND) - amsg("${CL_YEL}evdev \t${CL_GRN}libxkbcommon${CL_RST}") - set_property(SOURCE ${PLATFORM_ROOT}/evdev/event.c APPEND PROPERTY - COMPILE_DEFINITIONS HAVE_XKBCOMMON) - list(APPEND VIDEO_LIBRARIES ${XKB_LINK_LIBRARIES}) - list(APPEND INCLUDE_DIRS ${XKB_INCLUDE_DIRS}) - else() - amsg("${CL_YEL}evdev \t${CL_RED}no libxkbcommon${CL_RST}") - endif() -endif() - diff --git a/src/platform/evdev/event.c b/src/platform/evdev/event.c index 53b5297cd..54852c55a 100644 --- a/src/platform/evdev/event.c +++ b/src/platform/evdev/event.c @@ -33,18 +33,15 @@ #include "arcan_videoint.h" #include "keycode_xlate.h" -#ifndef __FreeBSD__ -#include -#endif - #ifdef HAVE_XKBCOMMON +static struct xkb_context* xkb_context; #include #include #include -/* - * shared between all event queues - */ -static struct xkb_context* xkb_context; +#endif + +#ifndef __FreeBSD__ +#include #endif #ifdef _DEBUG @@ -1017,6 +1014,23 @@ static void setup_led(struct devnode* dst, size_t bitn, int fd) } } +static int xkb_layout_to_fd(struct xkb_keymap* layout, const char** err) +{ + if (!layout){ + *err = "no active map"; + return -1; + } + + char* map = xkb_map_get_as_string(layout); + if (!map){ + *err = "serialization request rejected"; + return -1; + } + + int fd = arcan_strbuf_tempfile(map, strlen(map) + 1, err); + return fd; +} + static int alloc_node_slot(const char* path) { /* pre-existing? close old node and replace with this one, happens @@ -1095,7 +1109,8 @@ static void send_device_added(struct arcan_evctx* ctx, struct devnode* node) arcan_event_enqueue(ctx, &addev); } -bool platform_event_translation( + +int platform_event_translation( int devid, int action, const char** arg, const char** err) { struct devnode* node = NULL; @@ -1160,7 +1175,8 @@ bool platform_event_translation( names.layout = layout ? options : getenv("XKB_DEFAULT_LAYOUT"); } /* just fill struct from arg */ - else if (action == EVENT_TRANSLATION_SET){ + else if (action == EVENT_TRANSLATION_SET || + action == EVENT_TRANSLATION_SERIALIZE_SPEC){ names.layout = arg[0]; if (names.layout) names.model = arg[1]; @@ -1169,11 +1185,25 @@ bool platform_event_translation( if (names.variant) names.options = arg[3]; } + else if (action == EVENT_TRANSLATION_SERIALIZE_CURRENT){ + return xkb_layout_to_fd(node->keyboard.xkb_layout, err); + } else { *err = "Unsupported action"; return false; } +/* build the map and depending on if we should serialize or not, create a tmp + * file, write the string to it, seek back and return the descriptor */ + struct xkb_keymap* map = + xkb_keymap_new_from_names(xkb_context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS); + + if (action == EVENT_TRANSLATION_SERIALIZE_SPEC){ + int fd = xkb_layout_to_fd(map, err); + xkb_keymap_unref(map); + return fd; + } + if (node->keyboard.xkb_layout){ if (node->keyboard.xkb_state) xkb_state_unref(node->keyboard.xkb_state); @@ -1182,14 +1212,13 @@ bool platform_event_translation( node->keyboard.xkb_layout = NULL; } + node->keyboard.xkb_layout = map; + /* Disable xkb translation entirely */ if (!names.rules && !names.model && !names.variant && !names.options && !names.layout) return false; - node->keyboard.xkb_layout = - xkb_keymap_new_from_names(xkb_context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS); - if (node->keyboard.xkb_layout) node->keyboard.xkb_state = xkb_state_new(node->keyboard.xkb_layout); diff --git a/src/platform/event_platform.h b/src/platform/event_platform.h index 0985d2639..45d664456 100644 --- a/src/platform/event_platform.h +++ b/src/platform/event_platform.h @@ -97,14 +97,31 @@ enum translation_actions { * Revert to config or environment default. */ EVENT_TRANSLATION_CLEAR = 0, + /* * Apply a preset (e.g. "sv") */ EVENT_TRANSLATION_SET = 1, + /* * Apply a custom remap (e.g. code+mods=ucs4) */ - EVENT_TRANSLATION_REMAP = 2 + EVENT_TRANSLATION_REMAP = 2, + +/* + * Extract the current device map into some custom format for inspection + * or serializing to a system with the same translation language. + * + * Returns a fd or -1. + */ + EVENT_TRANSLATION_SERIALIZE_CURRENT = 3, + +/* + * Like serialize_current but on a presentation like _SET. + * + * Returns a fd or -1. + */ + EVENT_TRANSLATION_SERIALIZE_SPEC = 4 }; /* @@ -117,7 +134,7 @@ enum translation_actions { * Returns false of ailure and sets *errmsg to a user presentable string * indicating the cause. */ -bool platform_event_translation( +int platform_event_translation( int devid, int action, const char** names, const char** errmsg); /* diff --git a/src/platform/headless/event.c b/src/platform/headless/event.c index 4f1158852..0a661c436 100644 --- a/src/platform/headless/event.c +++ b/src/platform/headless/event.c @@ -43,7 +43,7 @@ void platform_event_analogfilter(int devid, { } -bool platform_event_translation( +int platform_event_translation( int devid, int action, const char** names, const char** err) { *err = "Unsupported"; diff --git a/src/platform/os_platform.h b/src/platform/os_platform.h index 2eae92c5c..28fd940bc 100644 --- a/src/platform/os_platform.h +++ b/src/platform/os_platform.h @@ -289,7 +289,6 @@ void arcan_override_namespace(const char* path, enum arcan_namespaces space); */ void arcan_softoverride_namespace(const char* newp, enum arcan_namespaces space); - /* * implemented in /namespace.c, * prevent the specific slot from being overridden with either soft/hard @@ -298,6 +297,12 @@ void arcan_softoverride_namespace(const char* newp, enum arcan_namespaces space) */ void arcan_pin_namespace(enum arcan_namespaces space); +/* + * implemented in /tempfile.c, + * take a buffer, write into a temporary file, unlink and return the descriptor + */ +int arcan_strbuf_tempfile(const char* msg, size_t msg_sz, const char** err); + /* * implemented in /appl.c * ensure a sane setup (all namespaces have mapped paths + proper permissions) diff --git a/src/platform/sdl/event.c b/src/platform/sdl/event.c index 1fc466901..b6c8ebc79 100644 --- a/src/platform/sdl/event.c +++ b/src/platform/sdl/event.c @@ -611,7 +611,7 @@ static unsigned gen_devid(unsigned hid) return hid; } -bool platform_event_translation( +int platform_event_translation( int devid, int action, const char** names, const char** err) { *err = "Unsupported"; diff --git a/src/platform/sdl2/event.c b/src/platform/sdl2/event.c index 9ff3997bf..682620137 100644 --- a/src/platform/sdl2/event.c +++ b/src/platform/sdl2/event.c @@ -216,7 +216,7 @@ void platform_event_samplebase(int devid, float xyz[3]) */ } -bool platform_event_translation( +int platform_event_translation( int devid, int action, const char** names, const char** err) { *err = "Unsupported"; diff --git a/src/platform/stub/event.c b/src/platform/stub/event.c index 4a76b071b..a00139ca8 100644 --- a/src/platform/stub/event.c +++ b/src/platform/stub/event.c @@ -28,7 +28,7 @@ void platform_event_analogall(bool enable, bool mouse) { } -bool platform_event_translation( +int platform_event_translation( int devid, int action, const char** names, const char** err) { *err = "Unsupported"; diff --git a/src/platform/syscons/event.c b/src/platform/syscons/event.c index 052e41915..65bd390a1 100644 --- a/src/platform/syscons/event.c +++ b/src/platform/syscons/event.c @@ -251,7 +251,7 @@ static struct bsdkey decode_tok(char* tok) return res; } -bool platform_event_translation( +int platform_event_translation( int devid, int action, const char** names, const char** err) { *err = "Unsupported"; diff --git a/src/platform/wscons/event.c b/src/platform/wscons/event.c index 49918db6d..321ff3a2e 100644 --- a/src/platform/wscons/event.c +++ b/src/platform/wscons/event.c @@ -319,7 +319,7 @@ void platform_event_keyrepeat(arcan_evctx* ctx, int* period, int* delay) } } -bool platform_event_translation( +int platform_event_translation( int devid, int action, const char** names, const char** err) { *err = "Unsupported"; diff --git a/src/shmif/arcan_shmif_evpack.c b/src/shmif/arcan_shmif_evpack.c index f2416ee8c..988657610 100644 --- a/src/shmif/arcan_shmif_evpack.c +++ b/src/shmif/arcan_shmif_evpack.c @@ -212,8 +212,11 @@ const char* arcan_shmif_eventstr(arcan_event* aev, char* dbuf, size_t dsz) ev.ext.netstate.name ); break; + case EVENT_EXTERNAL_PRIVDROP: + snprintf(work, dsz,"EXT:PRIVDROP(level=%d)", (int)ev.tgt.ioevs[0].iv); + break; default: - snprintf(work, dsz,"EXT:UNKNOWN(!)"); + snprintf(work, dsz,"EXT:UNKNOWN(%d)", (int)ev.ext.kind); break; } }