summaryrefslogtreecommitdiff
path: root/chromium/ui/gfx
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-11-18 16:35:47 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-11-18 15:45:54 +0000
commit32f5a1c56531e4210bc4cf8d8c7825d66e081888 (patch)
treeeeeec6822f4d738d8454525233fd0e2e3a659e6d /chromium/ui/gfx
parent99677208ff3b216fdfec551fbe548da5520cd6fb (diff)
downloadqtwebengine-chromium-32f5a1c56531e4210bc4cf8d8c7825d66e081888.tar.gz
BASELINE: Update Chromium to 87.0.4280.67
Change-Id: Ib157360be8c2ffb2c73125751a89f60e049c1d54 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/ui/gfx')
-rw-r--r--chromium/ui/gfx/BUILD.gn10
-rw-r--r--chromium/ui/gfx/android/java_bitmap.cc3
-rw-r--r--chromium/ui/gfx/animation/BUILD.gn6
-rw-r--r--chromium/ui/gfx/canvas_skia.cc2
-rw-r--r--chromium/ui/gfx/color_transform_unittest.cc7
-rw-r--r--chromium/ui/gfx/font_fallback_mac.mm22
-rw-r--r--chromium/ui/gfx/font_fallback_mac_unittest.cc33
-rw-r--r--chromium/ui/gfx/geometry/BUILD.gn2
-rw-r--r--chromium/ui/gfx/geometry/dip_util.cc183
-rw-r--r--chromium/ui/gfx/geometry/dip_util.h90
-rw-r--r--chromium/ui/gfx/geometry/insets.cc42
-rw-r--r--chromium/ui/gfx/geometry/insets.h28
-rw-r--r--chromium/ui/gfx/geometry/insets_conversions.cc31
-rw-r--r--chromium/ui/gfx/geometry/insets_conversions.h25
-rw-r--r--chromium/ui/gfx/geometry/insets_f.h15
-rw-r--r--chromium/ui/gfx/geometry/insets_unittest.cc64
-rw-r--r--chromium/ui/gfx/gpu_fence.cc58
-rw-r--r--chromium/ui/gfx/gpu_fence.h15
-rw-r--r--chromium/ui/gfx/gpu_fence_handle.cc41
-rw-r--r--chromium/ui/gfx/gpu_fence_handle.h40
-rw-r--r--chromium/ui/gfx/gpu_memory_buffer.cc2
-rw-r--r--chromium/ui/gfx/image/image_mac_unittest.mm4
-rw-r--r--chromium/ui/gfx/image/image_skia_operations.cc42
-rw-r--r--chromium/ui/gfx/image/image_skia_operations.h6
-rw-r--r--chromium/ui/gfx/image/image_unittest.cc17
-rw-r--r--chromium/ui/gfx/image/image_unittest_util.cc11
-rw-r--r--chromium/ui/gfx/image/image_unittest_util.h10
-rw-r--r--chromium/ui/gfx/image/mojom/image.mojom2
-rw-r--r--chromium/ui/gfx/ipc/gfx_param_traits_macros.h6
-rw-r--r--chromium/ui/gfx/linux/BUILD.gn2
-rw-r--r--chromium/ui/gfx/linux/client_native_pixmap_dmabuf.cc2
-rw-r--r--chromium/ui/gfx/mac/io_surface.cc86
-rw-r--r--chromium/ui/gfx/mac/io_surface.h9
-rw-r--r--chromium/ui/gfx/mojom/BUILD.gn22
-rw-r--r--chromium/ui/gfx/mojom/gpu_fence_handle.mojom6
-rw-r--r--chromium/ui/gfx/mojom/gpu_fence_handle_mojom_traits.cc34
-rw-r--r--chromium/ui/gfx/mojom/gpu_fence_handle_mojom_traits.h35
-rw-r--r--chromium/ui/gfx/range/BUILD.gn6
-rw-r--r--chromium/ui/gfx/render_text.cc28
-rw-r--r--chromium/ui/gfx/render_text.h4
-rw-r--r--chromium/ui/gfx/render_text_harfbuzz.cc6
-rw-r--r--chromium/ui/gfx/render_text_test_api.h4
-rw-r--r--chromium/ui/gfx/render_text_unittest.cc82
-rw-r--r--chromium/ui/gfx/skbitmap_operations.cc2
-rw-r--r--chromium/ui/gfx/x/BUILD.gn4
-rw-r--r--chromium/ui/gfx/x/connection.cc123
-rw-r--r--chromium/ui/gfx/x/connection.h20
-rw-r--r--chromium/ui/gfx/x/event.cc8
-rw-r--r--chromium/ui/gfx/x/event.h17
-rw-r--r--chromium/ui/gfx/x/gen_xproto.py34
-rw-r--r--chromium/ui/gfx/x/keysyms/BUILD.gn7
-rw-r--r--chromium/ui/gfx/x/keysyms/keysyms.h1161
-rw-r--r--chromium/ui/gfx/x/x11.h152
-rw-r--r--chromium/ui/gfx/x/x11_atom_cache.cc4
-rw-r--r--chromium/ui/gfx/x/x11_error_tracker.cc15
-rw-r--r--chromium/ui/gfx/x/x11_error_tracker.h7
-rw-r--r--chromium/ui/gfx/x/x11_path.cc5
-rw-r--r--chromium/ui/gfx/x/x11_types.cc7
-rw-r--r--chromium/ui/gfx/x/x11_types.h5
-rw-r--r--chromium/ui/gfx/x/xproto_internal.cc48
-rw-r--r--chromium/ui/gfx/x/xproto_internal.h7
-rw-r--r--chromium/ui/gfx/x/xproto_types.cc14
-rw-r--r--chromium/ui/gfx/x/xproto_types.h3
-rw-r--r--chromium/ui/gfx/x/xproto_util.cc35
-rw-r--r--chromium/ui/gfx/x/xproto_util.h29
65 files changed, 2256 insertions, 594 deletions
diff --git a/chromium/ui/gfx/BUILD.gn b/chromium/ui/gfx/BUILD.gn
index e688b1c5cd6..3a076e1cf13 100644
--- a/chromium/ui/gfx/BUILD.gn
+++ b/chromium/ui/gfx/BUILD.gn
@@ -12,12 +12,6 @@ if (is_android) {
import("//build/config/android/rules.gni")
}
-# Reset sources_assignment_filter for the BUILD.gn file to prevent
-# regression during the migration of Chromium away from the feature.
-# See docs/no_sources_assignment_filter.md for more information.
-# TODO(crbug.com/1018739): remove this when migration is done.
-set_sources_assignment_filter([])
-
# Several targets want to include this header file, and some of them are
# child dependencies of "gfx". Therefore, we separate it out here so multiple
# targets can all have a dependency for header checking purposes without
@@ -304,7 +298,7 @@ component("gfx") {
"//third_party/zlib",
]
- if (!is_mac && !is_ios) {
+ if (!is_apple) {
sources += [
"platform_font_skia.cc",
"platform_font_skia.h",
@@ -796,7 +790,7 @@ test("gfx_unittests") {
deps += [ "//ui/resources:ui_test_pak_bundle_data" ]
}
- if (!is_mac && !is_ios) {
+ if (!is_apple) {
sources += [
"interpolated_transform_unittest.cc",
"transform_unittest.cc",
diff --git a/chromium/ui/gfx/android/java_bitmap.cc b/chromium/ui/gfx/android/java_bitmap.cc
index 2a5d5883e7c..db7efd1fe69 100644
--- a/chromium/ui/gfx/android/java_bitmap.cc
+++ b/chromium/ui/gfx/android/java_bitmap.cc
@@ -10,6 +10,7 @@
#include "base/bits.h"
#include "base/check_op.h"
#include "base/notreached.h"
+#include "base/numerics/safe_conversions.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gfx_jni_headers/BitmapHelper_jni.h"
@@ -86,6 +87,8 @@ ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(const SkBitmap* skbitmap,
JavaBitmap dst_lock(jbitmap);
void* src_pixels = skbitmap->getPixels();
void* dst_pixels = dst_lock.pixels();
+ CHECK_GE(base::checked_cast<size_t>(dst_lock.byte_count()),
+ skbitmap->computeByteSize());
memcpy(dst_pixels, src_pixels, skbitmap->computeByteSize());
return jbitmap;
diff --git a/chromium/ui/gfx/animation/BUILD.gn b/chromium/ui/gfx/animation/BUILD.gn
index 49b6c01a7a7..b0184a6af5e 100644
--- a/chromium/ui/gfx/animation/BUILD.gn
+++ b/chromium/ui/gfx/animation/BUILD.gn
@@ -4,12 +4,6 @@
import("//build/config/ui.gni")
-# Reset sources_assignment_filter for the BUILD.gn file to prevent
-# regression during the migration of Chromium away from the feature.
-# See docs/no_sources_assignment_filter.md for more information.
-# TODO(crbug.com/1018739): remove this when migration is done.
-set_sources_assignment_filter([])
-
if (is_android) {
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
diff --git a/chromium/ui/gfx/canvas_skia.cc b/chromium/ui/gfx/canvas_skia.cc
index 53522c181d9..ddc60e28c8d 100644
--- a/chromium/ui/gfx/canvas_skia.cc
+++ b/chromium/ui/gfx/canvas_skia.cc
@@ -206,7 +206,7 @@ void Canvas::DrawStringRectWithFlags(const base::string16& text,
Range range = StripAcceleratorChars(flags, &adjusted_text);
bool elide_text = ((flags & NO_ELLIPSIS) == 0);
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_CHROMEOS)
// On Linux, eliding really means fading the end of the string. But only
// for LTR text. RTL text is still elided (on the left) with "...".
if (elide_text) {
diff --git a/chromium/ui/gfx/color_transform_unittest.cc b/chromium/ui/gfx/color_transform_unittest.cc
index 372c3ca1c03..b2801a54fe3 100644
--- a/chromium/ui/gfx/color_transform_unittest.cc
+++ b/chromium/ui/gfx/color_transform_unittest.cc
@@ -519,8 +519,11 @@ TEST(SimpleColorSpace, CanParseSkShaderSource) {
for (const auto& dst : common_color_spaces) {
auto transform = ColorTransform::NewColorTransform(
src, dst, ColorTransform::Intent::INTENT_PERCEPTUAL);
- std::string source = "void main(inout half4 color) {" +
- transform->GetSkShaderSource() + "}";
+ std::string source =
+ "in shader child;\n"
+ "half4 main() {\n"
+ " half4 color = sample(child);\n" +
+ transform->GetSkShaderSource() + " return color; }";
auto result =
SkRuntimeEffect::Make(SkString(source.c_str(), source.length()));
EXPECT_NE(std::get<0>(result), nullptr);
diff --git a/chromium/ui/gfx/font_fallback_mac.mm b/chromium/ui/gfx/font_fallback_mac.mm
index 839b37122e7..d3664d356de 100644
--- a/chromium/ui/gfx/font_fallback_mac.mm
+++ b/chromium/ui/gfx/font_fallback_mac.mm
@@ -7,17 +7,34 @@
#include <CoreText/CoreText.h>
#import <Foundation/Foundation.h>
+#include "base/i18n/char_iterator.h"
#include "base/mac/foundation_util.h"
#import "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
#import "base/strings/sys_string_conversions.h"
#include "base/trace_event/trace_event.h"
+#include "third_party/icu/source/common/unicode/uchar.h"
#include "ui/gfx/font.h"
#include "ui/gfx/font_fallback_skia_impl.h"
#include "ui/gfx/platform_font.h"
namespace gfx {
+namespace {
+
+bool TextSequenceHasEmoji(base::StringPiece16 text) {
+ base::i18n::UTF16CharIterator iter(text.data(), text.length());
+ while (!iter.end()) {
+ const UChar32 codepoint = iter.get();
+ if (u_hasBinaryProperty(codepoint, UCHAR_EMOJI))
+ return true;
+ iter.Advance();
+ }
+ return false;
+}
+
+} // namespace
+
std::vector<Font> GetFallbackFonts(const Font& font) {
DCHECK(font.GetNativeFont());
// On Mac "There is a system default cascade list (which is polymorphic, based
@@ -57,6 +74,11 @@ bool GetFallbackFont(const Font& font,
Font* result) {
TRACE_EVENT0("fonts", "gfx::GetFallbackFont");
+ if (TextSequenceHasEmoji(text)) {
+ *result = Font("Apple Color Emoji", font.GetFontSize());
+ return true;
+ }
+
sk_sp<SkTypeface> fallback_typeface =
GetSkiaFallbackTypeface(font, locale, text);
diff --git a/chromium/ui/gfx/font_fallback_mac_unittest.cc b/chromium/ui/gfx/font_fallback_mac_unittest.cc
index 8b9349b7acf..aaca9deadc1 100644
--- a/chromium/ui/gfx/font_fallback_mac_unittest.cc
+++ b/chromium/ui/gfx/font_fallback_mac_unittest.cc
@@ -4,6 +4,7 @@
#include "ui/gfx/font_fallback.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/font.h"
@@ -33,7 +34,7 @@ TEST(FontFallbackMacTest, GetFallbackFont) {
const base::string16 hebrew = base::WideToUTF16(L"\x5d0\x5d1\x5d2");
const base::string16 emoji = base::UTF8ToUTF16("😋");
- gfx::Font fallback;
+ Font fallback;
EXPECT_TRUE(
GetFallbackFont(arial, kDefaultApplicationLocale, hebrew, &fallback));
EXPECT_EQ("Lucida Grande", fallback.GetFontName());
@@ -42,4 +43,34 @@ TEST(FontFallbackMacTest, GetFallbackFont) {
EXPECT_EQ("Apple Color Emoji", fallback.GetFontName());
}
+TEST(FontFallbackMacTest, GetFallbackFontForEmoji) {
+ static struct {
+ const char* test_name;
+ const wchar_t* text;
+ } kEmojiTests[] = {
+ {"aries", L"\u2648"},
+ {"candle", L"\U0001F56F"},
+ {"anchor", L"\u2693"},
+ {"grinning_face", L"\U0001F600"},
+ {"flag_andorra", L"\U0001F1E6\U0001F1E9"},
+ {"woman_man_hands_light", L"\U0001F46B\U0001F3FB"},
+ {"hole_text", L"\U0001F573\uFE0E"},
+ {"hole_emoji", L"\U0001F573\uFE0F"},
+ {"man_judge_medium", L"\U0001F468\U0001F3FD\u200D\u2696\uFE0F"},
+ {"woman_turban", L"\U0001F473\u200D\u2640\uFE0F"},
+ {"rainbow_flag", L"\U0001F3F3\uFE0F\u200D\U0001F308"},
+ {"eye_bubble", L"\U0001F441\uFE0F\u200D\U0001F5E8\uFE0F"},
+ };
+
+ Font font;
+ for (const auto& test : kEmojiTests) {
+ SCOPED_TRACE(
+ base::StringPrintf("GetFallbackFontForEmoji [%s]", test.test_name));
+ Font fallback;
+ EXPECT_TRUE(GetFallbackFont(font, kDefaultApplicationLocale,
+ base::WideToUTF16(test.text), &fallback));
+ EXPECT_EQ("Apple Color Emoji", fallback.GetFontName());
+ }
+}
+
} // namespace gfx
diff --git a/chromium/ui/gfx/geometry/BUILD.gn b/chromium/ui/gfx/geometry/BUILD.gn
index 563eb24b40d..f4e4a7d8859 100644
--- a/chromium/ui/gfx/geometry/BUILD.gn
+++ b/chromium/ui/gfx/geometry/BUILD.gn
@@ -17,6 +17,8 @@ component("geometry") {
"geometry_export.h",
"insets.cc",
"insets.h",
+ "insets_conversions.cc",
+ "insets_conversions.h",
"insets_f.cc",
"insets_f.h",
"matrix3_f.cc",
diff --git a/chromium/ui/gfx/geometry/dip_util.cc b/chromium/ui/gfx/geometry/dip_util.cc
index db8e1be5d56..11a15f74040 100644
--- a/chromium/ui/gfx/geometry/dip_util.cc
+++ b/chromium/ui/gfx/geometry/dip_util.cc
@@ -4,9 +4,11 @@
#include "ui/gfx/geometry/dip_util.h"
+#include "base/numerics/safe_conversions.h"
+#include "build/build_config.h"
#include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/geometry/insets_f.h"
#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_conversions.h"
@@ -15,74 +17,153 @@
namespace gfx {
-Insets ConvertInsetsToDIP(float scale_factor,
- const gfx::Insets& insets_in_pixel) {
- if (scale_factor == 1.f)
- return insets_in_pixel;
- return insets_in_pixel.Scale(1.f / scale_factor);
+#if defined(OS_MAC)
+// Returns true if the floating point value is holding an integer, modulo
+// floating point error. The value `f` can be safely converted to its integer
+// form with base::ClampRound().
+static bool IsIntegerInFloat(float f) {
+ return std::abs(f - base::ClampRound(f)) < 0.01f;
}
+#endif
-Point ConvertPointToDIP(float scale_factor, const Point& point_in_pixel) {
- if (scale_factor == 1.f)
- return point_in_pixel;
- return ScaleToFlooredPoint(point_in_pixel, 1.f / scale_factor);
+PointF ConvertPointToDips(const Point& point_in_pixels,
+ float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScalePoint(PointF(point_in_pixels), 1.f / device_scale_factor);
}
-PointF ConvertPointToDIP(float scale_factor, const PointF& point_in_pixel) {
- if (scale_factor == 1.f)
- return point_in_pixel;
- return ScalePoint(point_in_pixel, 1.f / scale_factor);
+PointF ConvertPointToDips(const PointF& point_in_pixels,
+ float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScalePoint(point_in_pixels, 1.f / device_scale_factor);
}
-Size ConvertSizeToDIP(float scale_factor, const Size& size_in_pixel) {
- if (scale_factor == 1.f)
- return size_in_pixel;
- return ScaleToFlooredSize(size_in_pixel, 1.f / scale_factor);
+PointF ConvertPointToPixels(const Point& point_in_dips,
+ float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScalePoint(PointF(point_in_dips), device_scale_factor);
}
-Rect ConvertRectToDIP(float scale_factor, const Rect& rect_in_pixel) {
- if (scale_factor == 1.f)
- return rect_in_pixel;
- return ToFlooredRectDeprecated(
- ScaleRect(RectF(rect_in_pixel), 1.f / scale_factor));
+PointF ConvertPointToPixels(const PointF& point_in_dips,
+ float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScalePoint(point_in_dips, device_scale_factor);
}
-Insets ConvertInsetsToPixel(float scale_factor,
- const gfx::Insets& insets_in_dip) {
- if (scale_factor == 1.f)
- return insets_in_dip;
- return insets_in_dip.Scale(scale_factor);
+SizeF ConvertSizeToDips(const Size& size_in_pixels, float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScaleSize(SizeF(size_in_pixels), 1.f / device_scale_factor);
}
-Point ConvertPointToPixel(float scale_factor, const Point& point_in_dip) {
- if (scale_factor == 1.f)
- return point_in_dip;
- return ScaleToFlooredPoint(point_in_dip, scale_factor);
+SizeF ConvertSizeToDips(const SizeF& size_in_pixels,
+ float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScaleSize(size_in_pixels, 1.f / device_scale_factor);
}
-PointF ConvertPointToPixel(float scale_factor, const PointF& point_in_dip) {
- if (scale_factor == 1.f)
- return point_in_dip;
- return ScalePoint(point_in_dip, scale_factor);
+SizeF ConvertSizeToPixels(const Size& size_in_dips, float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScaleSize(SizeF(size_in_dips), device_scale_factor);
}
-Size ConvertSizeToPixel(float scale_factor, const Size& size_in_dip) {
- if (scale_factor == 1.f)
- return size_in_dip;
- return ScaleToFlooredSize(size_in_dip, scale_factor);
+SizeF ConvertSizeToPixels(const SizeF& size_in_dips,
+ float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScaleSize(size_in_dips, device_scale_factor);
}
-Rect ConvertRectToPixel(float scale_factor, const Rect& rect_in_dip) {
- // Use ToEnclosingRect() to ensure we paint all the possible pixels
- // touched. ToEnclosingRect() floors the origin, and ceils the max
- // coordinate. To do otherwise (such as flooring the size) potentially
- // results in rounding down and not drawing all the pixels that are
- // touched.
- if (scale_factor == 1.f)
- return rect_in_dip;
- return ToEnclosingRect(
- RectF(ScalePoint(gfx::PointF(rect_in_dip.origin()), scale_factor),
- ScaleSize(gfx::SizeF(rect_in_dip.size()), scale_factor)));
+RectF ConvertRectToDips(const Rect& rect_in_pixels, float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScaleRect(RectF(rect_in_pixels), 1.f / device_scale_factor);
+}
+
+RectF ConvertRectToDips(const RectF& rect_in_pixels,
+ float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScaleRect(rect_in_pixels, 1.f / device_scale_factor);
+}
+
+RectF ConvertRectToPixels(const Rect& rect_in_dips, float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScaleRect(RectF(rect_in_dips), device_scale_factor);
+}
+
+RectF ConvertRectToPixels(const RectF& rect_in_dips,
+ float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScaleRect(rect_in_dips, device_scale_factor);
+}
+
+InsetsF ConvertInsetsToDips(const gfx::Insets& insets_in_pixels,
+ float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScaleInsets(InsetsF(insets_in_pixels), 1.f / device_scale_factor);
+}
+
+InsetsF ConvertInsetsToDips(const gfx::InsetsF& insets_in_pixels,
+ float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScaleInsets(insets_in_pixels, 1.f / device_scale_factor);
+}
+
+InsetsF ConvertInsetsToPixels(const gfx::Insets& insets_in_dips,
+ float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScaleInsets(InsetsF(insets_in_dips), device_scale_factor);
+}
+
+InsetsF ConvertInsetsToPixels(const gfx::InsetsF& insets_in_dips,
+ float device_scale_factor) {
+#if defined(OS_MAC)
+ // Device scale factor on MacOSX is always an integer.
+ DCHECK(IsIntegerInFloat(device_scale_factor));
+#endif
+ return ScaleInsets(insets_in_dips, device_scale_factor);
}
} // namespace gfx
diff --git a/chromium/ui/gfx/geometry/dip_util.h b/chromium/ui/gfx/geometry/dip_util.h
index cb344c93fed..cc542a833bf 100644
--- a/chromium/ui/gfx/geometry/dip_util.h
+++ b/chromium/ui/gfx/geometry/dip_util.h
@@ -10,36 +10,74 @@
namespace gfx {
class Insets;
+class InsetsF;
class Point;
class PointF;
class Rect;
+class RectF;
class Size;
+class SizeF;
-GEOMETRY_EXPORT gfx::Insets ConvertInsetsToDIP(
- float scale_factor,
- const gfx::Insets& insets_in_pixel);
-GEOMETRY_EXPORT gfx::Point ConvertPointToDIP(float scale_factor,
- const gfx::Point& point_in_pixel);
-GEOMETRY_EXPORT gfx::PointF ConvertPointToDIP(
- float scale_factor,
- const gfx::PointF& point_in_pixel);
-GEOMETRY_EXPORT gfx::Size ConvertSizeToDIP(float scale_factor,
- const gfx::Size& size_in_pixel);
-GEOMETRY_EXPORT gfx::Rect ConvertRectToDIP(float scale_factor,
- const gfx::Rect& rect_in_pixel);
-
-GEOMETRY_EXPORT gfx::Insets ConvertInsetsToPixel(
- float scale_factor,
- const gfx::Insets& insets_in_dip);
-GEOMETRY_EXPORT gfx::Point ConvertPointToPixel(float scale_factor,
- const gfx::Point& point_in_dip);
-GEOMETRY_EXPORT gfx::PointF ConvertPointToPixel(
- float scale_factor,
- const gfx::PointF& point_in_dip);
-GEOMETRY_EXPORT gfx::Size ConvertSizeToPixel(float scale_factor,
- const gfx::Size& size_in_dip);
-GEOMETRY_EXPORT gfx::Rect ConvertRectToPixel(float scale_factor,
- const gfx::Rect& rect_in_dip);
-} // gfx
+// This file contains helper functions to move between DIPs (device-independent
+// pixels) and physical pixels, by multiplying or dividing by device scale
+// factor. These help show the intent of the caller by naming the operation,
+// instead of directly performing a scale operation. More complicated
+// transformations between coordinate spaces than DIP<->physical pixels should
+// be done via more explicit means.
+//
+// Note that functions that receive integer values will convert them to floating
+// point values, which can itself be a lossy operation for large integers. The
+// intention of these methods is to be used for UI values which are relatively
+// small.
+
+GEOMETRY_EXPORT gfx::PointF ConvertPointToDips(
+ const gfx::Point& point_in_pixels,
+ float device_scale_factor);
+GEOMETRY_EXPORT gfx::PointF ConvertPointToDips(
+ const gfx::PointF& point_in_pixels,
+ float device_scale_factor);
+
+GEOMETRY_EXPORT gfx::PointF ConvertPointToPixels(
+ const gfx::Point& point_in_dips,
+ float device_scale_factor);
+GEOMETRY_EXPORT gfx::PointF ConvertPointToPixels(
+ const gfx::PointF& point_in_dips,
+ float device_scale_factor);
+
+GEOMETRY_EXPORT gfx::SizeF ConvertSizeToDips(const gfx::Size& size_in_pixels,
+ float device_scale_factor);
+GEOMETRY_EXPORT gfx::SizeF ConvertSizeToDips(const gfx::SizeF& size_in_pixels,
+ float device_scale_factor);
+
+GEOMETRY_EXPORT gfx::SizeF ConvertSizeToPixels(const gfx::Size& size_in_dips,
+ float device_scale_factor);
+GEOMETRY_EXPORT gfx::SizeF ConvertSizeToPixels(const gfx::SizeF& size_in_dips,
+ float device_scale_factor);
+
+GEOMETRY_EXPORT gfx::RectF ConvertRectToDips(const gfx::Rect& rect_in_pixels,
+ float device_scale_factor);
+GEOMETRY_EXPORT gfx::RectF ConvertRectToDips(const gfx::RectF& rect_in_pixels,
+ float device_scale_factor);
+
+GEOMETRY_EXPORT gfx::RectF ConvertRectToPixels(const gfx::Rect& rect_in_dips,
+ float device_scale_factor);
+GEOMETRY_EXPORT gfx::RectF ConvertRectToPixels(const gfx::RectF& rect_in_dips,
+ float device_scale_factor);
+
+GEOMETRY_EXPORT gfx::InsetsF ConvertInsetsToDips(
+ const gfx::Insets& insets_in_pixels,
+ float device_scale_factor);
+GEOMETRY_EXPORT gfx::InsetsF ConvertInsetsToDips(
+ const gfx::InsetsF& insets_in_pixels,
+ float device_scale_factor);
+
+GEOMETRY_EXPORT gfx::InsetsF ConvertInsetsToPixels(
+ const gfx::Insets& insets_in_dips,
+ float device_scale_factor);
+GEOMETRY_EXPORT gfx::InsetsF ConvertInsetsToPixels(
+ const gfx::InsetsF& insets_in_dips,
+ float device_scale_factor);
+
+} // namespace gfx
#endif // UI_GFX_GEOMETRY_DIP_UTIL_H_
diff --git a/chromium/ui/gfx/geometry/insets.cc b/chromium/ui/gfx/geometry/insets.cc
index 88b563bda86..0e706e1dc87 100644
--- a/chromium/ui/gfx/geometry/insets.cc
+++ b/chromium/ui/gfx/geometry/insets.cc
@@ -5,6 +5,8 @@
#include "ui/gfx/geometry/insets.h"
#include "base/strings/stringprintf.h"
+#include "ui/gfx/geometry/insets_conversions.h"
+#include "ui/gfx/geometry/insets_f.h"
#include "ui/gfx/geometry/vector2d.h"
namespace gfx {
@@ -21,4 +23,44 @@ Insets Insets::Offset(const gfx::Vector2d& vector) const {
base::ClampSub(right(), vector.x()));
}
+Insets ScaleToCeiledInsets(const Insets& insets, float x_scale, float y_scale) {
+ if (x_scale == 1.f && y_scale == 1.f)
+ return insets;
+ return ToCeiledInsets(ScaleInsets(gfx::InsetsF(insets), x_scale, y_scale));
+}
+
+Insets ScaleToCeiledInsets(const Insets& insets, float scale) {
+ if (scale == 1.f)
+ return insets;
+ return ToCeiledInsets(ScaleInsets(gfx::InsetsF(insets), scale));
+}
+
+Insets ScaleToFlooredInsets(const Insets& insets,
+ float x_scale,
+ float y_scale) {
+ if (x_scale == 1.f && y_scale == 1.f)
+ return insets;
+ return ToFlooredInsets(ScaleInsets(gfx::InsetsF(insets), x_scale, y_scale));
+}
+
+Insets ScaleToFlooredInsets(const Insets& insets, float scale) {
+ if (scale == 1.f)
+ return insets;
+ return ToFlooredInsets(ScaleInsets(gfx::InsetsF(insets), scale));
+}
+
+Insets ScaleToRoundedInsets(const Insets& insets,
+ float x_scale,
+ float y_scale) {
+ if (x_scale == 1.f && y_scale == 1.f)
+ return insets;
+ return ToRoundedInsets(ScaleInsets(gfx::InsetsF(insets), x_scale, y_scale));
+}
+
+Insets ScaleToRoundedInsets(const Insets& insets, float scale) {
+ if (scale == 1.f)
+ return insets;
+ return ToRoundedInsets(ScaleInsets(gfx::InsetsF(insets), scale));
+}
+
} // namespace gfx
diff --git a/chromium/ui/gfx/geometry/insets.h b/chromium/ui/gfx/geometry/insets.h
index 598e0d38ff2..9d83dca0f30 100644
--- a/chromium/ui/gfx/geometry/insets.h
+++ b/chromium/ui/gfx/geometry/insets.h
@@ -109,15 +109,6 @@ class GEOMETRY_EXPORT Insets {
-base::MakeClampedNum(right_));
}
- Insets Scale(float scale) const { return Scale(scale, scale); }
-
- Insets Scale(float x_scale, float y_scale) const {
- return Insets(static_cast<int>(base::ClampMul(top(), y_scale)),
- static_cast<int>(base::ClampMul(left(), x_scale)),
- static_cast<int>(base::ClampMul(bottom(), y_scale)),
- static_cast<int>(base::ClampMul(right(), x_scale)));
- }
-
// Adjusts the vertical and horizontal dimensions by the values described in
// |vector|. Offsetting insets before applying to a rectangle would be
// equivalent to offseting the rectangle then applying the insets.
@@ -174,6 +165,11 @@ class GEOMETRY_EXPORT Insets {
}
};
+// This is declared here for use in gtest-based unit tests but is defined in
+// the //ui/gfx:test_support target. Depend on that to use this in your unit
+// test. This should not be used in production code - call ToString() instead.
+void PrintTo(const Insets& point, ::std::ostream* os);
+
inline Insets operator+(Insets lhs, const Insets& rhs) {
lhs += rhs;
return lhs;
@@ -184,6 +180,20 @@ inline Insets operator-(Insets lhs, const Insets& rhs) {
return lhs;
}
+// Helper methods to scale a gfx::Insets to a new gfx::Insets.
+GEOMETRY_EXPORT Insets ScaleToCeiledInsets(const Insets& insets,
+ float x_scale,
+ float y_scale);
+GEOMETRY_EXPORT Insets ScaleToCeiledInsets(const Insets& insets, float scale);
+GEOMETRY_EXPORT Insets ScaleToFlooredInsets(const Insets& insets,
+ float x_scale,
+ float y_scale);
+GEOMETRY_EXPORT Insets ScaleToFlooredInsets(const Insets& insets, float scale);
+GEOMETRY_EXPORT Insets ScaleToRoundedInsets(const Insets& insets,
+ float x_scale,
+ float y_scale);
+GEOMETRY_EXPORT Insets ScaleToRoundedInsets(const Insets& insets, float scale);
+
} // namespace gfx
#endif // UI_GFX_GEOMETRY_INSETS_H_
diff --git a/chromium/ui/gfx/geometry/insets_conversions.cc b/chromium/ui/gfx/geometry/insets_conversions.cc
new file mode 100644
index 00000000000..e41a600b5e5
--- /dev/null
+++ b/chromium/ui/gfx/geometry/insets_conversions.cc
@@ -0,0 +1,31 @@
+// 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/geometry/insets_conversions.h"
+
+#include "base/numerics/safe_conversions.h"
+#include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/geometry/insets_f.h"
+
+namespace gfx {
+
+Insets ToFlooredInsets(const InsetsF& insets) {
+ return Insets(base::ClampFloor(insets.top()), base::ClampFloor(insets.left()),
+ base::ClampFloor(insets.bottom()),
+ base::ClampFloor(insets.right()));
+}
+
+Insets ToCeiledInsets(const InsetsF& insets) {
+ return Insets(base::ClampCeil(insets.top()), base::ClampCeil(insets.left()),
+ base::ClampCeil(insets.bottom()),
+ base::ClampCeil(insets.right()));
+}
+
+Insets ToRoundedInsets(const InsetsF& insets) {
+ return Insets(base::ClampRound(insets.top()), base::ClampRound(insets.left()),
+ base::ClampRound(insets.bottom()),
+ base::ClampRound(insets.right()));
+}
+
+} // namespace gfx
diff --git a/chromium/ui/gfx/geometry/insets_conversions.h b/chromium/ui/gfx/geometry/insets_conversions.h
new file mode 100644
index 00000000000..613515046c7
--- /dev/null
+++ b/chromium/ui/gfx/geometry/insets_conversions.h
@@ -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.
+
+#ifndef UI_GFX_GEOMETRY_INSETS_CONVERSIONS_H_
+#define UI_GFX_GEOMETRY_INSETS_CONVERSIONS_H_
+
+#include "ui/gfx/geometry/geometry_export.h"
+
+namespace gfx {
+class Insets;
+class InsetsF;
+
+// Returns an Insets with each component from the input InsetsF floored.
+GEOMETRY_EXPORT Insets ToFlooredInsets(const InsetsF& insets);
+
+// Returns an Insets with each component from the input InsetsF ceiled.
+GEOMETRY_EXPORT Insets ToCeiledInsets(const InsetsF& insets);
+
+// Returns a Point with each component from the input PointF rounded.
+GEOMETRY_EXPORT Insets ToRoundedInsets(const InsetsF& insets);
+
+} // namespace gfx
+
+#endif // UI_GFX_GEOMETRY_INSETS_CONVERSIONS_H_
diff --git a/chromium/ui/gfx/geometry/insets_f.h b/chromium/ui/gfx/geometry/insets_f.h
index 281a599b97d..3d9380cf4a0 100644
--- a/chromium/ui/gfx/geometry/insets_f.h
+++ b/chromium/ui/gfx/geometry/insets_f.h
@@ -90,6 +90,21 @@ class GEOMETRY_EXPORT InsetsF {
float right_;
};
+// This is declared here for use in gtest-based unit tests but is defined in
+// the //ui/gfx:test_support target. Depend on that to use this in your unit
+// test. This should not be used in production code - call ToString() instead.
+void PrintTo(const InsetsF& point, ::std::ostream* os);
+
+inline InsetsF ScaleInsets(const InsetsF& i, float scale) {
+ return InsetsF(i.top() * scale, i.left() * scale, i.bottom() * scale,
+ i.right() * scale);
+}
+
+inline InsetsF ScaleInsets(const InsetsF& i, float x_scale, float y_scale) {
+ return InsetsF(i.top() * y_scale, i.left() * x_scale, i.bottom() * y_scale,
+ i.right() * x_scale);
+}
+
inline InsetsF operator+(InsetsF lhs, const InsetsF& rhs) {
lhs += rhs;
return lhs;
diff --git a/chromium/ui/gfx/geometry/insets_unittest.cc b/chromium/ui/gfx/geometry/insets_unittest.cc
index ac22c834560..83ef9107ad5 100644
--- a/chromium/ui/gfx/geometry/insets_unittest.cc
+++ b/chromium/ui/gfx/geometry/insets_unittest.cc
@@ -164,13 +164,61 @@ TEST(InsetsTest, Offset) {
}
TEST(InsetsTest, Scale) {
- gfx::Insets test(10, 5);
- test = test.Scale(2.f, 3.f);
- EXPECT_EQ(gfx::Insets(30, 10), test);
+ gfx::Insets in(7, 5);
+
+ gfx::InsetsF testf = gfx::ScaleInsets(in, 2.5f, 3.5f);
+ EXPECT_EQ(gfx::InsetsF(24.5f, 12.5f), testf);
+ testf = gfx::ScaleInsets(in, 2.5f);
+ EXPECT_EQ(gfx::InsetsF(17.5f, 12.5f), testf);
+
+ gfx::Insets test = gfx::ScaleToFlooredInsets(in, 2.5f, 3.5f);
+ EXPECT_EQ(gfx::Insets(24, 12), test);
+ test = gfx::ScaleToFlooredInsets(in, 2.5f);
+ EXPECT_EQ(gfx::Insets(17, 12), test);
+
+ test = gfx::ScaleToCeiledInsets(in, 2.5f, 3.5f);
+ EXPECT_EQ(gfx::Insets(25, 13), test);
+ test = gfx::ScaleToCeiledInsets(in, 2.5f);
+ EXPECT_EQ(gfx::Insets(18, 13), test);
+
+ test = gfx::ScaleToRoundedInsets(in, 2.49f, 3.49f);
+ EXPECT_EQ(gfx::Insets(24, 12), test);
+ test = gfx::ScaleToRoundedInsets(in, 2.49f);
+ EXPECT_EQ(gfx::Insets(17, 12), test);
+
+ test = gfx::ScaleToRoundedInsets(in, 2.5f, 3.5f);
+ EXPECT_EQ(gfx::Insets(25, 13), test);
+ test = gfx::ScaleToRoundedInsets(in, 2.5f);
+ EXPECT_EQ(gfx::Insets(18, 13), test);
+}
- test = gfx::Insets(7, 3);
- test = test.Scale(-2.f, -3.f);
- EXPECT_EQ(gfx::Insets(-21, -6), test);
+TEST(InsetsTest, ScaleNegative) {
+ gfx::Insets in(-7, -5);
+
+ gfx::InsetsF testf = gfx::ScaleInsets(in, 2.5f, 3.5f);
+ EXPECT_EQ(gfx::InsetsF(-24.5f, -12.5f), testf);
+ testf = gfx::ScaleInsets(in, 2.5f);
+ EXPECT_EQ(gfx::InsetsF(-17.5f, -12.5f), testf);
+
+ gfx::Insets test = gfx::ScaleToFlooredInsets(in, 2.5f, 3.5f);
+ EXPECT_EQ(gfx::Insets(-25, -13), test);
+ test = gfx::ScaleToFlooredInsets(in, 2.5f);
+ EXPECT_EQ(gfx::Insets(-18, -13), test);
+
+ test = gfx::ScaleToCeiledInsets(in, 2.5f, 3.5f);
+ EXPECT_EQ(gfx::Insets(-24, -12), test);
+ test = gfx::ScaleToCeiledInsets(in, 2.5f);
+ EXPECT_EQ(gfx::Insets(-17, -12), test);
+
+ test = gfx::ScaleToRoundedInsets(in, 2.49f, 3.49f);
+ EXPECT_EQ(gfx::Insets(-24, -12), test);
+ test = gfx::ScaleToRoundedInsets(in, 2.49f);
+ EXPECT_EQ(gfx::Insets(-17, -12), test);
+
+ test = gfx::ScaleToRoundedInsets(in, 2.5f, 3.5f);
+ EXPECT_EQ(gfx::Insets(-25, -13), test);
+ test = gfx::ScaleToRoundedInsets(in, 2.5f);
+ EXPECT_EQ(gfx::Insets(-18, -13), test);
}
TEST(InsetsTest, IntegerOverflow) {
@@ -189,7 +237,7 @@ TEST(InsetsTest, IntegerOverflow) {
EXPECT_EQ(gfx::Insets(int_max), negation_test);
gfx::Insets scale_test(int_max);
- scale_test = scale_test.Scale(2.f, 2.f);
+ scale_test = gfx::ScaleToRoundedInsets(scale_test, 2.f);
EXPECT_EQ(gfx::Insets(int_max), scale_test);
}
@@ -206,7 +254,7 @@ TEST(InsetsTest, IntegerUnderflow) {
EXPECT_EQ(gfx::Insets(int_min), minus_test);
gfx::Insets scale_test = gfx::Insets(int_min);
- scale_test = scale_test.Scale(2.f, 2.f);
+ scale_test = gfx::ScaleToRoundedInsets(scale_test, 2.f);
EXPECT_EQ(gfx::Insets(int_min), scale_test);
}
diff --git a/chromium/ui/gfx/gpu_fence.cc b/chromium/ui/gfx/gpu_fence.cc
index a8c2422c833..9fc65f3a506 100644
--- a/chromium/ui/gfx/gpu_fence.cc
+++ b/chromium/ui/gfx/gpu_fence.cc
@@ -14,38 +14,13 @@
namespace gfx {
-GpuFence::GpuFence(const GpuFenceHandle& handle) : type_(handle.type) {
- switch (type_) {
- case GpuFenceHandleType::kEmpty:
- break;
- case GpuFenceHandleType::kAndroidNativeFenceSync:
-#if defined(OS_POSIX)
- owned_fd_.reset(handle.native_fd.fd);
-#else
- NOTREACHED();
-#endif
- break;
- }
-}
+GpuFence::GpuFence(GpuFenceHandle fence_handle)
+ : fence_handle_(std::move(fence_handle)) {}
GpuFence::~GpuFence() = default;
-GpuFenceHandle GpuFence::GetGpuFenceHandle() const {
- gfx::GpuFenceHandle handle;
- switch (type_) {
- case GpuFenceHandleType::kEmpty:
- break;
- case GpuFenceHandleType::kAndroidNativeFenceSync:
-#if defined(OS_POSIX)
- handle.type = gfx::GpuFenceHandleType::kAndroidNativeFenceSync;
- handle.native_fd = base::FileDescriptor(owned_fd_.get(),
- /*auto_close=*/false);
-#else
- NOTREACHED();
-#endif
- break;
- }
- return handle;
+const GpuFenceHandle& GpuFence::GetGpuFenceHandle() const {
+ return fence_handle_;
}
ClientGpuFence GpuFence::AsClientGpuFence() {
@@ -58,21 +33,19 @@ GpuFence* GpuFence::FromClientGpuFence(ClientGpuFence gpu_fence) {
}
void GpuFence::Wait() {
- switch (type_) {
- case GpuFenceHandleType::kEmpty:
- break;
- case GpuFenceHandleType::kAndroidNativeFenceSync:
+ if (fence_handle_.is_null()) {
+ return;
+ }
+
#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)
- static const int kInfiniteSyncWaitTimeout = -1;
- DCHECK_GE(owned_fd_.get(), 0);
- if (sync_wait(owned_fd_.get(), kInfiniteSyncWaitTimeout) < 0) {
- LOG(FATAL) << "Failed while waiting for gpu fence fd";
- }
+ static const int kInfiniteSyncWaitTimeout = -1;
+ DCHECK_GE(fence_handle_.owned_fd.get(), 0);
+ if (sync_wait(fence_handle_.owned_fd.get(), kInfiniteSyncWaitTimeout) < 0) {
+ LOG(FATAL) << "Failed while waiting for gpu fence fd";
+ }
#else
- NOTREACHED();
+ NOTREACHED();
#endif
- break;
- }
}
// static
@@ -112,7 +85,8 @@ GpuFence::FenceStatus GpuFence::GetStatusChangeTime(int fd,
base::TimeTicks GpuFence::GetMaxTimestamp() const {
base::TimeTicks timestamp;
#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)
- FenceStatus status = GetStatusChangeTime(owned_fd_.get(), &timestamp);
+ FenceStatus status =
+ GetStatusChangeTime(fence_handle_.owned_fd.get(), &timestamp);
DCHECK_EQ(status, FenceStatus::kSignaled);
return timestamp;
#endif
diff --git a/chromium/ui/gfx/gpu_fence.h b/chromium/ui/gfx/gpu_fence.h
index 2d2a24be612..968cf168be5 100644
--- a/chromium/ui/gfx/gpu_fence.h
+++ b/chromium/ui/gfx/gpu_fence.h
@@ -23,14 +23,14 @@ namespace gfx {
class GFX_EXPORT GpuFence {
public:
// Constructor takes ownership of the source handle's resources.
- explicit GpuFence(const GpuFenceHandle& handle);
+ explicit GpuFence(GpuFenceHandle handle);
GpuFence() = delete;
~GpuFence();
- // This handle is an unowned view of the resources owned by this class for
- // use with CloneHandleForIPC. Don't pass this to a consuming method such as
- // GpuFence(handle) or to IPC, that would cause duplicate resource release.
- GpuFenceHandle GetGpuFenceHandle() const;
+ // Returns a const reference to the underlying GpuFenceHandle
+ // owned by GpuFence. If you'd like a duplicated handle for use
+ // with IPC, call the Clone method on the returned handle.
+ const GpuFenceHandle& GetGpuFenceHandle() const;
// Casts for use with the GLES interface.
ClientGpuFence AsClientGpuFence();
@@ -45,10 +45,7 @@ class GFX_EXPORT GpuFence {
base::TimeTicks GetMaxTimestamp() const;
private:
- gfx::GpuFenceHandleType type_;
-#if defined(OS_POSIX)
- base::ScopedFD owned_fd_;
-#endif
+ gfx::GpuFenceHandle fence_handle_;
DISALLOW_COPY_AND_ASSIGN(GpuFence);
};
diff --git a/chromium/ui/gfx/gpu_fence_handle.cc b/chromium/ui/gfx/gpu_fence_handle.cc
index f8cce06cd0c..485782ac9b8 100644
--- a/chromium/ui/gfx/gpu_fence_handle.cc
+++ b/chromium/ui/gfx/gpu_fence_handle.cc
@@ -14,34 +14,33 @@
namespace gfx {
-GpuFenceHandle::GpuFenceHandle() : type(GpuFenceHandleType::kEmpty) {}
+GpuFenceHandle::GpuFenceHandle() = default;
-GpuFenceHandle::GpuFenceHandle(const GpuFenceHandle& other) = default;
+GpuFenceHandle::GpuFenceHandle(GpuFenceHandle&& other) = default;
-GpuFenceHandle& GpuFenceHandle::operator=(const GpuFenceHandle& other) =
- default;
+GpuFenceHandle& GpuFenceHandle::operator=(GpuFenceHandle&& other) = default;
-GpuFenceHandle::~GpuFenceHandle() {}
+GpuFenceHandle::~GpuFenceHandle() = default;
-GpuFenceHandle CloneHandleForIPC(const GpuFenceHandle& source_handle) {
- switch (source_handle.type) {
- case GpuFenceHandleType::kEmpty:
- NOTREACHED();
- return source_handle;
- case GpuFenceHandleType::kAndroidNativeFenceSync: {
- gfx::GpuFenceHandle handle;
+bool GpuFenceHandle::is_null() const {
#if defined(OS_POSIX)
- handle.type = GpuFenceHandleType::kAndroidNativeFenceSync;
- int duped_handle = HANDLE_EINTR(dup(source_handle.native_fd.fd));
- if (duped_handle < 0)
- return GpuFenceHandle();
- handle.native_fd = base::FileDescriptor(duped_handle, true);
+ return !owned_fd.is_valid();
+#else
+ return true;
#endif
- return handle;
- }
- }
+}
+
+GpuFenceHandle GpuFenceHandle::Clone() const {
+ gfx::GpuFenceHandle handle;
+#if defined(OS_POSIX)
+ const int duped_handle = HANDLE_EINTR(dup(owned_fd.get()));
+ if (duped_handle < 0)
+ return GpuFenceHandle();
+ handle.owned_fd = base::ScopedFD(duped_handle);
+#else
NOTREACHED();
- return gfx::GpuFenceHandle();
+#endif
+ return handle;
}
} // namespace gfx
diff --git a/chromium/ui/gfx/gpu_fence_handle.h b/chromium/ui/gfx/gpu_fence_handle.h
index c79c23b6388..091ead03c9e 100644
--- a/chromium/ui/gfx/gpu_fence_handle.h
+++ b/chromium/ui/gfx/gpu_fence_handle.h
@@ -5,46 +5,40 @@
#ifndef UI_GFX_GPU_FENCE_HANDLE_H_
#define UI_GFX_GPU_FENCE_HANDLE_H_
+#include "base/macros.h"
#include "build/build_config.h"
#include "ui/gfx/gfx_export.h"
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
-#include "base/file_descriptor_posix.h"
+#include "base/files/scoped_file.h"
#endif
namespace gfx {
-enum class GpuFenceHandleType {
- // A null handle for transport. It cannot be used for making a waitable fence
- // object.
- kEmpty,
-
- // A file descriptor for a native fence object as used by the
- // EGL_ANDROID_native_fence_sync extension.
- kAndroidNativeFenceSync,
-
- kLast = kAndroidNativeFenceSync
-};
-
struct GFX_EXPORT GpuFenceHandle {
+ GpuFenceHandle(const GpuFenceHandle&) = delete;
+ GpuFenceHandle& operator=(const GpuFenceHandle&) = delete;
+
GpuFenceHandle();
- GpuFenceHandle(const GpuFenceHandle& other);
- GpuFenceHandle& operator=(const GpuFenceHandle& other);
+ GpuFenceHandle(GpuFenceHandle&& other);
+ GpuFenceHandle& operator=(GpuFenceHandle&& other);
~GpuFenceHandle();
- bool is_null() const { return type == GpuFenceHandleType::kEmpty; }
+ bool is_null() const;
+
+ // Returns an instance of |handle| which can be sent over IPC. This duplicates
+ // the handle so that IPC code can take ownership of it without invalidating
+ // |handle| itself.
+ GpuFenceHandle Clone() const;
- GpuFenceHandleType type;
+ // owned_fd is defined here for both OS_FUCHSIA and OS_POSIX but all
+ // of the handling for owned_fd is only for POSIX. Consider adjusting the
+ // defines in the future.
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
- base::FileDescriptor native_fd;
+ base::ScopedFD owned_fd;
#endif
};
-// Returns an instance of |handle| which can be sent over IPC. This duplicates
-// the file-handles as appropriate, so that the IPC code take ownership of them,
-// without invalidating |handle| itself.
-GFX_EXPORT GpuFenceHandle CloneHandleForIPC(const GpuFenceHandle& handle);
-
} // namespace gfx
#endif // UI_GFX_GPU_FENCE_HANDLE_H_
diff --git a/chromium/ui/gfx/gpu_memory_buffer.cc b/chromium/ui/gfx/gpu_memory_buffer.cc
index 56bda293133..b4e63ecf035 100644
--- a/chromium/ui/gfx/gpu_memory_buffer.cc
+++ b/chromium/ui/gfx/gpu_memory_buffer.cc
@@ -37,7 +37,7 @@ GpuMemoryBufferHandle GpuMemoryBufferHandle::Clone() const {
#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_FUCHSIA)
handle.native_pixmap_handle = CloneHandleForIPC(native_pixmap_handle);
#elif defined(OS_MAC)
- NOTIMPLEMENTED();
+ handle.mach_port = mach_port;
#elif defined(OS_WIN)
NOTIMPLEMENTED();
#elif defined(OS_ANDROID)
diff --git a/chromium/ui/gfx/image/image_mac_unittest.mm b/chromium/ui/gfx/image/image_mac_unittest.mm
index 95aa6134921..ddb44cd106a 100644
--- a/chromium/ui/gfx/image/image_mac_unittest.mm
+++ b/chromium/ui/gfx/image/image_mac_unittest.mm
@@ -199,10 +199,10 @@ TEST_F(ImageMacTest, MultiResolutionPNGToNSImage) {
// Convert to ImageSkia to check pixel contents of NSImageReps.
gfx::ImageSkia image_skia = gfx::ImageSkiaFromNSImage(ns_image);
EXPECT_TRUE(gt::ArePNGBytesCloseToBitmap(
- bytes1x, image_skia.GetRepresentation(1.0f).GetBitmap(),
+ *bytes1x, image_skia.GetRepresentation(1.0f).GetBitmap(),
gt::MaxColorSpaceConversionColorShift()));
EXPECT_TRUE(gt::ArePNGBytesCloseToBitmap(
- bytes2x, image_skia.GetRepresentation(2.0f).GetBitmap(),
+ *bytes2x, image_skia.GetRepresentation(2.0f).GetBitmap(),
gt::MaxColorSpaceConversionColorShift()));
}
diff --git a/chromium/ui/gfx/image/image_skia_operations.cc b/chromium/ui/gfx/image/image_skia_operations.cc
index da72f3a6786..60a3eba52f2 100644
--- a/chromium/ui/gfx/image/image_skia_operations.cc
+++ b/chromium/ui/gfx/image/image_skia_operations.cc
@@ -499,6 +499,38 @@ class ColorMaskSource : public gfx::ImageSkiaSource {
DISALLOW_COPY_AND_ASSIGN(ColorMaskSource);
};
+// Image source to create an image with a circle background.
+class ImageWithCircleBackgroundSource : public gfx::CanvasImageSource {
+ public:
+ ImageWithCircleBackgroundSource(int radius,
+ SkColor color,
+ const gfx::ImageSkia& image)
+ : gfx::CanvasImageSource(gfx::Size(radius * 2, radius * 2)),
+ radius_(radius),
+ color_(color),
+ image_(image) {}
+
+ ~ImageWithCircleBackgroundSource() override = default;
+
+ // gfx::CanvasImageSource:
+ void Draw(gfx::Canvas* canvas) override {
+ cc::PaintFlags flags;
+ flags.setAntiAlias(true);
+ flags.setStyle(cc::PaintFlags::kFill_Style);
+ flags.setColor(color_);
+ canvas->DrawCircle(gfx::Point(radius_, radius_), radius_, flags);
+ const int x = radius_ - image_.width() / 2;
+ const int y = radius_ - image_.height() / 2;
+ canvas->DrawImageInt(image_, x, y);
+ }
+
+ private:
+ const int radius_;
+ const SkColor color_;
+ const gfx::ImageSkia image_;
+
+ DISALLOW_COPY_AND_ASSIGN(ImageWithCircleBackgroundSource);
+};
} // namespace
// static
@@ -664,4 +696,14 @@ ImageSkia ImageSkiaOperations::CreateColorMask(const ImageSkia& image,
return ImageSkia(std::make_unique<ColorMaskSource>(image, color),
image.size());
}
+
+ImageSkia ImageSkiaOperations::CreateImageWithCircleBackground(
+ int radius,
+ SkColor color,
+ const ImageSkia& image) {
+ DCHECK_GE(radius * 2, image.width());
+ DCHECK_GE(radius * 2, image.height());
+ return gfx::CanvasImageSource::MakeImageSkia<ImageWithCircleBackgroundSource>(
+ radius, color, image);
+}
} // namespace gfx
diff --git a/chromium/ui/gfx/image/image_skia_operations.h b/chromium/ui/gfx/image/image_skia_operations.h
index 7f3a4b00e7a..a25afd429d9 100644
--- a/chromium/ui/gfx/image/image_skia_operations.h
+++ b/chromium/ui/gfx/image/image_skia_operations.h
@@ -113,6 +113,12 @@ class GFX_EXPORT ImageSkiaOperations {
// The image must use the kARGB_8888_Config config.
static ImageSkia CreateColorMask(const gfx::ImageSkia& image, SkColor color);
+ // Creates an image with a circle background. |color| and |radius| is the
+ // color and radius of the circle background.
+ static ImageSkia CreateImageWithCircleBackground(int radius,
+ SkColor color,
+ const ImageSkia& image);
+
private:
ImageSkiaOperations(); // Class for scoping only.
};
diff --git a/chromium/ui/gfx/image/image_unittest.cc b/chromium/ui/gfx/image/image_unittest.cc
index 453baa97b3a..40354aea1a9 100644
--- a/chromium/ui/gfx/image/image_unittest.cc
+++ b/chromium/ui/gfx/image/image_unittest.cc
@@ -208,7 +208,7 @@ TEST_F(ImageTest, MultiResolutionImageSkiaToPNG) {
gfx::Image image(image_skia);
EXPECT_TRUE(
- gt::ArePNGBytesCloseToBitmap(image.As1xPNGBytes(), bitmap_1x,
+ gt::ArePNGBytesCloseToBitmap(*image.As1xPNGBytes(), bitmap_1x,
gt::MaxColorSpaceConversionColorShift()));
EXPECT_TRUE(image.HasRepresentation(gfx::Image::kImageRepPNG));
}
@@ -230,10 +230,10 @@ TEST_F(ImageTest, MultiResolutionPNGToImageSkia) {
scales.push_back(2.0f);
gfx::ImageSkia image_skia = image.AsImageSkia();
EXPECT_TRUE(gt::ArePNGBytesCloseToBitmap(
- bytes1x, image_skia.GetRepresentation(1.0f).GetBitmap(),
+ *bytes1x, image_skia.GetRepresentation(1.0f).GetBitmap(),
gt::MaxColorSpaceConversionColorShift()));
EXPECT_TRUE(gt::ArePNGBytesCloseToBitmap(
- bytes2x, image_skia.GetRepresentation(2.0f).GetBitmap(),
+ *bytes2x, image_skia.GetRepresentation(2.0f).GetBitmap(),
gt::MaxColorSpaceConversionColorShift()));
EXPECT_TRUE(gt::ImageSkiaStructureMatches(image_skia, kSize1x, kSize1x,
scales));
@@ -269,16 +269,17 @@ TEST_F(ImageTest, MultiResolutionPNGToPlatform) {
EXPECT_EQ(scales.size(), 1U);
if (scales[0] == 1.0f)
EXPECT_TRUE(
- gt::ArePNGBytesCloseToBitmap(bytes1x, from_platform.AsBitmap(),
+ gt::ArePNGBytesCloseToBitmap(*bytes1x, from_platform.AsBitmap(),
gt::MaxColorSpaceConversionColorShift()));
else if (scales[0] == 2.0f)
- EXPECT_TRUE(gt::ArePNGBytesCloseToBitmap(bytes2x, from_platform.AsBitmap(),
- gt::MaxColorSpaceConversionColorShift()));
+ EXPECT_TRUE(
+ gt::ArePNGBytesCloseToBitmap(*bytes2x, from_platform.AsBitmap(),
+ gt::MaxColorSpaceConversionColorShift()));
else
ADD_FAILURE() << "Unexpected platform scale factor.";
#else
EXPECT_TRUE(
- gt::ArePNGBytesCloseToBitmap(bytes1x, from_platform.AsBitmap(),
+ gt::ArePNGBytesCloseToBitmap(*bytes1x, from_platform.AsBitmap(),
gt::MaxColorSpaceConversionColorShift()));
#endif // defined(OS_IOS)
}
@@ -316,7 +317,7 @@ TEST_F(ImageTest, PNGEncodeFromSkiaDecodeToPlatform) {
EXPECT_TRUE(gt::IsPlatformImageValid(gt::ToPlatformType(from_platform)));
EXPECT_TRUE(
- gt::ArePNGBytesCloseToBitmap(png_bytes, from_platform.AsBitmap(),
+ gt::ArePNGBytesCloseToBitmap(*png_bytes, from_platform.AsBitmap(),
gt::MaxColorSpaceConversionColorShift()));
}
diff --git a/chromium/ui/gfx/image/image_unittest_util.cc b/chromium/ui/gfx/image/image_unittest_util.cc
index 957b431e84f..9d6f74492c1 100644
--- a/chromium/ui/gfx/image/image_unittest_util.cc
+++ b/chromium/ui/gfx/image/image_unittest_util.cc
@@ -148,15 +148,12 @@ bool AreBitmapsClose(const SkBitmap& bmp1,
return true;
}
-bool ArePNGBytesCloseToBitmap(
- const scoped_refptr<base::RefCountedMemory>& bytes,
- const SkBitmap& bitmap,
- int max_deviation) {
+bool ArePNGBytesCloseToBitmap(base::span<const uint8_t> bytes,
+ const SkBitmap& bitmap,
+ int max_deviation) {
SkBitmap decoded;
- if (!bytes.get() ||
- !PNGCodec::Decode(bytes->front(), bytes->size(), &decoded)) {
+ if (!PNGCodec::Decode(bytes.data(), bytes.size(), &decoded))
return bitmap.isNull();
- }
return AreBitmapsClose(bitmap, decoded, max_deviation);
}
diff --git a/chromium/ui/gfx/image/image_unittest_util.h b/chromium/ui/gfx/image/image_unittest_util.h
index b068e9de59c..2680a241db3 100644
--- a/chromium/ui/gfx/image/image_unittest_util.h
+++ b/chromium/ui/gfx/image/image_unittest_util.h
@@ -8,6 +8,9 @@
#ifndef UI_GFX_IMAGE_IMAGE_UNITTEST_UTIL_H_
#define UI_GFX_IMAGE_IMAGE_UNITTEST_UTIL_H_
+#include <stdint.h>
+
+#include "base/containers/span.h"
#include "build/build_config.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/image/image.h"
@@ -60,10 +63,9 @@ bool AreBitmapsClose(const SkBitmap& bitmap1,
// Returns true if the passed in PNG bitmap is visually similar to the passed in
// SkBitmap.
-bool ArePNGBytesCloseToBitmap(
- const scoped_refptr<base::RefCountedMemory>& bytes,
- const SkBitmap& bitmap,
- int max_deviation);
+bool ArePNGBytesCloseToBitmap(base::span<const uint8_t> bytes,
+ const SkBitmap& bitmap,
+ int max_deviation);
// Returns the maximum color shift in the red, green, and blue components caused
// by converting a gfx::Image between colorspaces. Color shifts occur when
diff --git a/chromium/ui/gfx/image/mojom/image.mojom b/chromium/ui/gfx/image/mojom/image.mojom
index af602d6b90d..c117cf314c5 100644
--- a/chromium/ui/gfx/image/mojom/image.mojom
+++ b/chromium/ui/gfx/image/mojom/image.mojom
@@ -6,6 +6,7 @@ module gfx.mojom;
import "skia/public/mojom/bitmap.mojom";
+[Stable]
struct ImageSkiaRep {
// Transport of the bitmap in this representation.
skia.mojom.Bitmap bitmap;
@@ -17,6 +18,7 @@ struct ImageSkiaRep {
// Mojo transport for an ImageSkia via shared buffer. Note that transporting an
// ImageSkia over mojo will load all of its image representations for supported
// scales.
+[Stable]
struct ImageSkia {
array<ImageSkiaRep> image_reps;
};
diff --git a/chromium/ui/gfx/ipc/gfx_param_traits_macros.h b/chromium/ui/gfx/ipc/gfx_param_traits_macros.h
index f311c8d199c..bf257c74e75 100644
--- a/chromium/ui/gfx/ipc/gfx_param_traits_macros.h
+++ b/chromium/ui/gfx/ipc/gfx_param_traits_macros.h
@@ -32,9 +32,6 @@ IPC_ENUM_TRAITS_MAX_VALUE(gfx::SwapResult, gfx::SwapResult::SWAP_RESULT_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(gfx::SelectionBound::Type, gfx::SelectionBound::LAST)
-IPC_ENUM_TRAITS_MAX_VALUE(gfx::GpuFenceHandleType,
- gfx::GpuFenceHandleType::kLast)
-
IPC_STRUCT_TRAITS_BEGIN(gfx::CALayerParams)
IPC_STRUCT_TRAITS_MEMBER(is_empty)
#if defined(OS_MAC)
@@ -109,9 +106,8 @@ IPC_STRUCT_TRAITS_BEGIN(gfx::PresentationFeedback)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(gfx::GpuFenceHandle)
- IPC_STRUCT_TRAITS_MEMBER(type)
#if defined(OS_POSIX)
- IPC_STRUCT_TRAITS_MEMBER(native_fd)
+ IPC_STRUCT_TRAITS_MEMBER(owned_fd)
#endif
IPC_STRUCT_TRAITS_END()
diff --git a/chromium/ui/gfx/linux/BUILD.gn b/chromium/ui/gfx/linux/BUILD.gn
index c54b85f70f3..3574e02b14d 100644
--- a/chromium/ui/gfx/linux/BUILD.gn
+++ b/chromium/ui/gfx/linux/BUILD.gn
@@ -5,7 +5,7 @@
import("//build/config/ui.gni")
import("//ui/ozone/ozone.gni")
-assert(use_x11 || ozone_platform_gbm || ozone_platform_wayland)
+assert(use_x11 || ozone_platform_drm || ozone_platform_wayland)
source_set("drm") {
sources = [
diff --git a/chromium/ui/gfx/linux/client_native_pixmap_dmabuf.cc b/chromium/ui/gfx/linux/client_native_pixmap_dmabuf.cc
index ed404cd52f8..e570add75d5 100644
--- a/chromium/ui/gfx/linux/client_native_pixmap_dmabuf.cc
+++ b/chromium/ui/gfx/linux/client_native_pixmap_dmabuf.cc
@@ -104,7 +104,7 @@ bool ClientNativePixmapDmaBuf::IsConfigurationSupported(
#endif
bool disable_yuv_biplanar = true;
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || BUILDFLAG(IS_CHROMECAST)
// IsConfigurationSupported(SCANOUT_CPU_READ_WRITE) is used by the renderer
// to tell whether the platform supports sampling a given format. Zero-copy
// video capture and encoding requires gfx::BufferFormat::YUV_420_BIPLANAR to
diff --git a/chromium/ui/gfx/mac/io_surface.cc b/chromium/ui/gfx/mac/io_surface.cc
index 4f780768e5c..ec83bd814a0 100644
--- a/chromium/ui/gfx/mac/io_surface.cc
+++ b/chromium/ui/gfx/mac/io_surface.cc
@@ -70,7 +70,9 @@ int32_t BytesPerElement(gfx::BufferFormat format, int plane) {
return 0;
}
-int32_t PixelFormat(gfx::BufferFormat format) {
+} // namespace
+
+uint32_t BufferFormatToIOSurfacePixelFormat(gfx::BufferFormat format) {
switch (format) {
case gfx::BufferFormat::R_8:
return 'L008';
@@ -95,7 +97,6 @@ int32_t PixelFormat(gfx::BufferFormat format) {
// Technically RGBA_1010102 should be accepted as 'R10k', but then it won't
// be supported by CGLTexImageIOSurface2D(), so it's best to reject it here.
case gfx::BufferFormat::YVU_420:
- NOTREACHED();
return 0;
}
@@ -103,8 +104,6 @@ int32_t PixelFormat(gfx::BufferFormat format) {
return 0;
}
-} // namespace
-
namespace internal {
// static
@@ -205,43 +204,65 @@ IOSurfaceRef CreateIOSurface(const gfx::Size& size,
TRACE_EVENT0("ui", "CreateIOSurface");
base::TimeTicks start_time = base::TimeTicks::Now();
- size_t num_planes = gfx::NumberOfPlanesForLinearBufferFormat(format);
- base::ScopedCFTypeRef<CFMutableArrayRef> planes(CFArrayCreateMutable(
- kCFAllocatorDefault, num_planes, &kCFTypeArrayCallBacks));
+ base::ScopedCFTypeRef<CFMutableDictionaryRef> properties(
+ CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks));
+ AddIntegerValue(properties, kIOSurfaceWidth, size.width());
+ AddIntegerValue(properties, kIOSurfaceHeight, size.height());
+ AddIntegerValue(properties, kIOSurfacePixelFormat,
+ BufferFormatToIOSurfacePixelFormat(format));
// Don't specify plane information unless there are indeed multiple planes
// because DisplayLink drivers do not support this.
// http://crbug.com/527556
+ size_t num_planes = gfx::NumberOfPlanesForLinearBufferFormat(format);
if (num_planes > 1) {
+ base::ScopedCFTypeRef<CFMutableArrayRef> planes(CFArrayCreateMutable(
+ kCFAllocatorDefault, num_planes, &kCFTypeArrayCallBacks));
+ size_t total_bytes_alloc = 0;
for (size_t plane = 0; plane < num_planes; ++plane) {
- size_t factor = gfx::SubsamplingFactorForBufferFormat(format, plane);
+ const size_t factor =
+ gfx::SubsamplingFactorForBufferFormat(format, plane);
+ const size_t plane_width = size.width() / factor;
+ const size_t plane_height = size.height() / factor;
+ const size_t plane_bytes_per_element = BytesPerElement(format, plane);
+ const size_t plane_bytes_per_row = IOSurfaceAlignProperty(
+ kIOSurfacePlaneBytesPerRow, plane_width * plane_bytes_per_element);
+ const size_t plane_bytes_alloc = IOSurfaceAlignProperty(
+ kIOSurfacePlaneSize, plane_height * plane_bytes_per_row);
+ const size_t plane_offset =
+ IOSurfaceAlignProperty(kIOSurfacePlaneOffset, total_bytes_alloc);
base::ScopedCFTypeRef<CFMutableDictionaryRef> plane_info(
CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks));
- AddIntegerValue(plane_info, kIOSurfacePlaneWidth, size.width() / factor);
- AddIntegerValue(plane_info, kIOSurfacePlaneHeight,
- size.height() / factor);
+ AddIntegerValue(plane_info, kIOSurfacePlaneWidth, plane_width);
+ AddIntegerValue(plane_info, kIOSurfacePlaneHeight, plane_height);
AddIntegerValue(plane_info, kIOSurfacePlaneBytesPerElement,
- BytesPerElement(format, plane));
-
+ plane_bytes_per_element);
+ AddIntegerValue(plane_info, kIOSurfacePlaneBytesPerRow,
+ plane_bytes_per_row);
+ AddIntegerValue(plane_info, kIOSurfacePlaneSize, plane_bytes_alloc);
+ AddIntegerValue(plane_info, kIOSurfacePlaneOffset, plane_offset);
CFArrayAppendValue(planes, plane_info);
+ total_bytes_alloc = plane_offset + plane_bytes_alloc;
}
- }
-
- base::ScopedCFTypeRef<CFMutableDictionaryRef> properties(
- CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks));
- AddIntegerValue(properties, kIOSurfaceWidth, size.width());
- AddIntegerValue(properties, kIOSurfaceHeight, size.height());
- AddIntegerValue(properties, kIOSurfacePixelFormat, PixelFormat(format));
- if (num_planes > 1) {
CFDictionaryAddValue(properties, kIOSurfacePlaneInfo, planes);
+
+ total_bytes_alloc =
+ IOSurfaceAlignProperty(kIOSurfaceAllocSize, total_bytes_alloc);
+ AddIntegerValue(properties, kIOSurfaceAllocSize, total_bytes_alloc);
} else {
- AddIntegerValue(properties, kIOSurfaceBytesPerElement,
- BytesPerElement(format, 0));
+ const size_t bytes_per_element = BytesPerElement(format, 0);
+ const size_t bytes_per_row = IOSurfaceAlignProperty(
+ kIOSurfaceBytesPerRow, size.width() * bytes_per_element);
+ const size_t bytes_alloc = IOSurfaceAlignProperty(
+ kIOSurfaceAllocSize, size.height() * bytes_per_row);
+ AddIntegerValue(properties, kIOSurfaceBytesPerElement, bytes_per_element);
+ AddIntegerValue(properties, kIOSurfaceBytesPerRow, bytes_per_row);
+ AddIntegerValue(properties, kIOSurfaceAllocSize, bytes_alloc);
}
IOSurfaceRef surface = IOSurfaceCreate(properties);
@@ -292,4 +313,19 @@ void IOSurfaceSetColorSpace(IOSurfaceRef io_surface,
}
}
+GFX_EXPORT base::ScopedCFTypeRef<IOSurfaceRef> IOSurfaceMachPortToIOSurface(
+ ScopedRefCountedIOSurfaceMachPort io_surface_mach_port) {
+ base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
+ if (!io_surface_mach_port) {
+ DLOG(ERROR) << "Invalid mach port.";
+ return io_surface;
+ }
+ io_surface.reset(IOSurfaceLookupFromMachPort(io_surface_mach_port));
+ if (!io_surface) {
+ DLOG(ERROR) << "Unable to lookup IOSurface.";
+ return io_surface;
+ }
+ return io_surface;
+}
+
} // namespace gfx
diff --git a/chromium/ui/gfx/mac/io_surface.h b/chromium/ui/gfx/mac/io_surface.h
index 45fc4500402..72b2fbd8cbe 100644
--- a/chromium/ui/gfx/mac/io_surface.h
+++ b/chromium/ui/gfx/mac/io_surface.h
@@ -71,6 +71,15 @@ GFX_EXPORT bool IOSurfaceCanSetColorSpace(const gfx::ColorSpace& color_space);
GFX_EXPORT void IOSurfaceSetColorSpace(IOSurfaceRef io_surface,
const gfx::ColorSpace& color_space);
+// Return the expected four character code pixel format for an IOSurface with
+// the specified gfx::BufferFormat.
+GFX_EXPORT uint32_t
+BufferFormatToIOSurfacePixelFormat(gfx::BufferFormat format);
+
+// Return an IOSurface consuming |io_surface_mach_port|.
+GFX_EXPORT base::ScopedCFTypeRef<IOSurfaceRef> IOSurfaceMachPortToIOSurface(
+ ScopedRefCountedIOSurfaceMachPort io_surface_mach_port);
+
} // namespace gfx
#endif // UI_GFX_MAC_IO_SURFACE_H_
diff --git a/chromium/ui/gfx/mojom/BUILD.gn b/chromium/ui/gfx/mojom/BUILD.gn
index 723312a2b51..5faeacec59f 100644
--- a/chromium/ui/gfx/mojom/BUILD.gn
+++ b/chromium/ui/gfx/mojom/BUILD.gn
@@ -79,6 +79,8 @@ mojom("mojom") {
{
mojom = "gfx.mojom.GpuFenceHandle"
cpp = "::gfx::GpuFenceHandle"
+ move_only = true
+ nullable_is_same_type = true
},
]
traits_headers = [ "gpu_fence_handle_mojom_traits.h" ]
@@ -97,6 +99,16 @@ mojom("mojom") {
{
types = [
{
+ mojom = "gfx.mojom.SelectionBound"
+ cpp = "::gfx::SelectionBound"
+ },
+ ]
+ traits_headers = [ "selection_bound_mojom_traits.h" ]
+ traits_public_deps = [ "//ui/gfx/geometry/mojom:mojom_traits" ]
+ },
+ {
+ types = [
+ {
mojom = "gfx.mojom.SwapTimings"
cpp = "::gfx::SwapTimings"
},
@@ -187,16 +199,6 @@ mojom("mojom") {
{
types = [
{
- mojom = "gfx.mojom.SelectionBound"
- cpp = "::gfx::SelectionBound"
- },
- ]
- traits_headers = [ "selection_bound_mojom_traits.h" ]
- traits_public_deps = [ "//ui/gfx/geometry/mojom:mojom_traits" ]
- },
- {
- types = [
- {
mojom = "gfx.mojom.SwapResult"
cpp = "::gfx::SwapResult"
},
diff --git a/chromium/ui/gfx/mojom/gpu_fence_handle.mojom b/chromium/ui/gfx/mojom/gpu_fence_handle.mojom
index 7a9ba5c3cfa..9a7906c3ee3 100644
--- a/chromium/ui/gfx/mojom/gpu_fence_handle.mojom
+++ b/chromium/ui/gfx/mojom/gpu_fence_handle.mojom
@@ -5,12 +5,6 @@
module gfx.mojom;
// See ui/gfx/ipc/gpu_fence_handle.h
-enum GpuFenceHandleType {
- kEmpty,
- kAndroidNativeFenceSync,
-};
-
struct GpuFenceHandle {
- GpuFenceHandleType type;
handle<platform>? native_fd;
};
diff --git a/chromium/ui/gfx/mojom/gpu_fence_handle_mojom_traits.cc b/chromium/ui/gfx/mojom/gpu_fence_handle_mojom_traits.cc
index c5b500f372e..99538f9664a 100644
--- a/chromium/ui/gfx/mojom/gpu_fence_handle_mojom_traits.cc
+++ b/chromium/ui/gfx/mojom/gpu_fence_handle_mojom_traits.cc
@@ -9,13 +9,11 @@
namespace mojo {
-mojo::PlatformHandle StructTraits<
- gfx::mojom::GpuFenceHandleDataView,
- gfx::GpuFenceHandle>::native_fd(const gfx::GpuFenceHandle& handle) {
+mojo::PlatformHandle
+StructTraits<gfx::mojom::GpuFenceHandleDataView,
+ gfx::GpuFenceHandle>::native_fd(gfx::GpuFenceHandle& handle) {
#if defined(OS_POSIX)
- if (handle.type != gfx::GpuFenceHandleType::kAndroidNativeFenceSync)
- return mojo::PlatformHandle();
- return mojo::PlatformHandle(base::ScopedFD(handle.native_fd.fd));
+ return mojo::PlatformHandle(std::move(handle.owned_fd));
#else
return mojo::PlatformHandle();
#endif
@@ -23,21 +21,25 @@ mojo::PlatformHandle StructTraits<
bool StructTraits<gfx::mojom::GpuFenceHandleDataView, gfx::GpuFenceHandle>::
Read(gfx::mojom::GpuFenceHandleDataView data, gfx::GpuFenceHandle* out) {
- if (!data.ReadType(&out->type))
- return false;
-
- if (out->type == gfx::GpuFenceHandleType::kAndroidNativeFenceSync) {
#if defined(OS_POSIX)
- constexpr bool auto_close = true;
- out->native_fd =
- base::FileDescriptor(data.TakeNativeFd().ReleaseFD(), auto_close);
+ out->owned_fd = data.TakeNativeFd().TakeFD();
return true;
#else
- NOTREACHED();
return false;
#endif
- }
- return true;
+}
+
+void StructTraits<gfx::mojom::GpuFenceHandleDataView,
+ gfx::GpuFenceHandle>::SetToNull(gfx::GpuFenceHandle* handle) {
+#if defined(OS_POSIX)
+ handle->owned_fd.reset();
+#endif
+}
+
+bool StructTraits<gfx::mojom::GpuFenceHandleDataView,
+ gfx::GpuFenceHandle>::IsNull(const gfx::GpuFenceHandle&
+ handle) {
+ return handle.is_null();
}
} // namespace mojo
diff --git a/chromium/ui/gfx/mojom/gpu_fence_handle_mojom_traits.h b/chromium/ui/gfx/mojom/gpu_fence_handle_mojom_traits.h
index f688b2cb743..a3585b17551 100644
--- a/chromium/ui/gfx/mojom/gpu_fence_handle_mojom_traits.h
+++ b/chromium/ui/gfx/mojom/gpu_fence_handle_mojom_traits.h
@@ -13,41 +13,12 @@ namespace mojo {
template <>
struct COMPONENT_EXPORT(GFX_SHARED_MOJOM_TRAITS)
- EnumTraits<gfx::mojom::GpuFenceHandleType, gfx::GpuFenceHandleType> {
- static gfx::mojom::GpuFenceHandleType ToMojom(gfx::GpuFenceHandleType type) {
- switch (type) {
- case gfx::GpuFenceHandleType::kEmpty:
- return gfx::mojom::GpuFenceHandleType::kEmpty;
- case gfx::GpuFenceHandleType::kAndroidNativeFenceSync:
- return gfx::mojom::GpuFenceHandleType::kAndroidNativeFenceSync;
- }
- NOTREACHED();
- return gfx::mojom::GpuFenceHandleType::kEmpty;
- }
-
- static bool FromMojom(gfx::mojom::GpuFenceHandleType input,
- gfx::GpuFenceHandleType* out) {
- switch (input) {
- case gfx::mojom::GpuFenceHandleType::kEmpty:
- *out = gfx::GpuFenceHandleType::kEmpty;
- return true;
- case gfx::mojom::GpuFenceHandleType::kAndroidNativeFenceSync:
- *out = gfx::GpuFenceHandleType::kAndroidNativeFenceSync;
- return true;
- }
- return false;
- }
-};
-
-template <>
-struct COMPONENT_EXPORT(GFX_SHARED_MOJOM_TRAITS)
StructTraits<gfx::mojom::GpuFenceHandleDataView, gfx::GpuFenceHandle> {
- static gfx::GpuFenceHandleType type(const gfx::GpuFenceHandle& handle) {
- return handle.type;
- }
- static mojo::PlatformHandle native_fd(const gfx::GpuFenceHandle& handle);
+ static mojo::PlatformHandle native_fd(gfx::GpuFenceHandle& handle);
static bool Read(gfx::mojom::GpuFenceHandleDataView data,
gfx::GpuFenceHandle* handle);
+ static void SetToNull(gfx::GpuFenceHandle* handle);
+ static bool IsNull(const gfx::GpuFenceHandle& handle);
};
} // namespace mojo
diff --git a/chromium/ui/gfx/range/BUILD.gn b/chromium/ui/gfx/range/BUILD.gn
index 9d7814c49d3..d150518b592 100644
--- a/chromium/ui/gfx/range/BUILD.gn
+++ b/chromium/ui/gfx/range/BUILD.gn
@@ -2,12 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-# Reset sources_assignment_filter for the BUILD.gn file to prevent
-# regression during the migration of Chromium away from the feature.
-# See docs/no_sources_assignment_filter.md for more information.
-# TODO(crbug.com/1018739): remove this when migration is done.
-set_sources_assignment_filter([])
-
component("range") {
sources = [
"gfx_range_export.h",
diff --git a/chromium/ui/gfx/render_text.cc b/chromium/ui/gfx/render_text.cc
index 3dc9e4daf46..af1d3fa49ca 100644
--- a/chromium/ui/gfx/render_text.cc
+++ b/chromium/ui/gfx/render_text.cc
@@ -1958,6 +1958,30 @@ Rect RenderText::ExpandToBeVerticallySymmetric(const Rect& rect,
return result;
}
+// static
+void RenderText::MergeIntersectingRects(std::vector<Rect>& rects) {
+ if (rects.size() < 2)
+ return;
+
+ std::sort(rects.begin(), rects.end(),
+ [](const Rect& a, const Rect& b) { return a.x() < b.x(); });
+
+ size_t merge_candidate = 0;
+ for (size_t i = 1; i < rects.size(); i++) {
+ if (rects[i].Intersects(rects[merge_candidate])) {
+ DCHECK_EQ(rects[i].y(), rects[merge_candidate].y());
+ DCHECK_EQ(rects[i].height(), rects[merge_candidate].height());
+ rects[merge_candidate].Union(rects[i]);
+ } else {
+ merge_candidate++;
+ if (merge_candidate != i)
+ rects[merge_candidate] = rects[i];
+ }
+ }
+
+ rects.resize(merge_candidate + 1);
+}
+
void RenderText::OnTextAttributeChanged() {
layout_text_.clear();
display_text_.clear();
@@ -2059,8 +2083,10 @@ base::string16 RenderText::Elide(const base::string16& text,
}
// Append the ellipsis and the optional directional marker characters.
+ // Do not append the BiDi marker if the only codepoint in the text is
+ // an ellipsis.
new_text.append(ellipsis);
- if (trailing_text_direction != text_direction) {
+ if (new_text.size() != 1 && trailing_text_direction != text_direction) {
if (trailing_text_direction == base::i18n::LEFT_TO_RIGHT)
new_text += base::i18n::kLeftToRightMark;
else
diff --git a/chromium/ui/gfx/render_text.h b/chromium/ui/gfx/render_text.h
index 4b39abb9d16..be9c3457df7 100644
--- a/chromium/ui/gfx/render_text.h
+++ b/chromium/ui/gfx/render_text.h
@@ -808,6 +808,10 @@ class GFX_EXPORT RenderText {
static gfx::Rect ExpandToBeVerticallySymmetric(const gfx::Rect& rect,
const gfx::Rect& display_rect);
+ // Given |rects|, sort them along the x-axis and merge intersecting rects
+ // using union. Expects all selections in the text to be from the same line.
+ static void MergeIntersectingRects(std::vector<Rect>& rects);
+
// Resets |cached_cursor_x_| to null. When non-null, CURSOR_UP, CURSOR_DOWN
// movements use this value instead of the current cursor x position to
// determine the next cursor x position.
diff --git a/chromium/ui/gfx/render_text_harfbuzz.cc b/chromium/ui/gfx/render_text_harfbuzz.cc
index 16b6f85909c..02c97762835 100644
--- a/chromium/ui/gfx/render_text_harfbuzz.cc
+++ b/chromium/ui/gfx/render_text_harfbuzz.cc
@@ -1447,6 +1447,7 @@ std::vector<Rect> RenderTextHarfBuzz::GetSubstringBounds(const Range& range) {
if (line.segments.size() > 1 && IsNewlineSegment(line.segments[0]))
line_start_x += line.segments[0].width();
+ std::vector<Rect> current_line_rects;
for (const internal::LineSegment& segment : line.segments) {
const Range intersection = segment.char_range.Intersect(display_range);
DCHECK(!intersection.is_reversed());
@@ -1459,9 +1460,12 @@ std::vector<Rect> RenderTextHarfBuzz::GetSubstringBounds(const Range& range) {
int end_x = base::ClampCeil(selected_span.end() - line_start_x);
Rect rect(start_x, 0, end_x - start_x,
base::ClampCeil(line.size.height()));
- rects.push_back(rect + GetLineOffset(line_index));
+ current_line_rects.push_back(rect + GetLineOffset(line_index));
}
}
+ MergeIntersectingRects(current_line_rects);
+ rects.insert(rects.end(), current_line_rects.begin(),
+ current_line_rects.end());
}
return rects;
}
diff --git a/chromium/ui/gfx/render_text_test_api.h b/chromium/ui/gfx/render_text_test_api.h
index 1577a69b864..07c48f4a035 100644
--- a/chromium/ui/gfx/render_text_test_api.h
+++ b/chromium/ui/gfx/render_text_test_api.h
@@ -102,6 +102,10 @@ class RenderTextTestApi {
return RenderText::ExpandToBeVerticallySymmetric(rect, display_rect);
}
+ static void MergeIntersectingRects(std::vector<Rect>& rects) {
+ RenderText::MergeIntersectingRects(rects);
+ }
+
void reset_cached_cursor_x() { render_text_->reset_cached_cursor_x(); }
int GetLineContainingYCoord(float text_y) {
diff --git a/chromium/ui/gfx/render_text_unittest.cc b/chromium/ui/gfx/render_text_unittest.cc
index 0c92673e372..9801a0830b7 100644
--- a/chromium/ui/gfx/render_text_unittest.cc
+++ b/chromium/ui/gfx/render_text_unittest.cc
@@ -404,6 +404,16 @@ class TestRectangleBuffer {
}
}
+ // Test that the rect defined by |left|, |top|, |width| and |height| is filled
+ // with the same color.
+ void EnsureRectIsAllSameColor(int left,
+ int top,
+ int width,
+ int height) const {
+ SkColor buffer_color = buffer_[left + top * stride_];
+ EnsureSolidRect(buffer_color, left, top, width, height);
+ }
+
private:
const char* string_;
const SkColor* buffer_;
@@ -1048,6 +1058,40 @@ TEST_F(RenderTextTest, SelectRangeColored) {
ExpectTextLog({{6}});
}
+// Tests that when a selection is made and the selection background is
+// translucent, the selection renders properly. See crbug.com/1134440.
+TEST_F(RenderTextTest, SelectWithTranslucentBackground) {
+ constexpr float kGlyphWidth = 5.5f;
+ constexpr Size kCanvasSize(300, 50);
+ constexpr SkColor kTranslucentBlue = SkColorSetARGB(0x7F, 0x00, 0x00, 0xFF);
+ const char* kTestString{"A B C D"};
+
+ SkBitmap bitmap;
+ bitmap.allocPixels(
+ SkImageInfo::MakeN32Premul(kCanvasSize.width(), kCanvasSize.height()));
+ cc::SkiaPaintCanvas paint_canvas(bitmap);
+ Canvas canvas(&paint_canvas, 1.0f);
+ paint_canvas.clear(SK_ColorWHITE);
+
+ SetGlyphWidth(kGlyphWidth);
+ RenderText* render_text = GetRenderText();
+ render_text->set_selection_background_focused_color(kTranslucentBlue);
+ render_text->set_focused(true);
+
+ render_text->SetText(UTF8ToUTF16(kTestString));
+ render_text->SelectRange(Range(0, 7));
+ const Rect text_rect = Rect(render_text->GetStringSize());
+ render_text->SetDisplayRect(text_rect);
+ render_text->Draw(&canvas);
+ const uint32_t* buffer = static_cast<const uint32_t*>(bitmap.getPixels());
+ ASSERT_NE(nullptr, buffer);
+ TestRectangleBuffer rect_buffer(kTestString, buffer, kCanvasSize.width(),
+ kCanvasSize.height());
+
+ // This whole slice should be the same color and opacity.
+ rect_buffer.EnsureRectIsAllSameColor(0, 0, text_rect.width() - 1, 1);
+}
+
TEST_F(RenderTextTest, SelectRangeColoredGrapheme) {
RenderText* render_text = GetRenderText();
render_text->SetText(UTF8ToUTF16("x\u0065\u0301y"));
@@ -1906,7 +1950,7 @@ const ElideTextCase kElideTailTextCases[] = {
{"ltr_0", L"abc", L""},
{"rtl_3", L"\u05d0\u05d1\u05d2", L"\u05d0\u05d1\u05d2"},
{"rtl_2", L"\u05d0\u05d1\u05d2", L"\u05d0\u2026"},
- {"rtl_1", L"\u05d0\u05d1\u05d2", L"\u2026\x200E"},
+ {"rtl_1", L"\u05d0\u05d1\u05d2", L"\u2026"},
{"rtl_0", L"\u05d0\u05d1\u05d2", L""},
{"ltr_rtl_5", L"abc\u05d0\u05d1\u05d2", L"abc\u05d0\u2026\x200F"},
{"ltr_rtl_4", L"abc\u05d0\u05d1\u05d2", L"abc\u2026"},
@@ -7575,6 +7619,42 @@ TEST_F(RenderTextTest, ExpandToBeVerticallySymmetric) {
Rect(20, 20, 400, 40), test_display_rect));
}
+TEST_F(RenderTextTest, MergeIntersectingRects) {
+ // Basic case.
+ std::vector<Rect> test_rects{Rect(0, 0, 10, 10), Rect(5, 0, 10, 10),
+ Rect(10, 0, 5, 10), Rect(12, 0, 5, 10)};
+ test::RenderTextTestApi::MergeIntersectingRects(test_rects);
+ ASSERT_EQ(1u, test_rects.size());
+ EXPECT_EQ(Rect(0, 0, 17, 10), test_rects[0]);
+
+ // Case where some rects intersect and some don't.
+ test_rects = std::vector<Rect>{Rect(0, 0, 10, 10), Rect(5, 0, 10, 10),
+ Rect(16, 0, 10, 10), Rect(25, 0, 10, 10),
+ Rect(40, 0, 10, 10)};
+ test::RenderTextTestApi::MergeIntersectingRects(test_rects);
+ ASSERT_EQ(3u, test_rects.size());
+ EXPECT_EQ(Rect(0, 0, 15, 10), test_rects[0]);
+ EXPECT_EQ(Rect(16, 0, 19, 10), test_rects[1]);
+ EXPECT_EQ(Rect(40, 0, 10, 10), test_rects[2]);
+
+ // Case where no rects intersect.
+ test_rects = std::vector<Rect>{Rect(0, 0, 10, 10), Rect(11, 0, 10, 10),
+ Rect(22, 0, 10, 10), Rect(33, 0, 10, 10)};
+ test::RenderTextTestApi::MergeIntersectingRects(test_rects);
+ ASSERT_EQ(4u, test_rects.size());
+ EXPECT_EQ(Rect(0, 0, 10, 10), test_rects[0]);
+ EXPECT_EQ(Rect(11, 0, 10, 10), test_rects[1]);
+ EXPECT_EQ(Rect(22, 0, 10, 10), test_rects[2]);
+ EXPECT_EQ(Rect(33, 0, 10, 10), test_rects[3]);
+
+ // Rects are out-of-order.
+ test_rects = std::vector<Rect>{Rect(10, 0, 5, 10), Rect(0, 0, 10, 10),
+ Rect(12, 0, 5, 10), Rect(5, 0, 10, 10)};
+ test::RenderTextTestApi::MergeIntersectingRects(test_rects);
+ ASSERT_EQ(1u, test_rects.size());
+ EXPECT_EQ(Rect(0, 0, 17, 10), test_rects[0]);
+}
+
// Ensures that text is centered vertically and consistently when either the
// display rectangle height changes, or when the minimum line height changes.
// The difference between the two is the selection rectangle, which should match
diff --git a/chromium/ui/gfx/skbitmap_operations.cc b/chromium/ui/gfx/skbitmap_operations.cc
index 13abb4c0f8f..891fda76f73 100644
--- a/chromium/ui/gfx/skbitmap_operations.cc
+++ b/chromium/ui/gfx/skbitmap_operations.cc
@@ -630,6 +630,8 @@ SkBitmap SkBitmapOperations::UnPreMultiply(const SkBitmap& bitmap) {
return bitmap;
if (bitmap.alphaType() != kPremul_SkAlphaType)
return bitmap;
+ // It's expected this code is called with a 32bpp image.
+ CHECK_EQ(kN32_SkColorType, bitmap.colorType());
const SkImageInfo& opaque_info =
bitmap.info().makeAlphaType(kUnpremul_SkAlphaType);
diff --git a/chromium/ui/gfx/x/BUILD.gn b/chromium/ui/gfx/x/BUILD.gn
index 293f111afcf..6b87f8e0c12 100644
--- a/chromium/ui/gfx/x/BUILD.gn
+++ b/chromium/ui/gfx/x/BUILD.gn
@@ -65,7 +65,6 @@ action("gen_xprotos") {
foreach(proto, protos) {
sources += [ "$xcbproto_path/src/${proto}.xml" ]
outputs += [
- "$target_gen_dir/${proto}_undef.h",
"$target_gen_dir/${proto}.h",
"$target_gen_dir/${proto}.cc",
]
@@ -85,6 +84,7 @@ component("xprotos") {
"//base:i18n",
"//ui/events/platform",
]
+ public_deps = [ "//ui/gfx/x/keysyms" ]
sources = get_target_outputs(":gen_xprotos") + [
"xproto_internal.h",
"xproto_internal.cc",
@@ -98,6 +98,7 @@ component("xprotos") {
"event.cc",
"x11_switches.cc",
"x11_switches.h",
+ "x11.h",
]
configs += [
":x11_private_config",
@@ -110,7 +111,6 @@ component("x") {
sources = [
"../gfx_export.h",
- "x11.h",
"x11_atom_cache.cc",
"x11_atom_cache.h",
"x11_error_tracker.cc",
diff --git a/chromium/ui/gfx/x/connection.cc b/chromium/ui/gfx/x/connection.cc
index caf9a2b9e15..cea4895e776 100644
--- a/chromium/ui/gfx/x/connection.cc
+++ b/chromium/ui/gfx/x/connection.cc
@@ -4,13 +4,12 @@
#include "ui/gfx/x/connection.h"
-#include <X11/Xlib-xcb.h>
-#include <X11/Xlib.h>
-#include <X11/keysym.h>
#include <xcb/xcb.h>
+#include <xcb/xcbext.h>
#include <algorithm>
+#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/i18n/case_conversion.h"
#include "base/memory/scoped_refptr.h"
@@ -19,7 +18,9 @@
#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/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"
@@ -27,6 +28,22 @@
#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.
@@ -205,12 +222,12 @@ void ConvertCase(KeySym sym, KeySym* lower, KeySym* upper) {
*upper = static_cast<KeySym>(upper32);
}
-bool IsKeypadKey(KeySym keysym) {
+bool IsXKeypadKey(KeySym keysym) {
auto key = static_cast<uint32_t>(keysym);
return key >= XK_KP_Space && key <= XK_KP_Equal;
}
-bool IsPrivateKeypadKey(KeySym keysym) {
+bool IsPrivateXKeypadKey(KeySym keysym) {
auto key = static_cast<uint32_t>(keysym);
return key >= 0x11000000 && key <= 0x1100FFFF;
}
@@ -242,7 +259,14 @@ void Connection::Set(std::unique_ptr<x11::Connection> connection) {
}
Connection::Connection(const std::string& address)
- : XProto(this), display_(OpenNewXDisplay(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);
@@ -250,16 +274,7 @@ Connection::Connection(const std::string& address)
xcb_get_setup(XcbConnection())));
setup_ = Read<Setup>(&buf);
default_screen_ = &setup_.roots[DefaultScreenId()];
- default_root_depth_ = &*std::find_if(
- default_screen_->allowed_depths.begin(),
- default_screen_->allowed_depths.end(), [&](const Depth& depth) {
- return depth.depth == default_screen_->root_depth;
- });
- default_root_visual_ = &*std::find_if(
- default_root_depth_->visuals.begin(),
- default_root_depth_->visuals.end(), [&](const VisualType visual) {
- return visual.visual_id == default_screen_->root_visual;
- });
+ InitRootDepthAndVisual();
} else {
// Default-initialize the setup data so we always have something to return.
setup_.roots.emplace_back();
@@ -317,12 +332,22 @@ bool Connection::HasNextResponse() const {
requests_.front().sequence) >= 0;
}
+int Connection::GetFd() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ return Ready() ? xcb_get_file_descriptor(XcbConnection()) : -1;
+}
+
+const std::string& Connection::DisplayString() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ return display_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
// default screen. Instead, it's part of the display name. Eg in
// "localhost:0.0", the screen ID is the second "0".
- return DefaultScreen(display_);
+ return default_screen_id_;
}
bool Connection::Ready() const {
@@ -338,17 +363,44 @@ void Connection::Flush() {
void Connection::Sync() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- GetInputFocus({}).Sync();
+ if (syncing_)
+ return;
+ {
+ base::AutoReset<bool> auto_reset(&syncing_, true);
+ GetInputFocus({}).Sync();
+ }
+}
+
+void Connection::SynchronizeForTest(bool synchronous) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ XSynchronize(display(), synchronous);
+ synchronous_ = synchronous;
+ if (synchronous_)
+ Sync();
}
void Connection::ReadResponses() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
while (auto* event = xcb_poll_for_event(XcbConnection())) {
events_.emplace_back(base::MakeRefCounted<MallocedRefCountedMemory>(event),
- this);
+ this, true);
}
}
+Event Connection::WaitForNextEvent() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!events_.empty()) {
+ Event event = std::move(events_.front());
+ events_.pop_front();
+ return event;
+ }
+ if (auto* xcb_event = xcb_wait_for_event(XcbConnection())) {
+ return Event(base::MakeRefCounted<MallocedRefCountedMemory>(xcb_event),
+ this, true);
+ }
+ return Event();
+}
+
bool Connection::HasPendingResponses() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return !events_.empty() || HasNextResponse();
@@ -395,7 +447,7 @@ KeySym Connection::KeycodeToKeysym(uint32_t keycode, unsigned int modifiers) {
std::unique_ptr<Connection> Connection::Clone() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return std::make_unique<Connection>(display_ ? XDisplayString(display_) : "");
+ return std::make_unique<Connection>(display_string_);
}
void Connection::DetachFromSequence() {
@@ -462,6 +514,19 @@ void Connection::Dispatch(Delegate* delegate) {
}
}
+void Connection::InitRootDepthAndVisual() {
+ for (auto& depth : default_screen_->allowed_depths) {
+ for (auto& visual : depth.visuals) {
+ if (visual.visual_id == default_screen_->root_visual) {
+ default_root_depth_ = &depth;
+ default_root_visual_ = &visual;
+ return;
+ }
+ }
+ }
+ NOTREACHED();
+}
+
void Connection::AddRequest(unsigned int sequence,
FutureBase::ResponseCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -602,6 +667,9 @@ KeySym Connection::KeyCodetoKeySym(KeyCode keycode, int column) const {
// 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)
@@ -620,9 +688,9 @@ KeySym Connection::TranslateKey(uint32_t key, unsigned int modifiers) const {
if ((modifiers & num_lock_) &&
(n_keysyms > 1 &&
- (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) {
- if ((modifiers & ShiftMask) ||
- ((modifiers & LockMask) && (lock_meaning_ == XK_Shift_Lock))) {
+ (IsXKeypadKey(syms[1]) || IsPrivateXKeypadKey(syms[1])))) {
+ if ((modifiers & kShiftMask) ||
+ ((modifiers & kLockMask) && (lock_meaning_ == XK_Shift_Lock))) {
return syms[0];
}
return syms[1];
@@ -630,8 +698,9 @@ KeySym Connection::TranslateKey(uint32_t key, unsigned int modifiers) const {
KeySym lower;
KeySym upper;
- if (!(modifiers & ShiftMask) &&
- (!(modifiers & LockMask) || (lock_meaning_ == NoSymbol))) {
+ 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;
@@ -639,7 +708,7 @@ KeySym Connection::TranslateKey(uint32_t key, unsigned int modifiers) const {
return syms[0];
}
- if (!(modifiers & LockMask) || (lock_meaning_ != XK_Caps_Lock)) {
+ if (!(modifiers & kLockMask) || (lock_meaning_ != XK_Caps_Lock)) {
if ((n_keysyms == 1) || ((upper = syms[1]) == kNoSymbol))
ConvertCase(syms[0], &lower, &upper);
return upper;
@@ -649,7 +718,7 @@ KeySym Connection::TranslateKey(uint32_t key, unsigned int modifiers) const {
if ((n_keysyms == 1) || ((sym = syms[1]) == kNoSymbol))
sym = syms[0];
ConvertCase(sym, &lower, &upper);
- if (!(modifiers & ShiftMask) && (sym != syms[0]) &&
+ if (!(modifiers & kShiftMask) && (sym != syms[0]) &&
((sym != upper) || (lower == upper)))
ConvertCase(syms[0], &lower, &upper);
return upper;
diff --git a/chromium/ui/gfx/x/connection.h b/chromium/ui/gfx/x/connection.h
index d764be97e49..1e0fa6c2300 100644
--- a/chromium/ui/gfx/x/connection.h
+++ b/chromium/ui/gfx/x/connection.h
@@ -79,6 +79,12 @@ class COMPONENT_EXPORT(X11) Connection : public XProto,
return *default_root_visual_;
}
+ // Returns the underlying socket's FD if the connection is valid, or -1
+ // otherwise.
+ int GetFd();
+
+ const std::string& DisplayString() const;
+
int DefaultScreenId() const;
template <typename T>
@@ -96,9 +102,16 @@ class COMPONENT_EXPORT(X11) Connection : public XProto,
// Flush and block until the server has responded to all requests.
void Sync();
+ // If |synchronous| is true, this makes all requests Sync().
+ void SynchronizeForTest(bool synchronous);
+
+ bool synchronous() const { return synchronous_; }
+
// Read all responses from the socket without blocking.
void ReadResponses();
+ Event WaitForNextEvent();
+
// Are there any events, errors, or replies already buffered?
bool HasPendingResponses() const;
@@ -142,6 +155,8 @@ class COMPONENT_EXPORT(X11) Connection : public XProto,
FutureBase::ResponseCallback callback;
};
+ void InitRootDepthAndVisual();
+
void AddRequest(unsigned int sequence, FutureBase::ResponseCallback callback);
bool HasNextResponse() const;
@@ -158,8 +173,13 @@ class COMPONENT_EXPORT(X11) Connection : public XProto,
XDisplay* const display_;
+ bool synchronous_ = false;
+ bool syncing_ = false;
+
uint32_t extended_max_request_length_ = 0;
+ std::string display_string_;
+ int default_screen_id_ = 0;
Setup setup_;
Screen* default_screen_ = nullptr;
Depth* default_root_depth_ = nullptr;
diff --git a/chromium/ui/gfx/x/event.cc b/chromium/ui/gfx/x/event.cc
index 4ce77f09676..41cd3649702 100644
--- a/chromium/ui/gfx/x/event.cc
+++ b/chromium/ui/gfx/x/event.cc
@@ -4,6 +4,8 @@
#include "ui/gfx/x/event.h"
+#include <xcb/xcb.h>
+
#include <cstring>
#include "base/check_op.h"
@@ -35,17 +37,11 @@ Event::Event(scoped_refptr<base::RefCountedMemory> event_bytes,
bool sequence_valid) {
auto* xcb_event = reinterpret_cast<xcb_generic_event_t*>(
const_cast<uint8_t*>(event_bytes->data()));
- XDisplay* display = connection->display();
-
sequence_valid_ = sequence_valid;
sequence_ = xcb_event->full_sequence;
// KeymapNotify events are the only events that don't have a sequence.
if ((xcb_event->response_type & ~kSendEventMask) !=
x11::KeymapNotifyEvent::opcode) {
- // Rewrite the sequence to the last seen sequence so that Xlib doesn't
- // think the sequence wrapped around.
- xcb_event->sequence = XLastKnownRequestProcessed(display);
-
// On the wire, events are 32 bytes except for generic events which are
// trailed by additional data. XCB inserts an extended 4-byte sequence
// between the 32-byte event and the additional data, so we need to shift
diff --git a/chromium/ui/gfx/x/event.h b/chromium/ui/gfx/x/event.h
index 5ad11ca9ee3..7e3d41dc7ce 100644
--- a/chromium/ui/gfx/x/event.h
+++ b/chromium/ui/gfx/x/event.h
@@ -5,9 +5,6 @@
#ifndef UI_GFX_X_EVENT_H_
#define UI_GFX_X_EVENT_H_
-#include <X11/Xlib.h>
-#include <xcb/xcb.h>
-
#include <cstdint>
#include <utility>
@@ -28,14 +25,16 @@ void ReadEvent(Event* event, Connection* connection, ReadBuffer* buffer);
class COMPONENT_EXPORT(X11) Event {
public:
template <typename T>
- explicit Event(T&& xproto_event) {
+ explicit Event(T&& xproto_event, bool sequence_valid = true) {
+ using DecayT = std::decay_t<T>;
sequence_valid_ = true;
sequence_ = xproto_event.sequence;
- type_id_ = T::type_id;
- deleter_ = [](void* event) { delete reinterpret_cast<T*>(event); };
- T* event = new T(std::forward<T>(xproto_event));
+ type_id_ = DecayT::type_id;
+ deleter_ = [](void* event) { delete reinterpret_cast<DecayT*>(event); };
+ auto* event = new DecayT(std::forward<T>(xproto_event));
event_ = event;
window_ = event->GetWindow();
+ sequence_valid_ = sequence_valid;
}
Event();
@@ -72,6 +71,10 @@ class COMPONENT_EXPORT(X11) Event {
uint32_t sequence() const { return sequence_; }
x11::Window window() const { return window_ ? *window_ : x11::Window::None; }
+ void set_window(x11::Window window) {
+ if (window_)
+ *window_ = window;
+ }
private:
friend void ReadEvent(Event* event,
diff --git a/chromium/ui/gfx/x/gen_xproto.py b/chromium/ui/gfx/x/gen_xproto.py
index f5df00a7cbc..391779422fc 100644
--- a/chromium/ui/gfx/x/gen_xproto.py
+++ b/chromium/ui/gfx/x/gen_xproto.py
@@ -236,6 +236,10 @@ WRITE_SPECIAL = set([
('xcb', 'Expose'),
('xcb', 'UnmapNotify'),
('xcb', 'SelectionNotify'),
+ ('xcb', 'MotionNotify'),
+ ('xcb', 'Key'),
+ ('xcb', 'Button'),
+ ('xcb', 'PropertyNotify'),
])
@@ -365,8 +369,6 @@ class GenXproto(FileWriter):
self.xml_filename = os.path.join(proto_dir, '%s.xml' % proto)
self.header_file = open(os.path.join(gen_dir, '%s.h' % proto), 'w')
self.source_file = open(os.path.join(gen_dir, '%s.cc' % proto), 'w')
- self.undef_file = open(os.path.join(gen_dir, '%s_undef.h' % proto),
- 'w')
# Top-level xcbgen python module
self.xcbgen = xcbgen
@@ -495,8 +497,10 @@ class GenXproto(FileWriter):
if field.type.is_list:
len_name = field_name + '_len'
if not self.field_from_scope(len_name):
- self.write('size_t %s = %s;' %
- (len_name, list_size(field_name, field.type)))
+ len_expr = list_size(field_name, field.type)
+ if field.type.is_ref_counted_memory:
+ len_expr = '%s ? %s : 0' % (field_name, len_expr)
+ self.write('size_t %s = %s;' % (len_name, len_expr))
return 1
@@ -508,12 +512,6 @@ class GenXproto(FileWriter):
return field
return None
- # Work around conflicts caused by Xlib's liberal use of macros.
- def undef(self, name):
- print('#ifdef %s' % name, file=self.undef_file)
- print('#undef %s' % name, file=self.undef_file)
- print('#endif', file=self.undef_file)
-
def expr(self, expr):
if expr.op == 'popcount':
return 'PopCount(%s)' % self.expr(expr.rhs)
@@ -631,7 +629,11 @@ class GenXproto(FileWriter):
else:
container_type, container_name = field.parent
assert container_type.is_event
- opcode = container_type.opcodes[container_name]
+ # Extension events require offsetting the opcode, so make
+ # sure this path is only hit for non-extension events for now.
+ assert not self.module.namespace.is_ext
+ opcode = container_type.opcodes.get(container_name,
+ 'obj.opcode')
self.write('%s %s = %s;' % (type_name, name, opcode))
self.copy_primitive(name)
elif name in ('extension', 'error_code', 'event_type'):
@@ -825,10 +827,8 @@ class GenXproto(FileWriter):
def declare_enum(self, enum):
def declare_enum_entry(name, value):
name = safe_name(name)
- self.undef(name)
self.write('%s = %s,' % (name, value))
- self.undef(enum.name[-1])
with Indent(
self, 'enum class %s : %s {' %
(adjust_type_name(enum.name[-1]), self.enum_types[enum.name][0]
@@ -899,7 +899,6 @@ class GenXproto(FileWriter):
def declare_event(self, event, name):
event_name = name[-1] + 'Event'
- self.undef(event_name)
with Indent(self, 'struct %s {' % adjust_type_name(event_name), '};'):
self.write('static constexpr int type_id = %d;' % event.type_id)
if len(event.opcodes) == 1:
@@ -910,7 +909,6 @@ class GenXproto(FileWriter):
items = [(int(x), y)
for (y, x) in event.enum_opcodes.items()]
for opcode, opname in sorted(items):
- self.undef(opname)
self.write('%s = %s,' % (opname, opcode))
self.write('bool send_event{};')
self.declare_fields(event.fields)
@@ -923,7 +921,6 @@ class GenXproto(FileWriter):
def declare_container(self, struct, struct_name):
name = struct_name[-1] + self.type_suffix(struct)
- self.undef(name)
with Indent(self, 'struct %s {' % adjust_type_name(name), '};'):
self.declare_fields(struct.fields)
self.write()
@@ -1323,7 +1320,6 @@ class GenXproto(FileWriter):
imports.add(('xproto', 'xproto'))
for direct_import in sorted(list(imports)):
self.write('#include "%s.h"' % direct_import[-1])
- self.write('#include "%s_undef.h"' % self.module.namespace.header)
self.write()
self.write('namespace x11 {')
self.write()
@@ -1336,7 +1332,6 @@ class GenXproto(FileWriter):
self.declare_type(item, name)
name = self.class_name
- self.undef(name)
with Indent(self, 'class COMPONENT_EXPORT(X11) %s {' % name, '};'):
self.namespace = ['x11', self.class_name]
self.write('public:')
@@ -1450,9 +1445,6 @@ class GenExtensionManager(FileWriter):
self.write()
self.write('#include "base/component_export.h"')
self.write()
- self.write('// Avoid conflicts caused by the GenericEvent macro.')
- self.write('#include "ui/gfx/x/ge_undef.h"')
- self.write()
self.write('namespace x11 {')
self.write()
self.write('class Connection;')
diff --git a/chromium/ui/gfx/x/keysyms/BUILD.gn b/chromium/ui/gfx/x/keysyms/BUILD.gn
new file mode 100644
index 00000000000..7ebb583c5ec
--- /dev/null
+++ b/chromium/ui/gfx/x/keysyms/BUILD.gn
@@ -0,0 +1,7 @@
+# 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.
+
+source_set("keysyms") {
+ public = [ "keysyms.h" ]
+}
diff --git a/chromium/ui/gfx/x/keysyms/keysyms.h b/chromium/ui/gfx/x/keysyms/keysyms.h
new file mode 100644
index 00000000000..4d5fbcbcedb
--- /dev/null
+++ b/chromium/ui/gfx/x/keysyms/keysyms.h
@@ -0,0 +1,1161 @@
+// 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_KEYSYMS_KEYSYMS_H_
+#define UI_GFX_X_KEYSYMS_KEYSYMS_H_
+
+#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;
+
+#endif // UI_GFX_X_KEYSYMS_KEYSYMS_H_
diff --git a/chromium/ui/gfx/x/x11.h b/chromium/ui/gfx/x/x11.h
index c1ee10ab986..a19c26e01bb 100644
--- a/chromium/ui/gfx/x/x11.h
+++ b/chromium/ui/gfx/x/x11.h
@@ -2,106 +2,72 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// This header file replaces includes of X11 system includes while
-// preventing them from redefining and making a mess of commonly used
-// keywords like "None" and "Status". Instead those are placed inside
-// an X11 namespace where they will not clash with other code.
+// 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
-#define UI_GFX_X_X11
+#ifndef UI_GFX_X_X11_H_
+#define UI_GFX_X_X11_H_
-extern "C" {
-// Xlib.h defines base types so it must be included before the less
-// central X11 headers can be included.
-#include <X11/Xlib.h>
-
-// And the rest so that nobody needs to include them manually...
-#include <X11/X.h>
-#include <X11/XKBlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib-xcb.h>
-#include <X11/Xregion.h>
-#include <X11/Xutil.h>
-#include <X11/cursorfont.h>
-#include <X11/extensions/XShm.h>
-#include <X11/extensions/Xfixes.h>
-#include <X11/extensions/Xrender.h>
-#include <X11/extensions/sync.h>
-
-// Define XK_xxx before the #include of <X11/keysym.h> so that <X11/keysym.h>
-// defines all KeySyms we need.
-#define XK_3270 // For XK_3270_BackTab in particular.
-#define XK_MISCELLANY
-#define XK_LATIN1
-#define XK_LATIN2
-#define XK_LATIN3
-#define XK_LATIN4
-#define XK_LATIN8
-#define XK_LATIN9
-#define XK_KATAKANA
-#define XK_ARABIC
-#define XK_CYRILLIC
-#define XK_GREEK
-#define XK_TECHNICAL
-#define XK_SPECIAL
-#define XK_PUBLISHING
-#define XK_APL
-#define XK_HEBREW
-#define XK_THAI
-#define XK_KOREAN
-#define XK_ARMENIAN
-#define XK_GEORGIAN
-#define XK_CAUCASUS
-#define XK_VIETNAMESE
-#define XK_CURRENCY
-#define XK_MATHEMATICAL
-#define XK_BRAILLE
-#define XK_SINHALA
-#define XK_XKB_KEYS
+#include "ui/gfx/x/connection.h"
-#ifndef XK_dead_greek
-#define XK_dead_greek 0xfe8c
-#endif
+// Temporarily declare Xlib symbols we require. Do not add more Xlib
+// declarations here and do not include anything from <X11/*>.
-#include <X11/Sunkeysym.h>
-#include <X11/XF86keysym.h>
-#include <X11/keysym.h>
-}
+extern "C" {
-#include "ui/gfx/x/connection.h"
+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;
-// These commonly used names are undefined and if necessary recreated
-// in the x11 namespace below. This is the main purpose of this header
-// file.
+enum XEventQueueOwner { XlibOwnsEventQueue = 0, XCBOwnsEventQueue };
-// Not using common words is extra important for jumbo builds
-// where cc files are merged. Those merged filed get to see many more
-// headers than initially expected, including system headers like
-// those from X11.
+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;
+};
-#undef Status // Defined by X11/Xlib.h to int
-#undef Bool // Defined by X11/Xlib.h to int
-#undef RootWindow // Defined by X11/Xlib.h
-#undef DestroyAll // Defined by X11/X.h to 0
-#undef Always // Defined by X11/X.h to 2
-#undef FocusIn // Defined by X.h to 9
-#undef FocusOut // Defined by X.h to 10
-#undef None // Defined by X11/X.h to 0L
-#undef True // Defined by X11/Xlib.h to 1
-#undef False // Defined by X11/Xlib.h to 0
-#undef CurrentTime // Defined by X11/X.h to 0L
-#undef Success // Defined by X11/X.h to 0
+using XErrorHandler = int (*)(Display*, XErrorEvent*);
+using XIOErrorHandler = int (*)(Display*);
-// The x11 namespace allows to scope X11 constants and types that
-// would be problematic at the default preprocessor level.
-namespace x11 {
-static constexpr unsigned long None = 0L;
-static constexpr long CurrentTime = 0L;
-static constexpr int False = 0;
-static constexpr int True = 1;
-static constexpr int Success = 0;
-typedef int Bool;
-typedef int Status;
-} // namespace x11
+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
+#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 2e09c095eea..cf727cd23cf 100644
--- a/chromium/ui/gfx/x/x11_atom_cache.cc
+++ b/chromium/ui/gfx/x/x11_atom_cache.cc
@@ -4,9 +4,6 @@
#include "ui/gfx/x/x11_atom_cache.h"
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-
#include <utility>
#include <vector>
@@ -228,6 +225,7 @@ constexpr const char* kAtomsToCache[] = {
"chromium/x-web-custom-data",
"chromium/x-webkit-paste",
"image/png",
+ "image/svg+xml",
"marker_event",
"scaling mode",
"text/html",
diff --git a/chromium/ui/gfx/x/x11_error_tracker.cc b/chromium/ui/gfx/x/x11_error_tracker.cc
index 6592ae04838..5859a5e4b39 100644
--- a/chromium/ui/gfx/x/x11_error_tracker.cc
+++ b/chromium/ui/gfx/x/x11_error_tracker.cc
@@ -5,12 +5,12 @@
#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;
-static gfx::X11ErrorTracker* g_handler = nullptr;
int X11ErrorHandler(Display* display, XErrorEvent* error) {
g_x11_error_code = error->error_code;
@@ -22,22 +22,17 @@ int X11ErrorHandler(Display* display, XErrorEvent* error) {
namespace gfx {
X11ErrorTracker::X11ErrorTracker() {
- // This is a non-exhaustive check for incorrect usage. It disallows nested
- // X11ErrorTracker instances on the same thread.
- DCHECK(g_handler == nullptr);
- g_handler = this;
- XSync(GetXDisplay(), False);
- old_handler_ = XSetErrorHandler(X11ErrorHandler);
+ x11::Connection::Get()->Sync();
+ old_handler_ = reinterpret_cast<void*>(XSetErrorHandler(X11ErrorHandler));
g_x11_error_code = 0;
}
X11ErrorTracker::~X11ErrorTracker() {
- g_handler = nullptr;
- XSetErrorHandler(old_handler_);
+ XSetErrorHandler(reinterpret_cast<XErrorHandler>(old_handler_));
}
bool X11ErrorTracker::FoundNewError() {
- XSync(GetXDisplay(), False);
+ x11::Connection::Get()->Sync();
unsigned char error = g_x11_error_code;
g_x11_error_code = 0;
return error != 0;
diff --git a/chromium/ui/gfx/x/x11_error_tracker.h b/chromium/ui/gfx/x/x11_error_tracker.h
index 21031bed036..df06befc87f 100644
--- a/chromium/ui/gfx/x/x11_error_tracker.h
+++ b/chromium/ui/gfx/x/x11_error_tracker.h
@@ -5,8 +5,6 @@
#ifndef UI_GFX_X_X11_ERROR_TRACKER_H_
#define UI_GFX_X_X11_ERROR_TRACKER_H_
-#include <X11/Xlib.h>
-
#include "base/macros.h"
#include "ui/gfx/gfx_export.h"
@@ -26,7 +24,10 @@ class GFX_EXPORT X11ErrorTracker {
bool FoundNewError();
private:
- XErrorHandler old_handler_;
+ // 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);
};
diff --git a/chromium/ui/gfx/x/x11_path.cc b/chromium/ui/gfx/x/x11_path.cc
index 937e206007e..987d58345c2 100644
--- a/chromium/ui/gfx/x/x11_path.cc
+++ b/chromium/ui/gfx/x/x11_path.cc
@@ -17,11 +17,6 @@ std::unique_ptr<std::vector<x11::Rectangle>> CreateRegionFromSkRegion(
auto result = std::make_unique<std::vector<x11::Rectangle>>();
for (SkRegion::Iterator i(region); !i.done(); i.next()) {
- XRectangle rect;
- rect.x = i.rect().x();
- rect.y = i.rect().y();
- rect.width = i.rect().width();
- rect.height = i.rect().height();
result->push_back({
.x = i.rect().x(),
.y = i.rect().y(),
diff --git a/chromium/ui/gfx/x/x11_types.cc b/chromium/ui/gfx/x/x11_types.cc
index 756a1f59dc0..3e09d3e6a55 100644
--- a/chromium/ui/gfx/x/x11_types.cc
+++ b/chromium/ui/gfx/x/x11_types.cc
@@ -4,13 +4,13 @@
#include "ui/gfx/x/x11_types.h"
-#include <X11/Xlib.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 {
@@ -19,9 +19,4 @@ XDisplay* GetXDisplay() {
return x11::Connection::Get()->display();
}
-XDisplay* CloneXDisplay(XDisplay* display) {
- return XOpenDisplay(DisplayString(display));
-}
-
} // namespace gfx
-
diff --git a/chromium/ui/gfx/x/x11_types.h b/chromium/ui/gfx/x/x11_types.h
index 9bede0e7cdf..4b6b9ec0043 100644
--- a/chromium/ui/gfx/x/x11_types.h
+++ b/chromium/ui/gfx/x/x11_types.h
@@ -12,6 +12,7 @@
#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;
@@ -39,10 +40,6 @@ using XScopedPtr = std::unique_ptr<T, D>;
// Get the XDisplay singleton. Prefer x11::Connection::Get() instead.
GFX_EXPORT XDisplay* GetXDisplay();
-// Given a connection to an X server, opens a new parallel connection to the
-// same X server. It's the caller's responsibility to call XCloseDisplay().
-GFX_EXPORT XDisplay* CloneXDisplay(XDisplay* display);
-
} // namespace gfx
#endif // UI_GFX_X_X11_UTIL_H_
diff --git a/chromium/ui/gfx/x/xproto_internal.cc b/chromium/ui/gfx/x/xproto_internal.cc
index 2dbdd73e81b..83b8156a1dc 100644
--- a/chromium/ui/gfx/x/xproto_internal.cc
+++ b/chromium/ui/gfx/x/xproto_internal.cc
@@ -4,29 +4,11 @@
#include "ui/gfx/x/xproto_internal.h"
-// XCB used to send requests with FDs by sending each FD individually with
-// xcb_send_fd(), then the request with xcb_send_request(). However, there's a
-// race condition -- FDs can get mixed up if multiple threads are sending them
-// at the same time. xcb_send_request_with_fds() was introduced to atomically
-// handle this case, however it's only available on newer systems. In
-// particular it's not available on Ubuntu Xenial (which has LTS until April
-// 2024). We want to use the bug-free version when it's available, and fallback
-// to the buggy version otherwise.
-
-// Declare the function in case this is a packager build on an older distro with
-// use_sysroot=false.
-unsigned int xcb_send_request_with_fds(xcb_connection_t* c,
- int flags,
- struct iovec* vector,
- const xcb_protocol_request_t* request,
- unsigned int num_fds,
- int* fds);
-
-// Add the weak attribute to the symbol. This prevents the dynamic linker from
-// erroring out. Instead, if the function is not found, then it's address is
-// nullptr, so we can do a runtime check to test availability.
-extern "C" __attribute__((weak)) decltype(
- xcb_send_request_with_fds) xcb_send_request_with_fds;
+#include <stdint.h>
+#include <xcb/xcb.h>
+#include <xcb/xcbext.h>
+
+#include "ui/gfx/x/x11.h"
namespace x11 {
@@ -137,21 +119,15 @@ base::Optional<unsigned int> SendRequestImpl(x11::Connection* connection,
auto flags = XCB_REQUEST_CHECKED | XCB_REQUEST_RAW;
if (reply_has_fds)
flags |= XCB_REQUEST_REPLY_FDS;
- base::Optional<unsigned int> sequence;
- if (xcb_send_request_with_fds) {
- // Atomically send the request with its FDs if we can.
- sequence = xcb_send_request_with_fds(conn, flags, &io[2], &xpr,
- buf->fds().size(), buf->fds().data());
- } else {
- // Otherwise manually lock and send the fds, then the request.
- XLockDisplay(connection->display());
- for (int fd : buf->fds())
- xcb_send_fd(conn, fd);
- sequence = xcb_send_request(conn, flags, &io[2], &xpr);
- XUnlockDisplay(connection->display());
- }
+
+ for (int fd : buf->fds())
+ xcb_send_fd(conn, fd);
+ unsigned int sequence = xcb_send_request(conn, flags, &io[2], &xpr);
+
if (xcb_connection_has_error(conn))
return base::nullopt;
+ if (connection->synchronous())
+ connection->Sync();
return sequence;
}
diff --git a/chromium/ui/gfx/x/xproto_internal.h b/chromium/ui/gfx/x/xproto_internal.h
index f278ea8d9a5..61b930108ee 100644
--- a/chromium/ui/gfx/x/xproto_internal.h
+++ b/chromium/ui/gfx/x/xproto_internal.h
@@ -9,14 +9,7 @@
#error "This file should only be included by //ui/gfx/x:xprotos"
#endif
-#include <X11/Xlib-xcb.h>
-#include <stdint.h>
-#include <string.h>
-#include <xcb/xcb.h>
-#include <xcb/xcbext.h>
-
#include <bitset>
-#include <limits>
#include <type_traits>
#include "base/component_export.h"
diff --git a/chromium/ui/gfx/x/xproto_types.cc b/chromium/ui/gfx/x/xproto_types.cc
index 296862e8965..839d5466f52 100644
--- a/chromium/ui/gfx/x/xproto_types.cc
+++ b/chromium/ui/gfx/x/xproto_types.cc
@@ -4,9 +4,12 @@
#include "ui/gfx/x/xproto_types.h"
+#include <xcb/xcbext.h>
+
#include "base/memory/scoped_refptr.h"
#include "ui/gfx/x/connection.h"
#include "ui/gfx/x/xproto_internal.h"
+#include "ui/gfx/x/xproto_util.h"
namespace x11 {
@@ -92,15 +95,8 @@ FutureBase::~FutureBase() {
if (!error)
return;
- x11::LogErrorEventDescription(XErrorEvent({
- .type = error->response_type,
- .display = connection->display(),
- .resourceid = error->resource_id,
- .serial = error->full_sequence,
- .error_code = error->error_code,
- .request_code = error->major_code,
- .minor_code = error->minor_code,
- }));
+ x11::LogErrorEventDescription(error->full_sequence, error->error_code,
+ error->major_code, error->minor_code);
},
connection_));
}
diff --git a/chromium/ui/gfx/x/xproto_types.h b/chromium/ui/gfx/x/xproto_types.h
index 9e8e04d3429..37799e76dfd 100644
--- a/chromium/ui/gfx/x/xproto_types.h
+++ b/chromium/ui/gfx/x/xproto_types.h
@@ -6,19 +6,18 @@
#define UI_GFX_X_XPROTO_TYPES_H_
#include <xcb/xcb.h>
-#include <xcb/xcbext.h>
#include <cstdint>
#include <memory>
#include "base/bind.h"
#include "base/callback.h"
+#include "base/component_export.h"
#include "base/files/scoped_file.h"
#include "base/memory/free_deleter.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_refptr.h"
#include "base/optional.h"
-#include "ui/gfx/x/xproto_util.h"
typedef struct _XDisplay XDisplay;
diff --git a/chromium/ui/gfx/x/xproto_util.cc b/chromium/ui/gfx/x/xproto_util.cc
index e08bf4f6b5a..119fd902a46 100644
--- a/chromium/ui/gfx/x/xproto_util.cc
+++ b/chromium/ui/gfx/x/xproto_util.cc
@@ -8,11 +8,15 @@
#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(const XErrorEvent& error_event) {
+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.
@@ -22,24 +26,22 @@ void LogErrorEventDescription(const XErrorEvent& error_event) {
char error_str[256];
char request_str[256];
- XDisplay* dpy = error_event.display;
x11::Connection* conn = x11::Connection::Get();
- XGetErrorText(dpy, error_event.error_code, error_str, sizeof(error_str));
+ auto* dpy = conn->display();
+ XGetErrorText(dpy, error_code, error_str, sizeof(error_str));
strncpy(request_str, "Unknown", sizeof(request_str));
- if (error_event.request_code < 128) {
- std::string num = base::NumberToString(error_event.request_code);
+ 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) {
- int ext_code, first_event, first_error;
const char* name = str.name.c_str();
- XQueryExtension(dpy, name, &ext_code, &first_event, &first_error);
- if (error_event.request_code == ext_code) {
- std::string msg =
- base::StringPrintf("%s.%d", name, error_event.minor_code);
+ 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;
@@ -49,13 +51,12 @@ void LogErrorEventDescription(const XErrorEvent& error_event) {
}
LOG(WARNING) << "X error received: "
- << "serial " << error_event.serial << ", "
- << "error_code " << static_cast<int>(error_event.error_code)
- << " (" << error_str << "), "
- << "request_code " << static_cast<int>(error_event.request_code)
- << ", "
- << "minor_code " << static_cast<int>(error_event.minor_code)
- << " (" << request_str << ")";
+ << "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 baf2aaa540a..3a2486eb573 100644
--- a/chromium/ui/gfx/x/xproto_util.h
+++ b/chromium/ui/gfx/x/xproto_util.h
@@ -5,14 +5,39 @@
#ifndef UI_GFX_X_XPROTO_UTIL_H_
#define UI_GFX_X_XPROTO_UTIL_H_
-#include <X11/Xlib.h>
+#include <cstdint>
#include "base/component_export.h"
+#include "ui/gfx/x/connection.h"
+#include "ui/gfx/x/xproto.h"
+#include "ui/gfx/x/xproto_types.h"
namespace x11 {
+template <typename T>
+x11::Future<void> SendEvent(
+ const T& event,
+ x11::Window target,
+ x11::EventMask mask,
+ x11::Connection* connection = x11::Connection::Get()) {
+ static_assert(T::type_id > 0, "T must be an x11::*Event type");
+ auto write_buffer = x11::Write(event);
+ DCHECK_EQ(write_buffer.GetBuffers().size(), 1ul);
+ auto& first_buffer = write_buffer.GetBuffers()[0];
+ DCHECK_LE(first_buffer->size(), 32ul);
+ std::vector<uint8_t> event_bytes(32);
+ memcpy(event_bytes.data(), first_buffer->data(), first_buffer->size());
+
+ x11::SendEventRequest send_event{false, target, mask};
+ std::copy(event_bytes.begin(), event_bytes.end(), send_event.event.begin());
+ return connection->SendEvent(send_event);
+}
+
COMPONENT_EXPORT(X11)
-void LogErrorEventDescription(const XErrorEvent& error_event);
+void LogErrorEventDescription(unsigned long serial,
+ uint8_t error_code,
+ uint8_t request_code,
+ uint8_t minor_code);
} // namespace x11