summary refs log tree commit diff stats
path: root/rust/qmk-hid-com/src_c/src/keyboard
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--rust/qmk-hid-com/src_c/src/keyboard/keyboard.c135
-rw-r--r--rust/qmk-hid-com/src_c/src/keyboard/keyboard.h17
-rw-r--r--rust/qmk-hid-com/src_c/src/keyboard/virtual-keyboard-unstable-v1-client-protocol.h280
3 files changed, 432 insertions, 0 deletions
diff --git a/rust/qmk-hid-com/src_c/src/keyboard/keyboard.c b/rust/qmk-hid-com/src_c/src/keyboard/keyboard.c
new file mode 100644
index 0000000..4949085
--- /dev/null
+++ b/rust/qmk-hid-com/src_c/src/keyboard/keyboard.c
@@ -0,0 +1,135 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "virtual-keyboard-unstable-v1-client-protocol.h"
+
+#include "../error.h"
+#include "keyboard.h"
+
+
+static void handle_wl_event(void *data, struct wl_registry *registry,
+                            uint32_t name, const char *interface,
+                            uint32_t version);
+static void handle_wl_event_remove(void *data, struct wl_registry *registry,
+                                   uint32_t name);
+
+const struct wl_registry_listener registry_listener = {
+    .global = handle_wl_event,
+    .global_remove = handle_wl_event_remove,
+};
+
+struct qmk_unicode_type init_qmk_unicode() {
+  struct qmk_unicode_type qmk_unicode_type;
+
+  memset(&qmk_unicode_type, 0, sizeof(qmk_unicode_type));
+  qmk_unicode_type.display = wl_display_connect(NULL);
+
+  if (qmk_unicode_type.display == NULL) {
+    fail("Wayland connection failed");
+  }
+
+  qmk_unicode_type.registry = wl_display_get_registry(qmk_unicode_type.display);
+
+  wl_registry_add_listener(qmk_unicode_type.registry, &registry_listener,
+                           &qmk_unicode_type);
+  wl_display_dispatch(qmk_unicode_type.display);
+  wl_display_roundtrip(qmk_unicode_type.display);
+
+  if (qmk_unicode_type.manager == NULL) {
+    fail("Compositor does not support the virtual keyboard protocol");
+  }
+  if (qmk_unicode_type.seat == NULL) {
+    fail("No seat found");
+  }
+
+  qmk_unicode_type.keyboard =
+      zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(
+          qmk_unicode_type.manager, qmk_unicode_type.seat);
+
+  return qmk_unicode_type;
+}
+void destroy_qmk_unicode(struct qmk_unicode_type qmk_unicode_type) {
+  zwp_virtual_keyboard_v1_destroy(qmk_unicode_type.keyboard);
+  zwp_virtual_keyboard_manager_v1_destroy(qmk_unicode_type.manager);
+  wl_registry_destroy(qmk_unicode_type.registry);
+  wl_display_disconnect(qmk_unicode_type.display);
+}
+
+static void upload_keymap(struct qmk_unicode_type *qmk_unicode_type,
+                          uint32_t key_code);
+
+void type_keycode(struct qmk_unicode_type *qmk_unicode_type,
+                  uint32_t key_code) {
+  upload_keymap(qmk_unicode_type, key_code);
+
+  zwp_virtual_keyboard_v1_key(qmk_unicode_type->keyboard, 0, 1,
+                              WL_KEYBOARD_KEY_STATE_PRESSED);
+  wl_display_roundtrip(qmk_unicode_type->display);
+  usleep(2000);
+  zwp_virtual_keyboard_v1_key(qmk_unicode_type->keyboard, 0, 1,
+                              WL_KEYBOARD_KEY_STATE_RELEASED);
+  wl_display_roundtrip(qmk_unicode_type->display);
+  usleep(2000);
+}
+
+static void handle_wl_event(void *data, struct wl_registry *registry,
+                            uint32_t name, const char *interface,
+                            uint32_t version) {
+  struct qmk_unicode_type *qmk_unicode_type = (struct qmk_unicode_type *)data;
+
+  if (!strcmp(interface, wl_seat_interface.name)) {
+    qmk_unicode_type->seat = (struct wl_seat *)wl_registry_bind(
+        registry, name, &wl_seat_interface, version <= 7 ? version : 7);
+  } else if (!strcmp(interface,
+                     zwp_virtual_keyboard_manager_v1_interface.name)) {
+    qmk_unicode_type->manager =
+        (struct zwp_virtual_keyboard_manager_v1 *)wl_registry_bind(
+            registry, name, &zwp_virtual_keyboard_manager_v1_interface, 1);
+  }
+}
+
+static void
+handle_wl_event_remove(__attribute__((unused)) void *data,
+                       __attribute__((unused)) struct wl_registry *_registry,
+                       __attribute__((unused)) uint32_t _name) {}
+
+static void upload_keymap(struct qmk_unicode_type *qmk_unicode_type,
+                          uint32_t key_code) {
+  char filename[] = "/tmp/qmk_unicode_type-XXXXXX";
+  int fd = mkstemp(filename);
+  if (fd < 0) {
+    fail("Failed to create the temporary keymap file");
+  }
+  unlink(filename);
+  FILE *f = fdopen(fd, "w");
+
+  fprintf(f,
+          "xkb_keymap {\n"
+          "  xkb_keycodes \"(unnamed)\" {\n"
+          "      minimum = 8;\n"
+          "      maximum = 10;\n"
+          "      <K1> = 9;\n"
+          "  };\n"
+          // TODO: Is including "complete" here really a good idea?
+          "  xkb_types \"(unnamed)\" { include \"complete\" };\n"
+          "  xkb_compatibility \"(unnamed)\" { include \"complete\" };\n"
+          "  xkb_symbols \"(unnamed)\" {\n"
+          "      key <K1> {[U%X]};\n"
+          "  };\n"
+          "};\n",
+          key_code);
+
+  fputc('\0', f);
+  fflush(f);
+
+  uint32_t keymap_size = (uint32_t)ftell(f);
+  zwp_virtual_keyboard_v1_keymap(qmk_unicode_type->keyboard,
+                                 WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, fileno(f),
+                                 keymap_size);
+
+  wl_display_roundtrip(qmk_unicode_type->display);
+  fclose(f);
+}
diff --git a/rust/qmk-hid-com/src_c/src/keyboard/keyboard.h b/rust/qmk-hid-com/src_c/src/keyboard/keyboard.h
new file mode 100644
index 0000000..ac5d7bd
--- /dev/null
+++ b/rust/qmk-hid-com/src_c/src/keyboard/keyboard.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <stdint.h>
+
+struct qmk_unicode_type init_qmk_unicode();
+void destroy_qmk_unicode(struct qmk_unicode_type qmk_unicode_type);
+
+void type_keycode(struct qmk_unicode_type *qmk_unicode_type, uint32_t key_code);
+
+// Private
+struct qmk_unicode_type {
+  struct wl_display *display;
+  struct wl_registry *registry;
+  struct wl_seat *seat;
+  struct zwp_virtual_keyboard_manager_v1 *manager;
+  struct zwp_virtual_keyboard_v1 *keyboard;
+};
diff --git a/rust/qmk-hid-com/src_c/src/keyboard/virtual-keyboard-unstable-v1-client-protocol.h b/rust/qmk-hid-com/src_c/src/keyboard/virtual-keyboard-unstable-v1-client-protocol.h
new file mode 100644
index 0000000..81cac0b
--- /dev/null
+++ b/rust/qmk-hid-com/src_c/src/keyboard/virtual-keyboard-unstable-v1-client-protocol.h
@@ -0,0 +1,280 @@
+/* Generated by wayland-scanner 1.23.1 */
+
+#ifndef VIRTUAL_KEYBOARD_UNSTABLE_V1_CLIENT_PROTOCOL_H
+#define VIRTUAL_KEYBOARD_UNSTABLE_V1_CLIENT_PROTOCOL_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-client.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @page page_virtual_keyboard_unstable_v1 The virtual_keyboard_unstable_v1 protocol
+ * @section page_ifaces_virtual_keyboard_unstable_v1 Interfaces
+ * - @subpage page_iface_zwp_virtual_keyboard_v1 - virtual keyboard
+ * - @subpage page_iface_zwp_virtual_keyboard_manager_v1 - virtual keyboard manager
+ * @section page_copyright_virtual_keyboard_unstable_v1 Copyright
+ * <pre>
+ *
+ * Copyright © 2008-2011  Kristian Høgsberg
+ * Copyright © 2010-2013  Intel Corporation
+ * Copyright © 2012-2013  Collabora, Ltd.
+ * Copyright © 2018       Purism SPC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * </pre>
+ */
+struct wl_seat;
+struct zwp_virtual_keyboard_manager_v1;
+struct zwp_virtual_keyboard_v1;
+
+#ifndef ZWP_VIRTUAL_KEYBOARD_V1_INTERFACE
+#define ZWP_VIRTUAL_KEYBOARD_V1_INTERFACE
+/**
+ * @page page_iface_zwp_virtual_keyboard_v1 zwp_virtual_keyboard_v1
+ * @section page_iface_zwp_virtual_keyboard_v1_desc Description
+ *
+ * The virtual keyboard provides an application with requests which emulate
+ * the behaviour of a physical keyboard.
+ *
+ * This interface can be used by clients on its own to provide raw input
+ * events, or it can accompany the input method protocol.
+ * @section page_iface_zwp_virtual_keyboard_v1_api API
+ * See @ref iface_zwp_virtual_keyboard_v1.
+ */
+/**
+ * @defgroup iface_zwp_virtual_keyboard_v1 The zwp_virtual_keyboard_v1 interface
+ *
+ * The virtual keyboard provides an application with requests which emulate
+ * the behaviour of a physical keyboard.
+ *
+ * This interface can be used by clients on its own to provide raw input
+ * events, or it can accompany the input method protocol.
+ */
+extern const struct wl_interface zwp_virtual_keyboard_v1_interface;
+#endif
+#ifndef ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_INTERFACE
+#define ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_INTERFACE
+/**
+ * @page page_iface_zwp_virtual_keyboard_manager_v1 zwp_virtual_keyboard_manager_v1
+ * @section page_iface_zwp_virtual_keyboard_manager_v1_desc Description
+ *
+ * A virtual keyboard manager allows an application to provide keyboard
+ * input events as if they came from a physical keyboard.
+ * @section page_iface_zwp_virtual_keyboard_manager_v1_api API
+ * See @ref iface_zwp_virtual_keyboard_manager_v1.
+ */
+/**
+ * @defgroup iface_zwp_virtual_keyboard_manager_v1 The zwp_virtual_keyboard_manager_v1 interface
+ *
+ * A virtual keyboard manager allows an application to provide keyboard
+ * input events as if they came from a physical keyboard.
+ */
+extern const struct wl_interface zwp_virtual_keyboard_manager_v1_interface;
+#endif
+
+#ifndef ZWP_VIRTUAL_KEYBOARD_V1_ERROR_ENUM
+#define ZWP_VIRTUAL_KEYBOARD_V1_ERROR_ENUM
+enum zwp_virtual_keyboard_v1_error {
+	/**
+	 * No keymap was set
+	 */
+	ZWP_VIRTUAL_KEYBOARD_V1_ERROR_NO_KEYMAP = 0,
+};
+#endif /* ZWP_VIRTUAL_KEYBOARD_V1_ERROR_ENUM */
+
+#define ZWP_VIRTUAL_KEYBOARD_V1_KEYMAP 0
+#define ZWP_VIRTUAL_KEYBOARD_V1_KEY 1
+#define ZWP_VIRTUAL_KEYBOARD_V1_MODIFIERS 2
+#define ZWP_VIRTUAL_KEYBOARD_V1_DESTROY 3
+
+
+/**
+ * @ingroup iface_zwp_virtual_keyboard_v1
+ */
+#define ZWP_VIRTUAL_KEYBOARD_V1_KEYMAP_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_virtual_keyboard_v1
+ */
+#define ZWP_VIRTUAL_KEYBOARD_V1_KEY_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_virtual_keyboard_v1
+ */
+#define ZWP_VIRTUAL_KEYBOARD_V1_MODIFIERS_SINCE_VERSION 1
+/**
+ * @ingroup iface_zwp_virtual_keyboard_v1
+ */
+#define ZWP_VIRTUAL_KEYBOARD_V1_DESTROY_SINCE_VERSION 1
+
+/** @ingroup iface_zwp_virtual_keyboard_v1 */
+static inline void
+zwp_virtual_keyboard_v1_set_user_data(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, void *user_data)
+{
+	wl_proxy_set_user_data((struct wl_proxy *) zwp_virtual_keyboard_v1, user_data);
+}
+
+/** @ingroup iface_zwp_virtual_keyboard_v1 */
+static inline void *
+zwp_virtual_keyboard_v1_get_user_data(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1)
+{
+	return wl_proxy_get_user_data((struct wl_proxy *) zwp_virtual_keyboard_v1);
+}
+
+static inline uint32_t
+zwp_virtual_keyboard_v1_get_version(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1)
+{
+	return wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1);
+}
+
+/**
+ * @ingroup iface_zwp_virtual_keyboard_v1
+ *
+ * Provide a file descriptor to the compositor which can be
+ * memory-mapped to provide a keyboard mapping description.
+ *
+ * Format carries a value from the keymap_format enumeration.
+ */
+static inline void
+zwp_virtual_keyboard_v1_keymap(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, uint32_t format, int32_t fd, uint32_t size)
+{
+	wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_v1,
+			 ZWP_VIRTUAL_KEYBOARD_V1_KEYMAP, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1), 0, format, fd, size);
+}
+
+/**
+ * @ingroup iface_zwp_virtual_keyboard_v1
+ *
+ * A key was pressed or released.
+ * The time argument is a timestamp with millisecond granularity, with an
+ * undefined base. All requests regarding a single object must share the
+ * same clock.
+ *
+ * Keymap must be set before issuing this request.
+ *
+ * State carries a value from the key_state enumeration.
+ */
+static inline void
+zwp_virtual_keyboard_v1_key(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, uint32_t time, uint32_t key, uint32_t state)
+{
+	wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_v1,
+			 ZWP_VIRTUAL_KEYBOARD_V1_KEY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1), 0, time, key, state);
+}
+
+/**
+ * @ingroup iface_zwp_virtual_keyboard_v1
+ *
+ * Notifies the compositor that the modifier and/or group state has
+ * changed, and it should update state.
+ *
+ * The client should use wl_keyboard.modifiers event to synchronize its
+ * internal state with seat state.
+ *
+ * Keymap must be set before issuing this request.
+ */
+static inline void
+zwp_virtual_keyboard_v1_modifiers(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group)
+{
+	wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_v1,
+			 ZWP_VIRTUAL_KEYBOARD_V1_MODIFIERS, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1), 0, mods_depressed, mods_latched, mods_locked, group);
+}
+
+/**
+ * @ingroup iface_zwp_virtual_keyboard_v1
+ */
+static inline void
+zwp_virtual_keyboard_v1_destroy(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1)
+{
+	wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_v1,
+			 ZWP_VIRTUAL_KEYBOARD_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1), WL_MARSHAL_FLAG_DESTROY);
+}
+
+#ifndef ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_ERROR_ENUM
+#define ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_ERROR_ENUM
+enum zwp_virtual_keyboard_manager_v1_error {
+	/**
+	 * client not authorized to use the interface
+	 */
+	ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_ERROR_UNAUTHORIZED = 0,
+};
+#endif /* ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_ERROR_ENUM */
+
+#define ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_CREATE_VIRTUAL_KEYBOARD 0
+
+
+/**
+ * @ingroup iface_zwp_virtual_keyboard_manager_v1
+ */
+#define ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_CREATE_VIRTUAL_KEYBOARD_SINCE_VERSION 1
+
+/** @ingroup iface_zwp_virtual_keyboard_manager_v1 */
+static inline void
+zwp_virtual_keyboard_manager_v1_set_user_data(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1, void *user_data)
+{
+	wl_proxy_set_user_data((struct wl_proxy *) zwp_virtual_keyboard_manager_v1, user_data);
+}
+
+/** @ingroup iface_zwp_virtual_keyboard_manager_v1 */
+static inline void *
+zwp_virtual_keyboard_manager_v1_get_user_data(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1)
+{
+	return wl_proxy_get_user_data((struct wl_proxy *) zwp_virtual_keyboard_manager_v1);
+}
+
+static inline uint32_t
+zwp_virtual_keyboard_manager_v1_get_version(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1)
+{
+	return wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_manager_v1);
+}
+
+/** @ingroup iface_zwp_virtual_keyboard_manager_v1 */
+static inline void
+zwp_virtual_keyboard_manager_v1_destroy(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1)
+{
+	wl_proxy_destroy((struct wl_proxy *) zwp_virtual_keyboard_manager_v1);
+}
+
+/**
+ * @ingroup iface_zwp_virtual_keyboard_manager_v1
+ *
+ * Creates a new virtual keyboard associated to a seat.
+ *
+ * If the compositor enables a keyboard to perform arbitrary actions, it
+ * should present an error when an untrusted client requests a new
+ * keyboard.
+ */
+static inline struct zwp_virtual_keyboard_v1 *
+zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1, struct wl_seat *seat)
+{
+	struct wl_proxy *id;
+
+	id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_manager_v1,
+			 ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_CREATE_VIRTUAL_KEYBOARD, &zwp_virtual_keyboard_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_manager_v1), 0, seat, NULL);
+
+	return (struct zwp_virtual_keyboard_v1 *) id;
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif