LCOV - code coverage report
Current view: top level - xenolith/platform/linux - XLPlatformLinuxXkb.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 95 104 91.3 %
Date: 2024-05-12 00:16:13 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /**
       2             :  Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       3             : 
       4             :  Permission is hereby granted, free of charge, to any person obtaining a copy
       5             :  of this software and associated documentation files (the "Software"), to deal
       6             :  in the Software without restriction, including without limitation the rights
       7             :  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       8             :  copies of the Software, and to permit persons to whom the Software is
       9             :  furnished to do so, subject to the following conditions:
      10             : 
      11             :  The above copyright notice and this permission notice shall be included in
      12             :  all copies or substantial portions of the Software.
      13             : 
      14             :  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      17             :  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      18             :  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      19             :  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      20             :  THE SOFTWARE.
      21             :  **/
      22             : 
      23             : #include "XLPlatformLinuxXkb.h"
      24             : 
      25             : #if XL_LINK
      26             : extern "C" {
      27             : struct xkb_context * xkb_context_new(enum xkb_context_flags flags);
      28             : struct xkb_context * xkb_context_ref(struct xkb_context *context);
      29             : void xkb_context_unref (struct xkb_context *context);
      30             : void xkb_keymap_unref(struct xkb_keymap *keymap);
      31             : void xkb_state_unref(struct xkb_state *state);
      32             : struct xkb_keymap* xkb_keymap_new_from_string(struct xkb_context *context, const char *string,
      33             :                 enum xkb_keymap_format format, enum xkb_keymap_compile_flags flags);
      34             : struct xkb_state * xkb_state_new(struct xkb_keymap *keymap);
      35             : enum xkb_state_component xkb_state_update_mask(struct xkb_state *, xkb_mod_mask_t depressed_mods,
      36             :                 xkb_mod_mask_t latched_mods, xkb_mod_mask_t locked_mods, xkb_layout_index_t depressed_layout,
      37             :                 xkb_layout_index_t latched_layout, xkb_layout_index_t locked_layout);
      38             : int xkb_state_key_get_utf8(struct xkb_state *state, xkb_keycode_t key, char *buffer, size_t size);
      39             : uint32_t xkb_state_key_get_utf32(struct xkb_state *state, xkb_keycode_t key);
      40             : xkb_keysym_t xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t key);
      41             : int xkb_state_mod_index_is_active(struct xkb_state *state, xkb_mod_index_t idx, enum xkb_state_component type);
      42             : int xkb_state_key_get_syms(struct xkb_state *state, xkb_keycode_t key, const xkb_keysym_t **syms_out);
      43             : struct xkb_keymap * xkb_state_get_keymap(struct xkb_state *state);
      44             : void xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter, void *data);
      45             : const char * xkb_keymap_key_get_name(struct xkb_keymap *keymap, xkb_keycode_t key);
      46             : xkb_mod_index_t xkb_keymap_mod_get_index(struct xkb_keymap *keymap, const char *name);
      47             : int xkb_keymap_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t key);
      48             : uint32_t xkb_keysym_to_utf32(xkb_keysym_t keysym);
      49             : 
      50             : struct xkb_compose_table * xkb_compose_table_new_from_locale(struct xkb_context *context,
      51             :                 const char *locale, enum xkb_compose_compile_flags flags);
      52             : void xkb_compose_table_unref(struct xkb_compose_table *table);
      53             : struct xkb_compose_state* xkb_compose_state_new(struct xkb_compose_table *table, enum xkb_compose_state_flags flags);
      54             : enum xkb_compose_feed_result xkb_compose_state_feed(struct xkb_compose_state *state, xkb_keysym_t keysym);
      55             : void xkb_compose_state_reset(struct xkb_compose_state *state);
      56             : enum xkb_compose_status xkb_compose_state_get_status(struct xkb_compose_state *state);
      57             : xkb_keysym_t xkb_compose_state_get_one_sym(struct xkb_compose_state *state);
      58             : void xkb_compose_state_unref(struct xkb_compose_state *state);
      59             : 
      60             : int xkb_x11_setup_xkb_extension(xcb_connection_t *connection, uint16_t major_xkb_version, uint16_t minor_xkb_version,
      61             :                 enum xkb_x11_setup_xkb_extension_flags flags, uint16_t *major_xkb_version_out, uint16_t *minor_xkb_version_out,
      62             :                 uint8_t *base_event_out, uint8_t *base_error_out);
      63             : int32_t xkb_x11_get_core_keyboard_device_id(xcb_connection_t *connection);
      64             : struct xkb_keymap * xkb_x11_keymap_new_from_device(struct xkb_context *context,
      65             :                 xcb_connection_t *connection, int32_t device_id, enum xkb_keymap_compile_flags flags);
      66             : struct xkb_state * xkb_x11_state_new_from_device(struct xkb_keymap *keymap,
      67             :                 xcb_connection_t *connection, int32_t device_id);
      68             : }
      69             : #endif
      70             : 
      71             : namespace STAPPLER_VERSIONIZED stappler::xenolith::platform {
      72             : 
      73          25 : XkbLibrary *XkbLibrary::getInstance() {
      74             :         static Mutex s_mutex;
      75          25 :         static Rc<XkbLibrary> s_lib;
      76             : 
      77          25 :         std::unique_lock<Mutex> lock(s_mutex);
      78          25 :         if (!s_lib) {
      79          25 :                 s_lib = Rc<XkbLibrary>::create();
      80             :         }
      81             : 
      82          50 :         return s_lib;
      83          25 : }
      84             : 
      85          50 : XkbLibrary::~XkbLibrary() {
      86          25 :         close();
      87          50 : }
      88             : 
      89          25 : bool XkbLibrary::init() {
      90             : #ifndef XL_LINK
      91          25 :         _handle = Dso("libxkbcommon.so");
      92          25 :         if (!_handle) {
      93           0 :                 log::error("XkbLibrary", "Fail to open libxkbcommon.so");
      94           0 :                 return false;
      95             :         }
      96             : #endif
      97             : 
      98          25 :         if (open(_handle)) {
      99          25 :                 _context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
     100          25 :                 return true;
     101             :         } else {
     102           0 :                 _handle = Dso();
     103             :         }
     104           0 :         return false;
     105             : }
     106             : 
     107          25 : void XkbLibrary::close() {
     108          25 :         if (_context) {
     109          25 :                 xkb_context_unref(_context);
     110          25 :                 _context = nullptr;
     111             :         }
     112          25 : }
     113             : 
     114          25 : bool XkbLibrary::open(Dso &handle) {
     115             : #if XL_LINK
     116             :         this->xkb_context_new = &::xkb_context_new;
     117             :         this->xkb_context_ref = &::xkb_context_ref;
     118             :         this->xkb_context_unref = &::xkb_context_unref;
     119             :         this->xkb_keymap_unref = &::xkb_keymap_unref;
     120             :         this->xkb_state_unref = &::xkb_state_unref;
     121             :         this->xkb_keymap_new_from_string = &::xkb_keymap_new_from_string;
     122             :         this->xkb_state_new = &::xkb_state_new;
     123             :         this->xkb_state_update_mask = &::xkb_state_update_mask;
     124             :         this->xkb_state_key_get_utf8 = &::xkb_state_key_get_utf8;
     125             :         this->xkb_state_key_get_utf32 = &::xkb_state_key_get_utf32;
     126             :         this->xkb_state_key_get_one_sym = &::xkb_state_key_get_one_sym;
     127             :         this->xkb_state_mod_index_is_active = &::xkb_state_mod_index_is_active;
     128             :         this->xkb_state_key_get_syms = &::xkb_state_key_get_syms;
     129             :         this->xkb_state_get_keymap = &::xkb_state_get_keymap;
     130             :         this->xkb_keymap_key_for_each = &::xkb_keymap_key_for_each;
     131             :         this->xkb_keymap_key_get_name = &::xkb_keymap_key_get_name;
     132             :         this->xkb_keymap_mod_get_index = &::xkb_keymap_mod_get_index;
     133             :         this->xkb_keymap_key_repeats = &::xkb_keymap_key_repeats;
     134             :         this->xkb_keysym_to_utf32 = &::xkb_keysym_to_utf32;
     135             :         this->xkb_compose_table_new_from_locale = &::xkb_compose_table_new_from_locale;
     136             :         this->xkb_compose_table_unref = &::xkb_compose_table_unref;
     137             :         this->xkb_compose_state_new = &::xkb_compose_state_new;
     138             :         this->xkb_compose_state_feed = &::xkb_compose_state_feed;
     139             :         this->xkb_compose_state_reset = &::xkb_compose_state_reset;
     140             :         this->xkb_compose_state_get_status = &::xkb_compose_state_get_status;
     141             :         this->xkb_compose_state_get_one_sym = &::xkb_compose_state_get_one_sym;
     142             :         this->xkb_compose_state_unref = &::xkb_compose_state_unref;
     143             : #else
     144          25 :         xkb_context_new = handle.sym<decltype(xkb_context_new)>("xkb_context_new");
     145          25 :         xkb_context_ref = handle.sym<decltype(xkb_context_ref)>("xkb_context_ref");
     146          25 :         xkb_context_unref = handle.sym<decltype(xkb_context_unref)>("xkb_context_unref");
     147          25 :         xkb_keymap_unref = handle.sym<decltype(xkb_keymap_unref)>("xkb_keymap_unref");
     148          25 :         xkb_state_unref = handle.sym<decltype(xkb_state_unref)>("xkb_state_unref");
     149          25 :         xkb_keymap_new_from_string = handle.sym<decltype(xkb_keymap_new_from_string)>("xkb_keymap_new_from_string");
     150          25 :         xkb_state_new = handle.sym<decltype(xkb_state_new)>("xkb_state_new");
     151          25 :         xkb_state_update_mask = handle.sym<decltype(xkb_state_update_mask)>("xkb_state_update_mask");
     152          25 :         xkb_state_key_get_utf8 = handle.sym<decltype(xkb_state_key_get_utf8)>("xkb_state_key_get_utf8");
     153          25 :         xkb_state_key_get_utf32 = handle.sym<decltype(xkb_state_key_get_utf32)>("xkb_state_key_get_utf32");
     154          25 :         xkb_state_key_get_one_sym = handle.sym<decltype(xkb_state_key_get_one_sym)>("xkb_state_key_get_one_sym");
     155          25 :         xkb_state_mod_index_is_active = handle.sym<decltype(xkb_state_mod_index_is_active)>("xkb_state_mod_index_is_active");
     156          25 :         xkb_state_key_get_syms = handle.sym<decltype(xkb_state_key_get_syms)>("xkb_state_key_get_syms");
     157          25 :         xkb_state_get_keymap = handle.sym<decltype(xkb_state_get_keymap)>("xkb_state_get_keymap");
     158          25 :         xkb_keymap_key_for_each = handle.sym<decltype(xkb_keymap_key_for_each)>("xkb_keymap_key_for_each");
     159          25 :         xkb_keymap_key_get_name = handle.sym<decltype(xkb_keymap_key_get_name)>("xkb_keymap_key_get_name");
     160          25 :         xkb_keymap_mod_get_index = handle.sym<decltype(xkb_keymap_mod_get_index)>("xkb_keymap_mod_get_index");
     161          25 :         xkb_keymap_key_repeats = handle.sym<decltype(xkb_keymap_key_repeats)>("xkb_keymap_key_repeats");
     162          25 :         xkb_keysym_to_utf32 = handle.sym<decltype(xkb_keysym_to_utf32)>("xkb_keysym_to_utf32");
     163          25 :         xkb_compose_table_new_from_locale = handle.sym<decltype(xkb_compose_table_new_from_locale)>("xkb_compose_table_new_from_locale");
     164          25 :         xkb_compose_table_unref = handle.sym<decltype(xkb_compose_table_unref)>("xkb_compose_table_unref");
     165          25 :         xkb_compose_state_new = handle.sym<decltype(xkb_compose_state_new)>("xkb_compose_state_new");
     166          25 :         xkb_compose_state_feed = handle.sym<decltype(xkb_compose_state_feed)>("xkb_compose_state_feed");
     167          25 :         xkb_compose_state_reset = handle.sym<decltype(xkb_compose_state_reset)>("xkb_compose_state_reset");
     168          25 :         xkb_compose_state_get_status = handle.sym<decltype(xkb_compose_state_get_status)>("xkb_compose_state_get_status");
     169          25 :         xkb_compose_state_get_one_sym = handle.sym<decltype(xkb_compose_state_get_one_sym)>("xkb_compose_state_get_one_sym");
     170          25 :         xkb_compose_state_unref = handle.sym<decltype(xkb_compose_state_unref)>("xkb_compose_state_unref");
     171             : #endif
     172             : 
     173          25 :         if (this->xkb_context_new
     174          25 :                         && this->xkb_context_ref
     175          25 :                         && this->xkb_context_unref
     176          25 :                         && this->xkb_keymap_unref
     177          25 :                         && this->xkb_state_unref
     178          25 :                         && this->xkb_keymap_new_from_string
     179          25 :                         && this->xkb_state_new
     180          25 :                         && this->xkb_state_update_mask
     181          25 :                         && this->xkb_state_key_get_utf8
     182          25 :                         && this->xkb_state_key_get_utf32
     183          25 :                         && this->xkb_state_key_get_one_sym
     184          25 :                         && this->xkb_state_mod_index_is_active
     185          25 :                         && this->xkb_state_key_get_syms
     186          25 :                         && this->xkb_state_get_keymap
     187          25 :                         && this->xkb_keymap_key_for_each
     188          25 :                         && this->xkb_keymap_key_get_name
     189          25 :                         && this->xkb_keymap_mod_get_index
     190          25 :                         && this->xkb_keymap_key_repeats
     191          25 :                         && this->xkb_keysym_to_utf32
     192          25 :                         && this->xkb_compose_table_new_from_locale
     193          25 :                         && this->xkb_compose_table_unref
     194          25 :                         && this->xkb_compose_state_new
     195          25 :                         && this->xkb_compose_state_feed
     196          25 :                         && this->xkb_compose_state_reset
     197          25 :                         && this->xkb_compose_state_get_status
     198          25 :                         && this->xkb_compose_state_get_one_sym
     199          25 :                         && this->xkb_compose_state_unref) {
     200          25 :                 openAux();
     201          25 :                 return true;
     202             :         }
     203           0 :         return false;
     204             : }
     205             : 
     206          25 : void XkbLibrary::openAux() {
     207             : #if XL_LINK
     208             :         this->xkb_x11_setup_xkb_extension = &::xkb_x11_setup_xkb_extension;
     209             :         this->xkb_x11_get_core_keyboard_device_id = &::xkb_x11_get_core_keyboard_device_id;
     210             :         this->xkb_x11_keymap_new_from_device = &::xkb_x11_keymap_new_from_device;
     211             :         this->xkb_x11_state_new_from_device = &::xkb_x11_state_new_from_device;
     212             : #else
     213          25 :         if (auto handle = Dso("libxkbcommon-x11.so")) {
     214          25 :                 this->xkb_x11_setup_xkb_extension =
     215          25 :                                 handle.sym<decltype(this->xkb_x11_setup_xkb_extension)>("xkb_x11_setup_xkb_extension");
     216          25 :                 this->xkb_x11_get_core_keyboard_device_id =
     217          25 :                                 handle.sym<decltype(this->xkb_x11_get_core_keyboard_device_id)>("xkb_x11_get_core_keyboard_device_id");
     218          25 :                 this->xkb_x11_keymap_new_from_device =
     219          25 :                                 handle.sym<decltype(this->xkb_x11_keymap_new_from_device)>("xkb_x11_keymap_new_from_device");
     220          25 :                 this->xkb_x11_state_new_from_device =
     221          25 :                                 handle.sym<decltype(this->xkb_x11_state_new_from_device)>("xkb_x11_state_new_from_device");
     222             : 
     223          25 :                 if (this->xkb_x11_setup_xkb_extension
     224          25 :                                 && xkb_x11_get_core_keyboard_device_id
     225          25 :                                 && xkb_x11_keymap_new_from_device
     226          25 :                                 && xkb_x11_state_new_from_device) {
     227          25 :                         _x11 = move(handle);
     228             :                 } else {
     229           0 :                         this->xkb_x11_setup_xkb_extension = nullptr;
     230           0 :                         this->xkb_x11_get_core_keyboard_device_id = nullptr;
     231           0 :                         this->xkb_x11_keymap_new_from_device = nullptr;
     232           0 :                         this->xkb_x11_state_new_from_device = nullptr;
     233             :                 }
     234          25 :         }
     235             : #endif
     236          25 : }
     237             : 
     238             : }

Generated by: LCOV version 1.14