/* Private-display integration helper; stdin uses Linux evdev key codes. * Compile via dev/build-input-probe.sh inside the temporary tools shell. */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include "virtual-keyboard-client-protocol.h" static struct wl_seat *seat; static struct zwp_virtual_keyboard_manager_v1 *manager; static void global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) { (void)data; (void)version; if (!strcmp(interface,"wl_seat")) seat = wl_registry_bind(registry,id,&wl_seat_interface,1); else if (!strcmp(interface,"zwp_virtual_keyboard_manager_v1")) manager = wl_registry_bind(registry,id,&zwp_virtual_keyboard_manager_v1_interface,1); } static void removed(void *data,struct wl_registry *registry,uint32_t id) { (void)data; (void)registry; (void)id; } int main(void) { /* The caller supplies the separately created scratch Wayland runtime. */ assert(getenv("WAYLAND_DISPLAY") && getenv("XDG_RUNTIME_DIR")); struct wl_display *display = wl_display_connect(NULL); assert(display); struct wl_registry *registry = wl_display_get_registry(display); struct wl_registry_listener listener={global,removed}; wl_registry_add_listener(registry,&listener,NULL); wl_display_roundtrip(display); assert(seat && manager); struct zwp_virtual_keyboard_v1 *keyboard = zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(manager,seat); struct xkb_context *context=xkb_context_new(XKB_CONTEXT_NO_FLAGS); struct xkb_rule_names names={.rules="evdev",.model="pc105",.layout="us"}; struct xkb_keymap *map=xkb_keymap_new_from_names(context,&names,XKB_KEYMAP_COMPILE_NO_FLAGS); assert(map); struct xkb_state *state=xkb_state_new(map); assert(state); char *text=xkb_keymap_get_as_string(map,XKB_KEYMAP_FORMAT_TEXT_V1); size_t size=strlen(text)+1; int fd=memfd_create("hydra-private-keymap",0); assert(fd>=0); assert(write(fd,text,size)==(ssize_t)size); zwp_virtual_keyboard_v1_keymap(keyboard,WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,fd,size); wl_display_roundtrip(display); close(fd); free(text); char command[16]; unsigned key; unsigned tick=0; while (scanf("%15s %u",command,&key)==2) { if (!strcmp(command,"wait")) { usleep(key*1000); continue; } unsigned down=!strcmp(command,"down"); assert(down || !strcmp(command,"up")); xkb_state_update_key(state,key+8,down?XKB_KEY_DOWN:XKB_KEY_UP); zwp_virtual_keyboard_v1_key(keyboard,++tick,key,down); zwp_virtual_keyboard_v1_modifiers(keyboard, xkb_state_serialize_mods(state,XKB_STATE_MODS_DEPRESSED), xkb_state_serialize_mods(state,XKB_STATE_MODS_LATCHED), xkb_state_serialize_mods(state,XKB_STATE_MODS_LOCKED), xkb_state_serialize_layout(state,XKB_STATE_LAYOUT_EFFECTIVE)); assert(wl_display_roundtrip(display)>=0); } zwp_virtual_keyboard_v1_destroy(keyboard); wl_display_roundtrip(display); xkb_state_unref(state); xkb_keymap_unref(map); xkb_context_unref(context); wl_display_disconnect(display); return 0; }