From 3dc9cfdbd2771c28c770d432b99e571db43fe599 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Tue, 5 May 2015 14:49:12 +0300 Subject: Don't crash if loading the keymap fails Instead throw a warning and keep using the old one. Change-Id: I1533b3930d4d8c884db922b0d6dd567ef7e4f67c Reviewed-by: Pier Luigi Fiorini --- src/compositor/wayland_wrapper/qwlkeyboard.cpp | 56 +++++++++++++++++--------- src/compositor/wayland_wrapper/qwlkeyboard_p.h | 1 + 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/compositor/wayland_wrapper/qwlkeyboard.cpp b/src/compositor/wayland_wrapper/qwlkeyboard.cpp index d80c4b1f..59b69a3c 100644 --- a/src/compositor/wayland_wrapper/qwlkeyboard.cpp +++ b/src/compositor/wayland_wrapper/qwlkeyboard.cpp @@ -72,6 +72,7 @@ Keyboard::Keyboard(Compositor *compositor, InputDevice *seat) , m_group() , m_pendingKeymap(false) #ifndef QT_NO_WAYLAND_XKB + , m_keymap_fd(-1) , m_state(0) #endif { @@ -337,42 +338,57 @@ void Keyboard::initXKB() createXKBKeymap(); } -void Keyboard::createXKBKeymap() +void Keyboard::createXKBState(xkb_keymap *keymap) { - if (!m_context) - return; - - if (m_state) - xkb_state_unref(m_state); - - struct xkb_rule_names rule_names = { strdup(qPrintable(m_keymap.rules())), - strdup(qPrintable(m_keymap.model())), - strdup(qPrintable(m_keymap.layout())), - strdup(qPrintable(m_keymap.variant())), - strdup(qPrintable(m_keymap.options())) }; - struct xkb_keymap *keymap = xkb_keymap_new_from_names(m_context, &rule_names, static_cast(0)); - char *keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1); - if (!keymap_str) - qFatal("Failed to compile global XKB keymap"); + if (!keymap_str) { + qWarning("Failed to compile global XKB keymap"); + return; + } m_keymap_size = strlen(keymap_str) + 1; + if (m_keymap_fd >= 0) + close(m_keymap_fd); m_keymap_fd = createAnonymousFile(m_keymap_size); - if (m_keymap_fd < 0) - qFatal("Failed to create anonymous file of size %lu", static_cast(m_keymap_size)); + if (m_keymap_fd < 0) { + qWarning("Failed to create anonymous file of size %lu", static_cast(m_keymap_size)); + return; + } m_keymap_area = static_cast(mmap(0, m_keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_keymap_fd, 0)); if (m_keymap_area == MAP_FAILED) { close(m_keymap_fd); - qFatal("Failed to map shared memory segment"); + m_keymap_fd = -1; + qWarning("Failed to map shared memory segment"); + return; } strcpy(m_keymap_area, keymap_str); free(keymap_str); + if (m_state) + xkb_state_unref(m_state); m_state = xkb_state_new(keymap); +} + +void Keyboard::createXKBKeymap() +{ + if (!m_context) + return; - xkb_keymap_unref(keymap); + struct xkb_rule_names rule_names = { strdup(qPrintable(m_keymap.rules())), + strdup(qPrintable(m_keymap.model())), + strdup(qPrintable(m_keymap.layout())), + strdup(qPrintable(m_keymap.variant())), + strdup(qPrintable(m_keymap.options())) }; + struct xkb_keymap *keymap = xkb_keymap_new_from_names(m_context, &rule_names, static_cast(0)); + + if (keymap) { + createXKBState(keymap); + xkb_keymap_unref(keymap); + } else { + qWarning("Failed to load the '%s' XKB keymap.", qPrintable(m_keymap.layout())); + } free((char *)rule_names.rules); free((char *)rule_names.model); diff --git a/src/compositor/wayland_wrapper/qwlkeyboard_p.h b/src/compositor/wayland_wrapper/qwlkeyboard_p.h index 44503114..2ace8c00 100644 --- a/src/compositor/wayland_wrapper/qwlkeyboard_p.h +++ b/src/compositor/wayland_wrapper/qwlkeyboard_p.h @@ -121,6 +121,7 @@ private: #ifndef QT_NO_WAYLAND_XKB void initXKB(); void createXKBKeymap(); + void createXKBState(xkb_keymap *keymap); #endif Compositor *m_compositor; -- cgit v1.2.3