diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-18 16:35:47 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-18 15:45:54 +0000 |
commit | 32f5a1c56531e4210bc4cf8d8c7825d66e081888 (patch) | |
tree | eeeec6822f4d738d8454525233fd0e2e3a659e6d /chromium/ui/gfx | |
parent | 99677208ff3b216fdfec551fbe548da5520cd6fb (diff) | |
download | qtwebengine-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')
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(), ×tamp); + FenceStatus status = + GetStatusChangeTime(fence_handle_.owned_fd.get(), ×tamp); 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 |