feat: implemented unicode input mode (#966)

Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com>
This commit is contained in:
ABeltramo 2023-03-08 13:35:34 +00:00 committed by GitHub
parent f238cf5303
commit 7d01b50498
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 83 additions and 3 deletions

View File

@ -281,6 +281,7 @@ jobs:
sudo apt-get update -y
sudo apt-get install -y \
libboost-filesystem1.71-dev \
libboost-locale1.71-dev \
libboost-log1.71-dev \
libboost-regex1.71-dev \
libboost-thread1.71-dev \
@ -307,6 +308,7 @@ jobs:
sudo apt-get install -y \
cmake \
libboost-filesystem-dev \
libboost-locale-dev \
libboost-log-dev \
libboost-thread-dev \
libboost-program-options-dev

View File

@ -78,7 +78,7 @@ if(WIN32)
set(Boost_NO_BOOST_CMAKE ON) # cmake-lint: disable=C0103
endif()
find_package(Boost COMPONENTS log filesystem program_options REQUIRED)
find_package(Boost COMPONENTS locale log filesystem program_options REQUIRED)
list(APPEND SUNSHINE_COMPILE_OPTIONS -Wall -Wno-missing-braces -Wno-maybe-uninitialized -Wno-sign-compare)
@ -790,6 +790,7 @@ elseif(UNIX)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "\
${CPACK_DEB_PLATFORM_PACKAGE_DEPENDS} \
libboost-filesystem${Boost_VERSION}, \
libboost-locale${Boost_VERSION}, \
libboost-log${Boost_VERSION}, \
libboost-program-options${Boost_VERSION}, \
libboost-thread${Boost_VERSION}, \
@ -809,6 +810,7 @@ elseif(UNIX)
set(CPACK_RPM_PACKAGE_REQUIRES "\
${CPACK_RPM_PLATFORM_PACKAGE_REQUIRES} \
boost-filesystem >= ${Boost_VERSION}, \
boost-locale >= ${Boost_VERSION}, \
boost-log >= ${Boost_VERSION}, \
boost-program-options >= ${Boost_VERSION}, \
boost-thread >= ${Boost_VERSION}, \

View File

@ -25,6 +25,7 @@ apt-get install -y --no-install-recommends \
cmake=3.18.4* \
libavdevice-dev=7:4.3.* \
libboost-filesystem-dev=1.74.0* \
libboost-locale-dev=1.74.0* \
libboost-log-dev=1.74.0* \
libboost-program-options-dev=1.74.0* \
libboost-thread-dev=1.74.0* \

View File

@ -26,6 +26,7 @@ apt-get install -y --no-install-recommends \
g++-10=10.3.0* \
libavdevice-dev=7:4.2.* \
libboost-filesystem-dev=1.71.0* \
libboost-locale-dev=1.71.0* \
libboost-log-dev=1.71.0* \
libboost-program-options-dev=1.71.0* \
libboost-thread-dev=1.71.0* \

View File

@ -25,6 +25,7 @@ apt-get install -y --no-install-recommends \
cmake=3.22.1* \
libavdevice-dev=7:4.4.* \
libboost-filesystem-dev=1.74.0* \
libboost-locale-dev=1.74.0* \
libboost-log-dev=1.74.0* \
libboost-program-options-dev=1.74.0* \
libboost-thread-dev=1.74.0* \

View File

@ -16,6 +16,7 @@ Install Requirements
cmake \
libavdevice-dev \
libboost-filesystem-dev \
libboost-locale-dev \
libboost-log-dev \
libboost-program-options-dev \
libboost-thread-dev \
@ -95,6 +96,7 @@ Install Requirements
g++-10 \
libavdevice-dev \
libboost-filesystem-dev \
libboost-locale-dev \
libboost-log-dev \
libboost-thread-dev \
libboost-program-options-dev \
@ -142,6 +144,7 @@ Install Requirements
cmake \
libavdevice-dev \
libboost-filesystem-dev \
libboost-locale-dev \
libboost-log-dev \
libboost-thread-dev \
libboost-program-options-dev \

View File

@ -33,7 +33,7 @@ modules:
buildsystem: simple
build-commands:
- cd tools/build && bison -y -d -o src/engine/jamgram.cpp src/engine/jamgram.y
- ./bootstrap.sh --prefix=$FLATPAK_DEST --with-libraries=system,thread,log,program_options || cat bootstrap.log
- ./bootstrap.sh --prefix=$FLATPAK_DEST --with-libraries=locale,log,program_options,system,thread
- ./b2 install variant=release link=shared runtime-link=shared cxxflags="$CXXFLAGS" linkflags="$LDFLAGS"
-j $FLATPAK_BUILDER_N_JOBS
sources:

View File

@ -5,6 +5,7 @@
#include <libevdev/libevdev-uinput.h>
#include <libevdev/libevdev.h>
#include <boost/locale.hpp>
#include <cmath>
#include <cstring>
#include <filesystem>
@ -1024,8 +1025,77 @@ void keyboard(input_t &input, uint16_t modcode, bool release) {
keycode.pressed = 1;
}
void keyboard_ev(libevdev_uinput *keyboard, int linux_code, int event_code = 1) {
libevdev_uinput_write_event(keyboard, EV_KEY, linux_code, event_code);
libevdev_uinput_write_event(keyboard, EV_SYN, SYN_REPORT, 0);
}
/**
* Takes an UTF-32 encoded string and returns a hex string representation of the bytes (uppercase)
*
* ex: ['👱'] = "1F471" // see UTF encoding at https://www.compart.com/en/unicode/U+1F471
*
* adapted from: https://stackoverflow.com/a/7639754
*/
std::string to_hex(const std::basic_string<char32_t> &str) {
std::stringstream ss;
ss << std::hex << std::setfill('0');
for(const auto &ch : str) {
ss << ch;
}
std::string hex_unicode(ss.str());
std::transform(hex_unicode.begin(), hex_unicode.end(), hex_unicode.begin(), ::toupper);
return hex_unicode;
}
/**
* Here we receive a single UTF-8 encoded char at a time,
* the trick is to convert it to UTF-32 then send CTRL+SHIFT+U+<HEXCODE> in order to produce any
* unicode character, see: https://en.wikipedia.org/wiki/Unicode_input
*
* ex:
* - when receiving UTF-8 [0xF0 0x9F 0x91 0xB1] (which is '👱')
* - we'll convert it to UTF-32 [0x1F471]
* - then type: CTRL+SHIFT+U+1F471
* see the conversion at: https://www.compart.com/en/unicode/U+1F471
*/
void unicode(input_t &input, char *utf8, int size) {
BOOST_LOG(info) << "unicode: Unicode input not yet implemented for Linux."sv;
auto kb = ((input_raw_t *)input.get())->keyboard_input.get();
if(!kb) {
return;
}
/* Reading input text as UTF-8 */
auto utf8_str = boost::locale::conv::to_utf<wchar_t>(utf8, utf8 + size, "UTF-8");
/* Converting to UTF-32 */
auto utf32_str = boost::locale::conv::utf_to_utf<char32_t>(utf8_str);
/* To HEX string */
auto hex_unicode = to_hex(utf32_str);
BOOST_LOG(debug) << "Unicode, typing U+"sv << hex_unicode;
/* pressing <CTRL> + <SHIFT> + U */
keyboard_ev(kb, KEY_LEFTCTRL, 1);
keyboard_ev(kb, KEY_LEFTSHIFT, 1);
keyboard_ev(kb, KEY_U, 1);
keyboard_ev(kb, KEY_U, 0);
/* input each HEX character */
for(auto &ch : hex_unicode) {
auto key_str = "KEY_"s + ch;
auto keycode = libevdev_event_code_from_name(EV_KEY, key_str.c_str());
if(keycode == -1) {
BOOST_LOG(warning) << "Unicode, unable to find keycode for: "sv << ch;
}
else {
keyboard_ev(kb, keycode, 1);
keyboard_ev(kb, keycode, 0);
}
}
/* releasing <SHIFT> and <CTRL> */
keyboard_ev(kb, KEY_LEFTSHIFT, 0);
keyboard_ev(kb, KEY_LEFTCTRL, 0);
}
int alloc_gamepad(input_t &input, int nr, rumble_queue_t rumble_queue) {