From 1d007af3d00e1aaf9bb8f97bcf4c9f58f67e664f Mon Sep 17 00:00:00 2001 From: bjornstahl Date: Sun, 25 Jun 2023 14:49:17 +0200 Subject: [PATCH] (core/platform/lua) support keymap forward In order to deal with top-down and recursive handling of clients that are stuck with xkb forever (so x11 / wayland) it would help to not sideband the keymap in at the bridge level but rather get it through the engine so it would work network transparently. This patch adds xkb to all platforms (should it be desired and available) and adds the wiring to extract the current map or the spec of one from lua via input_remap_translation, and then pass it onward through open_nonblock(vid, ...). This match changes done to durden as well as to Xarcan, arcan-wayland bits missing still. --- CHANGELOG.md | 3 + doc/input_remap_translation.lua | 12 ++- doc/open_nonblock.lua | 16 +++- src/CMakeLists.txt | 12 +++ src/engine/alt/nbio.c | 36 ++++++--- src/engine/arcan_lua.c | 37 +++++++-- src/platform/arcan/video.c | 108 +++++++++++++++++++++++++-- src/platform/cmake/CMakeLists.BSD | 1 + src/platform/cmake/CMakeLists.Darwin | 1 + src/platform/cmake/CMakeLists.Linux | 1 + src/platform/cmake/CMakeLists.Video | 13 ---- src/platform/evdev/event.c | 55 ++++++++++---- src/platform/event_platform.h | 21 +++++- src/platform/headless/event.c | 2 +- src/platform/os_platform.h | 7 +- src/platform/sdl/event.c | 2 +- src/platform/sdl2/event.c | 2 +- src/platform/stub/event.c | 2 +- src/platform/syscons/event.c | 2 +- src/platform/wscons/event.c | 2 +- src/shmif/arcan_shmif_evpack.c | 5 +- 21 files changed, 276 insertions(+), 64 deletions(-) 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; } }