diff options
Diffstat (limited to 'chromium/ui/gfx/x')
33 files changed, 958 insertions, 1957 deletions
diff --git a/chromium/ui/gfx/x/BUILD.gn b/chromium/ui/gfx/x/BUILD.gn index 6b87f8e0c12..96f72a4369a 100644 --- a/chromium/ui/gfx/x/BUILD.gn +++ b/chromium/ui/gfx/x/BUILD.gn @@ -2,8 +2,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/ozone.gni") import("//build/config/ui.gni") -import("//ui/ozone/ozone.gni") +import("//tools/generate_library_loader/generate_library_loader.gni") assert(use_x11 || ozone_platform_x11) @@ -20,6 +21,22 @@ config("x11_private_config") { defines = [ "IS_X11_IMPL" ] } +generate_library_loader("xlib_loader") { + name = "XlibLoader" + output_h = "xlib_loader.h" + output_cc = "xlib_loader.cc" + header = "\"ui/gfx/x/xlib.h\"" + + functions = [ + "XInitThreads", + "XOpenDisplay", + "XCloseDisplay", + "XFlush", + "XSynchronize", + "XSetErrorHandler", + ] +} + action("gen_xprotos") { visibility = [ ":xprotos" ] script = "gen_xproto.py" @@ -59,6 +76,7 @@ action("gen_xprotos") { sources = [] outputs = [ "$target_gen_dir/read_event.cc", + "$target_gen_dir/read_error.cc", "$target_gen_dir/extension_manager.h", "$target_gen_dir/extension_manager.cc", ] @@ -80,30 +98,35 @@ action("gen_xprotos") { component("xprotos") { deps = [ ":gen_xprotos", + ":xlib_loader", "//base", "//base:i18n", "//ui/events/platform", ] public_deps = [ "//ui/gfx/x/keysyms" ] sources = get_target_outputs(":gen_xprotos") + [ - "xproto_internal.h", - "xproto_internal.cc", - "xproto_types.h", - "xproto_types.cc", - "xproto_util.h", - "xproto_util.cc", "connection.h", "connection.cc", "event.h", "event.cc", + "error.h", + "error.cc", + "keyboard_state.h", + "keyboard_state.cc", + "scoped_ignore_errors.h", + "scoped_ignore_errors.cc", "x11_switches.cc", "x11_switches.h", - "x11.h", + "xlib_support.h", + "xlib_support.cc", + "xproto_internal.h", + "xproto_internal.cc", + "xproto_types.h", + "xproto_types.cc", + "xproto_util.h", ] - configs += [ - ":x11_private_config", - "//build/config/linux:x11", - ] + configs += [ ":x11_private_config" ] + libs = [ "xcb" ] } component("x") { @@ -113,18 +136,12 @@ component("x") { "../gfx_export.h", "x11_atom_cache.cc", "x11_atom_cache.h", - "x11_error_tracker.cc", - "x11_error_tracker.h", "x11_path.cc", "x11_path.h", - "x11_types.cc", - "x11_types.h", ] defines = [ "GFX_IMPLEMENTATION" ] - public_configs = [ "//build/config/linux:x11" ] - deps = [ "//base", "//skia", diff --git a/chromium/ui/gfx/x/DEPS b/chromium/ui/gfx/x/DEPS index a444e969cbd..eccf1f06866 100644 --- a/chromium/ui/gfx/x/DEPS +++ b/chromium/ui/gfx/x/DEPS @@ -1,3 +1,6 @@ include_rules = [ "+ui/events/platform/platform_event_source.h", + "+third_party/libx11", + "+third_party/libxcb-keysyms", + "+third_party/x11proto", ] diff --git a/chromium/ui/gfx/x/OWNERS b/chromium/ui/gfx/x/OWNERS index 079174d24bc..c5442ff2356 100644 --- a/chromium/ui/gfx/x/OWNERS +++ b/chromium/ui/gfx/x/OWNERS @@ -2,5 +2,3 @@ thomasanderson@chromium.org # Adding new atoms is allowed without OWNERS review. per-file x11_atom_cache.cc=* - -# COMPONENT: UI>GFX diff --git a/chromium/ui/gfx/x/connection.cc b/chromium/ui/gfx/x/connection.cc index cea4895e776..d6350747a89 100644 --- a/chromium/ui/gfx/x/connection.cc +++ b/chromium/ui/gfx/x/connection.cc @@ -11,55 +11,25 @@ #include "base/auto_reset.h" #include "base/command_line.h" -#include "base/i18n/case_conversion.h" +#include "base/memory/ptr_util.h" #include "base/memory/scoped_refptr.h" #include "base/no_destructor.h" #include "base/strings/string16.h" #include "base/threading/thread_local.h" #include "ui/gfx/x/bigreq.h" #include "ui/gfx/x/event.h" -#include "ui/gfx/x/keysyms/keysyms.h" +#include "ui/gfx/x/keyboard_state.h" #include "ui/gfx/x/randr.h" -#include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11_switches.h" #include "ui/gfx/x/xkb.h" #include "ui/gfx/x/xproto.h" #include "ui/gfx/x/xproto_internal.h" #include "ui/gfx/x/xproto_types.h" -extern "C" { -typedef struct { - int type; - unsigned long serial; - Bool send_event; - Display* display; - Window window; - Window root; - Window subwindow; - Time time; - int x, y; - int x_root, y_root; - unsigned int state; - unsigned int keycode; - Bool same_screen; -} XKeyEvent; - -// This is temporarily required to fix XKB key event processing (bugs 1125886, -// 1136265, 1136248, 1136206). It should be removed and replaced with an -// XProto equivalent. -int XLookupString(XKeyEvent* event_struct, - char* buffer_return, - int bytes_buffer, - ::KeySym* keysym_return, - void* status_in_out); -} - namespace x11 { namespace { -constexpr KeySym kNoSymbol = static_cast<KeySym>(0); - // On the wire, sequence IDs are 16 bits. In xcb, they're usually extended to // 32 and sometimes 64 bits. In Xlib, they're extended to unsigned long, which // may be 32 or 64 bits depending on the platform. This function is intended to @@ -81,161 +51,45 @@ auto CompareSequenceIds(T t, U u) { return static_cast<SignedType>(t0 - u0); } -XDisplay* OpenNewXDisplay(const std::string& address) { - if (!XInitThreads()) - return nullptr; - std::string display_str = - address.empty() - ? base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kX11Display) - : address; - return XOpenDisplay(display_str.empty() ? nullptr : display_str.c_str()); -} - -// Ported from XConvertCase: -// https://gitlab.freedesktop.org/xorg/lib/libx11/-/blob/2b7598221d87049d03e9a95fcb541c37c8728184/src/KeyBind.c#L645 -void ConvertCaseImpl(uint32_t sym, uint32_t* lower, uint32_t* upper) { - // Unicode keysym - if ((sym & 0xff000000) == 0x01000000) { - base::string16 string({sym & 0x00ffffff}); - auto lower_string = base::i18n::ToLower(string); - auto upper_string = base::i18n::ToUpper(string); - *lower = lower_string[0] | 0x01000000; - *upper = upper_string[0] | 0x01000000; - return; - } - - *lower = sym; - *upper = sym; - - switch (sym >> 8) { - // Latin 1 - case 0: - if ((sym >= XK_A) && (sym <= XK_Z)) - *lower += (XK_a - XK_A); - else if ((sym >= XK_a) && (sym <= XK_z)) - *upper -= (XK_a - XK_A); - else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) - *lower += (XK_agrave - XK_Agrave); - else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis)) - *upper -= (XK_agrave - XK_Agrave); - else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn)) - *lower += (XK_oslash - XK_Ooblique); - else if ((sym >= XK_oslash) && (sym <= XK_thorn)) - *upper -= (XK_oslash - XK_Ooblique); - break; - // Latin 2 - case 1: - if (sym == XK_Aogonek) - *lower = XK_aogonek; - else if (sym >= XK_Lstroke && sym <= XK_Sacute) - *lower += (XK_lstroke - XK_Lstroke); - else if (sym >= XK_Scaron && sym <= XK_Zacute) - *lower += (XK_scaron - XK_Scaron); - else if (sym >= XK_Zcaron && sym <= XK_Zabovedot) - *lower += (XK_zcaron - XK_Zcaron); - else if (sym == XK_aogonek) - *upper = XK_Aogonek; - else if (sym >= XK_lstroke && sym <= XK_sacute) - *upper -= (XK_lstroke - XK_Lstroke); - else if (sym >= XK_scaron && sym <= XK_zacute) - *upper -= (XK_scaron - XK_Scaron); - else if (sym >= XK_zcaron && sym <= XK_zabovedot) - *upper -= (XK_zcaron - XK_Zcaron); - else if (sym >= XK_Racute && sym <= XK_Tcedilla) - *lower += (XK_racute - XK_Racute); - else if (sym >= XK_racute && sym <= XK_tcedilla) - *upper -= (XK_racute - XK_Racute); - break; - // Latin 3 - case 2: - if (sym >= XK_Hstroke && sym <= XK_Hcircumflex) - *lower += (XK_hstroke - XK_Hstroke); - else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex) - *lower += (XK_gbreve - XK_Gbreve); - else if (sym >= XK_hstroke && sym <= XK_hcircumflex) - *upper -= (XK_hstroke - XK_Hstroke); - else if (sym >= XK_gbreve && sym <= XK_jcircumflex) - *upper -= (XK_gbreve - XK_Gbreve); - else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex) - *lower += (XK_cabovedot - XK_Cabovedot); - else if (sym >= XK_cabovedot && sym <= XK_scircumflex) - *upper -= (XK_cabovedot - XK_Cabovedot); - break; - // Latin 4 - case 3: - if (sym >= XK_Rcedilla && sym <= XK_Tslash) - *lower += (XK_rcedilla - XK_Rcedilla); - else if (sym >= XK_rcedilla && sym <= XK_tslash) - *upper -= (XK_rcedilla - XK_Rcedilla); - else if (sym == XK_ENG) - *lower = XK_eng; - else if (sym == XK_eng) - *upper = XK_ENG; - else if (sym >= XK_Amacron && sym <= XK_Umacron) - *lower += (XK_amacron - XK_Amacron); - else if (sym >= XK_amacron && sym <= XK_umacron) - *upper -= (XK_amacron - XK_Amacron); - break; - // Cyrillic - case 6: - if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE) - *lower -= (XK_Serbian_DJE - XK_Serbian_dje); - else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze) - *upper += (XK_Serbian_DJE - XK_Serbian_dje); - else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN) - *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu); - else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign) - *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu); - break; - // Greek - case 7: - if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent) - *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent); - else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent && - sym != XK_Greek_iotaaccentdieresis && - sym != XK_Greek_upsilonaccentdieresis) - *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent); - else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA) - *lower += (XK_Greek_alpha - XK_Greek_ALPHA); - else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega && - sym != XK_Greek_finalsmallsigma) - *upper -= (XK_Greek_alpha - XK_Greek_ALPHA); - break; - // Latin 9 - case 0x13: - if (sym == XK_OE) - *lower = XK_oe; - else if (sym == XK_oe) - *upper = XK_OE; - else if (sym == XK_Ydiaeresis) - *lower = XK_ydiaeresis; - break; - } +base::ThreadLocalOwnedPointer<Connection>& GetConnectionTLS() { + static base::NoDestructor<base::ThreadLocalOwnedPointer<Connection>> tls; + return *tls; } -void ConvertCase(KeySym sym, KeySym* lower, KeySym* upper) { - uint32_t lower32; - uint32_t upper32; - ConvertCaseImpl(static_cast<uint32_t>(sym), &lower32, &upper32); - *lower = static_cast<KeySym>(lower32); - *upper = static_cast<KeySym>(upper32); +void DefaultErrorHandler(const x11::Error* error, const char* request_name) { + LOG(WARNING) << "X error received. Request: x11::" << request_name + << "Request, Error: " << error->ToString(); } -bool IsXKeypadKey(KeySym keysym) { - auto key = static_cast<uint32_t>(keysym); - return key >= XK_KP_Space && key <= XK_KP_Equal; +void DefaultIOErrorHandler() { + LOG(ERROR) << "X connection error received."; } -bool IsPrivateXKeypadKey(KeySym keysym) { - auto key = static_cast<uint32_t>(keysym); - return key >= 0x11000000 && key <= 0x1100FFFF; -} +class UnknownError : public Error { + public: + explicit UnknownError(FutureBase::RawError error_bytes) + : error_bytes_(error_bytes) {} -base::ThreadLocalOwnedPointer<Connection>& GetConnectionTLS() { - static base::NoDestructor<base::ThreadLocalOwnedPointer<Connection>> tls; - return *tls; -} + ~UnknownError() override = default; + + std::string ToString() const override { + std::stringstream ss; + ss << "x11::UnknownError{"; + // Errors are always a fixed 32 bytes. + for (size_t i = 0; i < 32; i++) { + char buf[3]; + sprintf(buf, "%02x", error_bytes_->data()[i]); + ss << "0x" << buf; + if (i != 31) + ss << ", "; + } + ss << "}"; + return ss.str(); + } + + private: + FutureBase::RawError error_bytes_; +}; } // namespace @@ -260,16 +114,18 @@ void Connection::Set(std::unique_ptr<x11::Connection> connection) { Connection::Connection(const std::string& address) : XProto(this), - display_(OpenNewXDisplay(address)), - display_string_(address) { - char* host = nullptr; - int display = 0; - xcb_parse_display(address.c_str(), &host, &display, &default_screen_id_); - if (host) - free(host); - if (display_) { - XSetEventQueueOwner(display_, XCBOwnsEventQueue); - + display_string_( + address.empty() + ? base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kX11Display) + : address), + error_handler_(base::BindRepeating(DefaultErrorHandler)), + io_error_handler_(base::BindOnce(DefaultIOErrorHandler)) { + connection_ = + xcb_connect(display_string_.empty() ? nullptr : display_string_.c_str(), + &default_screen_id_); + DCHECK(connection_); + if (Ready()) { auto buf = ReadBuffer(base::MakeRefCounted<UnretainedRefCountedMemory>( xcb_get_setup(XcbConnection()))); setup_ = Read<Setup>(&buf); @@ -286,7 +142,17 @@ Connection::Connection(const std::string& address) } ExtensionManager::Init(this); - if (auto response = bigreq().Enable({}).Sync()) + auto enable_bigreq = bigreq().Enable({}); + // Xlib enables XKB on display creation, so we do that here to maintain + // compatibility. + xkb() + .UseExtension({x11::Xkb::major_version, x11::Xkb::minor_version}) + .OnResponse(base::BindOnce([](x11::Xkb::UseExtensionResponse response) { + if (!response || !response->supported) + DVLOG(1) << "Xkb extension not available."; + })); + Flush(); + if (auto response = enable_bigreq.Sync()) extended_max_request_length_ = response->maximum_request_length; const Format* formats[256]; @@ -300,21 +166,30 @@ Connection::Connection(const std::string& address) default_screen_visuals_[visual.visual_id] = VisualInfo{format, &visual}; } - ResetKeyboardState(); + keyboard_state_ = CreateKeyboardState(this); + + InitErrorParsers(); } Connection::~Connection() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + platform_event_source.reset(); - if (display_) - XCloseDisplay(display_); + xcb_disconnect(connection_); } xcb_connection_t* Connection::XcbConnection() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!display()) - return nullptr; - return XGetXCBConnection(display()); + if (io_error_handler_ && xcb_connection_has_error(connection_)) + std::move(io_error_handler_).Run(); + return connection_; +} + +XlibDisplayWrapper Connection::GetXlibDisplay(XlibDisplayType type) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (!xlib_display_) + xlib_display_ = base::WrapUnique(new XlibDisplay(display_string_)); + return XlibDisplayWrapper(xlib_display_->display_, type); } Connection::Request::Request(unsigned int sequence, @@ -322,14 +197,39 @@ Connection::Request::Request(unsigned int sequence, : sequence(sequence), callback(std::move(callback)) {} Connection::Request::Request(Request&& other) - : sequence(other.sequence), callback(std::move(other.callback)) {} + : sequence(other.sequence), + callback(std::move(other.callback)), + have_response(other.have_response), + reply(std::move(other.reply)), + error(std::move(other.error)) {} Connection::Request::~Request() = default; -bool Connection::HasNextResponse() const { - return !requests_.empty() && - CompareSequenceIds(XLastKnownRequestProcessed(display_), - requests_.front().sequence) >= 0; +bool Connection::HasNextResponse() { + if (requests_.empty()) + return false; + auto& request = requests_.front(); + if (request.have_response) + return true; + + void* reply = nullptr; + xcb_generic_error_t* error = nullptr; + request.have_response = + xcb_poll_for_reply(XcbConnection(), request.sequence, &reply, &error); + if (reply) + request.reply = base::MakeRefCounted<MallocedRefCountedMemory>(reply); + if (error) + request.error = base::MakeRefCounted<MallocedRefCountedMemory>(error); + return request.have_response; +} + +bool Connection::HasNextEvent() { + while (!events_.empty()) { + if (events_.front().Initialized()) + return true; + events_.pop_front(); + } + return false; } int Connection::GetFd() { @@ -342,6 +242,19 @@ const std::string& Connection::DisplayString() const { return display_string_; } +std::string Connection::GetConnectionHostname() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + char* host = nullptr; + int display_id = 0; + int screen = 0; + if (xcb_parse_display(display_string_.c_str(), &host, &display_id, &screen)) { + std::string name = host; + free(host); + return name; + } + return std::string(); +} + int Connection::DefaultScreenId() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // This is not part of the setup data as the server has no concept of a @@ -352,13 +265,12 @@ int Connection::DefaultScreenId() const { bool Connection::Ready() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return display_ && !xcb_connection_has_error(XGetXCBConnection(display_)); + return !xcb_connection_has_error(connection_); } void Connection::Flush() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (display_) - XFlush(display_); + xcb_flush(connection_); } void Connection::Sync() { @@ -373,7 +285,6 @@ void Connection::Sync() { void Connection::SynchronizeForTest(bool synchronous) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - XSynchronize(display(), synchronous); synchronous_ = synchronous; if (synchronous_) Sync(); @@ -389,7 +300,7 @@ void Connection::ReadResponses() { Event Connection::WaitForNextEvent() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!events_.empty()) { + if (HasNextEvent()) { Event event = std::move(events_.front()); events_.pop_front(); return event; @@ -401,9 +312,9 @@ Event Connection::WaitForNextEvent() { return Event(); } -bool Connection::HasPendingResponses() const { +bool Connection::HasPendingResponses() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return !events_.empty() || HasNextResponse(); + return HasNextEvent() || HasNextResponse(); } const Connection::VisualInfo* Connection::GetVisualInfoFromId( @@ -415,34 +326,15 @@ const Connection::VisualInfo* Connection::GetVisualInfoFromId( return nullptr; } -KeyCode Connection::KeysymToKeycode(KeySym keysym) { +KeyCode Connection::KeysymToKeycode(uint32_t keysym) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - uint8_t min_keycode = static_cast<uint8_t>(setup_.min_keycode); - uint8_t max_keycode = static_cast<uint8_t>(setup_.max_keycode); - uint8_t count = max_keycode - min_keycode + 1; - DCHECK_EQ(count * keyboard_mapping_.keysyms_per_keycode, - static_cast<int>(keyboard_mapping_.keysyms.size())); - for (size_t i = 0; i < keyboard_mapping_.keysyms.size(); i++) { - if (keyboard_mapping_.keysyms[i] == keysym) { - return static_cast<KeyCode>(min_keycode + - i / keyboard_mapping_.keysyms_per_keycode); - } - } - return {}; + return keyboard_state_->KeysymToKeycode(keysym); } -KeySym Connection::KeycodeToKeysym(uint32_t keycode, unsigned int modifiers) { +uint32_t Connection::KeycodeToKeysym(KeyCode keycode, + uint32_t modifiers) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - XKeyEvent key_event{ - .type = KeyEvent::Press, - .display = display_, - .state = modifiers, - .keycode = keycode, - }; - ::KeySym keysym; - XLookupString(&key_event, nullptr, 0, &keysym, nullptr); - return static_cast<x11::KeySym>(keysym); + return keyboard_state_->KeycodeToKeysym(keycode, modifiers); } std::unique_ptr<Connection> Connection::Clone() const { @@ -457,25 +349,18 @@ void Connection::DetachFromSequence() { void Connection::Dispatch(Delegate* delegate) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(display_); auto process_next_response = [&] { - xcb_connection_t* connection = XGetXCBConnection(display_); - auto request = std::move(requests_.front()); - requests_.pop(); - - void* raw_reply = nullptr; - xcb_generic_error_t* raw_error = nullptr; - xcb_poll_for_reply(connection, request.sequence, &raw_reply, &raw_error); + DCHECK(!requests_.empty()); + DCHECK(requests_.front().have_response); - scoped_refptr<MallocedRefCountedMemory> reply; - if (raw_reply) - reply = base::MakeRefCounted<MallocedRefCountedMemory>(raw_reply); - std::move(request.callback).Run(reply, FutureBase::RawError{raw_error}); + Request request = std::move(requests_.front()); + requests_.pop(); + std::move(request.callback).Run(request.reply, request.error); }; auto process_next_event = [&] { - DCHECK(!events_.empty()); + DCHECK(HasNextEvent()); Event event = std::move(events_.front()); events_.pop_front(); @@ -488,7 +373,7 @@ void Connection::Dispatch(Delegate* delegate) { Flush(); ReadResponses(); - if (HasNextResponse() && !events_.empty()) { + if (HasNextResponse() && HasNextEvent()) { if (!events_.front().sequence_valid()) { process_next_event(); continue; @@ -506,7 +391,7 @@ void Connection::Dispatch(Delegate* delegate) { process_next_event(); } else if (HasNextResponse()) { process_next_response(); - } else if (!events_.empty()) { + } else if (HasNextEvent()) { process_next_event(); } else { break; @@ -514,6 +399,18 @@ void Connection::Dispatch(Delegate* delegate) { } } +Connection::ErrorHandler Connection::SetErrorHandler(ErrorHandler new_handler) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + return std::exchange(error_handler_, new_handler); +} + +void Connection::SetIOErrorHandler(IOErrorHandler new_handler) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + io_error_handler_ = std::move(new_handler); +} + void Connection::InitRootDepthAndVisual() { for (auto& depth : default_screen_->allowed_depths) { for (auto& visual : depth.visuals) { @@ -543,13 +440,13 @@ void Connection::PreDispatchEvent(const Event& event) { setup_.min_keycode = mapping->first_keycode; setup_.max_keycode = static_cast<x11::KeyCode>( static_cast<int>(mapping->first_keycode) + mapping->count - 1); - ResetKeyboardState(); + keyboard_state_->UpdateMapping(); } } if (auto* notify = event.As<x11::Xkb::NewKeyboardNotifyEvent>()) { setup_.min_keycode = notify->minKeyCode; setup_.max_keycode = notify->maxKeyCode; - ResetKeyboardState(); + keyboard_state_->UpdateMapping(); } // This is adapted from XRRUpdateConfiguration. @@ -587,141 +484,23 @@ int Connection::ScreenIndexFromRootWindow(Window root) const { return -1; } -void Connection::ResetKeyboardState() { - uint8_t min_keycode = static_cast<uint8_t>(setup_.min_keycode); - uint8_t max_keycode = static_cast<uint8_t>(setup_.max_keycode); - uint8_t count = max_keycode - min_keycode + 1; - auto keyboard_future = GetKeyboardMapping({setup_.min_keycode, count}); - auto modifier_future = GetModifierMapping({}); - Flush(); - if (auto reply = keyboard_future.Sync()) - keyboard_mapping_ = std::move(*reply.reply); - if (auto reply = modifier_future.Sync()) - modifier_mapping_ = std::move(*reply.reply); - - for (uint8_t i = 0; i < modifier_mapping_.keycodes_per_modifier; i++) { - // Lock modifiers are in the second row of the matrix - size_t index = 2 * modifier_mapping_.keycodes_per_modifier + i; - for (uint8_t j = 0; j < keyboard_mapping_.keysyms_per_keycode; j++) { - auto sym = static_cast<uint32_t>( - KeyCodetoKeySym(modifier_mapping_.keycodes[index], j)); - if (sym == XK_Caps_Lock || sym == XK_ISO_Lock) { - lock_meaning_ = XK_Caps_Lock; - break; - } - if (sym == XK_Shift_Lock) - lock_meaning_ = XK_Shift_Lock; - } - } - - // Mod<n> is at row (n + 2) of the matrix. This iterates from Mod1 to Mod5. - for (int mod = 3; mod < 8; mod++) { - for (size_t i = 0; i < modifier_mapping_.keycodes_per_modifier; i++) { - size_t index = mod * modifier_mapping_.keycodes_per_modifier + i; - for (uint8_t j = 0; j < keyboard_mapping_.keysyms_per_keycode; j++) { - auto sym = static_cast<uint32_t>( - KeyCodetoKeySym(modifier_mapping_.keycodes[index], j)); - if (sym == XK_Mode_switch) - mode_switch_ |= 1 << mod; - if (sym == XK_Num_Lock) - num_lock_ |= 1 << mod; - } - } - } +std::unique_ptr<Error> Connection::ParseError( + FutureBase::RawError error_bytes) { + if (!error_bytes) + return nullptr; + struct ErrorHeader { + uint8_t response_type; + uint8_t error_code; + uint16_t sequence; + }; + auto error_code = error_bytes->front_as<ErrorHeader>()->error_code; + if (auto parser = error_parsers_[error_code]) + return parser(error_bytes); + return std::make_unique<UnknownError>(error_bytes); } -// Ported from xcb_key_symbols_get_keysym -// https://gitlab.freedesktop.org/xorg/lib/libxcb-keysyms/-/blob/691515491a4a3c119adc6c769c29de264b3f3806/keysyms/keysyms.c#L189 -KeySym Connection::KeyCodetoKeySym(KeyCode keycode, int column) const { - uint8_t key = static_cast<uint8_t>(keycode); - uint8_t n_keysyms = keyboard_mapping_.keysyms_per_keycode; - - uint8_t min_key = static_cast<uint8_t>(setup_.min_keycode); - uint8_t max_key = static_cast<uint8_t>(setup_.max_keycode); - if (column < 0 || (column >= n_keysyms && column > 3) || key < min_key || - key > max_key) { - return kNoSymbol; - } - - const auto* syms = &keyboard_mapping_.keysyms[(key - min_key) * n_keysyms]; - if (column < 4) { - if (column > 1) { - while ((n_keysyms > 2) && (syms[n_keysyms - 1] == kNoSymbol)) - n_keysyms--; - if (n_keysyms < 3) - column -= 2; - } - if ((n_keysyms <= (column | 1)) || (syms[column | 1] == kNoSymbol)) { - KeySym lsym, usym; - ConvertCase(syms[column & ~1], &lsym, &usym); - if (!(column & 1)) - return lsym; - if (usym == lsym) - return kNoSymbol; - return usym; - } - } - return syms[column]; -} - -// Ported from _XTranslateKey: -// https://gitlab.freedesktop.org/xorg/lib/libx11/-/blob/2b7598221d87049d03e9a95fcb541c37c8728184/src/KeyBind.c#L761 -KeySym Connection::TranslateKey(uint32_t key, unsigned int modifiers) const { - constexpr auto kShiftMask = static_cast<unsigned int>(x11::ModMask::Shift); - constexpr auto kLockMask = static_cast<unsigned int>(x11::ModMask::Lock); - - uint8_t min_key = static_cast<uint8_t>(setup_.min_keycode); - uint8_t max_key = static_cast<uint8_t>(setup_.max_keycode); - if (key < min_key || key > max_key) - return kNoSymbol; - - uint8_t n_keysyms = keyboard_mapping_.keysyms_per_keycode; - if (!n_keysyms) - return {}; - const auto* syms = &keyboard_mapping_.keysyms[(key - min_key) * n_keysyms]; - while ((n_keysyms > 2) && (syms[n_keysyms - 1] == kNoSymbol)) - n_keysyms--; - if ((n_keysyms > 2) && (modifiers & mode_switch_)) { - syms += 2; - n_keysyms -= 2; - } - - if ((modifiers & num_lock_) && - (n_keysyms > 1 && - (IsXKeypadKey(syms[1]) || IsPrivateXKeypadKey(syms[1])))) { - if ((modifiers & kShiftMask) || - ((modifiers & kLockMask) && (lock_meaning_ == XK_Shift_Lock))) { - return syms[0]; - } - return syms[1]; - } - - KeySym lower; - KeySym upper; - if (!(modifiers & kShiftMask) && - (!(modifiers & kLockMask) || - (static_cast<x11::KeySym>(lock_meaning_) == kNoSymbol))) { - if ((n_keysyms == 1) || (syms[1] == kNoSymbol)) { - ConvertCase(syms[0], &lower, &upper); - return lower; - } - return syms[0]; - } - - if (!(modifiers & kLockMask) || (lock_meaning_ != XK_Caps_Lock)) { - if ((n_keysyms == 1) || ((upper = syms[1]) == kNoSymbol)) - ConvertCase(syms[0], &lower, &upper); - return upper; - } - - KeySym sym; - if ((n_keysyms == 1) || ((sym = syms[1]) == kNoSymbol)) - sym = syms[0]; - ConvertCase(sym, &lower, &upper); - if (!(modifiers & kShiftMask) && (sym != syms[0]) && - ((sym != upper) || (lower == upper))) - ConvertCase(syms[0], &lower, &upper); - return upper; +uint32_t Connection::GenerateIdImpl() { + return xcb_generate_id(connection_); } } // namespace x11 diff --git a/chromium/ui/gfx/x/connection.h b/chromium/ui/gfx/x/connection.h index 1e0fa6c2300..6b16ae22dc2 100644 --- a/chromium/ui/gfx/x/connection.h +++ b/chromium/ui/gfx/x/connection.h @@ -5,22 +5,30 @@ #ifndef UI_GFX_X_CONNECTION_H_ #define UI_GFX_X_CONNECTION_H_ -#include <list> #include <queue> #include "base/component_export.h" +#include "base/containers/circular_deque.h" #include "base/sequence_checker.h" #include "ui/events/platform/platform_event_source.h" #include "ui/gfx/x/event.h" #include "ui/gfx/x/extension_manager.h" +#include "ui/gfx/x/xlib_support.h" #include "ui/gfx/x/xproto.h" +typedef struct xcb_connection_t xcb_connection_t; + namespace x11 { +class KeyboardState; + // Represents a socket to the X11 server. class COMPONENT_EXPORT(X11) Connection : public XProto, public ExtensionManager { public: + using ErrorHandler = base::RepeatingCallback<void(const Error*, const char*)>; + using IOErrorHandler = base::OnceClosure; + class Delegate { public: virtual bool ShouldContinueStream() const = 0; @@ -47,12 +55,16 @@ class COMPONENT_EXPORT(X11) Connection : public XProto, Connection(const Connection&) = delete; Connection(Connection&&) = delete; - XDisplay* display() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return display_; - } xcb_connection_t* XcbConnection(); + // Obtain an Xlib display that's connected to the same server as |this|. This + // is meant to be used only for compatibility with components like GLX, + // Vulkan, and VAAPI. The underlying socket is not shared, so synchronization + // with |this| may be necessary. The |type| parameter can be used to achieve + // synchronization. The returned wrapper should not be saved. + XlibDisplayWrapper GetXlibDisplay( + XlibDisplayType type = XlibDisplayType::kNormal); + uint32_t extended_max_request_length() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return extended_max_request_length_; @@ -85,12 +97,14 @@ class COMPONENT_EXPORT(X11) Connection : public XProto, const std::string& DisplayString() const; + std::string GetConnectionHostname() const; + int DefaultScreenId() const; template <typename T> T GenerateId() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return static_cast<T>(xcb_generate_id(XcbConnection())); + return static_cast<T>(GenerateIdImpl()); } // Is the connection up and error-free? @@ -113,21 +127,28 @@ class COMPONENT_EXPORT(X11) Connection : public XProto, Event WaitForNextEvent(); // Are there any events, errors, or replies already buffered? - bool HasPendingResponses() const; + bool HasPendingResponses(); // Dispatch any buffered events, errors, or replies. void Dispatch(Delegate* delegate); + // Returns the old error handler. + ErrorHandler SetErrorHandler(ErrorHandler new_handler); + + void SetIOErrorHandler(IOErrorHandler new_handler); + // Returns the visual data for |id|, or nullptr if the visual with that ID // doesn't exist or only exists on a non-default screen. const VisualInfo* GetVisualInfoFromId(VisualId id) const; - KeyCode KeysymToKeycode(KeySym keysym); + KeyCode KeysymToKeycode(uint32_t keysym) const; - KeySym KeycodeToKeysym(uint32_t keycode, unsigned int modifiers); + uint32_t KeycodeToKeysym(KeyCode keycode, uint32_t modifiers) const; - // Access the event buffer. Clients can add, delete, or modify events. - std::list<Event>& events() { + // Access the event buffer. Clients may modify the queue, including + // "deleting" events by setting events[i] = x11::Event(), which will + // guarantee all calls to x11::Event::As() will return nullptr. + base::circular_deque<Event>& events() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return events_; } @@ -153,25 +174,32 @@ class COMPONENT_EXPORT(X11) Connection : public XProto, const unsigned int sequence; FutureBase::ResponseCallback callback; + bool have_response = false; + FutureBase::RawReply reply; + FutureBase::RawError error; }; void InitRootDepthAndVisual(); void AddRequest(unsigned int sequence, FutureBase::ResponseCallback callback); - bool HasNextResponse() const; + bool HasNextResponse(); + + bool HasNextEvent(); void PreDispatchEvent(const Event& event); int ScreenIndexFromRootWindow(x11::Window root) const; - void ResetKeyboardState(); + // This function is implemented in the generated read_error.cc. + void InitErrorParsers(); - KeySym KeyCodetoKeySym(KeyCode keycode, int column) const; + std::unique_ptr<Error> ParseError(FutureBase::RawError error_bytes); - KeySym TranslateKey(uint32_t keycode, unsigned int modifiers) const; + uint32_t GenerateIdImpl(); - XDisplay* const display_; + xcb_connection_t* connection_ = nullptr; + std::unique_ptr<XlibDisplay> xlib_display_; bool synchronous_ = false; bool syncing_ = false; @@ -187,17 +215,19 @@ class COMPONENT_EXPORT(X11) Connection : public XProto, std::unordered_map<VisualId, VisualInfo> default_screen_visuals_; - // Keyboard state. - GetKeyboardMappingReply keyboard_mapping_; - GetModifierMappingReply modifier_mapping_; - uint16_t lock_meaning_ = 0; - uint8_t mode_switch_ = 0; - uint8_t num_lock_ = 0; + std::unique_ptr<KeyboardState> keyboard_state_; - std::list<Event> events_; + base::circular_deque<Event> events_; std::queue<Request> requests_; + using ErrorParser = + std::unique_ptr<Error> (*)(FutureBase::RawError error_bytes); + std::array<ErrorParser, 256> error_parsers_{}; + + ErrorHandler error_handler_; + IOErrorHandler io_error_handler_; + SEQUENCE_CHECKER(sequence_checker_); }; diff --git a/chromium/ui/gfx/x/connection_unittest.cc b/chromium/ui/gfx/x/connection_unittest.cc index 42e581c69cc..4f140e05aea 100644 --- a/chromium/ui/gfx/x/connection_unittest.cc +++ b/chromium/ui/gfx/x/connection_unittest.cc @@ -37,13 +37,13 @@ Window CreateWindow(Connection* connection) { TEST(X11ConnectionTest, Basic) { Connection connection; ASSERT_TRUE(connection.XcbConnection()); - EXPECT_FALSE(xcb_connection_has_error(connection.XcbConnection())); + EXPECT_TRUE(connection.Ready()); } TEST(X11ConnectionTest, Request) { Connection connection; ASSERT_TRUE(connection.XcbConnection()); - EXPECT_FALSE(xcb_connection_has_error(connection.XcbConnection())); + EXPECT_TRUE(connection.Ready()); Window window = CreateWindow(&connection); @@ -63,7 +63,7 @@ TEST(X11ConnectionTest, Request) { TEST(X11ConnectionTest, Event) { Connection connection; ASSERT_TRUE(connection.XcbConnection()); - EXPECT_FALSE(xcb_connection_has_error(connection.XcbConnection())); + EXPECT_TRUE(connection.Ready()); Window window = CreateWindow(&connection); @@ -95,15 +95,17 @@ TEST(X11ConnectionTest, Event) { TEST(X11ConnectionTest, Error) { Connection connection; ASSERT_TRUE(connection.XcbConnection()); - EXPECT_FALSE(xcb_connection_has_error(connection.XcbConnection())); + EXPECT_TRUE(connection.Ready()); Window invalid_window = connection.GenerateId<Window>(); auto geometry = connection.GetGeometry({invalid_window}).Sync(); ASSERT_FALSE(geometry); - xcb_generic_error_t* error = geometry.error.get(); - EXPECT_EQ(error->error_code, XCB_DRAWABLE); - EXPECT_EQ(error->resource_id, static_cast<uint32_t>(invalid_window)); + auto* error = geometry.error.get(); + ASSERT_TRUE(error); + // TODO(thomasanderson): Implement As<> for errors, similar to events. + auto* drawable_error = reinterpret_cast<x11::DrawableError*>(error); + EXPECT_EQ(drawable_error->bad_value, static_cast<uint32_t>(invalid_window)); } } // namespace x11 diff --git a/chromium/ui/gfx/x/error.cc b/chromium/ui/gfx/x/error.cc new file mode 100644 index 00000000000..f33de1a474a --- /dev/null +++ b/chromium/ui/gfx/x/error.cc @@ -0,0 +1,13 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/x/error.h" + +namespace x11 { + +Error::Error() = default; + +Error::~Error() = default; + +} // namespace x11 diff --git a/chromium/ui/gfx/x/error.h b/chromium/ui/gfx/x/error.h new file mode 100644 index 00000000000..a9de90bfab5 --- /dev/null +++ b/chromium/ui/gfx/x/error.h @@ -0,0 +1,26 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_X_ERROR_H_ +#define UI_GFX_X_ERROR_H_ + +#include <string> + +#include "base/component_export.h" + +namespace x11 { + +// This class is a generic interface for X11 errors. Currently the only +// functionality is printing the error as a human-readable string. +class COMPONENT_EXPORT(X11) Error { + public: + Error(); + virtual ~Error(); + + virtual std::string ToString() const = 0; +}; + +} // namespace x11 + +#endif // UI_GFX_X_ERROR_H_ diff --git a/chromium/ui/gfx/x/event.cc b/chromium/ui/gfx/x/event.cc index 41cd3649702..3d0637ca39b 100644 --- a/chromium/ui/gfx/x/event.cc +++ b/chromium/ui/gfx/x/event.cc @@ -19,19 +19,6 @@ namespace x11 { Event::Event() = default; -Event::Event(xcb_generic_event_t* xcb_event, - x11::Connection* connection, - bool sequence_valid) - : Event(base::MakeRefCounted<x11::UnretainedRefCountedMemory>(xcb_event), - connection, - sequence_valid) { - // Make sure the event is a fixed-size (32 bytes) event, otherwise - // UnretainedRefCountedMemory may be unsafe to use if the event contains - // variable-sized data. - DCHECK_NE(xcb_event->response_type & ~x11::kSendEventMask, - x11::GeGenericEvent::opcode); -} - Event::Event(scoped_refptr<base::RefCountedMemory> event_bytes, x11::Connection* connection, bool sequence_valid) { diff --git a/chromium/ui/gfx/x/event.h b/chromium/ui/gfx/x/event.h index 7e3d41dc7ce..c13e94228b6 100644 --- a/chromium/ui/gfx/x/event.h +++ b/chromium/ui/gfx/x/event.h @@ -38,9 +38,7 @@ class COMPONENT_EXPORT(X11) Event { } Event(); - Event(xcb_generic_event_t* xcb_event, - Connection* connection, - bool sequence_valid = true); + // |event_bytes| is modified and will not be valid after this call. // A copy is necessary if the original data is still needed. Event(scoped_refptr<base::RefCountedMemory> event_bytes, @@ -76,6 +74,8 @@ class COMPONENT_EXPORT(X11) Event { *window_ = window; } + bool Initialized() const { return deleter_; } + private: friend void ReadEvent(Event* event, Connection* connection, diff --git a/chromium/ui/gfx/x/gen_xproto.py b/chromium/ui/gfx/x/gen_xproto.py index 391779422fc..94df052aa4f 100644 --- a/chromium/ui/gfx/x/gen_xproto.py +++ b/chromium/ui/gfx/x/gen_xproto.py @@ -919,6 +919,14 @@ class GenXproto(FileWriter): self.write('x11::Window* GetWindow() { return %s; }' % ret) self.write() + def declare_error(self, error, name): + name = adjust_type_name(name[-1] + 'Error') + with Indent(self, 'struct %s : public x11::Error {' % name, '};'): + self.declare_fields(error.fields) + self.write() + self.write('std::string ToString() const override;') + self.write() + def declare_container(self, struct, struct_name): name = struct_name[-1] + self.type_suffix(struct) with Indent(self, 'struct %s {' % adjust_type_name(name), '};'): @@ -1025,8 +1033,9 @@ class GenXproto(FileWriter): self.write('Align(&buf, 4);') self.write() reply_has_fds = reply and any(field.isfd for field in reply.fields) - self.write('return x11::SendRequest<%s>(connection_, &buf, %s);' % - (reply_name, 'true' if reply_has_fds else 'false')) + self.write( + 'return x11::SendRequest<%s>(connection_, &buf, %s, "%s");' % + (reply_name, 'true' if reply_has_fds else 'false', prefix)) self.write() if not reply: @@ -1066,6 +1075,29 @@ class GenXproto(FileWriter): self.write('DCHECK_LE(buf.offset, 32ul);') self.write() + def define_error(self, error, name): + self.namespace = ['x11'] + name = self.qualtype(error, name) + with Indent(self, 'std::string %s::ToString() const {' % name, '}'): + self.write('std::stringstream ss_;') + self.write('ss_ << "x11::%s{";' % name) + fields = [field for field in error.fields if field.visible] + for i, field in enumerate(fields): + terminator = '' if i == len(fields) - 1 else ' << ", "' + self.write('ss_ << ".%s = " << static_cast<uint64_t>(%s)%s;' % + (field.field_name, field.field_name, terminator)) + self.write('ss_ << "}";') + self.write('return ss_.str();') + self.write() + self.write('template <>') + self.write('void ReadError<%s>(' % name) + with Indent(self, ' %s* error_, ReadBuffer* buffer) {' % name, '}'): + self.write('auto& buf = *buffer;') + self.write() + self.is_read = True + self.copy_container(error, '(*error_)') + self.write('DCHECK_LE(buf.offset, 32ul);') + def define_type(self, item, name): if name in READ_SPECIAL: self.read_special_container(item, name) @@ -1075,6 +1107,8 @@ class GenXproto(FileWriter): self.define_request(item) elif item.is_event: self.define_event(item, name) + elif isinstance(item, self.xcbgen.xtypes.Error): + self.define_error(item, name) def declare_type(self, item, name): if item.is_union: @@ -1083,6 +1117,8 @@ class GenXproto(FileWriter): self.declare_request(item) elif item.is_event: self.declare_event(item, name) + elif isinstance(item, self.xcbgen.xtypes.Error): + self.declare_error(item, name) elif item.is_container: self.declare_container(item, name) elif isinstance(item, self.xcbgen.xtypes.Enum): @@ -1314,6 +1350,7 @@ class GenXproto(FileWriter): self.write('#include "base/memory/scoped_refptr.h"') self.write('#include "base/optional.h"') self.write('#include "base/files/scoped_file.h"') + self.write('#include "ui/gfx/x/error.h"') self.write('#include "ui/gfx/x/xproto_types.h"') imports = set(self.module.direct_imports) if self.module.namespace.is_ext: @@ -1493,6 +1530,8 @@ class GenExtensionManager(FileWriter): self.write( 'auto %s_future = conn->QueryExtension({"%s"});' % (extension.proto, extension.module.namespace.ext_xname)) + # Flush so all requests are sent before waiting on any replies. + self.write('conn->Flush();') self.write() for extension in self.extensions: name = extension.proto @@ -1578,6 +1617,8 @@ class GenReadEvent(FileWriter): self.file = open(os.path.join(self.gen_dir, 'read_event.cc'), 'w') self.write('#include "ui/gfx/x/event.h"') self.write() + self.write('#include <xcb/xcb.h>') + self.write() self.write('#include "ui/gfx/x/connection.h"') for genproto in self.genprotos: self.write('#include "ui/gfx/x/%s.h"' % genproto.proto) @@ -1601,6 +1642,90 @@ class GenReadEvent(FileWriter): self.write('} // namespace x11') +class GenReadError(FileWriter): + def __init__(self, gen_dir, genprotos, xcbgen): + FileWriter.__init__(self) + + self.gen_dir = gen_dir + self.genprotos = genprotos + self.xcbgen = xcbgen + + def get_errors_for_proto(self, proto): + errors = {} + for _, item in proto.module.all: + if isinstance(item, self.xcbgen.xtypes.Error): + for name in item.opcodes: + id = int(item.opcodes[name]) + if id < 0: + continue + name = [adjust_type_name(part) for part in name[1:]] + typename = '::'.join(name) + 'Error' + errors[id] = typename + return errors + + def gen_errors_for_proto(self, errors, proto): + if proto.module.namespace.is_ext: + cond = 'if (%s().present()) {' % proto.proto + first_error = '%s().first_error()' % proto.proto + else: + cond = '{' + first_error = '0' + with Indent(self, cond, '}'): + self.write('uint8_t first_error = %s;' % first_error) + for id, name in sorted(errors.items()): + with Indent(self, '{', '}'): + self.write('auto error_code = first_error + %d;' % id) + self.write('auto parse = MakeError<%s>;' % name) + self.write('add_parser(error_code, first_error, parse);') + self.write() + + def gen_init_error_parsers(self): + self.write('uint8_t first_errors[256];') + self.write('memset(first_errors, 0, sizeof(first_errors));') + self.write() + args = 'uint8_t error_code, uint8_t first_error, ErrorParser parser' + with Indent(self, 'auto add_parser = [&](%s) {' % args, '};'): + cond = ('!error_parsers_[error_code] || ' + + 'first_error > first_errors[error_code]') + with Indent(self, 'if (%s) {' % cond, '}'): + self.write('first_errors[error_code] = error_code;') + self.write('error_parsers_[error_code] = parser;') + self.write() + for proto in self.genprotos: + errors = self.get_errors_for_proto(proto) + if errors: + self.gen_errors_for_proto(errors, proto) + + def gen_source(self): + self.file = open(os.path.join(self.gen_dir, 'read_error.cc'), 'w') + self.write('#include "ui/gfx/x/connection.h"') + self.write('#include "ui/gfx/x/error.h"') + self.write('#include "ui/gfx/x/xproto_internal.h"') + self.write() + for genproto in self.genprotos: + self.write('#include "ui/gfx/x/%s.h"' % genproto.proto) + self.write() + self.write('namespace x11 {') + self.write() + self.write('namespace {') + self.write() + self.write('template <typename T>') + sig = 'std::unique_ptr<Error> MakeError(FutureBase::RawError error_)' + with Indent(self, '%s {' % sig, '}'): + self.write('ReadBuffer buf(error_);') + self.write('auto error = std::make_unique<T>();') + self.write('ReadError(error.get(), &buf);') + self.write('return error;') + self.write() + self.write('} // namespace') + self.write() + with Indent(self, 'void Connection::InitErrorParsers() {', '}'): + self.gen_init_error_parsers() + + self.write() + self.write('} // namespace x11') + + def main(): parser = argparse.ArgumentParser() parser.add_argument('xcbproto_dir', type=str) @@ -1639,8 +1764,9 @@ def main(): gen_extension_manager.gen_header() gen_extension_manager.gen_source() - gen_read_event = GenReadEvent(args.gen_dir, genprotos) - gen_read_event.gen_source() + GenReadEvent(args.gen_dir, genprotos).gen_source() + + GenReadError(args.gen_dir, genprotos, xcbgen).gen_source() return 0 diff --git a/chromium/ui/gfx/x/keyboard_state.cc b/chromium/ui/gfx/x/keyboard_state.cc new file mode 100644 index 00000000000..3ca1e8084bc --- /dev/null +++ b/chromium/ui/gfx/x/keyboard_state.cc @@ -0,0 +1,136 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/x/keyboard_state.h" + +#include "base/i18n/case_conversion.h" +#include "ui/gfx/x/connection.h" +#include "ui/gfx/x/keysyms/keysyms.h" +#include "ui/gfx/x/xkb.h" +#include "ui/gfx/x/xproto.h" + +namespace x11 { + +namespace { + +constexpr KeySym kNoSymbol = static_cast<KeySym>(0); + +void ConvertCaseImpl(uint32_t sym, uint32_t* lower, uint32_t* upper); + +void ConvertCase(KeySym sym, KeySym* lower, KeySym* upper) { + uint32_t lower32; + uint32_t upper32; + ConvertCaseImpl(static_cast<uint32_t>(sym), &lower32, &upper32); + *lower = static_cast<KeySym>(lower32); + *upper = static_cast<KeySym>(upper32); +} + +bool IsPublicOrPrivateKeypadKey(KeySym keysym) { + auto key = static_cast<uint32_t>(keysym); + return (key >= XK_KP_Space && key <= XK_KP_Equal) || + (key >= 0x11000000 && key <= 0x1100FFFF); +} + +int GetXkbGroupFromState(int state) { + return (state >> 13) & 0x3; +} + +#include "third_party/libx11/src/KeyBind.c" +#include "third_party/libx11/src/xkb/XKBBind.c" +#include "third_party/libxcb-keysyms/keysyms/keysyms.c" + +} // namespace + +KeyboardState::KeyboardState() = default; + +KeyboardState::~KeyboardState() = default; + +// Non-XKB (core protocol) implementation of KeysymToKeycode and +// KeycodeToKeysym. +class CoreKeyboardState : public KeyboardState { + public: + explicit CoreKeyboardState(Connection* connection) : connection_(connection) { + UpdateMapping(); + } + + ~CoreKeyboardState() override = default; + + KeyCode KeysymToKeycode(uint32_t keysym) const override { + auto min_keycode = static_cast<uint8_t>(connection_->setup().min_keycode); + auto max_keycode = static_cast<uint8_t>(connection_->setup().max_keycode); + int count = max_keycode - min_keycode + 1; + DCHECK_EQ(count * keyboard_mapping_.keysyms_per_keycode, + static_cast<int>(keyboard_mapping_.keysyms.size())); + for (size_t i = 0; i < keyboard_mapping_.keysyms.size(); i++) { + auto keycode = min_keycode + i / keyboard_mapping_.keysyms_per_keycode; + if (keyboard_mapping_.keysyms[i] == static_cast<x11::KeySym>(keysym)) + return static_cast<KeyCode>(keycode); + } + return {}; + } + + uint32_t KeycodeToKeysym(KeyCode keycode, uint32_t modifiers) const override { + auto sym = static_cast<uint32_t>(KeycodeToKeysymCoreImpl( + keycode, modifiers, connection_, keyboard_mapping_, lock_meaning_, + mode_switch_, num_lock_)); + return sym == XK_VoidSymbol ? 0 : sym; + } + + private: + void UpdateMapping() override { + UpdateMappingImpl(connection_, &keyboard_mapping_, &lock_meaning_, + &mode_switch_, &num_lock_); + } + + x11::Connection* const connection_; + GetKeyboardMappingReply keyboard_mapping_; + uint16_t lock_meaning_ = 0; + uint8_t mode_switch_ = 0; + uint8_t num_lock_ = 0; +}; + +// XKB implementation of KeysymToKeycode and KeycodeToKeysym. +class XkbKeyboardState : public KeyboardState { + public: + explicit XkbKeyboardState(Connection* connection) : connection_(connection) { + UpdateMapping(); + } + + ~XkbKeyboardState() override = default; + + KeyCode KeysymToKeycode(uint32_t keysym) const override { + int first_keycode = static_cast<int>(map_.firstKeySym); + for (int keycode = 0; keycode < map_.nKeySyms; keycode++) { + for (auto sym : map_.syms_rtrn->at(keycode).syms) { + if (static_cast<uint32_t>(sym) == keysym) + return static_cast<KeyCode>(keycode + first_keycode); + } + } + return {}; + } + + uint32_t KeycodeToKeysym(KeyCode key, uint32_t modifiers) const override { + return KeycodeToKeysymXkbImpl(key, modifiers, map_); + } + + private: + void UpdateMapping() override { + auto future = connection_->xkb().GetMap( + {static_cast<Xkb::DeviceSpec>(Xkb::Id::UseCoreKbd), + Xkb::MapPart::KeyTypes | Xkb::MapPart::KeySyms}); + if (auto response = future.Sync()) + map_ = std::move(*response.reply); + } + + x11::Connection* const connection_; + Xkb::GetMapReply map_; +}; + +std::unique_ptr<KeyboardState> CreateKeyboardState(Connection* connection) { + if (connection->xkb().present()) + return std::make_unique<XkbKeyboardState>(connection); + return std::make_unique<CoreKeyboardState>(connection); +} + +} // namespace x11 diff --git a/chromium/ui/gfx/x/keyboard_state.h b/chromium/ui/gfx/x/keyboard_state.h new file mode 100644 index 00000000000..d28fe595f39 --- /dev/null +++ b/chromium/ui/gfx/x/keyboard_state.h @@ -0,0 +1,37 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_X_KEYBOARD_STATE_H_ +#define UI_GFX_X_KEYBOARD_STATE_H_ + +#include <memory> + +#include "ui/gfx/x/xproto.h" + +namespace x11 { + +class Connection; + +// This is an interface used by Connection to manage conversion between keycodes +// (8 bit values) and keysyms (32 bit values). +class KeyboardState { + public: + KeyboardState(); + virtual ~KeyboardState(); + + virtual KeyCode KeysymToKeycode(uint32_t keysym) const = 0; + virtual uint32_t KeycodeToKeysym(KeyCode keycode, + uint32_t modifiers) const = 0; + + private: + friend class Connection; + + virtual void UpdateMapping() = 0; +}; + +std::unique_ptr<KeyboardState> CreateKeyboardState(Connection* connection); + +} // namespace x11 + +#endif // UI_GFX_X_KEYBOARD_STATE_H_ diff --git a/chromium/ui/gfx/x/keysyms/keysyms.h b/chromium/ui/gfx/x/keysyms/keysyms.h index 4d5fbcbcedb..c43ca1a4072 100644 --- a/chromium/ui/gfx/x/keysyms/keysyms.h +++ b/chromium/ui/gfx/x/keysyms/keysyms.h @@ -7,1155 +7,6 @@ #include <cstdint> -static constexpr uint32_t XK_space = 0x20; -static constexpr uint32_t XK_exclam = 0x21; -static constexpr uint32_t XK_quotedbl = 0x22; -static constexpr uint32_t XK_numbersign = 0x23; -static constexpr uint32_t XK_dollar = 0x24; -static constexpr uint32_t XK_percent = 0x25; -static constexpr uint32_t XK_ampersand = 0x26; -static constexpr uint32_t XK_quoteright = 0x27; -static constexpr uint32_t XK_parenleft = 0x28; -static constexpr uint32_t XK_parenright = 0x29; -static constexpr uint32_t XK_asterisk = 0x2A; -static constexpr uint32_t XK_plus = 0x2B; -static constexpr uint32_t XK_comma = 0x2C; -static constexpr uint32_t XK_minus = 0x2D; -static constexpr uint32_t XK_period = 0x2E; -static constexpr uint32_t XK_slash = 0x2F; -static constexpr uint32_t XK_0 = 0x30; -static constexpr uint32_t XK_1 = 0x31; -static constexpr uint32_t XK_2 = 0x32; -static constexpr uint32_t XK_3 = 0x33; -static constexpr uint32_t XK_4 = 0x34; -static constexpr uint32_t XK_5 = 0x35; -static constexpr uint32_t XK_6 = 0x36; -static constexpr uint32_t XK_7 = 0x37; -static constexpr uint32_t XK_8 = 0x38; -static constexpr uint32_t XK_9 = 0x39; -static constexpr uint32_t XK_colon = 0x3A; -static constexpr uint32_t XK_semicolon = 0x3B; -static constexpr uint32_t XK_less = 0x3C; -static constexpr uint32_t XK_equal = 0x3D; -static constexpr uint32_t XK_greater = 0x3E; -static constexpr uint32_t XK_question = 0x3F; -static constexpr uint32_t XK_at = 0x40; -static constexpr uint32_t XK_A = 0x41; -static constexpr uint32_t XK_Z = 0x5A; -static constexpr uint32_t XK_bracketleft = 0x5B; -static constexpr uint32_t XK_backslash = 0x5C; -static constexpr uint32_t XK_bracketright = 0x5D; -static constexpr uint32_t XK_asciicircum = 0x5E; -static constexpr uint32_t XK_underscore = 0x5F; -static constexpr uint32_t XK_quoteleft = 0x60; -static constexpr uint32_t XK_a = 0x61; -static constexpr uint32_t XK_z = 0x7A; -static constexpr uint32_t XK_braceleft = 0x7B; -static constexpr uint32_t XK_bar = 0x7C; -static constexpr uint32_t XK_braceright = 0x7D; -static constexpr uint32_t XK_asciitilde = 0x7E; -static constexpr uint32_t XK_exclamdown = 0xA1; -static constexpr uint32_t XK_brokenbar = 0xA6; -static constexpr uint32_t XK_guillemotleft = 0xAB; -static constexpr uint32_t XK_degree = 0xB0; -static constexpr uint32_t XK_periodcentered = 0xB7; -static constexpr uint32_t XK_guillemotright = 0xBB; -static constexpr uint32_t XK_questiondown = 0xBF; -static constexpr uint32_t XK_Agrave = 0xC0; -static constexpr uint32_t XK_Odiaeresis = 0xD6; -static constexpr uint32_t XK_multiply = 0xD7; -static constexpr uint32_t XK_Ooblique = 0xD8; -static constexpr uint32_t XK_Ugrave = 0xD9; -static constexpr uint32_t XK_Thorn = 0xDE; -static constexpr uint32_t XK_agrave = 0xE0; -static constexpr uint32_t XK_odiaeresis = 0xF6; -static constexpr uint32_t XK_oslash = 0xF8; -static constexpr uint32_t XK_ugrave = 0xF9; -static constexpr uint32_t XK_thorn = 0xFE; -static constexpr uint32_t XK_ydiaeresis = 0xFF; -static constexpr uint32_t XK_Aogonek = 0x1A1; -static constexpr uint32_t XK_breve = 0x1A2; -static constexpr uint32_t XK_Lstroke = 0x1A3; -static constexpr uint32_t XK_Lcaron = 0x1A5; -static constexpr uint32_t XK_Sacute = 0x1A6; -static constexpr uint32_t XK_Scaron = 0x1A9; -static constexpr uint32_t XK_Scedilla = 0x1AA; -static constexpr uint32_t XK_Tcaron = 0x1AB; -static constexpr uint32_t XK_Zacute = 0x1AC; -static constexpr uint32_t XK_Zcaron = 0x1AE; -static constexpr uint32_t XK_Zabovedot = 0x1AF; -static constexpr uint32_t XK_aogonek = 0x1B1; -static constexpr uint32_t XK_ogonek = 0x1B2; -static constexpr uint32_t XK_lstroke = 0x1B3; -static constexpr uint32_t XK_lcaron = 0x1B5; -static constexpr uint32_t XK_sacute = 0x1B6; -static constexpr uint32_t XK_caron = 0x1B7; -static constexpr uint32_t XK_scaron = 0x1B9; -static constexpr uint32_t XK_scedilla = 0x1BA; -static constexpr uint32_t XK_tcaron = 0x1BB; -static constexpr uint32_t XK_zacute = 0x1BC; -static constexpr uint32_t XK_doubleacute = 0x1BD; -static constexpr uint32_t XK_zcaron = 0x1BE; -static constexpr uint32_t XK_zabovedot = 0x1BF; -static constexpr uint32_t XK_Racute = 0x1C0; -static constexpr uint32_t XK_Abreve = 0x1C3; -static constexpr uint32_t XK_Lacute = 0x1C5; -static constexpr uint32_t XK_Cacute = 0x1C6; -static constexpr uint32_t XK_Ccaron = 0x1C8; -static constexpr uint32_t XK_Eogonek = 0x1CA; -static constexpr uint32_t XK_Ecaron = 0x1CC; -static constexpr uint32_t XK_Dcaron = 0x1CF; -static constexpr uint32_t XK_Dstroke = 0x1D0; -static constexpr uint32_t XK_Nacute = 0x1D1; -static constexpr uint32_t XK_Ncaron = 0x1D2; -static constexpr uint32_t XK_Odoubleacute = 0x1D5; -static constexpr uint32_t XK_Rcaron = 0x1D8; -static constexpr uint32_t XK_Uring = 0x1D9; -static constexpr uint32_t XK_Udoubleacute = 0x1DB; -static constexpr uint32_t XK_Tcedilla = 0x1DE; -static constexpr uint32_t XK_racute = 0x1E0; -static constexpr uint32_t XK_abreve = 0x1E3; -static constexpr uint32_t XK_lacute = 0x1E5; -static constexpr uint32_t XK_cacute = 0x1E6; -static constexpr uint32_t XK_ccaron = 0x1E8; -static constexpr uint32_t XK_eogonek = 0x1EA; -static constexpr uint32_t XK_ecaron = 0x1EC; -static constexpr uint32_t XK_dcaron = 0x1EF; -static constexpr uint32_t XK_dstroke = 0x1F0; -static constexpr uint32_t XK_nacute = 0x1F1; -static constexpr uint32_t XK_ncaron = 0x1F2; -static constexpr uint32_t XK_odoubleacute = 0x1F5; -static constexpr uint32_t XK_rcaron = 0x1F8; -static constexpr uint32_t XK_uring = 0x1F9; -static constexpr uint32_t XK_udoubleacute = 0x1FB; -static constexpr uint32_t XK_tcedilla = 0x1FE; -static constexpr uint32_t XK_abovedot = 0x1FF; -static constexpr uint32_t XK_Hstroke = 0x2A1; -static constexpr uint32_t XK_Hcircumflex = 0x2A6; -static constexpr uint32_t XK_Iabovedot = 0x2A9; -static constexpr uint32_t XK_Gbreve = 0x2AB; -static constexpr uint32_t XK_Jcircumflex = 0x2AC; -static constexpr uint32_t XK_hstroke = 0x2B1; -static constexpr uint32_t XK_hcircumflex = 0x2B6; -static constexpr uint32_t XK_idotless = 0x2B9; -static constexpr uint32_t XK_gbreve = 0x2BB; -static constexpr uint32_t XK_jcircumflex = 0x2BC; -static constexpr uint32_t XK_Cabovedot = 0x2C5; -static constexpr uint32_t XK_Ccircumflex = 0x2C6; -static constexpr uint32_t XK_Gabovedot = 0x2D5; -static constexpr uint32_t XK_Gcircumflex = 0x2D8; -static constexpr uint32_t XK_Ubreve = 0x2DD; -static constexpr uint32_t XK_Scircumflex = 0x2DE; -static constexpr uint32_t XK_cabovedot = 0x2E5; -static constexpr uint32_t XK_ccircumflex = 0x2E6; -static constexpr uint32_t XK_gabovedot = 0x2F5; -static constexpr uint32_t XK_gcircumflex = 0x2F8; -static constexpr uint32_t XK_ubreve = 0x2FD; -static constexpr uint32_t XK_scircumflex = 0x2FE; -static constexpr uint32_t XK_kra = 0x3A2; -static constexpr uint32_t XK_Rcedilla = 0x3A3; -static constexpr uint32_t XK_Itilde = 0x3A5; -static constexpr uint32_t XK_Lcedilla = 0x3A6; -static constexpr uint32_t XK_Emacron = 0x3AA; -static constexpr uint32_t XK_Gcedilla = 0x3AB; -static constexpr uint32_t XK_Tslash = 0x3AC; -static constexpr uint32_t XK_rcedilla = 0x3B3; -static constexpr uint32_t XK_itilde = 0x3B5; -static constexpr uint32_t XK_lcedilla = 0x3B6; -static constexpr uint32_t XK_emacron = 0x3BA; -static constexpr uint32_t XK_gcedilla = 0x3BB; -static constexpr uint32_t XK_tslash = 0x3BC; -static constexpr uint32_t XK_ENG = 0x3BD; -static constexpr uint32_t XK_eng = 0x3BF; -static constexpr uint32_t XK_Amacron = 0x3C0; -static constexpr uint32_t XK_Iogonek = 0x3C7; -static constexpr uint32_t XK_Eabovedot = 0x3CC; -static constexpr uint32_t XK_Imacron = 0x3CF; -static constexpr uint32_t XK_Ncedilla = 0x3D1; -static constexpr uint32_t XK_Omacron = 0x3D2; -static constexpr uint32_t XK_Kcedilla = 0x3D3; -static constexpr uint32_t XK_Uogonek = 0x3D9; -static constexpr uint32_t XK_Utilde = 0x3DD; -static constexpr uint32_t XK_Umacron = 0x3DE; -static constexpr uint32_t XK_amacron = 0x3E0; -static constexpr uint32_t XK_iogonek = 0x3E7; -static constexpr uint32_t XK_eabovedot = 0x3EC; -static constexpr uint32_t XK_imacron = 0x3EF; -static constexpr uint32_t XK_ncedilla = 0x3F1; -static constexpr uint32_t XK_omacron = 0x3F2; -static constexpr uint32_t XK_kcedilla = 0x3F3; -static constexpr uint32_t XK_uogonek = 0x3F9; -static constexpr uint32_t XK_utilde = 0x3FD; -static constexpr uint32_t XK_umacron = 0x3FE; -static constexpr uint32_t XK_overline = 0x47E; -static constexpr uint32_t XK_kana_fullstop = 0x4A1; -static constexpr uint32_t XK_kana_openingbracket = 0x4A2; -static constexpr uint32_t XK_kana_closingbracket = 0x4A3; -static constexpr uint32_t XK_kana_comma = 0x4A4; -static constexpr uint32_t XK_kana_conjunctive = 0x4A5; -static constexpr uint32_t XK_kana_WO = 0x4A6; -static constexpr uint32_t XK_kana_a = 0x4A7; -static constexpr uint32_t XK_kana_i = 0x4A8; -static constexpr uint32_t XK_kana_u = 0x4A9; -static constexpr uint32_t XK_kana_e = 0x4AA; -static constexpr uint32_t XK_kana_o = 0x4AB; -static constexpr uint32_t XK_kana_ya = 0x4AC; -static constexpr uint32_t XK_kana_yu = 0x4AD; -static constexpr uint32_t XK_kana_yo = 0x4AE; -static constexpr uint32_t XK_kana_tsu = 0x4AF; -static constexpr uint32_t XK_prolongedsound = 0x4B0; -static constexpr uint32_t XK_kana_A = 0x4B1; -static constexpr uint32_t XK_kana_I = 0x4B2; -static constexpr uint32_t XK_kana_U = 0x4B3; -static constexpr uint32_t XK_kana_E = 0x4B4; -static constexpr uint32_t XK_kana_O = 0x4B5; -static constexpr uint32_t XK_kana_KA = 0x4B6; -static constexpr uint32_t XK_kana_KI = 0x4B7; -static constexpr uint32_t XK_kana_KU = 0x4B8; -static constexpr uint32_t XK_kana_KE = 0x4B9; -static constexpr uint32_t XK_kana_KO = 0x4BA; -static constexpr uint32_t XK_kana_SA = 0x4BB; -static constexpr uint32_t XK_kana_SHI = 0x4BC; -static constexpr uint32_t XK_kana_SU = 0x4BD; -static constexpr uint32_t XK_kana_SE = 0x4BE; -static constexpr uint32_t XK_kana_SO = 0x4BF; -static constexpr uint32_t XK_kana_TA = 0x4C0; -static constexpr uint32_t XK_kana_CHI = 0x4C1; -static constexpr uint32_t XK_kana_TSU = 0x4C2; -static constexpr uint32_t XK_kana_TE = 0x4C3; -static constexpr uint32_t XK_kana_TO = 0x4C4; -static constexpr uint32_t XK_kana_NA = 0x4C5; -static constexpr uint32_t XK_kana_NI = 0x4C6; -static constexpr uint32_t XK_kana_NU = 0x4C7; -static constexpr uint32_t XK_kana_NE = 0x4C8; -static constexpr uint32_t XK_kana_NO = 0x4C9; -static constexpr uint32_t XK_kana_HA = 0x4CA; -static constexpr uint32_t XK_kana_HI = 0x4CB; -static constexpr uint32_t XK_kana_FU = 0x4CC; -static constexpr uint32_t XK_kana_HE = 0x4CD; -static constexpr uint32_t XK_kana_HO = 0x4CE; -static constexpr uint32_t XK_kana_MA = 0x4CF; -static constexpr uint32_t XK_kana_MI = 0x4D0; -static constexpr uint32_t XK_kana_MU = 0x4D1; -static constexpr uint32_t XK_kana_ME = 0x4D2; -static constexpr uint32_t XK_kana_MO = 0x4D3; -static constexpr uint32_t XK_kana_YA = 0x4D4; -static constexpr uint32_t XK_kana_YU = 0x4D5; -static constexpr uint32_t XK_kana_YO = 0x4D6; -static constexpr uint32_t XK_kana_RA = 0x4D7; -static constexpr uint32_t XK_kana_RI = 0x4D8; -static constexpr uint32_t XK_kana_RU = 0x4D9; -static constexpr uint32_t XK_kana_RE = 0x4DA; -static constexpr uint32_t XK_kana_RO = 0x4DB; -static constexpr uint32_t XK_kana_WA = 0x4DC; -static constexpr uint32_t XK_kana_N = 0x4DD; -static constexpr uint32_t XK_voicedsound = 0x4DE; -static constexpr uint32_t XK_semivoicedsound = 0x4DF; -static constexpr uint32_t XK_Arabic_comma = 0x5AC; -static constexpr uint32_t XK_Arabic_semicolon = 0x5BB; -static constexpr uint32_t XK_Arabic_question_mark = 0x5BF; -static constexpr uint32_t XK_Arabic_hamza = 0x5C1; -static constexpr uint32_t XK_Arabic_maddaonalef = 0x5C2; -static constexpr uint32_t XK_Arabic_hamzaonalef = 0x5C3; -static constexpr uint32_t XK_Arabic_hamzaonwaw = 0x5C4; -static constexpr uint32_t XK_Arabic_hamzaunderalef = 0x5C5; -static constexpr uint32_t XK_Arabic_hamzaonyeh = 0x5C6; -static constexpr uint32_t XK_Arabic_alef = 0x5C7; -static constexpr uint32_t XK_Arabic_beh = 0x5C8; -static constexpr uint32_t XK_Arabic_tehmarbuta = 0x5C9; -static constexpr uint32_t XK_Arabic_teh = 0x5CA; -static constexpr uint32_t XK_Arabic_theh = 0x5CB; -static constexpr uint32_t XK_Arabic_jeem = 0x5CC; -static constexpr uint32_t XK_Arabic_hah = 0x5CD; -static constexpr uint32_t XK_Arabic_khah = 0x5CE; -static constexpr uint32_t XK_Arabic_dal = 0x5CF; -static constexpr uint32_t XK_Arabic_thal = 0x5D0; -static constexpr uint32_t XK_Arabic_ra = 0x5D1; -static constexpr uint32_t XK_Arabic_zain = 0x5D2; -static constexpr uint32_t XK_Arabic_seen = 0x5D3; -static constexpr uint32_t XK_Arabic_sheen = 0x5D4; -static constexpr uint32_t XK_Arabic_sad = 0x5D5; -static constexpr uint32_t XK_Arabic_dad = 0x5D6; -static constexpr uint32_t XK_Arabic_tah = 0x5D7; -static constexpr uint32_t XK_Arabic_zah = 0x5D8; -static constexpr uint32_t XK_Arabic_ain = 0x5D9; -static constexpr uint32_t XK_Arabic_ghain = 0x5DA; -static constexpr uint32_t XK_Arabic_tatweel = 0x5E0; -static constexpr uint32_t XK_Arabic_feh = 0x5E1; -static constexpr uint32_t XK_Arabic_qaf = 0x5E2; -static constexpr uint32_t XK_Arabic_kaf = 0x5E3; -static constexpr uint32_t XK_Arabic_lam = 0x5E4; -static constexpr uint32_t XK_Arabic_meem = 0x5E5; -static constexpr uint32_t XK_Arabic_noon = 0x5E6; -static constexpr uint32_t XK_Arabic_ha = 0x5E7; -static constexpr uint32_t XK_Arabic_waw = 0x5E8; -static constexpr uint32_t XK_Arabic_alefmaksura = 0x5E9; -static constexpr uint32_t XK_Arabic_yeh = 0x5EA; -static constexpr uint32_t XK_Arabic_fathatan = 0x5EB; -static constexpr uint32_t XK_Arabic_dammatan = 0x5EC; -static constexpr uint32_t XK_Arabic_kasratan = 0x5ED; -static constexpr uint32_t XK_Arabic_fatha = 0x5EE; -static constexpr uint32_t XK_Arabic_damma = 0x5EF; -static constexpr uint32_t XK_Arabic_kasra = 0x5F0; -static constexpr uint32_t XK_Arabic_shadda = 0x5F1; -static constexpr uint32_t XK_Arabic_sukun = 0x5F2; -static constexpr uint32_t XK_Serbian_dje = 0x6A1; -static constexpr uint32_t XK_Macedonia_gje = 0x6A2; -static constexpr uint32_t XK_Cyrillic_io = 0x6A3; -static constexpr uint32_t XK_Ukrainian_ie = 0x6A4; -static constexpr uint32_t XK_Macedonia_dse = 0x6A5; -static constexpr uint32_t XK_Ukrainian_i = 0x6A6; -static constexpr uint32_t XK_Ukrainian_yi = 0x6A7; -static constexpr uint32_t XK_Cyrillic_je = 0x6A8; -static constexpr uint32_t XK_Cyrillic_lje = 0x6A9; -static constexpr uint32_t XK_Cyrillic_nje = 0x6AA; -static constexpr uint32_t XK_Serbian_tshe = 0x6AB; -static constexpr uint32_t XK_Macedonia_kje = 0x6AC; -static constexpr uint32_t XK_Ukrainian_ghe_with_upturn = 0x6AD; -static constexpr uint32_t XK_Byelorussian_shortu = 0x6AE; -static constexpr uint32_t XK_Cyrillic_dzhe = 0x6AF; -static constexpr uint32_t XK_Serbian_dze = 0x6AF; -static constexpr uint32_t XK_numerosign = 0x6B0; -static constexpr uint32_t XK_Serbian_DJE = 0x6B1; -static constexpr uint32_t XK_Macedonia_GJE = 0x6B2; -static constexpr uint32_t XK_Cyrillic_IO = 0x6B3; -static constexpr uint32_t XK_Ukrainian_IE = 0x6B4; -static constexpr uint32_t XK_Macedonia_DSE = 0x6B5; -static constexpr uint32_t XK_Ukrainian_I = 0x6B6; -static constexpr uint32_t XK_Ukrainian_YI = 0x6B7; -static constexpr uint32_t XK_Cyrillic_JE = 0x6B8; -static constexpr uint32_t XK_Cyrillic_LJE = 0x6B9; -static constexpr uint32_t XK_Cyrillic_NJE = 0x6BA; -static constexpr uint32_t XK_Serbian_TSHE = 0x6BB; -static constexpr uint32_t XK_Macedonia_KJE = 0x6BC; -static constexpr uint32_t XK_Ukrainian_GHE_WITH_UPTURN = 0x6BD; -static constexpr uint32_t XK_Byelorussian_SHORTU = 0x6BE; -static constexpr uint32_t XK_Cyrillic_DZHE = 0x6BF; -static constexpr uint32_t XK_Serbian_DZE = 0x6BF; -static constexpr uint32_t XK_Cyrillic_yu = 0x6C0; -static constexpr uint32_t XK_Cyrillic_a = 0x6C1; -static constexpr uint32_t XK_Cyrillic_be = 0x6C2; -static constexpr uint32_t XK_Cyrillic_tse = 0x6C3; -static constexpr uint32_t XK_Cyrillic_de = 0x6C4; -static constexpr uint32_t XK_Cyrillic_ie = 0x6C5; -static constexpr uint32_t XK_Cyrillic_ef = 0x6C6; -static constexpr uint32_t XK_Cyrillic_ghe = 0x6C7; -static constexpr uint32_t XK_Cyrillic_ha = 0x6C8; -static constexpr uint32_t XK_Cyrillic_i = 0x6C9; -static constexpr uint32_t XK_Cyrillic_shorti = 0x6CA; -static constexpr uint32_t XK_Cyrillic_ka = 0x6CB; -static constexpr uint32_t XK_Cyrillic_el = 0x6CC; -static constexpr uint32_t XK_Cyrillic_em = 0x6CD; -static constexpr uint32_t XK_Cyrillic_en = 0x6CE; -static constexpr uint32_t XK_Cyrillic_o = 0x6CF; -static constexpr uint32_t XK_Cyrillic_pe = 0x6D0; -static constexpr uint32_t XK_Cyrillic_ya = 0x6D1; -static constexpr uint32_t XK_Cyrillic_er = 0x6D2; -static constexpr uint32_t XK_Cyrillic_es = 0x6D3; -static constexpr uint32_t XK_Cyrillic_te = 0x6D4; -static constexpr uint32_t XK_Cyrillic_u = 0x6D5; -static constexpr uint32_t XK_Cyrillic_zhe = 0x6D6; -static constexpr uint32_t XK_Cyrillic_ve = 0x6D7; -static constexpr uint32_t XK_Cyrillic_softsign = 0x6D8; -static constexpr uint32_t XK_Cyrillic_yeru = 0x6D9; -static constexpr uint32_t XK_Cyrillic_ze = 0x6DA; -static constexpr uint32_t XK_Cyrillic_sha = 0x6DB; -static constexpr uint32_t XK_Cyrillic_e = 0x6DC; -static constexpr uint32_t XK_Cyrillic_shcha = 0x6DD; -static constexpr uint32_t XK_Cyrillic_che = 0x6DE; -static constexpr uint32_t XK_Cyrillic_hardsign = 0x6DF; -static constexpr uint32_t XK_Cyrillic_YU = 0x6E0; -static constexpr uint32_t XK_Cyrillic_A = 0x6E1; -static constexpr uint32_t XK_Cyrillic_BE = 0x6E2; -static constexpr uint32_t XK_Cyrillic_TSE = 0x6E3; -static constexpr uint32_t XK_Cyrillic_DE = 0x6E4; -static constexpr uint32_t XK_Cyrillic_IE = 0x6E5; -static constexpr uint32_t XK_Cyrillic_EF = 0x6E6; -static constexpr uint32_t XK_Cyrillic_GHE = 0x6E7; -static constexpr uint32_t XK_Cyrillic_HA = 0x6E8; -static constexpr uint32_t XK_Cyrillic_I = 0x6E9; -static constexpr uint32_t XK_Cyrillic_SHORTI = 0x6EA; -static constexpr uint32_t XK_Cyrillic_KA = 0x6EB; -static constexpr uint32_t XK_Cyrillic_EL = 0x6EC; -static constexpr uint32_t XK_Cyrillic_EM = 0x6ED; -static constexpr uint32_t XK_Cyrillic_EN = 0x6EE; -static constexpr uint32_t XK_Cyrillic_O = 0x6EF; -static constexpr uint32_t XK_Cyrillic_PE = 0x6F0; -static constexpr uint32_t XK_Cyrillic_YA = 0x6F1; -static constexpr uint32_t XK_Cyrillic_ER = 0x6F2; -static constexpr uint32_t XK_Cyrillic_ES = 0x6F3; -static constexpr uint32_t XK_Cyrillic_TE = 0x6F4; -static constexpr uint32_t XK_Cyrillic_U = 0x6F5; -static constexpr uint32_t XK_Cyrillic_ZHE = 0x6F6; -static constexpr uint32_t XK_Cyrillic_VE = 0x6F7; -static constexpr uint32_t XK_Cyrillic_SOFTSIGN = 0x6F8; -static constexpr uint32_t XK_Cyrillic_YERU = 0x6F9; -static constexpr uint32_t XK_Cyrillic_ZE = 0x6FA; -static constexpr uint32_t XK_Cyrillic_SHA = 0x6FB; -static constexpr uint32_t XK_Cyrillic_E = 0x6FC; -static constexpr uint32_t XK_Cyrillic_SHCHA = 0x6FD; -static constexpr uint32_t XK_Cyrillic_CHE = 0x6FE; -static constexpr uint32_t XK_Cyrillic_HARDSIGN = 0x6FF; -static constexpr uint32_t XK_Greek_ALPHAaccent = 0x7A1; -static constexpr uint32_t XK_Greek_EPSILONaccent = 0x7A2; -static constexpr uint32_t XK_Greek_ETAaccent = 0x7A3; -static constexpr uint32_t XK_Greek_IOTAaccent = 0x7A4; -static constexpr uint32_t XK_Greek_IOTAdiaeresis = 0x7A5; -static constexpr uint32_t XK_Greek_IOTAdieresis = 0x7A5; -static constexpr uint32_t XK_Greek_OMICRONaccent = 0x7A7; -static constexpr uint32_t XK_Greek_UPSILONaccent = 0x7A8; -static constexpr uint32_t XK_Greek_UPSILONdieresis = 0x7A9; -static constexpr uint32_t XK_Greek_OMEGAaccent = 0x7AB; -static constexpr uint32_t XK_Greek_accentdieresis = 0x7AE; -static constexpr uint32_t XK_Greek_horizbar = 0x7AF; -static constexpr uint32_t XK_Greek_alphaaccent = 0x7B1; -static constexpr uint32_t XK_Greek_epsilonaccent = 0x7B2; -static constexpr uint32_t XK_Greek_etaaccent = 0x7B3; -static constexpr uint32_t XK_Greek_iotaaccent = 0x7B4; -static constexpr uint32_t XK_Greek_iotadieresis = 0x7B5; -static constexpr uint32_t XK_Greek_iotaaccentdieresis = 0x7B6; -static constexpr uint32_t XK_Greek_omicronaccent = 0x7B7; -static constexpr uint32_t XK_Greek_upsilonaccent = 0x7B8; -static constexpr uint32_t XK_Greek_upsilondieresis = 0x7B9; -static constexpr uint32_t XK_Greek_upsilonaccentdieresis = 0x7BA; -static constexpr uint32_t XK_Greek_omegaaccent = 0x7BB; -static constexpr uint32_t XK_Greek_ALPHA = 0x7C1; -static constexpr uint32_t XK_Greek_BETA = 0x7C2; -static constexpr uint32_t XK_Greek_GAMMA = 0x7C3; -static constexpr uint32_t XK_Greek_DELTA = 0x7C4; -static constexpr uint32_t XK_Greek_EPSILON = 0x7C5; -static constexpr uint32_t XK_Greek_ZETA = 0x7C6; -static constexpr uint32_t XK_Greek_ETA = 0x7C7; -static constexpr uint32_t XK_Greek_THETA = 0x7C8; -static constexpr uint32_t XK_Greek_IOTA = 0x7C9; -static constexpr uint32_t XK_Greek_KAPPA = 0x7CA; -static constexpr uint32_t XK_Greek_LAMBDA = 0x7CB; -static constexpr uint32_t XK_Greek_LAMDA = 0x7CB; -static constexpr uint32_t XK_Greek_MU = 0x7CC; -static constexpr uint32_t XK_Greek_NU = 0x7CD; -static constexpr uint32_t XK_Greek_XI = 0x7CE; -static constexpr uint32_t XK_Greek_OMICRON = 0x7CF; -static constexpr uint32_t XK_Greek_PI = 0x7D0; -static constexpr uint32_t XK_Greek_RHO = 0x7D1; -static constexpr uint32_t XK_Greek_SIGMA = 0x7D2; -static constexpr uint32_t XK_Greek_TAU = 0x7D4; -static constexpr uint32_t XK_Greek_UPSILON = 0x7D5; -static constexpr uint32_t XK_Greek_PHI = 0x7D6; -static constexpr uint32_t XK_Greek_CHI = 0x7D7; -static constexpr uint32_t XK_Greek_PSI = 0x7D8; -static constexpr uint32_t XK_Greek_OMEGA = 0x7D9; -static constexpr uint32_t XK_Greek_alpha = 0x7E1; -static constexpr uint32_t XK_Greek_beta = 0x7E2; -static constexpr uint32_t XK_Greek_gamma = 0x7E3; -static constexpr uint32_t XK_Greek_delta = 0x7E4; -static constexpr uint32_t XK_Greek_epsilon = 0x7E5; -static constexpr uint32_t XK_Greek_zeta = 0x7E6; -static constexpr uint32_t XK_Greek_eta = 0x7E7; -static constexpr uint32_t XK_Greek_theta = 0x7E8; -static constexpr uint32_t XK_Greek_iota = 0x7E9; -static constexpr uint32_t XK_Greek_kappa = 0x7EA; -static constexpr uint32_t XK_Greek_lambda = 0x7EB; -static constexpr uint32_t XK_Greek_lamda = 0x7EB; -static constexpr uint32_t XK_Greek_mu = 0x7EC; -static constexpr uint32_t XK_Greek_nu = 0x7ED; -static constexpr uint32_t XK_Greek_xi = 0x7EE; -static constexpr uint32_t XK_Greek_omicron = 0x7EF; -static constexpr uint32_t XK_Greek_pi = 0x7F0; -static constexpr uint32_t XK_Greek_rho = 0x7F1; -static constexpr uint32_t XK_Greek_sigma = 0x7F2; -static constexpr uint32_t XK_Greek_finalsmallsigma = 0x7F3; -static constexpr uint32_t XK_Greek_tau = 0x7F4; -static constexpr uint32_t XK_Greek_upsilon = 0x7F5; -static constexpr uint32_t XK_Greek_phi = 0x7F6; -static constexpr uint32_t XK_Greek_chi = 0x7F7; -static constexpr uint32_t XK_Greek_psi = 0x7F8; -static constexpr uint32_t XK_Greek_omega = 0x7F9; -static constexpr uint32_t XK_leftradical = 0x8A1; -static constexpr uint32_t XK_topleftradical = 0x8A2; -static constexpr uint32_t XK_horizconnector = 0x8A3; -static constexpr uint32_t XK_topintegral = 0x8A4; -static constexpr uint32_t XK_botintegral = 0x8A5; -static constexpr uint32_t XK_vertconnector = 0x8A6; -static constexpr uint32_t XK_topleftsqbracket = 0x8A7; -static constexpr uint32_t XK_botleftsqbracket = 0x8A8; -static constexpr uint32_t XK_toprightsqbracket = 0x8A9; -static constexpr uint32_t XK_botrightsqbracket = 0x8AA; -static constexpr uint32_t XK_topleftparens = 0x8AB; -static constexpr uint32_t XK_botleftparens = 0x8AC; -static constexpr uint32_t XK_toprightparens = 0x8AD; -static constexpr uint32_t XK_botrightparens = 0x8AE; -static constexpr uint32_t XK_leftmiddlecurlybrace = 0x8AF; -static constexpr uint32_t XK_rightmiddlecurlybrace = 0x8B0; -static constexpr uint32_t XK_lessthanequal = 0x8BC; -static constexpr uint32_t XK_notequal = 0x8BD; -static constexpr uint32_t XK_greaterthanequal = 0x8BE; -static constexpr uint32_t XK_integral = 0x8BF; -static constexpr uint32_t XK_therefore = 0x8C0; -static constexpr uint32_t XK_variation = 0x8C1; -static constexpr uint32_t XK_infinity = 0x8C2; -static constexpr uint32_t XK_nabla = 0x8C5; -static constexpr uint32_t XK_approximate = 0x8C8; -static constexpr uint32_t XK_similarequal = 0x8C9; -static constexpr uint32_t XK_ifonlyif = 0x8CD; -static constexpr uint32_t XK_implies = 0x8CE; -static constexpr uint32_t XK_identical = 0x8CF; -static constexpr uint32_t XK_radical = 0x8D6; -static constexpr uint32_t XK_includedin = 0x8DA; -static constexpr uint32_t XK_includes = 0x8DB; -static constexpr uint32_t XK_intersection = 0x8DC; -static constexpr uint32_t XK_union = 0x8DD; -static constexpr uint32_t XK_logicaland = 0x8DE; -static constexpr uint32_t XK_logicalor = 0x8DF; -static constexpr uint32_t XK_partialderivative = 0x8EF; -static constexpr uint32_t XK_function = 0x8F6; -static constexpr uint32_t XK_leftarrow = 0x8FB; -static constexpr uint32_t XK_uparrow = 0x8FC; -static constexpr uint32_t XK_rightarrow = 0x8FD; -static constexpr uint32_t XK_downarrow = 0x8FE; -static constexpr uint32_t XK_soliddiamond = 0x9E0; -static constexpr uint32_t XK_checkerboard = 0x9E1; -static constexpr uint32_t XK_ht = 0x9E2; -static constexpr uint32_t XK_ff = 0x9E3; -static constexpr uint32_t XK_cr = 0x9E4; -static constexpr uint32_t XK_lf = 0x9E5; -static constexpr uint32_t XK_nl = 0x9E8; -static constexpr uint32_t XK_vt = 0x9E9; -static constexpr uint32_t XK_lowrightcorner = 0x9EA; -static constexpr uint32_t XK_uprightcorner = 0x9EB; -static constexpr uint32_t XK_upleftcorner = 0x9EC; -static constexpr uint32_t XK_lowleftcorner = 0x9ED; -static constexpr uint32_t XK_crossinglines = 0x9EE; -static constexpr uint32_t XK_horizlinescan1 = 0x9EF; -static constexpr uint32_t XK_horizlinescan3 = 0x9F0; -static constexpr uint32_t XK_horizlinescan5 = 0x9F1; -static constexpr uint32_t XK_horizlinescan7 = 0x9F2; -static constexpr uint32_t XK_horizlinescan9 = 0x9F3; -static constexpr uint32_t XK_leftt = 0x9F4; -static constexpr uint32_t XK_rightt = 0x9F5; -static constexpr uint32_t XK_bott = 0x9F6; -static constexpr uint32_t XK_topt = 0x9F7; -static constexpr uint32_t XK_vertbar = 0x9F8; -static constexpr uint32_t XK_emspace = 0xAA1; -static constexpr uint32_t XK_enspace = 0xAA2; -static constexpr uint32_t XK_em3space = 0xAA3; -static constexpr uint32_t XK_em4space = 0xAA4; -static constexpr uint32_t XK_digitspace = 0xAA5; -static constexpr uint32_t XK_punctspace = 0xAA6; -static constexpr uint32_t XK_thinspace = 0xAA7; -static constexpr uint32_t XK_hairspace = 0xAA8; -static constexpr uint32_t XK_emdash = 0xAA9; -static constexpr uint32_t XK_endash = 0xAAA; -static constexpr uint32_t XK_signifblank = 0xAAC; -static constexpr uint32_t XK_ellipsis = 0xAAE; -static constexpr uint32_t XK_doubbaselinedot = 0xAAF; -static constexpr uint32_t XK_onethird = 0xAB0; -static constexpr uint32_t XK_twothirds = 0xAB1; -static constexpr uint32_t XK_onefifth = 0xAB2; -static constexpr uint32_t XK_twofifths = 0xAB3; -static constexpr uint32_t XK_threefifths = 0xAB4; -static constexpr uint32_t XK_fourfifths = 0xAB5; -static constexpr uint32_t XK_onesixth = 0xAB6; -static constexpr uint32_t XK_fivesixths = 0xAB7; -static constexpr uint32_t XK_careof = 0xAB8; -static constexpr uint32_t XK_figdash = 0xABB; -static constexpr uint32_t XK_leftanglebracket = 0xABC; -static constexpr uint32_t XK_decimalpoint = 0xABD; -static constexpr uint32_t XK_rightanglebracket = 0xABE; -static constexpr uint32_t XK_oneeighth = 0xAC3; -static constexpr uint32_t XK_threeeighths = 0xAC4; -static constexpr uint32_t XK_fiveeighths = 0xAC5; -static constexpr uint32_t XK_seveneighths = 0xAC6; -static constexpr uint32_t XK_trademark = 0xAC9; -static constexpr uint32_t XK_signaturemark = 0xACA; -static constexpr uint32_t XK_leftopentriangle = 0xACC; -static constexpr uint32_t XK_rightopentriangle = 0xACD; -static constexpr uint32_t XK_emopencircle = 0xACE; -static constexpr uint32_t XK_emopenrectangle = 0xACF; -static constexpr uint32_t XK_leftsinglequotemark = 0xAD0; -static constexpr uint32_t XK_rightsinglequotemark = 0xAD1; -static constexpr uint32_t XK_leftdoublequotemark = 0xAD2; -static constexpr uint32_t XK_rightdoublequotemark = 0xAD3; -static constexpr uint32_t XK_prescription = 0xAD4; -static constexpr uint32_t XK_minutes = 0xAD6; -static constexpr uint32_t XK_seconds = 0xAD7; -static constexpr uint32_t XK_latincross = 0xAD9; -static constexpr uint32_t XK_filledrectbullet = 0xADB; -static constexpr uint32_t XK_filledlefttribullet = 0xADC; -static constexpr uint32_t XK_filledrighttribullet = 0xADD; -static constexpr uint32_t XK_emfilledcircle = 0xADE; -static constexpr uint32_t XK_emfilledrect = 0xADF; -static constexpr uint32_t XK_enopencircbullet = 0xAE0; -static constexpr uint32_t XK_enopensquarebullet = 0xAE1; -static constexpr uint32_t XK_openrectbullet = 0xAE2; -static constexpr uint32_t XK_opentribulletup = 0xAE3; -static constexpr uint32_t XK_opentribulletdown = 0xAE4; -static constexpr uint32_t XK_openstar = 0xAE5; -static constexpr uint32_t XK_enfilledcircbullet = 0xAE6; -static constexpr uint32_t XK_enfilledsqbullet = 0xAE7; -static constexpr uint32_t XK_filledtribulletup = 0xAE8; -static constexpr uint32_t XK_filledtribulletdown = 0xAE9; -static constexpr uint32_t XK_leftpointer = 0xAEA; -static constexpr uint32_t XK_rightpointer = 0xAEB; -static constexpr uint32_t XK_club = 0xAEC; -static constexpr uint32_t XK_diamond = 0xAED; -static constexpr uint32_t XK_heart = 0xAEE; -static constexpr uint32_t XK_maltesecross = 0xAF0; -static constexpr uint32_t XK_dagger = 0xAF1; -static constexpr uint32_t XK_doubledagger = 0xAF2; -static constexpr uint32_t XK_checkmark = 0xAF3; -static constexpr uint32_t XK_ballotcross = 0xAF4; -static constexpr uint32_t XK_musicalsharp = 0xAF5; -static constexpr uint32_t XK_musicalflat = 0xAF6; -static constexpr uint32_t XK_malesymbol = 0xAF7; -static constexpr uint32_t XK_femalesymbol = 0xAF8; -static constexpr uint32_t XK_telephone = 0xAF9; -static constexpr uint32_t XK_telephonerecorder = 0xAFA; -static constexpr uint32_t XK_phonographcopyright = 0xAFB; -static constexpr uint32_t XK_caret = 0xAFC; -static constexpr uint32_t XK_singlelowquotemark = 0xAFD; -static constexpr uint32_t XK_doublelowquotemark = 0xAFE; -static constexpr uint32_t XK_leftcaret = 0xBA3; -static constexpr uint32_t XK_rightcaret = 0xBA6; -static constexpr uint32_t XK_downcaret = 0xBA8; -static constexpr uint32_t XK_upcaret = 0xBA9; -static constexpr uint32_t XK_overbar = 0xBC0; -static constexpr uint32_t XK_downtack = 0xBC2; -static constexpr uint32_t XK_upshoe = 0xBC3; -static constexpr uint32_t XK_downstile = 0xBC4; -static constexpr uint32_t XK_underbar = 0xBC6; -static constexpr uint32_t XK_jot = 0xBCA; -static constexpr uint32_t XK_quad = 0xBCC; -static constexpr uint32_t XK_uptack = 0xBCE; -static constexpr uint32_t XK_circle = 0xBCF; -static constexpr uint32_t XK_upstile = 0xBD3; -static constexpr uint32_t XK_downshoe = 0xBD6; -static constexpr uint32_t XK_rightshoe = 0xBD8; -static constexpr uint32_t XK_leftshoe = 0xBDA; -static constexpr uint32_t XK_lefttack = 0xBDC; -static constexpr uint32_t XK_righttack = 0xBFC; -static constexpr uint32_t XK_hebrew_doublelowline = 0xCDF; -static constexpr uint32_t XK_hebrew_aleph = 0xCE0; -static constexpr uint32_t XK_hebrew_bet = 0xCE1; -static constexpr uint32_t XK_hebrew_gimel = 0xCE2; -static constexpr uint32_t XK_hebrew_dalet = 0xCE3; -static constexpr uint32_t XK_hebrew_he = 0xCE4; -static constexpr uint32_t XK_hebrew_waw = 0xCE5; -static constexpr uint32_t XK_hebrew_zain = 0xCE6; -static constexpr uint32_t XK_hebrew_chet = 0xCE7; -static constexpr uint32_t XK_hebrew_tet = 0xCE8; -static constexpr uint32_t XK_hebrew_yod = 0xCE9; -static constexpr uint32_t XK_hebrew_finalkaph = 0xCEA; -static constexpr uint32_t XK_hebrew_kaph = 0xCEB; -static constexpr uint32_t XK_hebrew_lamed = 0xCEC; -static constexpr uint32_t XK_hebrew_finalmem = 0xCED; -static constexpr uint32_t XK_hebrew_mem = 0xCEE; -static constexpr uint32_t XK_hebrew_finalnun = 0xCEF; -static constexpr uint32_t XK_hebrew_nun = 0xCF0; -static constexpr uint32_t XK_hebrew_samech = 0xCF1; -static constexpr uint32_t XK_hebrew_ayin = 0xCF2; -static constexpr uint32_t XK_hebrew_finalpe = 0xCF3; -static constexpr uint32_t XK_hebrew_pe = 0xCF4; -static constexpr uint32_t XK_hebrew_finalzade = 0xCF5; -static constexpr uint32_t XK_hebrew_zade = 0xCF6; -static constexpr uint32_t XK_hebrew_qoph = 0xCF7; -static constexpr uint32_t XK_hebrew_resh = 0xCF8; -static constexpr uint32_t XK_hebrew_shin = 0xCF9; -static constexpr uint32_t XK_hebrew_taw = 0xCFA; -static constexpr uint32_t XK_Thai_kokai = 0xDA1; -static constexpr uint32_t XK_Thai_khokhai = 0xDA2; -static constexpr uint32_t XK_Thai_khokhuat = 0xDA3; -static constexpr uint32_t XK_Thai_khokhwai = 0xDA4; -static constexpr uint32_t XK_Thai_khokhon = 0xDA5; -static constexpr uint32_t XK_Thai_khorakhang = 0xDA6; -static constexpr uint32_t XK_Thai_ngongu = 0xDA7; -static constexpr uint32_t XK_Thai_chochan = 0xDA8; -static constexpr uint32_t XK_Thai_choching = 0xDA9; -static constexpr uint32_t XK_Thai_chochang = 0xDAA; -static constexpr uint32_t XK_Thai_soso = 0xDAB; -static constexpr uint32_t XK_Thai_chochoe = 0xDAC; -static constexpr uint32_t XK_Thai_yoying = 0xDAD; -static constexpr uint32_t XK_Thai_dochada = 0xDAE; -static constexpr uint32_t XK_Thai_topatak = 0xDAF; -static constexpr uint32_t XK_Thai_thothan = 0xDB0; -static constexpr uint32_t XK_Thai_thonangmontho = 0xDB1; -static constexpr uint32_t XK_Thai_thophuthao = 0xDB2; -static constexpr uint32_t XK_Thai_nonen = 0xDB3; -static constexpr uint32_t XK_Thai_dodek = 0xDB4; -static constexpr uint32_t XK_Thai_totao = 0xDB5; -static constexpr uint32_t XK_Thai_thothung = 0xDB6; -static constexpr uint32_t XK_Thai_thothahan = 0xDB7; -static constexpr uint32_t XK_Thai_thothong = 0xDB8; -static constexpr uint32_t XK_Thai_nonu = 0xDB9; -static constexpr uint32_t XK_Thai_bobaimai = 0xDBA; -static constexpr uint32_t XK_Thai_popla = 0xDBB; -static constexpr uint32_t XK_Thai_phophung = 0xDBC; -static constexpr uint32_t XK_Thai_fofa = 0xDBD; -static constexpr uint32_t XK_Thai_phophan = 0xDBE; -static constexpr uint32_t XK_Thai_fofan = 0xDBF; -static constexpr uint32_t XK_Thai_phosamphao = 0xDC0; -static constexpr uint32_t XK_Thai_moma = 0xDC1; -static constexpr uint32_t XK_Thai_yoyak = 0xDC2; -static constexpr uint32_t XK_Thai_rorua = 0xDC3; -static constexpr uint32_t XK_Thai_ru = 0xDC4; -static constexpr uint32_t XK_Thai_loling = 0xDC5; -static constexpr uint32_t XK_Thai_lu = 0xDC6; -static constexpr uint32_t XK_Thai_wowaen = 0xDC7; -static constexpr uint32_t XK_Thai_sosala = 0xDC8; -static constexpr uint32_t XK_Thai_sorusi = 0xDC9; -static constexpr uint32_t XK_Thai_sosua = 0xDCA; -static constexpr uint32_t XK_Thai_hohip = 0xDCB; -static constexpr uint32_t XK_Thai_lochula = 0xDCC; -static constexpr uint32_t XK_Thai_oang = 0xDCD; -static constexpr uint32_t XK_Thai_honokhuk = 0xDCE; -static constexpr uint32_t XK_Thai_paiyannoi = 0xDCF; -static constexpr uint32_t XK_Thai_saraa = 0xDD0; -static constexpr uint32_t XK_Thai_maihanakat = 0xDD1; -static constexpr uint32_t XK_Thai_saraaa = 0xDD2; -static constexpr uint32_t XK_Thai_saraam = 0xDD3; -static constexpr uint32_t XK_Thai_sarai = 0xDD4; -static constexpr uint32_t XK_Thai_saraii = 0xDD5; -static constexpr uint32_t XK_Thai_saraue = 0xDD6; -static constexpr uint32_t XK_Thai_sarauee = 0xDD7; -static constexpr uint32_t XK_Thai_sarau = 0xDD8; -static constexpr uint32_t XK_Thai_sarauu = 0xDD9; -static constexpr uint32_t XK_Thai_phinthu = 0xDDA; -static constexpr uint32_t XK_Thai_baht = 0xDDF; -static constexpr uint32_t XK_Thai_sarae = 0xDE0; -static constexpr uint32_t XK_Thai_saraae = 0xDE1; -static constexpr uint32_t XK_Thai_sarao = 0xDE2; -static constexpr uint32_t XK_Thai_saraaimaimuan = 0xDE3; -static constexpr uint32_t XK_Thai_saraaimaimalai = 0xDE4; -static constexpr uint32_t XK_Thai_lakkhangyao = 0xDE5; -static constexpr uint32_t XK_Thai_maiyamok = 0xDE6; -static constexpr uint32_t XK_Thai_maitaikhu = 0xDE7; -static constexpr uint32_t XK_Thai_maiek = 0xDE8; -static constexpr uint32_t XK_Thai_maitho = 0xDE9; -static constexpr uint32_t XK_Thai_maitri = 0xDEA; -static constexpr uint32_t XK_Thai_maichattawa = 0xDEB; -static constexpr uint32_t XK_Thai_thanthakhat = 0xDEC; -static constexpr uint32_t XK_Thai_nikhahit = 0xDED; -static constexpr uint32_t XK_Thai_leksun = 0xDF0; -static constexpr uint32_t XK_Thai_leknung = 0xDF1; -static constexpr uint32_t XK_Thai_leksong = 0xDF2; -static constexpr uint32_t XK_Thai_leksam = 0xDF3; -static constexpr uint32_t XK_Thai_leksi = 0xDF4; -static constexpr uint32_t XK_Thai_lekha = 0xDF5; -static constexpr uint32_t XK_Thai_lekhok = 0xDF6; -static constexpr uint32_t XK_Thai_lekchet = 0xDF7; -static constexpr uint32_t XK_Thai_lekpaet = 0xDF8; -static constexpr uint32_t XK_Thai_lekkao = 0xDF9; -static constexpr uint32_t XK_Hangul_Kiyeog = 0xEA1; -static constexpr uint32_t XK_Hangul_SsangKiyeog = 0xEA2; -static constexpr uint32_t XK_Hangul_KiyeogSios = 0xEA3; -static constexpr uint32_t XK_Hangul_Nieun = 0xEA4; -static constexpr uint32_t XK_Hangul_NieunJieuj = 0xEA5; -static constexpr uint32_t XK_Hangul_NieunHieuh = 0xEA6; -static constexpr uint32_t XK_Hangul_Dikeud = 0xEA7; -static constexpr uint32_t XK_Hangul_SsangDikeud = 0xEA8; -static constexpr uint32_t XK_Hangul_Rieul = 0xEA9; -static constexpr uint32_t XK_Hangul_RieulKiyeog = 0xEAA; -static constexpr uint32_t XK_Hangul_RieulMieum = 0xEAB; -static constexpr uint32_t XK_Hangul_RieulPieub = 0xEAC; -static constexpr uint32_t XK_Hangul_RieulSios = 0xEAD; -static constexpr uint32_t XK_Hangul_RieulTieut = 0xEAE; -static constexpr uint32_t XK_Hangul_RieulPhieuf = 0xEAF; -static constexpr uint32_t XK_Hangul_RieulHieuh = 0xEB0; -static constexpr uint32_t XK_Hangul_Mieum = 0xEB1; -static constexpr uint32_t XK_Hangul_Pieub = 0xEB2; -static constexpr uint32_t XK_Hangul_SsangPieub = 0xEB3; -static constexpr uint32_t XK_Hangul_PieubSios = 0xEB4; -static constexpr uint32_t XK_Hangul_Sios = 0xEB5; -static constexpr uint32_t XK_Hangul_SsangSios = 0xEB6; -static constexpr uint32_t XK_Hangul_Ieung = 0xEB7; -static constexpr uint32_t XK_Hangul_Jieuj = 0xEB8; -static constexpr uint32_t XK_Hangul_SsangJieuj = 0xEB9; -static constexpr uint32_t XK_Hangul_Cieuc = 0xEBA; -static constexpr uint32_t XK_Hangul_Khieuq = 0xEBB; -static constexpr uint32_t XK_Hangul_Tieut = 0xEBC; -static constexpr uint32_t XK_Hangul_Phieuf = 0xEBD; -static constexpr uint32_t XK_Hangul_Hieuh = 0xEBE; -static constexpr uint32_t XK_Hangul_A = 0xEBF; -static constexpr uint32_t XK_Hangul_AE = 0xEC0; -static constexpr uint32_t XK_Hangul_YA = 0xEC1; -static constexpr uint32_t XK_Hangul_YAE = 0xEC2; -static constexpr uint32_t XK_Hangul_EO = 0xEC3; -static constexpr uint32_t XK_Hangul_E = 0xEC4; -static constexpr uint32_t XK_Hangul_YEO = 0xEC5; -static constexpr uint32_t XK_Hangul_YE = 0xEC6; -static constexpr uint32_t XK_Hangul_O = 0xEC7; -static constexpr uint32_t XK_Hangul_WA = 0xEC8; -static constexpr uint32_t XK_Hangul_WAE = 0xEC9; -static constexpr uint32_t XK_Hangul_OE = 0xECA; -static constexpr uint32_t XK_Hangul_YO = 0xECB; -static constexpr uint32_t XK_Hangul_U = 0xECC; -static constexpr uint32_t XK_Hangul_WEO = 0xECD; -static constexpr uint32_t XK_Hangul_WE = 0xECE; -static constexpr uint32_t XK_Hangul_WI = 0xECF; -static constexpr uint32_t XK_Hangul_YU = 0xED0; -static constexpr uint32_t XK_Hangul_EU = 0xED1; -static constexpr uint32_t XK_Hangul_YI = 0xED2; -static constexpr uint32_t XK_Hangul_I = 0xED3; -static constexpr uint32_t XK_Hangul_J_Kiyeog = 0xED4; -static constexpr uint32_t XK_Hangul_J_SsangKiyeog = 0xED5; -static constexpr uint32_t XK_Hangul_J_KiyeogSios = 0xED6; -static constexpr uint32_t XK_Hangul_J_Nieun = 0xED7; -static constexpr uint32_t XK_Hangul_J_NieunJieuj = 0xED8; -static constexpr uint32_t XK_Hangul_J_NieunHieuh = 0xED9; -static constexpr uint32_t XK_Hangul_J_Dikeud = 0xEDA; -static constexpr uint32_t XK_Hangul_J_Rieul = 0xEDB; -static constexpr uint32_t XK_Hangul_J_RieulKiyeog = 0xEDC; -static constexpr uint32_t XK_Hangul_J_RieulMieum = 0xEDD; -static constexpr uint32_t XK_Hangul_J_RieulPieub = 0xEDE; -static constexpr uint32_t XK_Hangul_J_RieulSios = 0xEDF; -static constexpr uint32_t XK_Hangul_J_RieulTieut = 0xEE0; -static constexpr uint32_t XK_Hangul_J_RieulPhieuf = 0xEE1; -static constexpr uint32_t XK_Hangul_J_RieulHieuh = 0xEE2; -static constexpr uint32_t XK_Hangul_J_Mieum = 0xEE3; -static constexpr uint32_t XK_Hangul_J_Pieub = 0xEE4; -static constexpr uint32_t XK_Hangul_J_PieubSios = 0xEE5; -static constexpr uint32_t XK_Hangul_J_Sios = 0xEE6; -static constexpr uint32_t XK_Hangul_J_SsangSios = 0xEE7; -static constexpr uint32_t XK_Hangul_J_Ieung = 0xEE8; -static constexpr uint32_t XK_Hangul_J_Jieuj = 0xEE9; -static constexpr uint32_t XK_Hangul_J_Cieuc = 0xEEA; -static constexpr uint32_t XK_Hangul_J_Khieuq = 0xEEB; -static constexpr uint32_t XK_Hangul_J_Tieut = 0xEEC; -static constexpr uint32_t XK_Hangul_J_Phieuf = 0xEED; -static constexpr uint32_t XK_Hangul_J_Hieuh = 0xEEE; -static constexpr uint32_t XK_Hangul_RieulYeorinHieuh = 0xEEF; -static constexpr uint32_t XK_Hangul_SunkyeongeumMieum = 0xEF0; -static constexpr uint32_t XK_Hangul_SunkyeongeumPieub = 0xEF1; -static constexpr uint32_t XK_Hangul_PanSios = 0xEF2; -static constexpr uint32_t XK_Hangul_KkogjiDalrinIeung = 0xEF3; -static constexpr uint32_t XK_Hangul_SunkyeongeumPhieuf = 0xEF4; -static constexpr uint32_t XK_Hangul_YeorinHieuh = 0xEF5; -static constexpr uint32_t XK_Hangul_AraeA = 0xEF6; -static constexpr uint32_t XK_Hangul_AraeAE = 0xEF7; -static constexpr uint32_t XK_Hangul_J_PanSios = 0xEF8; -static constexpr uint32_t XK_Hangul_J_KkogjiDalrinIeung = 0xEF9; -static constexpr uint32_t XK_Hangul_J_YeorinHieuh = 0xEFA; -static constexpr uint32_t XK_Korean_Won = 0xEFF; -static constexpr uint32_t XK_OE = 0x13BC; -static constexpr uint32_t XK_oe = 0x13BD; -static constexpr uint32_t XK_Ydiaeresis = 0x13BE; -static constexpr uint32_t XK_EuroSign = 0x20AC; -static constexpr uint32_t XK_3270_Duplicate = 0xFD01; -static constexpr uint32_t XK_3270_FieldMark = 0xFD02; -static constexpr uint32_t XK_3270_Right2 = 0xFD03; -static constexpr uint32_t XK_3270_Left2 = 0xFD04; -static constexpr uint32_t XK_3270_BackTab = 0xFD05; -static constexpr uint32_t XK_3270_EraseEOF = 0xFD06; -static constexpr uint32_t XK_3270_EraseInput = 0xFD07; -static constexpr uint32_t XK_3270_Reset = 0xFD08; -static constexpr uint32_t XK_3270_Quit = 0xFD09; -static constexpr uint32_t XK_3270_PA1 = 0xFD0A; -static constexpr uint32_t XK_3270_PA2 = 0xFD0B; -static constexpr uint32_t XK_3270_PA3 = 0xFD0C; -static constexpr uint32_t XK_3270_Test = 0xFD0D; -static constexpr uint32_t XK_3270_Attn = 0xFD0E; -static constexpr uint32_t XK_3270_CursorBlink = 0xFD0F; -static constexpr uint32_t XK_3270_AltCursor = 0xFD10; -static constexpr uint32_t XK_3270_KeyClick = 0xFD11; -static constexpr uint32_t XK_3270_Jump = 0xFD12; -static constexpr uint32_t XK_3270_Ident = 0xFD13; -static constexpr uint32_t XK_3270_Rule = 0xFD14; -static constexpr uint32_t XK_3270_Copy = 0xFD15; -static constexpr uint32_t XK_3270_Play = 0xFD16; -static constexpr uint32_t XK_3270_Setup = 0xFD17; -static constexpr uint32_t XK_3270_Record = 0xFD18; -static constexpr uint32_t XK_3270_ChangeScreen = 0xFD19; -static constexpr uint32_t XK_3270_DeleteWord = 0xFD1A; -static constexpr uint32_t XK_3270_ExSelect = 0xFD1B; -static constexpr uint32_t XK_3270_CursorSelect = 0xFD1C; -static constexpr uint32_t XK_3270_PrintScreen = 0xFD1D; -static constexpr uint32_t XK_3270_Enter = 0xFD1E; -static constexpr uint32_t XK_ISO_Lock = 0xFE01; -static constexpr uint32_t XK_ISO_Level3_Shift = 0xFE03; -static constexpr uint32_t XK_ISO_Level3_Latch = 0xFE04; -static constexpr uint32_t XK_ISO_Next_Group = 0xFE08; -static constexpr uint32_t XK_ISO_Next_Group_Lock = 0xFE09; -static constexpr uint32_t XK_ISO_Prev_Group = 0xFE0A; -static constexpr uint32_t XK_ISO_Prev_Group_Lock = 0xFE0B; -static constexpr uint32_t XK_ISO_First_Group = 0xFE0C; -static constexpr uint32_t XK_ISO_First_Group_Lock = 0xFE0D; -static constexpr uint32_t XK_ISO_Last_Group = 0xFE0E; -static constexpr uint32_t XK_ISO_Last_Group_Lock = 0xFE0F; -static constexpr uint32_t XK_ISO_Level5_Shift = 0xFE11; -static constexpr uint32_t XK_ISO_Level5_Lock = 0xFE13; -static constexpr uint32_t XK_ISO_Left_Tab = 0xFE20; -static constexpr uint32_t XK_ISO_Enter = 0xFE34; -static constexpr uint32_t XK_dead_grave = 0xFE50; -static constexpr uint32_t XK_dead_acute = 0xFE51; -static constexpr uint32_t XK_dead_circumflex = 0xFE52; -static constexpr uint32_t XK_dead_tilde = 0xFE53; -static constexpr uint32_t XK_dead_macron = 0xFE54; -static constexpr uint32_t XK_dead_breve = 0xFE55; -static constexpr uint32_t XK_dead_abovedot = 0xFE56; -static constexpr uint32_t XK_dead_diaeresis = 0xFE57; -static constexpr uint32_t XK_dead_abovering = 0xFE58; -static constexpr uint32_t XK_dead_doubleacute = 0xFE59; -static constexpr uint32_t XK_dead_caron = 0xFE5A; -static constexpr uint32_t XK_dead_cedilla = 0xFE5B; -static constexpr uint32_t XK_dead_ogonek = 0xFE5C; -static constexpr uint32_t XK_dead_iota = 0xFE5D; -static constexpr uint32_t XK_dead_voiced_sound = 0xFE5E; -static constexpr uint32_t XK_dead_semivoiced_sound = 0xFE5F; -static constexpr uint32_t XK_dead_belowdot = 0xFE60; -static constexpr uint32_t XK_dead_hook = 0xFE61; -static constexpr uint32_t XK_dead_horn = 0xFE62; -static constexpr uint32_t XK_dead_stroke = 0xFE63; -static constexpr uint32_t XK_dead_abovecomma = 0xFE64; -static constexpr uint32_t XK_dead_abovereversedcomma = 0xFE65; -static constexpr uint32_t XK_dead_doublegrave = 0xFE66; -static constexpr uint32_t XK_dead_belowring = 0xFE67; -static constexpr uint32_t XK_dead_belowmacron = 0xFE68; -static constexpr uint32_t XK_dead_belowcircumflex = 0xFE69; -static constexpr uint32_t XK_dead_belowtilde = 0xFE6A; -static constexpr uint32_t XK_dead_belowbreve = 0xFE6B; -static constexpr uint32_t XK_dead_belowdiaeresis = 0xFE6C; -static constexpr uint32_t XK_dead_invertedbreve = 0xFE6D; -static constexpr uint32_t XK_dead_belowcomma = 0xFE6E; -static constexpr uint32_t XK_dead_currency = 0xFE6F; -static constexpr uint32_t XK_dead_greek = 0xFE8C; -static constexpr uint32_t XK_Next_Virtual_Screen = 0xFED2; -static constexpr uint32_t XK_BackSpace = 0xFF08; -static constexpr uint32_t XK_Tab = 0xFF09; -static constexpr uint32_t XK_Linefeed = 0xFF0A; -static constexpr uint32_t XK_Clear = 0xFF0B; -static constexpr uint32_t XK_Return = 0xFF0D; -static constexpr uint32_t XK_Pause = 0xFF13; -static constexpr uint32_t XK_Scroll_Lock = 0xFF14; -static constexpr uint32_t XK_Sys_Req = 0xFF15; -static constexpr uint32_t XK_Escape = 0xFF1B; -static constexpr uint32_t XK_Multi_key = 0xFF20; -static constexpr uint32_t XK_Kanji = 0xFF21; -static constexpr uint32_t XK_Muhenkan = 0xFF22; -static constexpr uint32_t XK_Henkan = 0xFF23; -static constexpr uint32_t XK_Henkan_Mode = 0xFF23; -static constexpr uint32_t XK_Romaji = 0xFF24; -static constexpr uint32_t XK_Hiragana = 0xFF25; -static constexpr uint32_t XK_Katakana = 0xFF26; -static constexpr uint32_t XK_Hiragana_Katakana = 0xFF27; -static constexpr uint32_t XK_Zenkaku = 0xFF28; -static constexpr uint32_t XK_Hankaku = 0xFF29; -static constexpr uint32_t XK_Zenkaku_Hankaku = 0xFF2A; -static constexpr uint32_t XK_Kana_Lock = 0xFF2D; -static constexpr uint32_t XK_Kana_Shift = 0xFF2E; -static constexpr uint32_t XK_Eisu_Shift = 0xFF2F; -static constexpr uint32_t XK_Eisu_toggle = 0xFF30; -static constexpr uint32_t XK_Hangul = 0xFF31; -static constexpr uint32_t XK_Hangul_Start = 0xFF32; -static constexpr uint32_t XK_Hangul_End = 0xFF33; -static constexpr uint32_t XK_Hangul_Hanja = 0xFF34; -static constexpr uint32_t XK_Hangul_Jamo = 0xFF35; -static constexpr uint32_t XK_Hangul_Romaja = 0xFF36; -static constexpr uint32_t XK_Codeinput = 0xFF37; -static constexpr uint32_t XK_Hangul_Jeonja = 0xFF38; -static constexpr uint32_t XK_Hangul_Banja = 0xFF39; -static constexpr uint32_t XK_Hangul_PreHanja = 0xFF3A; -static constexpr uint32_t XK_Hangul_PostHanja = 0xFF3B; -static constexpr uint32_t XK_SingleCandidate = 0xFF3C; -static constexpr uint32_t XK_MultipleCandidate = 0xFF3D; -static constexpr uint32_t XK_PreviousCandidate = 0xFF3E; -static constexpr uint32_t XK_Hangul_Special = 0xFF3F; -static constexpr uint32_t XK_Home = 0xFF50; -static constexpr uint32_t XK_Left = 0xFF51; -static constexpr uint32_t XK_Up = 0xFF52; -static constexpr uint32_t XK_Right = 0xFF53; -static constexpr uint32_t XK_Down = 0xFF54; -static constexpr uint32_t XK_Page_Up = 0xFF55; -static constexpr uint32_t XK_Prior = 0xFF55; -static constexpr uint32_t XK_Next = 0xFF56; -static constexpr uint32_t XK_Page_Down = 0xFF56; -static constexpr uint32_t XK_End = 0xFF57; -static constexpr uint32_t XK_Select = 0xFF60; -static constexpr uint32_t XK_Print = 0xFF61; -static constexpr uint32_t XK_Execute = 0xFF62; -static constexpr uint32_t XK_Insert = 0xFF63; -static constexpr uint32_t XK_Undo = 0xFF65; -static constexpr uint32_t XK_Redo = 0xFF66; -static constexpr uint32_t XK_Menu = 0xFF67; -static constexpr uint32_t XK_Find = 0xFF68; -static constexpr uint32_t XK_Cancel = 0xFF69; -static constexpr uint32_t XK_Help = 0xFF6A; -static constexpr uint32_t XK_Break = 0xFF6B; -static constexpr uint32_t XK_Mode_switch = 0xFF7E; -static constexpr uint32_t XK_Num_Lock = 0xFF7F; -static constexpr uint32_t XK_KP_Space = 0xFF80; -static constexpr uint32_t XK_KP_Tab = 0xFF89; -static constexpr uint32_t XK_KP_Enter = 0xFF8D; -static constexpr uint32_t XK_KP_F1 = 0xFF91; -static constexpr uint32_t XK_KP_F2 = 0xFF92; -static constexpr uint32_t XK_KP_F3 = 0xFF93; -static constexpr uint32_t XK_KP_F4 = 0xFF94; -static constexpr uint32_t XK_KP_Home = 0xFF95; -static constexpr uint32_t XK_KP_Left = 0xFF96; -static constexpr uint32_t XK_KP_Up = 0xFF97; -static constexpr uint32_t XK_KP_Right = 0xFF98; -static constexpr uint32_t XK_KP_Down = 0xFF99; -static constexpr uint32_t XK_KP_Page_Up = 0xFF9A; -static constexpr uint32_t XK_KP_Prior = 0xFF9A; -static constexpr uint32_t XK_KP_Next = 0xFF9B; -static constexpr uint32_t XK_KP_Page_Down = 0xFF9B; -static constexpr uint32_t XK_KP_End = 0xFF9C; -static constexpr uint32_t XK_KP_Begin = 0xFF9D; -static constexpr uint32_t XK_KP_Insert = 0xFF9E; -static constexpr uint32_t XK_KP_Delete = 0xFF9F; -static constexpr uint32_t XK_KP_Multiply = 0xFFAA; -static constexpr uint32_t XK_KP_Add = 0xFFAB; -static constexpr uint32_t XK_KP_Separator = 0xFFAC; -static constexpr uint32_t XK_KP_Subtract = 0xFFAD; -static constexpr uint32_t XK_KP_Decimal = 0xFFAE; -static constexpr uint32_t XK_KP_Divide = 0xFFAF; -static constexpr uint32_t XK_KP_0 = 0xFFB0; -static constexpr uint32_t XK_KP_1 = 0xFFB1; -static constexpr uint32_t XK_KP_2 = 0xFFB2; -static constexpr uint32_t XK_KP_3 = 0xFFB3; -static constexpr uint32_t XK_KP_4 = 0xFFB4; -static constexpr uint32_t XK_KP_5 = 0xFFB5; -static constexpr uint32_t XK_KP_6 = 0xFFB6; -static constexpr uint32_t XK_KP_7 = 0xFFB7; -static constexpr uint32_t XK_KP_8 = 0xFFB8; -static constexpr uint32_t XK_KP_9 = 0xFFB9; -static constexpr uint32_t XK_KP_Equal = 0xFFBD; -static constexpr uint32_t XK_F1 = 0xFFBE; -static constexpr uint32_t XK_F2 = 0xFFBF; -static constexpr uint32_t XK_F3 = 0xFFC0; -static constexpr uint32_t XK_F4 = 0xFFC1; -static constexpr uint32_t XK_F5 = 0xFFC2; -static constexpr uint32_t XK_F6 = 0xFFC3; -static constexpr uint32_t XK_F7 = 0xFFC4; -static constexpr uint32_t XK_F8 = 0xFFC5; -static constexpr uint32_t XK_F9 = 0xFFC6; -static constexpr uint32_t XK_F10 = 0xFFC7; -static constexpr uint32_t XK_F11 = 0xFFC8; -static constexpr uint32_t XK_F12 = 0xFFC9; -static constexpr uint32_t XK_F13 = 0xFFCA; -static constexpr uint32_t XK_F14 = 0xFFCB; -static constexpr uint32_t XK_F15 = 0xFFCC; -static constexpr uint32_t XK_F16 = 0xFFCD; -static constexpr uint32_t XK_F17 = 0xFFCE; -static constexpr uint32_t XK_F18 = 0xFFCF; -static constexpr uint32_t XK_F19 = 0xFFD0; -static constexpr uint32_t XK_F20 = 0xFFD1; -static constexpr uint32_t XK_F21 = 0xFFD2; -static constexpr uint32_t XK_F22 = 0xFFD3; -static constexpr uint32_t XK_F23 = 0xFFD4; -static constexpr uint32_t XK_F24 = 0xFFD5; -static constexpr uint32_t XK_F25 = 0xFFD6; -static constexpr uint32_t XK_F26 = 0xFFD7; -static constexpr uint32_t XK_F27 = 0xFFD8; -static constexpr uint32_t XK_F28 = 0xFFD9; -static constexpr uint32_t XK_F29 = 0xFFDA; -static constexpr uint32_t XK_F30 = 0xFFDB; -static constexpr uint32_t XK_F31 = 0xFFDC; -static constexpr uint32_t XK_F32 = 0xFFDD; -static constexpr uint32_t XK_F33 = 0xFFDE; -static constexpr uint32_t XK_F34 = 0xFFDF; -static constexpr uint32_t XK_F35 = 0xFFE0; -static constexpr uint32_t XK_Shift_L = 0xFFE1; -static constexpr uint32_t XK_Shift_R = 0xFFE2; -static constexpr uint32_t XK_Control_L = 0xFFE3; -static constexpr uint32_t XK_Control_R = 0xFFE4; -static constexpr uint32_t XK_Caps_Lock = 0xFFE5; -static constexpr uint32_t XK_Shift_Lock = 0xFFE6; -static constexpr uint32_t XK_Meta_L = 0xFFE7; -static constexpr uint32_t XK_Meta_R = 0xFFE8; -static constexpr uint32_t XK_Alt_L = 0xFFE9; -static constexpr uint32_t XK_Alt_R = 0xFFEA; -static constexpr uint32_t XK_Super_L = 0xFFEB; -static constexpr uint32_t XK_Super_R = 0xFFEC; -static constexpr uint32_t XK_Hyper_L = 0xFFED; -static constexpr uint32_t XK_Hyper_R = 0xFFEE; -static constexpr uint32_t XK_Delete = 0xFFFF; -static constexpr uint32_t XK_VoidSymbol = 0xFFFFFF; -static constexpr uint32_t SunXK_Props = 0x1005FF70; -static constexpr uint32_t SunXK_Copy = 0x1005FF72; -static constexpr uint32_t SunXK_Open = 0x1005FF73; -static constexpr uint32_t SunXK_Paste = 0x1005FF74; -static constexpr uint32_t SunXK_Cut = 0x1005FF75; -static constexpr uint32_t XF86XK_ClearGrab = 0x1008FE21; -static constexpr uint32_t XF86XK_Next_VMode = 0x1008FE22; -static constexpr uint32_t XF86XK_MonBrightnessUp = 0x1008FF02; -static constexpr uint32_t XF86XK_MonBrightnessDown = 0x1008FF03; -static constexpr uint32_t XF86XK_KbdBrightnessUp = 0x1008FF05; -static constexpr uint32_t XF86XK_KbdBrightnessDown = 0x1008FF06; -static constexpr uint32_t XF86XK_Standby = 0x1008FF10; -static constexpr uint32_t XF86XK_AudioLowerVolume = 0x1008FF11; -static constexpr uint32_t XF86XK_AudioMute = 0x1008FF12; -static constexpr uint32_t XF86XK_AudioRaiseVolume = 0x1008FF13; -static constexpr uint32_t XF86XK_AudioPlay = 0x1008FF14; -static constexpr uint32_t XF86XK_AudioStop = 0x1008FF15; -static constexpr uint32_t XF86XK_AudioPrev = 0x1008FF16; -static constexpr uint32_t XF86XK_AudioNext = 0x1008FF17; -static constexpr uint32_t XF86XK_HomePage = 0x1008FF18; -static constexpr uint32_t XF86XK_Mail = 0x1008FF19; -static constexpr uint32_t XF86XK_Search = 0x1008FF1B; -static constexpr uint32_t XF86XK_AudioRecord = 0x1008FF1C; -static constexpr uint32_t XF86XK_Calculator = 0x1008FF1D; -static constexpr uint32_t XF86XK_Calendar = 0x1008FF20; -static constexpr uint32_t XF86XK_Back = 0x1008FF26; -static constexpr uint32_t XF86XK_Forward = 0x1008FF27; -static constexpr uint32_t XF86XK_Stop = 0x1008FF28; -static constexpr uint32_t XF86XK_Refresh = 0x1008FF29; -static constexpr uint32_t XF86XK_PowerOff = 0x1008FF2A; -static constexpr uint32_t XF86XK_WakeUp = 0x1008FF2B; -static constexpr uint32_t XF86XK_Eject = 0x1008FF2C; -static constexpr uint32_t XF86XK_ScreenSaver = 0x1008FF2D; -static constexpr uint32_t XF86XK_WWW = 0x1008FF2E; -static constexpr uint32_t XF86XK_Sleep = 0x1008FF2F; -static constexpr uint32_t XF86XK_Favorites = 0x1008FF30; -static constexpr uint32_t XF86XK_AudioPause = 0x1008FF31; -static constexpr uint32_t XF86XK_AudioMedia = 0x1008FF32; -static constexpr uint32_t XF86XK_MyComputer = 0x1008FF33; -static constexpr uint32_t XF86XK_OpenURL = 0x1008FF38; -static constexpr uint32_t XF86XK_AudioRewind = 0x1008FF3E; -static constexpr uint32_t XF86XK_BackForward = 0x1008FF3F; -static constexpr uint32_t XF86XK_Launch5 = 0x1008FF45; -static constexpr uint32_t XF86XK_Launch6 = 0x1008FF46; -static constexpr uint32_t XF86XK_Launch7 = 0x1008FF47; -static constexpr uint32_t XF86XK_Launch8 = 0x1008FF48; -static constexpr uint32_t XF86XK_Launch9 = 0x1008FF49; -static constexpr uint32_t XF86XK_LaunchA = 0x1008FF4A; -static constexpr uint32_t XF86XK_LaunchB = 0x1008FF4B; -static constexpr uint32_t XF86XK_CD = 0x1008FF53; -static constexpr uint32_t XF86XK_Clear = 0x1008FF55; -static constexpr uint32_t XF86XK_Close = 0x1008FF56; -static constexpr uint32_t XF86XK_Copy = 0x1008FF57; -static constexpr uint32_t XF86XK_Cut = 0x1008FF58; -static constexpr uint32_t XF86XK_Display = 0x1008FF59; -static constexpr uint32_t XF86XK_Excel = 0x1008FF5C; -static constexpr uint32_t XF86XK_Explorer = 0x1008FF5D; -static constexpr uint32_t XF86XK_LogOff = 0x1008FF61; -static constexpr uint32_t XF86XK_MenuKB = 0x1008FF65; -static constexpr uint32_t XF86XK_MenuPB = 0x1008FF66; -static constexpr uint32_t XF86XK_New = 0x1008FF68; -static constexpr uint32_t XF86XK_News = 0x1008FF69; -static constexpr uint32_t XF86XK_OfficeHome = 0x1008FF6A; -static constexpr uint32_t XF86XK_Open = 0x1008FF6B; -static constexpr uint32_t XF86XK_Paste = 0x1008FF6D; -static constexpr uint32_t XF86XK_Reply = 0x1008FF72; -static constexpr uint32_t XF86XK_Reload = 0x1008FF73; -static constexpr uint32_t XF86XK_Save = 0x1008FF77; -static constexpr uint32_t XF86XK_ScrollUp = 0x1008FF78; -static constexpr uint32_t XF86XK_ScrollDown = 0x1008FF79; -static constexpr uint32_t XF86XK_Send = 0x1008FF7B; -static constexpr uint32_t XF86XK_Spell = 0x1008FF7C; -static constexpr uint32_t XF86XK_SplitScreen = 0x1008FF7D; -static constexpr uint32_t XF86XK_Tools = 0x1008FF81; -static constexpr uint32_t XF86XK_Video = 0x1008FF87; -static constexpr uint32_t XF86XK_Word = 0x1008FF89; -static constexpr uint32_t XF86XK_ZoomIn = 0x1008FF8B; -static constexpr uint32_t XF86XK_ZoomOut = 0x1008FF8C; -static constexpr uint32_t XF86XK_WebCam = 0x1008FF8F; -static constexpr uint32_t XF86XK_MailForward = 0x1008FF90; -static constexpr uint32_t XF86XK_Music = 0x1008FF92; -static constexpr uint32_t XF86XK_WLAN = 0x1008FF95; -static constexpr uint32_t XF86XK_AudioForward = 0x1008FF97; -static constexpr uint32_t XF86XK_AudioRandomPlay = 0x1008FF99; -static constexpr uint32_t XF86XK_Subtitle = 0x1008FF9A; -static constexpr uint32_t XF86XK_Select = 0x1008FFA0; -static constexpr uint32_t XF86XK_Suspend = 0x1008FFA7; -static constexpr uint32_t XF86XK_Hibernate = 0x1008FFA8; +#include "third_party/x11proto/keysymdef.h" #endif // UI_GFX_X_KEYSYMS_KEYSYMS_H_ diff --git a/chromium/ui/gfx/x/scoped_ignore_errors.cc b/chromium/ui/gfx/x/scoped_ignore_errors.cc new file mode 100644 index 00000000000..0d9e6dff0af --- /dev/null +++ b/chromium/ui/gfx/x/scoped_ignore_errors.cc @@ -0,0 +1,25 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/x/scoped_ignore_errors.h" + +namespace x11 { + +namespace { + +void IgnoreErrors(const x11::Error* error, const char* request_name) {} + +} // namespace + +ScopedIgnoreErrors::ScopedIgnoreErrors(Connection* connection) + : connection_(connection) { + old_error_handler_ = + connection_->SetErrorHandler(base::BindRepeating(IgnoreErrors)); +} + +ScopedIgnoreErrors::~ScopedIgnoreErrors() { + connection_->SetErrorHandler(old_error_handler_); +} + +} // namespace x11 diff --git a/chromium/ui/gfx/x/scoped_ignore_errors.h b/chromium/ui/gfx/x/scoped_ignore_errors.h new file mode 100644 index 00000000000..baa48b5fd5a --- /dev/null +++ b/chromium/ui/gfx/x/scoped_ignore_errors.h @@ -0,0 +1,26 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_X_SCOPED_IGNORE_ERRORS_H_ +#define UI_GFX_X_SCOPED_IGNORE_ERRORS_H_ + +#include "base/component_export.h" +#include "ui/gfx/x/connection.h" + +namespace x11 { + +// Sets a no-op error handler for a connection while this class is alive. +class COMPONENT_EXPORT(X11) ScopedIgnoreErrors { + public: + explicit ScopedIgnoreErrors(Connection* connection); + ~ScopedIgnoreErrors(); + + private: + Connection* const connection_; + Connection::ErrorHandler old_error_handler_; +}; + +} // namespace x11 + +#endif // UI_GFX_X_SCOPED_IGNORE_ERRORS_H_ diff --git a/chromium/ui/gfx/x/x11.h b/chromium/ui/gfx/x/x11.h deleted file mode 100644 index a19c26e01bb..00000000000 --- a/chromium/ui/gfx/x/x11.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This header file replaces <X11/Xlib.h>. https://crbug.com/1066670 is -// tracking removing usage of Xlib altogether. Do not add more Xlib -// declarations here. The intention is to incrementally remove declarations -// until there is nothing left, at which point this file will be removed. - -#ifndef UI_GFX_X_X11_H_ -#define UI_GFX_X_X11_H_ - -#include "ui/gfx/x/connection.h" - -// Temporarily declare Xlib symbols we require. Do not add more Xlib -// declarations here and do not include anything from <X11/*>. - -extern "C" { - -using Status = int; -using Bool = int; -using XID = unsigned long; -using KeySym = XID; -using KeyCode = unsigned char; -using Window = XID; -using Pixmap = XID; -using Font = XID; -using VisualID = unsigned long; -using XPointer = char*; -using Colormap = XID; -using Cursor = XID; -using Atom = unsigned long; -using Time = unsigned long; -using GC = struct _XGC*; -using Display = struct _XDisplay; -using xcb_connection_t = struct xcb_connection_t; - -enum XEventQueueOwner { XlibOwnsEventQueue = 0, XCBOwnsEventQueue }; - -using XErrorEvent = struct _XErrorEvent { - int type; - Display* display; - XID resourceid; - unsigned long serial; - unsigned char error_code; - unsigned char request_code; - unsigned char minor_code; -}; - -using XErrorHandler = int (*)(Display*, XErrorEvent*); -using XIOErrorHandler = int (*)(Display*); - -Status XInitThreads(void); -Display* XOpenDisplay(const char*); -int XCloseDisplay(Display*); -int XFlush(Display*); -xcb_connection_t* XGetXCBConnection(Display* dpy); -void XSetEventQueueOwner(Display* dpy, enum XEventQueueOwner owner); -unsigned long XLastKnownRequestProcessed(Display*); -int (*XSynchronize(Display*, Bool))(Display*); -int XGetErrorDatabaseText(Display*, - const char*, - const char*, - const char*, - char*, - int); -int XGetErrorText(Display*, int, char*, int); -XErrorHandler XSetErrorHandler(XErrorHandler); -XIOErrorHandler XSetIOErrorHandler(XIOErrorHandler); -int XStoreName(Display*, Window, const char*); -} - -#endif // UI_GFX_X_X11_H_ diff --git a/chromium/ui/gfx/x/x11_atom_cache.cc b/chromium/ui/gfx/x/x11_atom_cache.cc index cf727cd23cf..767bf21124b 100644 --- a/chromium/ui/gfx/x/x11_atom_cache.cc +++ b/chromium/ui/gfx/x/x11_atom_cache.cc @@ -257,7 +257,10 @@ X11AtomCache::X11AtomCache() : connection_(x11::Connection::Get()) { std::vector<x11::Future<x11::InternAtomReply>> requests; requests.reserve(kCacheCount); for (const char* name : kAtomsToCache) - requests.push_back(connection_->InternAtom({.name = name})); + requests.push_back( + connection_->InternAtom(x11::InternAtomRequest{.name = name})); + // Flush so all requests are sent before waiting on any replies. + connection_->Flush(); for (size_t i = 0; i < kCacheCount; ++i) { if (auto response = requests[i].Sync()) cached_atoms_[kAtomsToCache[i]] = static_cast<x11::Atom>(response->atom); @@ -272,7 +275,9 @@ x11::Atom X11AtomCache::GetAtom(const std::string& name) const { return it->second; x11::Atom atom = x11::Atom::None; - if (auto response = connection_->InternAtom({.name = name}).Sync()) { + if (auto response = + connection_->InternAtom(x11::InternAtomRequest{.name = name}) + .Sync()) { atom = static_cast<x11::Atom>(response->atom); cached_atoms_.emplace(name, atom); } else { diff --git a/chromium/ui/gfx/x/x11_atom_cache.h b/chromium/ui/gfx/x/x11_atom_cache.h index 53fb799875f..03b8f4a50df 100644 --- a/chromium/ui/gfx/x/x11_atom_cache.h +++ b/chromium/ui/gfx/x/x11_atom_cache.h @@ -10,7 +10,7 @@ #include "base/macros.h" #include "ui/gfx/gfx_export.h" -#include "ui/gfx/x/x11_types.h" +#include "ui/gfx/x/xproto.h" namespace base { template <typename T> diff --git a/chromium/ui/gfx/x/x11_error_tracker.cc b/chromium/ui/gfx/x/x11_error_tracker.cc deleted file mode 100644 index 5859a5e4b39..00000000000 --- a/chromium/ui/gfx/x/x11_error_tracker.cc +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/gfx/x/x11_error_tracker.h" - -#include "base/check.h" -#include "ui/gfx/x/x11.h" -#include "ui/gfx/x/x11_types.h" - -namespace { - -unsigned char g_x11_error_code = 0; - -int X11ErrorHandler(Display* display, XErrorEvent* error) { - g_x11_error_code = error->error_code; - return 0; -} - -} // namespace - -namespace gfx { - -X11ErrorTracker::X11ErrorTracker() { - x11::Connection::Get()->Sync(); - old_handler_ = reinterpret_cast<void*>(XSetErrorHandler(X11ErrorHandler)); - g_x11_error_code = 0; -} - -X11ErrorTracker::~X11ErrorTracker() { - XSetErrorHandler(reinterpret_cast<XErrorHandler>(old_handler_)); -} - -bool X11ErrorTracker::FoundNewError() { - x11::Connection::Get()->Sync(); - unsigned char error = g_x11_error_code; - g_x11_error_code = 0; - return error != 0; -} - -} // namespace gfx diff --git a/chromium/ui/gfx/x/x11_error_tracker.h b/chromium/ui/gfx/x/x11_error_tracker.h deleted file mode 100644 index df06befc87f..00000000000 --- a/chromium/ui/gfx/x/x11_error_tracker.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_GFX_X_X11_ERROR_TRACKER_H_ -#define UI_GFX_X_X11_ERROR_TRACKER_H_ - -#include "base/macros.h" -#include "ui/gfx/gfx_export.h" - -namespace gfx { - -// X11ErrorTracker catches X11 errors in a non-fatal way. It does so by -// temporarily changing the X11 error handler. The old error handler is -// restored when the tracker is destroyed. -class GFX_EXPORT X11ErrorTracker { - public: - X11ErrorTracker(); - ~X11ErrorTracker(); - - // Returns whether an X11 error happened since this function was last called - // (or since the creation of the tracker). This is potentially expensive, - // since this causes a sync with the X server. - bool FoundNewError(); - - private: - // The real type of |old_handler_| is XErrorHandler, or "int - // (*handler)(Display *, XErrorEvent *)". However, XErrorEvent cannot be - // forward declared, so void* is necessary here. - void* old_handler_ = nullptr; - - DISALLOW_COPY_AND_ASSIGN(X11ErrorTracker); -}; - -} // namespace gfx - -#endif // UI_GFX_X_X11_ERROR_TRACKER_H_ diff --git a/chromium/ui/gfx/x/x11_path.cc b/chromium/ui/gfx/x/x11_path.cc index 987d58345c2..823b8b617aa 100644 --- a/chromium/ui/gfx/x/x11_path.cc +++ b/chromium/ui/gfx/x/x11_path.cc @@ -8,7 +8,6 @@ #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkRegion.h" -#include "ui/gfx/x/x11.h" namespace gfx { diff --git a/chromium/ui/gfx/x/x11_types.cc b/chromium/ui/gfx/x/x11_types.cc deleted file mode 100644 index 3e09d3e6a55..00000000000 --- a/chromium/ui/gfx/x/x11_types.cc +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/gfx/x/x11_types.h" - -#include <string.h> - -#include "base/command_line.h" -#include "base/logging.h" -#include "build/build_config.h" -#include "ui/gfx/x/connection.h" -#include "ui/gfx/x/x11.h" -#include "ui/gfx/x/x11_switches.h" - -namespace gfx { - -XDisplay* GetXDisplay() { - return x11::Connection::Get()->display(); -} - -} // namespace gfx diff --git a/chromium/ui/gfx/x/x11_types.h b/chromium/ui/gfx/x/x11_types.h deleted file mode 100644 index 4b6b9ec0043..00000000000 --- a/chromium/ui/gfx/x/x11_types.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_GFX_X_X11_UTIL_H_ -#define UI_GFX_X_X11_UTIL_H_ - -#include <stdint.h> - -#include <memory> - -#include "ui/gfx/gfx_export.h" -#include "ui/gfx/x/connection.h" - -typedef unsigned long XID; -typedef unsigned long VisualID; -typedef union _XEvent XEvent; -typedef struct _XImage XImage; -typedef struct _XGC* GC; -typedef struct _XDisplay XDisplay; -typedef struct _XRegion XRegion; -typedef struct __GLXFBConfigRec* GLXFBConfig; -typedef XID GLXWindow; -typedef XID GLXDrawable; - -extern "C" { -int XFree(void*); -} - -namespace gfx { - -template <class T, class R, R (*F)(T*)> -struct XObjectDeleter { - inline void operator()(void* ptr) const { F(static_cast<T*>(ptr)); } -}; - -template <class T, class D = XObjectDeleter<void, int, XFree>> -using XScopedPtr = std::unique_ptr<T, D>; - -// Get the XDisplay singleton. Prefer x11::Connection::Get() instead. -GFX_EXPORT XDisplay* GetXDisplay(); - -} // namespace gfx - -#endif // UI_GFX_X_X11_UTIL_H_ diff --git a/chromium/ui/gfx/x/xlib.h b/chromium/ui/gfx/x/xlib.h new file mode 100644 index 00000000000..68f4d3ec00e --- /dev/null +++ b/chromium/ui/gfx/x/xlib.h @@ -0,0 +1,17 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_X_XLIB_H_ +#define UI_GFX_X_XLIB_H_ + +extern "C" { +int XInitThreads(void); +struct _XDisplay* XOpenDisplay(const char*); +int XCloseDisplay(struct _XDisplay*); +int XFlush(struct _XDisplay*); +int XSynchronize(struct _XDisplay*, int); +int XSetErrorHandler(int (*)(void*, void*)); +} + +#endif // UI_GFX_X_XLIB_H_ diff --git a/chromium/ui/gfx/x/xlib_support.cc b/chromium/ui/gfx/x/xlib_support.cc new file mode 100644 index 00000000000..fe7846d0e9f --- /dev/null +++ b/chromium/ui/gfx/x/xlib_support.cc @@ -0,0 +1,101 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/x/xlib_support.h" + +#include "base/check.h" +#include "base/compiler_specific.h" +#include "base/logging.h" +#include "base/no_destructor.h" +#include "library_loaders/xlib_loader.h" + +namespace x11 { + +namespace { + +int XlibErrorHandler(void*, void*) { + DVLOG(1) << "Xlib error received"; + return 0; +} + +XlibLoader* GetXlibLoader() { + static base::NoDestructor<XlibLoader> xlib_loader; + return xlib_loader.get(); +} + +} // namespace + +DISABLE_CFI_ICALL +void InitXlib() { + auto* xlib_loader = GetXlibLoader(); + if (xlib_loader->loaded()) + return; + + CHECK(xlib_loader->Load("libX11.so.6")); + + CHECK(xlib_loader->XInitThreads()); + + // The default Xlib error handler calls exit(1), which we don't want. This + // shouldn't happen in the browser process since only XProto requests are + // made, but in the GPU process, GLX can make Xlib requests, so setting an + // error handler is necessary. Importantly, there's also an IO error handler, + // and Xlib always calls exit(1) with no way to change this behavior. + SetXlibErrorHandler(); +} + +DISABLE_CFI_ICALL +void SetXlibErrorHandler() { + GetXlibLoader()->XSetErrorHandler(XlibErrorHandler); +} + +DISABLE_CFI_ICALL +XlibDisplay::XlibDisplay(const std::string& address) { + InitXlib(); + + display_ = GetXlibLoader()->XOpenDisplay(address.empty() ? nullptr + : address.c_str()); +} + +DISABLE_CFI_ICALL +XlibDisplay::~XlibDisplay() { + if (display_) + GetXlibLoader()->XCloseDisplay(display_); +} + +DISABLE_CFI_ICALL +XlibDisplayWrapper::XlibDisplayWrapper(struct _XDisplay* display, + XlibDisplayType type) + : display_(display), type_(type) { + if (!display_) + return; + if (type == XlibDisplayType::kSyncing) + GetXlibLoader()->XSynchronize(display_, true); +} + +DISABLE_CFI_ICALL +XlibDisplayWrapper::~XlibDisplayWrapper() { + if (!display_) + return; + if (type_ == XlibDisplayType::kFlushing) + GetXlibLoader()->XFlush(display_); + else if (type_ == XlibDisplayType::kSyncing) + GetXlibLoader()->XSynchronize(display_, false); +} + +XlibDisplayWrapper::XlibDisplayWrapper(XlibDisplayWrapper&& other) { + display_ = other.display_; + type_ = other.type_; + other.display_ = nullptr; + other.type_ = XlibDisplayType::kNormal; +} + +XlibDisplayWrapper& XlibDisplayWrapper::operator=(XlibDisplayWrapper&& other) { + display_ = other.display_; + type_ = other.type_; + other.display_ = nullptr; + other.type_ = XlibDisplayType::kNormal; + return *this; +} + +} // namespace x11 diff --git a/chromium/ui/gfx/x/xlib_support.h b/chromium/ui/gfx/x/xlib_support.h new file mode 100644 index 00000000000..37ea34afcbd --- /dev/null +++ b/chromium/ui/gfx/x/xlib_support.h @@ -0,0 +1,73 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_X_XLIB_SUPPORT_H_ +#define UI_GFX_X_XLIB_SUPPORT_H_ + +#include <string> + +#include "base/component_export.h" + +struct _XDisplay; + +namespace x11 { + +// Specifies the behavior of XlibDisplayWrapper. +enum class XlibDisplayType { + // No action taken on wrapper construction or destruction. + kNormal, + + // Flushes the connection on destruction. + kFlushing, + + // Synchronizes all requests while the wrapper is alive. + kSyncing, +}; + +// Loads Xlib, initializes threads, and sets a default error handler. +COMPONENT_EXPORT(X11) void InitXlib(); + +// Sets an async error handler which only logs an error message. +COMPONENT_EXPORT(X11) void SetXlibErrorHandler(); + +// A scoped Xlib display. +class COMPONENT_EXPORT(X11) XlibDisplay { + public: + ~XlibDisplay(); + + private: + friend class Connection; + friend class XlibDisplayWrapper; + + explicit XlibDisplay(const std::string& address); + + struct _XDisplay* display_ = nullptr; +}; + +// A temporary wrapper around an unowned Xlib display that adds behavior +// on construction and destruction (see XlibDisplayType). +class COMPONENT_EXPORT(X11) XlibDisplayWrapper { + public: + ~XlibDisplayWrapper(); + + struct _XDisplay* display() { + return display_; + } + operator struct _XDisplay *() { return display_; } + + XlibDisplayWrapper(XlibDisplayWrapper&& other); + XlibDisplayWrapper& operator=(XlibDisplayWrapper&& other); + + private: + XlibDisplayWrapper(struct _XDisplay* display, XlibDisplayType type); + + friend class Connection; + + struct _XDisplay* display_; + XlibDisplayType type_; +}; + +} // namespace x11 + +#endif // UI_GFX_X_XLIB_SUPPORT_H_ diff --git a/chromium/ui/gfx/x/xproto_internal.cc b/chromium/ui/gfx/x/xproto_internal.cc index 83b8156a1dc..8a23cfc6da7 100644 --- a/chromium/ui/gfx/x/xproto_internal.cc +++ b/chromium/ui/gfx/x/xproto_internal.cc @@ -8,7 +8,6 @@ #include <xcb/xcb.h> #include <xcb/xcbext.h> -#include "ui/gfx/x/x11.h" namespace x11 { diff --git a/chromium/ui/gfx/x/xproto_internal.h b/chromium/ui/gfx/x/xproto_internal.h index 61b930108ee..6ba0604db48 100644 --- a/chromium/ui/gfx/x/xproto_internal.h +++ b/chromium/ui/gfx/x/xproto_internal.h @@ -37,6 +37,9 @@ struct EnumBase<T, typename std::enable_if_t<std::is_enum<T>::value>> { template <typename T> using EnumBaseType = typename EnumBase<T>::type; +template <typename T> +void ReadError(T* error, ReadBuffer* buf); + // Calls free() on the underlying data when the count drops to 0. class COMPONENT_EXPORT(X11) MallocedRefCountedMemory : public base::RefCountedMemory { @@ -137,10 +140,12 @@ base::Optional<unsigned int> SendRequestImpl(x11::Connection* connection, template <typename Reply> Future<Reply> SendRequest(x11::Connection* connection, WriteBuffer* buf, - bool reply_has_fds) { + bool reply_has_fds, + const char* request_name) { auto sequence = SendRequestImpl(connection, buf, std::is_void<Reply>::value, reply_has_fds); - return {sequence ? connection : nullptr, sequence}; + return {sequence ? connection : nullptr, sequence, + sequence ? request_name : nullptr}; } // Helper function for xcbproto popcount. Given an integral type, returns the diff --git a/chromium/ui/gfx/x/xproto_types.cc b/chromium/ui/gfx/x/xproto_types.cc index 839d5466f52..af509848f09 100644 --- a/chromium/ui/gfx/x/xproto_types.cc +++ b/chromium/ui/gfx/x/xproto_types.cc @@ -7,9 +7,9 @@ #include <xcb/xcbext.h> #include "base/memory/scoped_refptr.h" +#include "base/trace_event/trace_event.h" #include "ui/gfx/x/connection.h" #include "ui/gfx/x/xproto_internal.h" -#include "ui/gfx/x/xproto_util.h" namespace x11 { @@ -80,8 +80,11 @@ void WriteBuffer::AppendCurrentBuffer() { } FutureBase::FutureBase(Connection* connection, - base::Optional<unsigned int> sequence) - : connection_(connection), sequence_(sequence) {} + base::Optional<unsigned int> sequence, + const char* request_name) + : connection_(connection), + sequence_(sequence), + request_name_(request_name) {} // If a user-defined response-handler is not installed before this object goes // out of scope, a default response handler will be installed. The default @@ -91,45 +94,58 @@ FutureBase::~FutureBase() { return; OnResponseImpl(base::BindOnce( - [](Connection* connection, RawReply reply, RawError error) { - if (!error) + [](Connection* connection, const char* request_name, + Connection::ErrorHandler error_handler, RawReply raw_reply, + RawError raw_error) { + if (!raw_error) return; - x11::LogErrorEventDescription(error->full_sequence, error->error_code, - error->major_code, error->minor_code); + auto error = connection->ParseError(raw_error); + error_handler.Run(error.get(), request_name); }, - connection_)); + connection_, request_name_, connection_->error_handler_)); } FutureBase::FutureBase(FutureBase&& future) - : connection_(future.connection_), sequence_(future.sequence_) { - future.connection_ = nullptr; - future.sequence_ = base::nullopt; + : connection_(future.connection_), + sequence_(future.sequence_), + request_name_(future.request_name_) { + future.Reset(); } FutureBase& FutureBase::operator=(FutureBase&& future) { connection_ = future.connection_; sequence_ = future.sequence_; - future.connection_ = nullptr; - future.sequence_ = base::nullopt; + request_name_ = future.request_name_; + future.Reset(); return *this; } -void FutureBase::SyncImpl(Error** raw_error, - scoped_refptr<base::RefCountedMemory>* raw_reply) { +void FutureBase::SyncImpl(RawError* raw_error, RawReply* raw_reply) { if (!sequence_) return; - auto* reply = reinterpret_cast<uint8_t*>( - xcb_wait_for_reply(connection_->XcbConnection(), *sequence_, raw_error)); + xcb_generic_error_t* error = nullptr; + void* reply = nullptr; + if (!xcb_poll_for_reply(connection_->XcbConnection(), *sequence_, &reply, + &error)) { + TRACE_EVENT1("ui", "xcb_wait_for_reply", "request", request_name_); + reply = + xcb_wait_for_reply(connection_->XcbConnection(), *sequence_, &error); + } if (reply) *raw_reply = base::MakeRefCounted<MallocedRefCountedMemory>(reply); + if (error) + *raw_error = base::MakeRefCounted<MallocedRefCountedMemory>(error); sequence_ = base::nullopt; } -void FutureBase::SyncImpl(Error** raw_error) { +void FutureBase::SyncImpl(RawError* raw_error) { if (!sequence_) return; - *raw_error = xcb_request_check(connection_->XcbConnection(), {*sequence_}); + if (xcb_generic_error_t* error = + xcb_request_check(connection_->XcbConnection(), {*sequence_})) { + *raw_error = base::MakeRefCounted<MallocedRefCountedMemory>(error); + } sequence_ = base::nullopt; } @@ -140,4 +156,18 @@ void FutureBase::OnResponseImpl(ResponseCallback callback) { sequence_ = base::nullopt; } +// static +std::unique_ptr<Error> FutureBase::ParseErrorImpl(x11::Connection* connection, + RawError raw_error) { + if (!raw_error) + return nullptr; + return connection->ParseError(raw_error); +} + +void FutureBase::Reset() { + connection_ = nullptr; + sequence_ = base::nullopt; + request_name_ = nullptr; +} + } // namespace x11 diff --git a/chromium/ui/gfx/x/xproto_types.h b/chromium/ui/gfx/x/xproto_types.h index 37799e76dfd..e38c83f561d 100644 --- a/chromium/ui/gfx/x/xproto_types.h +++ b/chromium/ui/gfx/x/xproto_types.h @@ -5,8 +5,6 @@ #ifndef UI_GFX_X_XPROTO_TYPES_H_ #define UI_GFX_X_XPROTO_TYPES_H_ -#include <xcb/xcb.h> - #include <cstdint> #include <memory> @@ -18,8 +16,7 @@ #include "base/memory/ref_counted_memory.h" #include "base/memory/scoped_refptr.h" #include "base/optional.h" - -typedef struct _XDisplay XDisplay; +#include "ui/gfx/x/error.h" namespace x11 { @@ -100,8 +97,6 @@ std::unique_ptr<Reply> ReadReply(ReadBuffer* buffer); } // namespace detail -using Error = xcb_generic_error_t; - template <class Reply> class Future; @@ -121,31 +116,29 @@ struct Response { Reply* operator->() { return reply.get(); } std::unique_ptr<Reply> reply; - std::unique_ptr<Error, base::FreeDeleter> error; + std::unique_ptr<Error> error; private: friend class Future<Reply>; - Response(std::unique_ptr<Reply> reply, - std::unique_ptr<Error, base::FreeDeleter> error) + Response(std::unique_ptr<Reply> reply, std::unique_ptr<Error> error) : reply(std::move(reply)), error(std::move(error)) {} }; template <> struct Response<void> { - std::unique_ptr<Error, base::FreeDeleter> error; + std::unique_ptr<Error> error; private: friend class Future<void>; - explicit Response(std::unique_ptr<Error, base::FreeDeleter> error) - : error(std::move(error)) {} + explicit Response(std::unique_ptr<Error> error) : error(std::move(error)) {} }; class COMPONENT_EXPORT(X11) FutureBase { public: using RawReply = scoped_refptr<base::RefCountedMemory>; - using RawError = std::unique_ptr<xcb_generic_error_t, base::FreeDeleter>; + using RawError = scoped_refptr<base::RefCountedMemory>; using ResponseCallback = base::OnceCallback<void(RawReply reply, RawError error)>; @@ -153,21 +146,30 @@ class COMPONENT_EXPORT(X11) FutureBase { FutureBase& operator=(const FutureBase&) = delete; protected: - FutureBase(Connection* connection, base::Optional<unsigned int> sequence); + FutureBase(Connection* connection, + base::Optional<unsigned int> sequence, + const char* request_name); ~FutureBase(); FutureBase(FutureBase&& future); FutureBase& operator=(FutureBase&& future); - void SyncImpl(Error** raw_error, - scoped_refptr<base::RefCountedMemory>* raw_reply); - void SyncImpl(Error** raw_error); + void SyncImpl(RawError* raw_error, RawReply* raw_reply); + void SyncImpl(RawError* raw_error); void OnResponseImpl(ResponseCallback callback); + x11::Connection* connection() { return connection_; } + + static std::unique_ptr<Error> ParseErrorImpl(x11::Connection* connection, + RawError raw_error); + private: - Connection* connection_; + void Reset(); + + Connection* connection_ = nullptr; base::Optional<unsigned int> sequence_; + const char* request_name_ = nullptr; }; // An x11::Future wraps an asynchronous response from the X11 server. The @@ -178,12 +180,12 @@ class Future : public FutureBase { public: using Callback = base::OnceCallback<void(Response<Reply> response)>; - Future() : FutureBase(nullptr, base::nullopt) {} + Future() : FutureBase(nullptr, base::nullopt, nullptr) {} // Blocks until we receive the response from the server. Returns the response. Response<Reply> Sync() { - Error* raw_error = nullptr; - scoped_refptr<base::RefCountedMemory> raw_reply; + RawError raw_error; + RawReply raw_reply; SyncImpl(&raw_error, &raw_reply); std::unique_ptr<Reply> reply; @@ -192,9 +194,7 @@ class Future : public FutureBase { reply = detail::ReadReply<Reply>(&buf); } - std::unique_ptr<Error, base::FreeDeleter> error; - if (raw_error) - error.reset(raw_error); + std::unique_ptr<Error> error = ParseErrorImpl(connection(), raw_error); return {std::move(reply), std::move(error)}; } @@ -205,13 +205,17 @@ class Future : public FutureBase { // real Reply object before feeding the result to |callback|. This means // |callback| must be bound as the first argument of the intermediate // function. - auto wrapper = [](Callback callback, RawReply raw_reply, RawError error) { - ReadBuffer buf(raw_reply); - std::unique_ptr<Reply> reply = - raw_reply ? detail::ReadReply<Reply>(&buf) : nullptr; + auto wrapper = [](x11::Connection* connection, Callback callback, + RawReply raw_reply, RawError raw_error) { + std::unique_ptr<Reply> reply; + if (raw_reply) { + ReadBuffer buf(raw_reply); + reply = detail::ReadReply<Reply>(&buf); + } + std::unique_ptr<Error> error = ParseErrorImpl(connection, raw_error); std::move(callback).Run({std::move(reply), std::move(error)}); }; - OnResponseImpl(base::BindOnce(wrapper, std::move(callback))); + OnResponseImpl(base::BindOnce(wrapper, connection(), std::move(callback))); } void IgnoreError() { @@ -220,24 +224,21 @@ class Future : public FutureBase { private: template <typename R> - friend Future<R> SendRequest(Connection*, WriteBuffer*, bool); + friend Future<R> SendRequest(Connection*, WriteBuffer*, bool, const char*); - Future(Connection* connection, base::Optional<unsigned int> sequence) - : FutureBase(connection, sequence) {} + Future(Connection* connection, + base::Optional<unsigned int> sequence, + const char* request_name) + : FutureBase(connection, sequence, request_name) {} }; // Sync() specialization for requests that don't generate replies. The returned // response will only contain an error if there was one. template <> inline Response<void> Future<void>::Sync() { - Error* raw_error = nullptr; + RawError raw_error; SyncImpl(&raw_error); - - std::unique_ptr<Error, base::FreeDeleter> error; - if (raw_error) - error.reset(raw_error); - - return Response<void>{std::move(error)}; + return Response<void>{ParseErrorImpl(connection(), raw_error)}; } // OnResponse() specialization for requests that don't generate replies. The @@ -246,11 +247,12 @@ template <> inline void Future<void>::OnResponse(Callback callback) { // See Future<Reply>::OnResponse() for an explanation of why // this wrapper is necessary. - auto wrapper = [](Callback callback, RawReply reply, RawError error) { + auto wrapper = [](x11::Connection* connection, Callback callback, + RawReply reply, RawError error) { DCHECK(!reply); - std::move(callback).Run(Response<void>{std::move(error)}); + std::move(callback).Run(Response<void>{ParseErrorImpl(connection, error)}); }; - OnResponseImpl(base::BindOnce(wrapper, std::move(callback))); + OnResponseImpl(base::BindOnce(wrapper, connection(), std::move(callback))); } template <> diff --git a/chromium/ui/gfx/x/xproto_util.cc b/chromium/ui/gfx/x/xproto_util.cc deleted file mode 100644 index 119fd902a46..00000000000 --- a/chromium/ui/gfx/x/xproto_util.cc +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/gfx/x/xproto_util.h" - -#include "base/logging.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" -#include "ui/gfx/x/connection.h" -#include "ui/gfx/x/x11.h" -#include "ui/gfx/x/xproto.h" - -namespace x11 { - -void LogErrorEventDescription(unsigned long serial, - uint8_t error_code, - uint8_t request_code, - uint8_t minor_code) { - // This function may make some expensive round trips (XListExtensions, - // XQueryExtension), but the only effect this function has is LOG(WARNING), - // so early-return if the log would never be sent anyway. - if (!LOG_IS_ON(WARNING)) - return; - - char error_str[256]; - char request_str[256]; - - x11::Connection* conn = x11::Connection::Get(); - auto* dpy = conn->display(); - XGetErrorText(dpy, error_code, error_str, sizeof(error_str)); - - strncpy(request_str, "Unknown", sizeof(request_str)); - if (request_code < 128) { - std::string num = base::NumberToString(request_code); - XGetErrorDatabaseText(dpy, "XRequest", num.c_str(), "Unknown", request_str, - sizeof(request_str)); - } else { - if (auto response = conn->ListExtensions({}).Sync()) { - for (const auto& str : response->names) { - const char* name = str.name.c_str(); - auto query = conn->QueryExtension({name}).Sync(); - if (query && request_code == query->major_opcode) { - std::string msg = base::StringPrintf("%s.%d", name, minor_code); - XGetErrorDatabaseText(dpy, "XRequest", msg.c_str(), "Unknown", - request_str, sizeof(request_str)); - break; - } - } - } - } - - LOG(WARNING) << "X error received: " - << "serial " << serial << ", " - << "error_code " << static_cast<int>(error_code) << " (" - << error_str << "), " - << "request_code " << static_cast<int>(request_code) << ", " - << "minor_code " << static_cast<int>(minor_code) << " (" - << request_str << ")"; -} - -} // namespace x11 diff --git a/chromium/ui/gfx/x/xproto_util.h b/chromium/ui/gfx/x/xproto_util.h index 3a2486eb573..1b3b00578db 100644 --- a/chromium/ui/gfx/x/xproto_util.h +++ b/chromium/ui/gfx/x/xproto_util.h @@ -33,12 +33,6 @@ x11::Future<void> SendEvent( return connection->SendEvent(send_event); } -COMPONENT_EXPORT(X11) -void LogErrorEventDescription(unsigned long serial, - uint8_t error_code, - uint8_t request_code, - uint8_t minor_code); - } // namespace x11 #endif // UI_GFX_X_XPROTO_UTIL_H_ |