summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Roper <matthew.d.roper@intel.com>2013-06-24 16:52:44 +0100
committerKristian Høgsberg <krh@bitplanet.net>2013-06-28 19:55:29 -0400
commit01a9273bd2c2e80f1a9efeeadd6a6484b8b7e57c (patch)
tree122f5428f32396e7173afd55fc15b6799ee5854d
parente61561fd9c75588735cd5b1784bbc0e0479d5105 (diff)
downloadweston-01a9273bd2c2e80f1a9efeeadd6a6484b8b7e57c.tar.gz
weston-01a9273bd2c2e80f1a9efeeadd6a6484b8b7e57c.tar.bz2
weston-01a9273bd2c2e80f1a9efeeadd6a6484b8b7e57c.zip
input: Add support for making libxkbcommon optional
In embedded environments, devices that appear as evdev "keyboards" often have no resemblence to PC-style keyboards. It is not uncommon for such environments to have no concept of modifier keys and no need for XKB key mapping; in these cases libxkbcommon initialization becomes unnecessary startup overhead. On some SOC platforms, xkb keymap compilation can account for as much as 1/3 - 1/2 of the total compositor startup time. This patch introduces a 'use_xkbcommon' flag in the core compositor structure that indicates whether the compositor is running in "raw keyboard" mode. In raw keyboard mode, the compositor bypasses all libxkbcommon initialization and processing. 'key' events containing the integer keycode will continue to be delivered via the wl_keyboard interface, but no 'keymap' event will be sent to clients. No modifier handling or keysym mapping is performed in this mode. Note that upstream sample apps (e.g., weston-terminal or the desktop-shell client) will not recognize raw keycodes and will not react to keypresses when the compositor is operating in raw keyboard mode. This is expected behavior; key events are still being sent to the client, the client (and/or its toolkit) just isn't written to handle keypresses without doing xkb keysym mapping. Applications written specifically for such embedded environments would be handling keypresses via the raw keycode delivered as part of the 'key' event rather than using xkb keysym mapping. Whether to use xkbcommon is a global option that applies to all compositor keyboard devices on the system; it is an all-or-nothing flag. This patch simply adds conditional checks on whether xkbcommon is to be used or not. v3 don't send zero as the file descriptor - instead send the result of opening /dev/null v2 by Rob Bradford <rob@linux.intel.com>: the original version of the patch used a "raw_keycodes" flag instead of the "use_xkbcommon" used in this patch. v1: Reviewed-by: Singh, Satyeshwar <satyeshwar.singh@intel.com> v1: Reviewed-by: Bob Paauwe <bob.j.paauwe@intel.com>
-rw-r--r--src/compositor.c1
-rw-r--r--src/compositor.h3
-rw-r--r--src/input.c74
3 files changed, 57 insertions, 21 deletions
diff --git a/src/compositor.c b/src/compositor.c
index 43d8965c..df9a5bf4 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2829,6 +2829,7 @@ weston_compositor_init(struct weston_compositor *ec,
weston_plane_init(&ec->primary_plane, 0, 0);
weston_compositor_stack_plane(ec, &ec->primary_plane, NULL);
+ ec->use_xkbcommon = 1;
s = weston_config_get_section(ec->config, "keyboard", NULL, NULL);
weston_config_section_get_string(s, "keymap_rules",
(char **) &xkb_names.rules, NULL);
diff --git a/src/compositor.h b/src/compositor.h
index 41919502..bd6344d6 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -578,6 +578,9 @@ struct weston_compositor {
struct xkb_rule_names xkb_names;
struct xkb_context *xkb_context;
struct weston_xkb_info xkb_info;
+
+ /* Raw keyboard processing (no libxkbcommon initialization or handling) */
+ int use_xkbcommon;
};
struct weston_buffer {
diff --git a/src/input.c b/src/input.c
index 1737beb0..a86bb7e5 100644
--- a/src/input.c
+++ b/src/input.c
@@ -26,6 +26,7 @@
#include <sys/mman.h>
#include <assert.h>
#include <unistd.h>
+#include <fcntl.h>
#include "../shared/os-compatibility.h"
#include "compositor.h"
@@ -817,6 +818,10 @@ update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
{
enum xkb_key_direction direction;
+ /* Keyboard modifiers don't exist in raw keyboard mode */
+ if (!seat->compositor->use_xkbcommon)
+ return;
+
if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
direction = XKB_KEY_DOWN;
else
@@ -1206,9 +1211,17 @@ seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
wl_list_insert(&seat->keyboard->resource_list, wl_resource_get_link(cr));
wl_resource_set_destructor(cr, unbind_resource);
- wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
- seat->xkb_info.keymap_fd,
- seat->xkb_info.keymap_size);
+ if (seat->compositor->use_xkbcommon) {
+ wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
+ seat->xkb_info.keymap_fd,
+ seat->xkb_info.keymap_size);
+ } else {
+ int null_fd = open("/dev/null", O_RDONLY);
+ wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP,
+ null_fd,
+ 0);
+ close(null_fd);
+ }
if (seat->keyboard->focus &&
wl_resource_get_client(seat->keyboard->focus->resource) == client) {
@@ -1267,6 +1280,13 @@ int
weston_compositor_xkb_init(struct weston_compositor *ec,
struct xkb_rule_names *names)
{
+ /*
+ * If we're operating in raw keyboard mode, libxkbcommon isn't used and
+ * shouldn't be initialized.
+ */
+ if (!ec->use_xkbcommon)
+ return 0;
+
if (ec->xkb_context == NULL) {
ec->xkb_context = xkb_context_new(0);
if (ec->xkb_context == NULL) {
@@ -1301,6 +1321,13 @@ static void xkb_info_destroy(struct weston_xkb_info *xkb_info)
void
weston_compositor_xkb_destroy(struct weston_compositor *ec)
{
+ /*
+ * If we're operating in raw keyboard mode, we never initialized
+ * libxkbcommon so there's no cleanup to do either.
+ */
+ if (!ec->use_xkbcommon)
+ return;
+
free((char *) ec->xkb_names.rules);
free((char *) ec->xkb_names.model);
free((char *) ec->xkb_names.layout);
@@ -1405,25 +1432,28 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
if (seat->keyboard)
return 0;
- if (keymap != NULL) {
- seat->xkb_info.keymap = xkb_map_ref(keymap);
- if (weston_xkb_info_new_keymap(&seat->xkb_info) < 0)
- return -1;
- } else {
- if (weston_compositor_build_global_keymap(seat->compositor) < 0)
+
+ if (seat->compositor->use_xkbcommon) {
+ if (keymap != NULL) {
+ seat->xkb_info.keymap = xkb_map_ref(keymap);
+ if (weston_xkb_info_new_keymap(&seat->xkb_info) < 0)
+ return -1;
+ } else {
+ if (weston_compositor_build_global_keymap(seat->compositor) < 0)
+ return -1;
+ seat->xkb_info = seat->compositor->xkb_info;
+ seat->xkb_info.keymap = xkb_map_ref(seat->xkb_info.keymap);
+ }
+
+ seat->xkb_state.state = xkb_state_new(seat->xkb_info.keymap);
+ if (seat->xkb_state.state == NULL) {
+ weston_log("failed to initialise XKB state\n");
return -1;
- seat->xkb_info = seat->compositor->xkb_info;
- seat->xkb_info.keymap = xkb_map_ref(seat->xkb_info.keymap);
- }
+ }
- seat->xkb_state.state = xkb_state_new(seat->xkb_info.keymap);
- if (seat->xkb_state.state == NULL) {
- weston_log("failed to initialise XKB state\n");
- return -1;
+ seat->xkb_state.leds = 0;
}
- seat->xkb_state.leds = 0;
-
keyboard = weston_keyboard_create();
if (keyboard == NULL) {
weston_log("failed to allocate weston keyboard struct\n");
@@ -1507,9 +1537,11 @@ weston_seat_release(struct weston_seat *seat)
wl_list_remove(&seat->link);
/* The global object is destroyed at wl_display_destroy() time. */
- if (seat->xkb_state.state != NULL)
- xkb_state_unref(seat->xkb_state.state);
- xkb_info_destroy(&seat->xkb_info);
+ if (seat->compositor->use_xkbcommon) {
+ if (seat->xkb_state.state != NULL)
+ xkb_state_unref(seat->xkb_state.state);
+ xkb_info_destroy(&seat->xkb_info);
+ }
if (seat->pointer)
weston_pointer_destroy(seat->pointer);