From 32aa6f116acc6e3e20a1ec76cef45b29f7005ad7 Mon Sep 17 00:00:00 2001 From: Yuqian Yang Date: Fri, 17 Oct 2025 12:06:14 +0800 Subject: Remove String stage 1. --- src/platform/CMakeLists.txt | 1 - src/platform/Resource.cpp | 7 - src/platform/graphics/CMakeLists.txt | 2 - src/platform/graphics/Geometry.cpp | 14 +- src/platform/graphics/SvgGeometryBuilderMixin.cpp | 37 +-- .../graphics/cairo/CairoGraphicsFactory.cpp | 4 +- src/platform/graphics/cairo/CairoImageFactory.cpp | 2 +- src/platform/graphics/cairo/CairoPainter.cpp | 24 +- src/platform/graphics/cairo/CairoResource.cpp | 6 +- src/platform/graphics/cairo/PangoFont.cpp | 9 +- src/platform/graphics/cairo/PangoTextLayout.cpp | 56 ++--- src/platform/graphics/direct2d/ImageFactory.cpp | 2 +- src/platform/graphics/direct2d/Painter.cpp | 24 +- src/platform/graphics/direct2d/TextLayout.cpp | 4 +- src/platform/graphics/quartz/Factory.cpp | 2 +- src/platform/graphics/quartz/ImageFactory.cpp | 2 +- src/platform/graphics/quartz/Painter.cpp | 22 +- src/platform/graphics/quartz/TextLayout.cpp | 2 +- src/platform/graphics/web_canvas/Painter.cpp | 2 +- src/platform/gui/CMakeLists.txt | 2 +- src/platform/gui/Input.cpp | 140 +++++++++++ src/platform/gui/Keyboard.cpp | 140 ----------- src/platform/gui/UiApplication.cpp | 9 +- src/platform/gui/osx/Window.mm | 8 +- src/platform/gui/sdl/Window.cpp | 6 +- src/platform/gui/win/Window.cpp | 4 +- src/platform/gui/xcb/CMakeLists.txt | 2 +- src/platform/gui/xcb/Clipboard.cpp | 4 +- src/platform/gui/xcb/Cursor.cpp | 1 - src/platform/gui/xcb/Input.cpp | 279 ++++++++++++++++++++ src/platform/gui/xcb/InputMethod.cpp | 11 +- src/platform/gui/xcb/Keyboard.cpp | 280 --------------------- src/platform/gui/xcb/UiApplication.cpp | 3 +- src/platform/gui/xcb/Window.cpp | 15 +- 34 files changed, 544 insertions(+), 582 deletions(-) delete mode 100644 src/platform/Resource.cpp create mode 100644 src/platform/gui/Input.cpp delete mode 100644 src/platform/gui/Keyboard.cpp create mode 100644 src/platform/gui/xcb/Input.cpp delete mode 100644 src/platform/gui/xcb/Keyboard.cpp (limited to 'src/platform') diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt index a917f81f..9122e499 100644 --- a/src/platform/CMakeLists.txt +++ b/src/platform/CMakeLists.txt @@ -2,7 +2,6 @@ add_library(CruPlatformBase Color.cpp Exception.cpp GraphicsBase.cpp - Resource.cpp ) target_link_libraries(CruPlatformBase PUBLIC CruBase) target_compile_definitions(CruPlatformBase PRIVATE CRU_PLATFORM_EXPORT_API) diff --git a/src/platform/Resource.cpp b/src/platform/Resource.cpp deleted file mode 100644 index d0dbf53b..00000000 --- a/src/platform/Resource.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "cru/platform/Resource.h" - -namespace cru::platform { -std::string IPlatformResource::GetPlatformIdUtf8() const { - return GetPlatformId().ToUtf8(); -} -} // namespace cru::platform diff --git a/src/platform/graphics/CMakeLists.txt b/src/platform/graphics/CMakeLists.txt index 43ef80e0..e86e9c89 100644 --- a/src/platform/graphics/CMakeLists.txt +++ b/src/platform/graphics/CMakeLists.txt @@ -1,8 +1,6 @@ add_library(CruPlatformGraphics - ForDllExport.cpp Geometry.cpp Image.cpp - NullPainter.cpp SvgGeometryBuilderMixin.cpp ) target_compile_definitions(CruPlatformGraphics PRIVATE CRU_PLATFORM_GRAPHICS_EXPORT_API) diff --git a/src/platform/graphics/Geometry.cpp b/src/platform/graphics/Geometry.cpp index 2c842a6e..e88577ce 100644 --- a/src/platform/graphics/Geometry.cpp +++ b/src/platform/graphics/Geometry.cpp @@ -1,6 +1,7 @@ #include "cru/platform/graphics/Geometry.h" #include "cru/base/Exception.h" +#include "cru/base/String.h" #include "cru/platform/Exception.h" #include "cru/platform/graphics/Factory.h" @@ -15,7 +16,7 @@ bool IGeometry::StrokeContains(float width, const Point& point) { std::unique_ptr IGeometry::CreateStrokeGeometry( [[maybe_unused]] float width) { - throw PlatformUnsupportedException(GetPlatformIdUtf8(), "CreateStrokeGeometry", + throw PlatformUnsupportedException(GetPlatformId(), "CreateStrokeGeometry", "Create stroke geometry of a geometry is " "not supported on this platform."); } @@ -207,7 +208,7 @@ const std::unordered_set kSvgPathDataCommands = { 'S', 's', 'Q', 'q', 'T', 't', 'A', 'a', 'Z', 'z'}; } -void IGeometryBuilder::ParseAndApplySvgPathData(StringView path_d) { +void IGeometryBuilder::ParseAndApplySvgPathData(std::string_view path_d) { Index position = 0; const auto size = path_d.size(); @@ -236,8 +237,9 @@ void IGeometryBuilder::ParseAndApplySvgPathData(StringView path_d) { Index processed_count = 0; - auto result = path_d.substr(position).ParseToFloat( - &processed_count, StringToNumberFlags::kAllowTrailingJunk); + auto result = String::FromUtf8(path_d.substr(position)) + .ParseToFloat(&processed_count, + StringToNumberFlags::kAllowTrailingJunk); if (std::isnan(result)) throw Exception("Invalid svg path data number."); @@ -252,7 +254,7 @@ void IGeometryBuilder::ParseAndApplySvgPathData(StringView path_d) { return Point(x, y); }; - auto do_command = [&, this](char16_t command) { + auto do_command = [&, this](char command) { last_command = command; last_is_cubic = false; last_is_quad = false; @@ -442,7 +444,7 @@ void IGeometryBuilder::ParseAndApplySvgPathData(StringView path_d) { } std::unique_ptr CreateGeometryFromSvgPathData( - IGraphicsFactory* factory, StringView path_d) { + IGraphicsFactory* factory, std::string_view path_d) { auto builder = factory->CreateGeometryBuilder(); builder->ParseAndApplySvgPathData(path_d); return builder->Build(); diff --git a/src/platform/graphics/SvgGeometryBuilderMixin.cpp b/src/platform/graphics/SvgGeometryBuilderMixin.cpp index 73290da5..0863e5eb 100644 --- a/src/platform/graphics/SvgGeometryBuilderMixin.cpp +++ b/src/platform/graphics/SvgGeometryBuilderMixin.cpp @@ -1,7 +1,7 @@ #include "cru/platform/graphics/SvgGeometryBuilderMixin.h" #include "cru/platform/Exception.h" -#include "cru/base/Format.h" +#include namespace cru::platform::graphics { SvgGeometryBuilderMixin::SvgGeometryBuilderMixin() {} @@ -10,34 +10,34 @@ SvgGeometryBuilderMixin::~SvgGeometryBuilderMixin() {} Point SvgGeometryBuilderMixin::GetCurrentPosition() { throw PlatformUnsupportedException( - GetPlatformIdUtf8(), "GetCurrentPosition", + GetPlatformId(), "GetCurrentPosition", "Svg-based geometry does not support get current position."); } void SvgGeometryBuilderMixin::MoveTo(const Point& point) { - AppendCommand(u"M"); + AppendCommand("M"); Append(point); } void SvgGeometryBuilderMixin::RelativeMoveTo(const Point& offset) { - AppendCommand(u"m"); + AppendCommand("m"); Append(offset); } void SvgGeometryBuilderMixin::LineTo(const Point& point) { - AppendCommand(u"L"); + AppendCommand("L"); Append(point); } void SvgGeometryBuilderMixin::RelativeLineTo(const Point& offset) { - AppendCommand(u"l"); + AppendCommand("l"); Append(offset); } void SvgGeometryBuilderMixin::CubicBezierTo(const Point& start_control_point, const Point& end_control_point, const Point& end_point) { - AppendCommand(u"C"); + AppendCommand("C"); Append(start_control_point); Append(end_control_point); Append(end_point); @@ -46,7 +46,7 @@ void SvgGeometryBuilderMixin::CubicBezierTo(const Point& start_control_point, void SvgGeometryBuilderMixin::RelativeCubicBezierTo( const Point& start_control_offset, const Point& end_control_offset, const Point& end_offset) { - AppendCommand(u"c"); + AppendCommand("c"); Append(start_control_offset); Append(end_control_offset); Append(end_offset); @@ -54,14 +54,14 @@ void SvgGeometryBuilderMixin::RelativeCubicBezierTo( void SvgGeometryBuilderMixin::QuadraticBezierTo(const Point& control_point, const Point& end_point) { - AppendCommand(u"Q"); + AppendCommand("Q"); Append(control_point); Append(end_point); } void SvgGeometryBuilderMixin::RelativeQuadraticBezierTo( const Point& control_offset, const Point& end_offset) { - AppendCommand(u"q"); + AppendCommand("q"); Append(control_offset); Append(end_offset); } @@ -69,7 +69,7 @@ void SvgGeometryBuilderMixin::RelativeQuadraticBezierTo( void SvgGeometryBuilderMixin::ArcTo(const Point& radius, float angle, bool is_large_arc, bool is_clockwise, const Point& end_point) { - AppendCommand(u"A"); + AppendCommand("A"); Append(radius.x); Append(radius.y); Append(angle); @@ -82,7 +82,7 @@ void SvgGeometryBuilderMixin::RelativeArcTo(const Point& radius, float angle, bool is_large_arc, bool is_clockwise, const Point& end_offset) { - AppendCommand(u"a"); + AppendCommand("a"); Append(radius.x); Append(radius.y); Append(angle); @@ -92,14 +92,15 @@ void SvgGeometryBuilderMixin::RelativeArcTo(const Point& radius, float angle, } void SvgGeometryBuilderMixin::CloseFigure(bool close) { - if (close) AppendCommand(u"z"); + if (close) AppendCommand("z"); } -void SvgGeometryBuilderMixin::ParseAndApplySvgPathData(StringView path_d) { +void SvgGeometryBuilderMixin::ParseAndApplySvgPathData( + std::string_view path_d) { AppendCommand(path_d); } -void SvgGeometryBuilderMixin::AppendCommand(StringView command) { +void SvgGeometryBuilderMixin::AppendCommand(std::string_view command) { current_ += command; current_ += u' '; } @@ -110,14 +111,14 @@ void SvgGeometryBuilderMixin::Append(bool flag) { } void SvgGeometryBuilderMixin::Append(float number) { - current_ += cru::ToString(number); + current_ += std::to_string(number); current_ += u' '; } void SvgGeometryBuilderMixin::Append(const Point& point) { - current_ += cru::ToString(point.x); + current_ += std::to_string(point.x); current_ += u','; - current_ += cru::ToString(point.y); + current_ += std::to_string(point.y); current_ += u' '; } } // namespace cru::platform::graphics diff --git a/src/platform/graphics/cairo/CairoGraphicsFactory.cpp b/src/platform/graphics/cairo/CairoGraphicsFactory.cpp index 11d2e734..7414e14f 100644 --- a/src/platform/graphics/cairo/CairoGraphicsFactory.cpp +++ b/src/platform/graphics/cairo/CairoGraphicsFactory.cpp @@ -32,13 +32,13 @@ CairoGraphicsFactory::CreateGeometryBuilder() { return std::make_unique(this); } -std::unique_ptr CairoGraphicsFactory::CreateFont(String font_family, +std::unique_ptr CairoGraphicsFactory::CreateFont(std::string font_family, float font_size) { return std::make_unique(this, std::move(font_family), font_size); } std::unique_ptr CairoGraphicsFactory::CreateTextLayout( - std::shared_ptr font, String text) { + std::shared_ptr font, std::string text) { auto text_layout = std::make_unique(this, std::move(font)); text_layout->SetText(std::move(text)); return text_layout; diff --git a/src/platform/graphics/cairo/CairoImageFactory.cpp b/src/platform/graphics/cairo/CairoImageFactory.cpp index ff922e77..6225247a 100644 --- a/src/platform/graphics/cairo/CairoImageFactory.cpp +++ b/src/platform/graphics/cairo/CairoImageFactory.cpp @@ -212,7 +212,7 @@ std::unique_ptr CairoImageFactory::DecodeFromStream( void CairoImageFactory::EncodeToStream(IImage* image, io::Stream* stream, ImageFormat format, float quality) { - auto cairo_image = CheckPlatform(image, GetPlatformIdUtf8()); + auto cairo_image = CheckPlatform(image, GetPlatformId()); if (format == ImageFormat::Png) { EncodePng(cairo_image->GetCairoSurface(), stream); diff --git a/src/platform/graphics/cairo/CairoPainter.cpp b/src/platform/graphics/cairo/CairoPainter.cpp index 94111098..d043e686 100644 --- a/src/platform/graphics/cairo/CairoPainter.cpp +++ b/src/platform/graphics/cairo/CairoPainter.cpp @@ -56,7 +56,7 @@ void CairoPainter::Clear(const Color& color) { void CairoPainter::DrawLine(const Point& start, const Point& end, IBrush* brush, float width) { CheckValidation(); - auto cairo_brush = CheckPlatform(brush, GetPlatformIdUtf8()); + auto cairo_brush = CheckPlatform(brush, GetPlatformId()); auto cairo_pattern = cairo_brush->GetCairoPattern(); cairo_save(cairo_); cairo_set_source(cairo_, cairo_pattern); @@ -71,7 +71,7 @@ void CairoPainter::DrawLine(const Point& start, const Point& end, IBrush* brush, void CairoPainter::StrokeRectangle(const Rect& rectangle, IBrush* brush, float width) { CheckValidation(); - auto cairo_brush = CheckPlatform(brush, GetPlatformIdUtf8()); + auto cairo_brush = CheckPlatform(brush, GetPlatformId()); auto cairo_pattern = cairo_brush->GetCairoPattern(); cairo_save(cairo_); cairo_set_source(cairo_, cairo_pattern); @@ -85,7 +85,7 @@ void CairoPainter::StrokeRectangle(const Rect& rectangle, IBrush* brush, void CairoPainter::FillRectangle(const Rect& rectangle, IBrush* brush) { CheckValidation(); - auto cairo_brush = CheckPlatform(brush, GetPlatformIdUtf8()); + auto cairo_brush = CheckPlatform(brush, GetPlatformId()); auto cairo_pattern = cairo_brush->GetCairoPattern(); cairo_save(cairo_); cairo_set_source(cairo_, cairo_pattern); @@ -99,7 +99,7 @@ void CairoPainter::FillRectangle(const Rect& rectangle, IBrush* brush) { void CairoPainter::StrokeEllipse(const Rect& outline_rect, IBrush* brush, float width) { CheckValidation(); - auto cairo_brush = CheckPlatform(brush, GetPlatformIdUtf8()); + auto cairo_brush = CheckPlatform(brush, GetPlatformId()); auto cairo_pattern = cairo_brush->GetCairoPattern(); cairo_save(cairo_); cairo_set_source(cairo_, cairo_pattern); @@ -122,7 +122,7 @@ void CairoPainter::StrokeEllipse(const Rect& outline_rect, IBrush* brush, void CairoPainter::FillEllipse(const Rect& outline_rect, IBrush* brush) { CheckValidation(); - auto cairo_brush = CheckPlatform(brush, GetPlatformIdUtf8()); + auto cairo_brush = CheckPlatform(brush, GetPlatformId()); auto cairo_pattern = cairo_brush->GetCairoPattern(); cairo_save(cairo_); cairo_set_source(cairo_, cairo_pattern); @@ -145,8 +145,8 @@ void CairoPainter::FillEllipse(const Rect& outline_rect, IBrush* brush) { void CairoPainter::StrokeGeometry(IGeometry* geometry, IBrush* brush, float width) { CheckValidation(); - auto cairo_geometry = CheckPlatform(geometry, GetPlatformIdUtf8()); - auto cairo_brush = CheckPlatform(brush, GetPlatformIdUtf8()); + auto cairo_geometry = CheckPlatform(geometry, GetPlatformId()); + auto cairo_brush = CheckPlatform(brush, GetPlatformId()); auto cairo_path = cairo_geometry->GetCairoPath(); auto cairo_pattern = cairo_brush->GetCairoPattern(); @@ -162,8 +162,8 @@ void CairoPainter::StrokeGeometry(IGeometry* geometry, IBrush* brush, void CairoPainter::FillGeometry(IGeometry* geometry, IBrush* brush) { CheckValidation(); - auto cairo_geometry = CheckPlatform(geometry, GetPlatformIdUtf8()); - auto cairo_brush = CheckPlatform(brush, GetPlatformIdUtf8()); + auto cairo_geometry = CheckPlatform(geometry, GetPlatformId()); + auto cairo_brush = CheckPlatform(brush, GetPlatformId()); auto cairo_path = cairo_geometry->GetCairoPath(); auto cairo_pattern = cairo_brush->GetCairoPattern(); @@ -181,9 +181,9 @@ void CairoPainter::DrawText(const Point& offset, ITextLayout* text_layout, CheckValidation(); auto pango_text_layout = - CheckPlatform(text_layout, GetPlatformIdUtf8()); + CheckPlatform(text_layout, GetPlatformId()); - auto cairo_brush = CheckPlatform(brush, GetPlatformIdUtf8()); + auto cairo_brush = CheckPlatform(brush, GetPlatformId()); auto cairo_pattern = cairo_brush->GetCairoPattern(); cairo_save(cairo_); @@ -196,7 +196,7 @@ void CairoPainter::DrawText(const Point& offset, ITextLayout* text_layout, void CairoPainter::DrawImage(const Point& offset, IImage* image) { CheckValidation(); - auto cairo_image = CheckPlatform(image, GetPlatformIdUtf8()); + auto cairo_image = CheckPlatform(image, GetPlatformId()); cairo_save(cairo_); cairo_set_source_surface(cairo_, cairo_image->GetCairoSurface(), 0, 0); cairo_new_path(cairo_); diff --git a/src/platform/graphics/cairo/CairoResource.cpp b/src/platform/graphics/cairo/CairoResource.cpp index ee371efc..f8ce9666 100644 --- a/src/platform/graphics/cairo/CairoResource.cpp +++ b/src/platform/graphics/cairo/CairoResource.cpp @@ -2,14 +2,16 @@ #include "cru/platform/graphics/cairo/CairoGraphicsFactory.h" namespace cru::platform::graphics::cairo { -static const String kCairoGraphicsPlatformId(u"cairo"); +static const std::string kCairoGraphicsPlatformId("cairo"); CairoResource::CairoResource(CairoGraphicsFactory* factory) : factory_(factory) {} CairoResource::~CairoResource() {} -String CairoResource::GetPlatformId() const { return kCairoGraphicsPlatformId; } +std::string CairoResource::GetPlatformId() const { + return kCairoGraphicsPlatformId; +} IGraphicsFactory* CairoResource::GetGraphicsFactory() { return factory_; } } // namespace cru::platform::graphics::cairo diff --git a/src/platform/graphics/cairo/PangoFont.cpp b/src/platform/graphics/cairo/PangoFont.cpp index d5c1ad0b..e375d674 100644 --- a/src/platform/graphics/cairo/PangoFont.cpp +++ b/src/platform/graphics/cairo/PangoFont.cpp @@ -1,23 +1,24 @@ #include "cru/platform/graphics/cairo/PangoFont.h" namespace cru::platform::graphics::cairo { -PangoFont::PangoFont(CairoGraphicsFactory* factory, String font_family, +PangoFont::PangoFont(CairoGraphicsFactory* factory, std::string font_family, float font_size) : CairoResource(factory), font_family_(std::move(font_family)), font_size_(font_size) { pango_font_description_ = pango_font_description_new(); - auto font_family_str = font_family_.ToUtf8(); + auto font_family_str = font_family_; pango_font_description_set_family(pango_font_description_, font_family_str.c_str()); - pango_font_description_set_size(pango_font_description_, font_size * PANGO_SCALE); + pango_font_description_set_size(pango_font_description_, + font_size * PANGO_SCALE); } PangoFont::~PangoFont() { pango_font_description_free(pango_font_description_); } -String PangoFont::GetFontName() { return font_family_; } +std::string PangoFont::GetFontName() { return font_family_; } float PangoFont::GetFontSize() { return font_size_; } } // namespace cru::platform::graphics::cairo diff --git a/src/platform/graphics/cairo/PangoTextLayout.cpp b/src/platform/graphics/cairo/PangoTextLayout.cpp index 746056e2..f8ed20c7 100644 --- a/src/platform/graphics/cairo/PangoTextLayout.cpp +++ b/src/platform/graphics/cairo/PangoTextLayout.cpp @@ -1,5 +1,4 @@ #include "cru/platform/graphics/cairo/PangoTextLayout.h" -#include "cru/base/StringUtil.h" #include "cru/platform/Check.h" #include "cru/platform/GraphicsBase.h" #include "cru/platform/graphics/Base.h" @@ -24,7 +23,7 @@ PangoTextLayout::PangoTextLayout(CairoGraphicsFactory* factory, std::shared_ptr font) : CairoResource(factory) { Expects(font); - font_ = CheckPlatform(font, GetPlatformIdUtf8()); + font_ = CheckPlatform(font, GetPlatformId()); pango_layout_ = pango_cairo_create_layout(factory->GetDefaultCairo()); pango_layout_set_font_description(pango_layout_, font_->GetPangoFontDescription()); @@ -32,19 +31,18 @@ PangoTextLayout::PangoTextLayout(CairoGraphicsFactory* factory, PangoTextLayout::~PangoTextLayout() { g_object_unref(pango_layout_); } -String PangoTextLayout::GetText() { return text_; } +std::string PangoTextLayout::GetText() { return text_; } -void PangoTextLayout::SetText(String new_text) { +void PangoTextLayout::SetText(std::string new_text) { text_ = std::move(new_text); - utf8_text_ = text_.ToUtf8(); - pango_layout_set_text(pango_layout_, utf8_text_.c_str(), utf8_text_.size()); + pango_layout_set_text(pango_layout_, text_.c_str(), text_.size()); } std::shared_ptr PangoTextLayout::GetFont() { return font_; } void PangoTextLayout::SetFont(std::shared_ptr font) { Expects(font); - font_ = CheckPlatform(font, GetPlatformIdUtf8()); + font_ = CheckPlatform(font, GetPlatformId()); pango_layout_set_font_description(pango_layout_, font_->GetPangoFontDescription()); } @@ -63,9 +61,8 @@ void PangoTextLayout::SetEditMode(bool enable) { edit_mode_ = enable; } Index PangoTextLayout::GetLineIndexFromCharIndex(Index char_index) { int line; - pango_layout_index_to_line_x(pango_layout_, - FromUtf16IndexToUtf8Index(char_index), false, - &line, nullptr); + pango_layout_index_to_line_x(pango_layout_, char_index, false, &line, + nullptr); return line; } @@ -80,27 +77,6 @@ float PangoTextLayout::GetLineHeight(Index line_index) { return static_cast(height) / PANGO_SCALE; } -Index PangoTextLayout::FromUtf8IndexToUtf16Index(Index index) { - Utf8CodePointIterator iter(utf8_text_.data(), utf8_text_.size()); - int cp_count = 0; - while ((!iter.IsPastEnd()) && iter.GetPosition() < index) { - ++iter; - cp_count++; - } - return text_.IndexFromCodePointToCodeUnit(cp_count); -} - -Index PangoTextLayout::FromUtf16IndexToUtf8Index(Index index) { - Index cp_index = text_.IndexFromCodeUnitToCodePoint(index); - Utf8CodePointIterator iter(utf8_text_.data(), utf8_text_.size()); - - for (Index i = 0; i < cp_index; ++i) { - ++iter; - } - - return iter.GetPosition(); -} - Rect PangoTextLayout::GetTextBounds(bool includingTrailingSpace) { PangoRectangle rectangle; pango_layout_get_extents(pango_layout_, nullptr, &rectangle); @@ -110,17 +86,17 @@ Rect PangoTextLayout::GetTextBounds(bool includingTrailingSpace) { std::vector PangoTextLayout::TextRangeRect(const TextRange& text_range) { auto tr = text_range.Normalize(); - auto utf8_start_index = FromUtf16IndexToUtf8Index(tr.GetStart()); - auto utf8_end_index = FromUtf16IndexToUtf8Index(tr.GetEnd()); + auto start_index = tr.GetStart(); + auto end_index = tr.GetEnd(); PangoRectangle rectangle; int start_line_index, end_line_index, start_x_pos, end_x_pos; - pango_layout_index_to_line_x(pango_layout_, utf8_start_index, false, + pango_layout_index_to_line_x(pango_layout_, start_index, false, &start_line_index, &start_x_pos); - pango_layout_index_to_line_x(pango_layout_, utf8_end_index, false, - &end_line_index, &end_x_pos); + pango_layout_index_to_line_x(pango_layout_, end_index, false, &end_line_index, + &end_x_pos); - pango_layout_index_to_pos(pango_layout_, utf8_start_index, &rectangle); + pango_layout_index_to_pos(pango_layout_, start_index, &rectangle); auto top = rectangle.y; if (start_line_index == end_line_index) { @@ -161,9 +137,8 @@ std::vector PangoTextLayout::TextRangeRect(const TextRange& text_range) { } Rect PangoTextLayout::TextSinglePoint(Index position, bool trailing) { - auto utf8_index = FromUtf16IndexToUtf8Index(position); int line_index, x_pos, y_pos = 0; - pango_layout_index_to_line_x(pango_layout_, utf8_index, trailing, &line_index, + pango_layout_index_to_line_x(pango_layout_, position, trailing, &line_index, &x_pos); for (int i = 0; i < line_index; i++) { @@ -186,8 +161,7 @@ TextHitTestResult PangoTextLayout::HitTest(const Point& point) { auto inside_text = pango_layout_xy_to_index(pango_layout_, point.x * PANGO_SCALE, point.y * PANGO_SCALE, &index, &trailing); - return TextHitTestResult{FromUtf8IndexToUtf16Index(index), trailing != 0, - inside_text != 0}; + return TextHitTestResult{index, trailing != 0, inside_text != 0}; } } // namespace cru::platform::graphics::cairo diff --git a/src/platform/graphics/direct2d/ImageFactory.cpp b/src/platform/graphics/direct2d/ImageFactory.cpp index b9e9221a..aff411c4 100644 --- a/src/platform/graphics/direct2d/ImageFactory.cpp +++ b/src/platform/graphics/direct2d/ImageFactory.cpp @@ -74,7 +74,7 @@ GUID ConvertImageFormatToGUID(ImageFormat format) { void WinImageFactory::EncodeToStream(IImage* image, io::Stream* stream, ImageFormat format, float quality) { - auto direct_image = CheckPlatform(image, GetPlatformIdUtf8()); + auto direct_image = CheckPlatform(image, GetPlatformId()); Microsoft::WRL::ComPtr com_stream( platform::win::ConvertStreamToComStream(stream)); diff --git a/src/platform/graphics/direct2d/Painter.cpp b/src/platform/graphics/direct2d/Painter.cpp index 29ddcabb..fabcdafd 100644 --- a/src/platform/graphics/direct2d/Painter.cpp +++ b/src/platform/graphics/direct2d/Painter.cpp @@ -55,7 +55,7 @@ void D2DDeviceContextPainter::Clear(const Color& color) { void D2DDeviceContextPainter::DrawLine(const Point& start, const Point& end, IBrush* brush, float width) { CheckValidation(); - const auto b = CheckPlatform(brush, GetPlatformIdUtf8()); + const auto b = CheckPlatform(brush, GetPlatformId()); device_context_->DrawLine(Convert(start), Convert(end), b->GetD2DBrushInterface(), width); } @@ -63,7 +63,7 @@ void D2DDeviceContextPainter::DrawLine(const Point& start, const Point& end, void D2DDeviceContextPainter::StrokeRectangle(const Rect& rectangle, IBrush* brush, float width) { CheckValidation(); - const auto b = CheckPlatform(brush, GetPlatformIdUtf8()); + const auto b = CheckPlatform(brush, GetPlatformId()); device_context_->DrawRectangle(Convert(rectangle), b->GetD2DBrushInterface(), width); } @@ -71,14 +71,14 @@ void D2DDeviceContextPainter::StrokeRectangle(const Rect& rectangle, void D2DDeviceContextPainter::FillRectangle(const Rect& rectangle, IBrush* brush) { CheckValidation(); - const auto b = CheckPlatform(brush, GetPlatformIdUtf8()); + const auto b = CheckPlatform(brush, GetPlatformId()); device_context_->FillRectangle(Convert(rectangle), b->GetD2DBrushInterface()); } void D2DDeviceContextPainter::StrokeEllipse(const Rect& outline_rect, IBrush* brush, float width) { CheckValidation(); - const auto b = CheckPlatform(brush, GetPlatformIdUtf8()); + const auto b = CheckPlatform(brush, GetPlatformId()); device_context_->DrawEllipse( D2D1::Ellipse(Convert(outline_rect.GetCenter()), outline_rect.width / 2.0f, outline_rect.height / 2.0f), @@ -87,7 +87,7 @@ void D2DDeviceContextPainter::StrokeEllipse(const Rect& outline_rect, void D2DDeviceContextPainter::FillEllipse(const Rect& outline_rect, IBrush* brush) { CheckValidation(); - const auto b = CheckPlatform(brush, GetPlatformIdUtf8()); + const auto b = CheckPlatform(brush, GetPlatformId()); device_context_->FillEllipse( D2D1::Ellipse(Convert(outline_rect.GetCenter()), outline_rect.width / 2.0f, outline_rect.height / 2.0f), @@ -97,16 +97,16 @@ void D2DDeviceContextPainter::FillEllipse(const Rect& outline_rect, void D2DDeviceContextPainter::StrokeGeometry(IGeometry* geometry, IBrush* brush, float width) { CheckValidation(); - const auto g = CheckPlatform(geometry, GetPlatformIdUtf8()); - const auto b = CheckPlatform(brush, GetPlatformIdUtf8()); + const auto g = CheckPlatform(geometry, GetPlatformId()); + const auto b = CheckPlatform(brush, GetPlatformId()); device_context_->DrawGeometry(g->GetComInterface(), b->GetD2DBrushInterface(), width); } void D2DDeviceContextPainter::FillGeometry(IGeometry* geometry, IBrush* brush) { CheckValidation(); - const auto g = CheckPlatform(geometry, GetPlatformIdUtf8()); - const auto b = CheckPlatform(brush, GetPlatformIdUtf8()); + const auto g = CheckPlatform(geometry, GetPlatformId()); + const auto b = CheckPlatform(brush, GetPlatformId()); device_context_->FillGeometry(g->GetComInterface(), b->GetD2DBrushInterface()); } @@ -115,15 +115,15 @@ void D2DDeviceContextPainter::DrawText(const Point& offset, ITextLayout* text_layout, IBrush* brush) { CheckValidation(); - const auto t = CheckPlatform(text_layout, GetPlatformIdUtf8()); - const auto b = CheckPlatform(brush, GetPlatformIdUtf8()); + const auto t = CheckPlatform(text_layout, GetPlatformId()); + const auto b = CheckPlatform(brush, GetPlatformId()); device_context_->DrawTextLayout(Convert(offset), t->GetComInterface(), b->GetD2DBrushInterface()); } void D2DDeviceContextPainter::DrawImage(const Point& offset, IImage* image) { CheckValidation(); - const auto i = CheckPlatform(image, GetPlatformIdUtf8()); + const auto i = CheckPlatform(image, GetPlatformId()); Microsoft::WRL::ComPtr device_context; diff --git a/src/platform/graphics/direct2d/TextLayout.cpp b/src/platform/graphics/direct2d/TextLayout.cpp index 7a2074ec..06bbcaa6 100644 --- a/src/platform/graphics/direct2d/TextLayout.cpp +++ b/src/platform/graphics/direct2d/TextLayout.cpp @@ -14,7 +14,7 @@ DWriteTextLayout::DWriteTextLayout(DirectGraphicsFactory* factory, std::shared_ptr font, String text) : DirectGraphicsResource(factory), text_(std::move(text)) { Expects(font); - font_ = CheckPlatform(font, GetPlatformIdUtf8()); + font_ = CheckPlatform(font, GetPlatformId()); ThrowIfFailed(factory->GetDWriteFactory()->CreateTextLayout( reinterpret_cast(text_.c_str()), @@ -39,7 +39,7 @@ std::shared_ptr DWriteTextLayout::GetFont() { } void DWriteTextLayout::SetFont(std::shared_ptr font) { - font_ = CheckPlatform(font, GetPlatformIdUtf8()); + font_ = CheckPlatform(font, GetPlatformId()); ThrowIfFailed(GetDirectFactory()->GetDWriteFactory()->CreateTextLayout( reinterpret_cast(text_.c_str()), static_cast(text_.size()), font_->GetComInterface(), max_width_, diff --git a/src/platform/graphics/quartz/Factory.cpp b/src/platform/graphics/quartz/Factory.cpp index 5d5b48b5..862c0966 100644 --- a/src/platform/graphics/quartz/Factory.cpp +++ b/src/platform/graphics/quartz/Factory.cpp @@ -33,7 +33,7 @@ std::unique_ptr QuartzGraphicsFactory::CreateFont(String font_family, std::unique_ptr QuartzGraphicsFactory::CreateTextLayout( std::shared_ptr font, String text) { - auto f = CheckPlatform(font, GetPlatformIdUtf8()); + auto f = CheckPlatform(font, GetPlatformId()); return std::make_unique(this, f, text); } diff --git a/src/platform/graphics/quartz/ImageFactory.cpp b/src/platform/graphics/quartz/ImageFactory.cpp index 62229bcb..2090828c 100644 --- a/src/platform/graphics/quartz/ImageFactory.cpp +++ b/src/platform/graphics/quartz/ImageFactory.cpp @@ -49,7 +49,7 @@ void QuartzImageFactory::EncodeToStream(IImage* image, io::Stream* stream, throw Exception("Invalid quality value."); } - auto quartz_image = CheckPlatform(image, GetPlatformIdUtf8()); + auto quartz_image = CheckPlatform(image, GetPlatformId()); auto cg_image = quartz_image->GetCGImage(); auto uti = ToCFString(GetImageFormatUniformTypeIdentifier(format)); diff --git a/src/platform/graphics/quartz/Painter.cpp b/src/platform/graphics/quartz/Painter.cpp index fe0f5d43..45dee716 100644 --- a/src/platform/graphics/quartz/Painter.cpp +++ b/src/platform/graphics/quartz/Painter.cpp @@ -66,7 +66,7 @@ void QuartzCGContextPainter::DrawLine(const Point& start, const Point& end, CGContextMoveToPoint(cg_context_, start.x, start.y); CGContextAddLineToPoint(cg_context_, end.x, end.y); - QuartzBrush* b = CheckPlatform(brush, GetPlatformIdUtf8()); + QuartzBrush* b = CheckPlatform(brush, GetPlatformId()); b->Select(cg_context_); SetLineWidth(width); @@ -77,7 +77,7 @@ void QuartzCGContextPainter::StrokeRectangle(const Rect& rectangle, IBrush* brush, float width) { Validate(); - QuartzBrush* b = CheckPlatform(brush, GetPlatformIdUtf8()); + QuartzBrush* b = CheckPlatform(brush, GetPlatformId()); b->Select(cg_context_); CGContextStrokeRectWithWidth(cg_context_, Convert(rectangle), width); } @@ -86,7 +86,7 @@ void QuartzCGContextPainter::FillRectangle(const Rect& rectangle, IBrush* brush) { Validate(); - QuartzBrush* b = CheckPlatform(brush, GetPlatformIdUtf8()); + QuartzBrush* b = CheckPlatform(brush, GetPlatformId()); b->Select(cg_context_); CGContextFillRect(cg_context_, Convert(rectangle)); } @@ -95,7 +95,7 @@ void QuartzCGContextPainter::StrokeEllipse(const Rect& outline_rect, IBrush* brush, float width) { Validate(); - QuartzBrush* b = CheckPlatform(brush, GetPlatformIdUtf8()); + QuartzBrush* b = CheckPlatform(brush, GetPlatformId()); b->Select(cg_context_); SetLineWidth(width); @@ -106,7 +106,7 @@ void QuartzCGContextPainter::FillEllipse(const Rect& outline_rect, IBrush* brush) { Validate(); - QuartzBrush* b = CheckPlatform(brush, GetPlatformIdUtf8()); + QuartzBrush* b = CheckPlatform(brush, GetPlatformId()); b->Select(cg_context_); CGContextFillEllipseInRect(cg_context_, Convert(outline_rect)); } @@ -115,8 +115,8 @@ void QuartzCGContextPainter::StrokeGeometry(IGeometry* geometry, IBrush* brush, float width) { Validate(); - QuartzGeometry* g = CheckPlatform(geometry, GetPlatformIdUtf8()); - QuartzBrush* b = CheckPlatform(brush, GetPlatformIdUtf8()); + QuartzGeometry* g = CheckPlatform(geometry, GetPlatformId()); + QuartzBrush* b = CheckPlatform(brush, GetPlatformId()); b->Select(cg_context_); SetLineWidth(width); @@ -129,8 +129,8 @@ void QuartzCGContextPainter::StrokeGeometry(IGeometry* geometry, IBrush* brush, void QuartzCGContextPainter::FillGeometry(IGeometry* geometry, IBrush* brush) { Validate(); - QuartzGeometry* g = CheckPlatform(geometry, GetPlatformIdUtf8()); - QuartzBrush* b = CheckPlatform(brush, GetPlatformIdUtf8()); + QuartzGeometry* g = CheckPlatform(geometry, GetPlatformId()); + QuartzBrush* b = CheckPlatform(brush, GetPlatformId()); b->Select(cg_context_); CGContextBeginPath(cg_context_); @@ -142,7 +142,7 @@ void QuartzCGContextPainter::DrawText(const Point& offset, ITextLayout* text_layout, IBrush* brush) { Validate(); - auto tl = CheckPlatform(text_layout, GetPlatformIdUtf8()); + auto tl = CheckPlatform(text_layout, GetPlatformId()); Color color; @@ -169,7 +169,7 @@ void QuartzCGContextPainter::DrawText(const Point& offset, void QuartzCGContextPainter::DrawImage(const Point& offset, IImage* image) { Validate(); - auto i = CheckPlatform(image, GetPlatformIdUtf8()); + auto i = CheckPlatform(image, GetPlatformId()); auto cg_image = i->GetCGImage(); diff --git a/src/platform/graphics/quartz/TextLayout.cpp b/src/platform/graphics/quartz/TextLayout.cpp index 41a2f176..8c573c7a 100644 --- a/src/platform/graphics/quartz/TextLayout.cpp +++ b/src/platform/graphics/quartz/TextLayout.cpp @@ -31,7 +31,7 @@ OsxCTTextLayout::~OsxCTTextLayout() { } void OsxCTTextLayout::SetFont(std::shared_ptr font) { - font_ = CheckPlatform(font, GetPlatformIdUtf8()); + font_ = CheckPlatform(font, GetPlatformId()); RecreateFrame(); } diff --git a/src/platform/graphics/web_canvas/Painter.cpp b/src/platform/graphics/web_canvas/Painter.cpp index f928de35..c9184165 100644 --- a/src/platform/graphics/web_canvas/Painter.cpp +++ b/src/platform/graphics/web_canvas/Painter.cpp @@ -94,7 +94,7 @@ void WebCanvasPainter::SetFillStyle(IBrush* brush) { } WebCanvasBrush* WebCanvasPainter::ConvertBrush(IBrush* brush) const { - return CheckPlatform(brush, GetPlatformIdUtf8()); + return CheckPlatform(brush, GetPlatformId()); } WebCanvasRef WebCanvasPainter::GetCanvas() { diff --git a/src/platform/gui/CMakeLists.txt b/src/platform/gui/CMakeLists.txt index b541428e..70ae62f9 100644 --- a/src/platform/gui/CMakeLists.txt +++ b/src/platform/gui/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(CruPlatformGui - Keyboard.cpp + Input.cpp Menu.cpp UiApplication.cpp Window.cpp diff --git a/src/platform/gui/Input.cpp b/src/platform/gui/Input.cpp new file mode 100644 index 00000000..a5e25dc8 --- /dev/null +++ b/src/platform/gui/Input.cpp @@ -0,0 +1,140 @@ +#include "cru/platform/gui/Input.h" + +#include +#include +#include + +namespace cru::platform::gui { +const std::array(KeyCode::NumPad9) + 1> + key_code_string_list{"Unknown", + "LeftButton", + "MiddleButton", + "RightButton", + "Escape", + "F1", + "F2", + "F3", + "F4", + "F5", + "F6", + "F7", + "F8", + "F9", + "F10", + "F11", + "F12", + "N0", + "N1", + "N2", + "N3", + "N4", + "N5", + "N6", + "N7", + "N8", + "N9", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "GraveAccent", + "Tab", + "CapsLock", + "LeftShift", + "LeftCtrl", + "LeftSuper", + "LeftAlt", + "Minus", + "Equal", + "Backspace", + "LeftSquareBracket", + "RightSquareBracket", + "BackSlash", + "Semicolon", + "Quote", + "Comma", + "Period", + "Slash", + "RightShift", + "RightCtrl", + "RightSuper", + "RightAlt", + "Insert", + "Delete", + "Home", + "End", + "PageUp", + "PageDown", + "Up", + "Left", + "Down", + "Right", + "PrintScreen", + "ScrollLock", + "Pause", + "NumPad0", + "NumPad1", + "NumPad2", + "NumPad3", + "NumPad4", + "NumPad5", + "NumPad6", + "NumPad7", + "NumPad8", + "NumPad9"}; + +std::string ToString(KeyCode key_code) { + if (static_cast(key_code) < 0 || + static_cast(key_code) >= + static_cast(key_code_string_list.size())) + return "UNKNOWN_KEYCODENAME"; + + return std::string(key_code_string_list[static_cast(key_code)]); +} + +std::string ToString(KeyModifier key_modifier, std::string_view separator) { + std::vector list; + if (key_modifier & KeyModifiers::Shift) { + list.push_back("Shift"); + } + + if (key_modifier & KeyModifiers::Ctrl) { + list.push_back("Ctrl"); + } + + if (key_modifier & KeyModifiers::Alt) { + list.push_back("Shift"); + } + + if (list.empty()) return ""; + std::string result = list.front(); + for (auto iter = list.cbegin() + 1; iter != list.cend(); ++iter) { + result += separator; + result += *iter; + } + + return result; +} +} // namespace cru::platform::gui diff --git a/src/platform/gui/Keyboard.cpp b/src/platform/gui/Keyboard.cpp deleted file mode 100644 index 775995c2..00000000 --- a/src/platform/gui/Keyboard.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include "cru/platform/gui/Keyboard.h" - -#include -#include -#include - -namespace cru::platform::gui { -const std::array(KeyCode::NumPad9) + 1> - key_code_string_list{u"Unknown", - u"LeftButton", - u"MiddleButton", - u"RightButton", - u"Escape", - u"F1", - u"F2", - u"F3", - u"F4", - u"F5", - u"F6", - u"F7", - u"F8", - u"F9", - u"F10", - u"F11", - u"F12", - u"N0", - u"N1", - u"N2", - u"N3", - u"N4", - u"N5", - u"N6", - u"N7", - u"N8", - u"N9", - u"A", - u"B", - u"C", - u"D", - u"E", - u"F", - u"G", - u"H", - u"I", - u"J", - u"K", - u"L", - u"M", - u"N", - u"O", - u"P", - u"Q", - u"R", - u"S", - u"T", - u"U", - u"V", - u"W", - u"X", - u"Y", - u"Z", - u"GraveAccent", - u"Tab", - u"CapsLock", - u"LeftShift", - u"LeftCtrl", - u"LeftSuper", - u"LeftAlt", - u"Minus", - u"Equal", - u"Backspace", - u"LeftSquareBracket", - u"RightSquareBracket", - u"BackSlash", - u"Semicolon", - u"Quote", - u"Comma", - u"Period", - u"Slash", - u"RightShift", - u"RightCtrl", - u"RightSuper", - u"RightAlt", - u"Insert", - u"Delete", - u"Home", - u"End", - u"PageUp", - u"PageDown", - u"Up", - u"Left", - u"Down", - u"Right", - u"PrintScreen", - u"ScrollLock", - u"Pause", - u"NumPad0", - u"NumPad1", - u"NumPad2", - u"NumPad3", - u"NumPad4", - u"NumPad5", - u"NumPad6", - u"NumPad7", - u"NumPad8", - u"NumPad9"}; - -String ToString(KeyCode key_code) { - if (static_cast(key_code) < 0 || - static_cast(key_code) >= - static_cast(key_code_string_list.size())) - return u"UNKNOWN_KEYCODENAME"; - - return key_code_string_list[static_cast(key_code)].ToString(); -} - -String ToString(KeyModifier key_modifier, StringView separator) { - std::vector list; - if (key_modifier & KeyModifiers::shift) { - list.push_back(u"Shift"); - } - - if (key_modifier & KeyModifiers::ctrl) { - list.push_back(u"Ctrl"); - } - - if (key_modifier & KeyModifiers::alt) { - list.push_back(u"Shift"); - } - - if (list.empty()) return u""; - String result = list.front(); - for (auto iter = list.cbegin() + 1; iter != list.cend(); ++iter) { - result += separator; - result += *iter; - } - - return result; -} -} // namespace cru::platform::gui diff --git a/src/platform/gui/UiApplication.cpp b/src/platform/gui/UiApplication.cpp index ac93a57d..086440c0 100644 --- a/src/platform/gui/UiApplication.cpp +++ b/src/platform/gui/UiApplication.cpp @@ -1,5 +1,6 @@ #include "cru/platform/gui/UiApplication.h" +#include "cru/base/Base.h" #include "cru/base/Exception.h" namespace cru::platform::gui { @@ -22,13 +23,13 @@ IUiApplication::~IUiApplication() { instance = nullptr; } IMenu* IUiApplication::GetApplicationMenu() { return nullptr; } -std::optional IUiApplication::ShowSaveDialog( +std::optional IUiApplication::ShowSaveDialog( SaveDialogOptions options) { - throw Exception("Not implemented."); + NotImplemented(); } -std::optional> IUiApplication::ShowOpenDialog( +std::optional> IUiApplication::ShowOpenDialog( OpenDialogOptions options) { - throw Exception("Not implemented."); + NotImplemented(); } } // namespace cru::platform::gui diff --git a/src/platform/gui/osx/Window.mm b/src/platform/gui/osx/Window.mm index 7381ca55..6559cf70 100644 --- a/src/platform/gui/osx/Window.mm +++ b/src/platform/gui/osx/Window.mm @@ -64,7 +64,7 @@ void OsxWindowPrivate::OnWindowWillClose() { bool quit = true; for (auto window : all_window) { - auto w = CheckPlatform(window, osx_window_->GetPlatformIdUtf8()); + auto w = CheckPlatform(window, osx_window_->GetPlatformId()); if (w->p_->window_) { quit = false; break; @@ -179,7 +179,7 @@ void OsxWindowPrivate::CreateWindow() { [window_ setDelegate:window_delegate_]; if (parent_) { - auto parent = CheckPlatform(parent_, this->osx_window_->GetPlatformIdUtf8()); + auto parent = CheckPlatform(parent_, this->osx_window_->GetPlatformId()); [window_ setParentWindow:parent->p_->window_]; } @@ -231,7 +231,7 @@ void OsxWindow::Close() { INativeWindow* OsxWindow::GetParent() { return p_->parent_; } void OsxWindow::SetParent(INativeWindow* parent) { - auto p = CheckPlatform(parent, GetPlatformIdUtf8()); + auto p = CheckPlatform(parent, GetPlatformId()); p_->parent_ = parent; @@ -366,7 +366,7 @@ bool OsxWindow::CaptureMouse() { return true; } bool OsxWindow::ReleaseMouse() { return true; } void OsxWindow::SetCursor(std::shared_ptr cursor) { - p_->cursor_ = CheckPlatform(cursor, GetPlatformIdUtf8()); + p_->cursor_ = CheckPlatform(cursor, GetPlatformId()); p_->UpdateCursor(); } diff --git a/src/platform/gui/sdl/Window.cpp b/src/platform/gui/sdl/Window.cpp index e802b82f..84cf0ad4 100644 --- a/src/platform/gui/sdl/Window.cpp +++ b/src/platform/gui/sdl/Window.cpp @@ -35,7 +35,7 @@ void SdlWindow::Close() { INativeWindow *SdlWindow::GetParent() { return parent_; } void SdlWindow::SetParent(INativeWindow *parent) { - parent_ = CheckPlatform(parent, GetPlatformIdUtf8()); + parent_ = CheckPlatform(parent, GetPlatformId()); NotImplemented(); } @@ -46,9 +46,9 @@ void SdlWindow::SetStyleFlag(WindowStyleFlag flag) { NotImplemented(); } -String SdlWindow::GetTitle() { NotImplemented(); } +std::string SdlWindow::GetTitle() { NotImplemented(); } -void SdlWindow::SetTitle(String title) { NotImplemented(); } +void SdlWindow::SetTitle(std::string title) { NotImplemented(); } WindowVisibilityType SdlWindow::GetVisibility() { NotImplemented(); } diff --git a/src/platform/gui/win/Window.cpp b/src/platform/gui/win/Window.cpp index 5739d0f3..eeb2cde4 100644 --- a/src/platform/gui/win/Window.cpp +++ b/src/platform/gui/win/Window.cpp @@ -79,7 +79,7 @@ void WinNativeWindow::Close() { } void WinNativeWindow::SetParent(INativeWindow* parent) { - auto p = CheckPlatform(parent, GetPlatformIdUtf8()); + auto p = CheckPlatform(parent, GetPlatformId()); parent_window_ = p; if (hwnd_) { @@ -228,7 +228,7 @@ void WinNativeWindow::SetCursor(std::shared_ptr cursor) { throw std::runtime_error("Can't use a nullptr as cursor."); } - cursor_ = CheckPlatform(cursor, GetPlatformIdUtf8()); + cursor_ = CheckPlatform(cursor, GetPlatformId()); if (hwnd_) return; diff --git a/src/platform/gui/xcb/CMakeLists.txt b/src/platform/gui/xcb/CMakeLists.txt index cafc2e67..676fc7b1 100644 --- a/src/platform/gui/xcb/CMakeLists.txt +++ b/src/platform/gui/xcb/CMakeLists.txt @@ -6,8 +6,8 @@ find_library(LIBRARY_XKBCOMMON_X11 xkbcommon-x11 REQUIRED) add_library(CruPlatformGuiXcb Clipboard.cpp Cursor.cpp + Input.cpp InputMethod.cpp - Keyboard.cpp UiApplication.cpp Window.cpp ) diff --git a/src/platform/gui/xcb/Clipboard.cpp b/src/platform/gui/xcb/Clipboard.cpp index d0d9d74f..a42130ab 100644 --- a/src/platform/gui/xcb/Clipboard.cpp +++ b/src/platform/gui/xcb/Clipboard.cpp @@ -7,7 +7,7 @@ XcbClipboard::XcbClipboard(XcbUiApplication* application) XcbClipboard::~XcbClipboard() {} -String XcbClipboard::GetText() { return String{}; } +std::string XcbClipboard::GetText() { return {}; } -void XcbClipboard::SetText(String text) {} +void XcbClipboard::SetText(std::string text) {} } // namespace cru::platform::gui::xcb diff --git a/src/platform/gui/xcb/Cursor.cpp b/src/platform/gui/xcb/Cursor.cpp index 5582c6a6..69d904df 100644 --- a/src/platform/gui/xcb/Cursor.cpp +++ b/src/platform/gui/xcb/Cursor.cpp @@ -1,6 +1,5 @@ #include "cru/platform/gui/xcb/Cursor.h" #include "cru/base/Exception.h" -#include "cru/platform/gui/Cursor.h" #include "cru/platform/gui/xcb/UiApplication.h" #include diff --git a/src/platform/gui/xcb/Input.cpp b/src/platform/gui/xcb/Input.cpp new file mode 100644 index 00000000..9b6d76c2 --- /dev/null +++ b/src/platform/gui/xcb/Input.cpp @@ -0,0 +1,279 @@ +#include "cru/platform/gui/xcb/Input.h" +#include "cru/base/Exception.h" +#include "cru/base/Guard.h" +#include "cru/platform/gui/xcb/UiApplication.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace cru::platform::gui::xcb { +// Refer to +// https://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html#keysym_encoding +KeyCode XorgKeysymToCruKeyCode(xcb_keysym_t keysym) { + if (keysym >= 'A' && keysym <= 'Z') { + return KeyCode(static_cast(KeyCode::A) + (keysym - 'A')); + } + + if (keysym >= 'a' && keysym <= 'z') { + return KeyCode(static_cast(KeyCode::A) + (keysym - 'a')); + } + + if (keysym >= '0' && keysym <= '9') { + return KeyCode(static_cast(KeyCode::N0) + (keysym - '0')); + } + + if (keysym >= 0xFFB0 && keysym <= 0xFFB9) { + return KeyCode(static_cast(KeyCode::NumPad0) + (keysym - 0xFFB0)); + } + + if (keysym >= 0xFFBE && keysym <= 0xFFC9) { + return KeyCode(static_cast(KeyCode::F1) + (keysym - 0xFFBE)); + } + + switch (keysym) { +#define CRU_DEFINE_KEYCODE_MAP(keysym, cru) \ + case keysym: \ + return cru; + + CRU_DEFINE_KEYCODE_MAP(',', KeyCode::Comma) + CRU_DEFINE_KEYCODE_MAP('.', KeyCode::Period) + CRU_DEFINE_KEYCODE_MAP('/', KeyCode::Slash) + CRU_DEFINE_KEYCODE_MAP(';', KeyCode::Semicolon) + CRU_DEFINE_KEYCODE_MAP('\'', KeyCode::Quote) + CRU_DEFINE_KEYCODE_MAP('{', KeyCode::LeftSquareBracket) + CRU_DEFINE_KEYCODE_MAP('}', KeyCode::RightSquareBracket) + CRU_DEFINE_KEYCODE_MAP('-', KeyCode::Minus) + CRU_DEFINE_KEYCODE_MAP('=', KeyCode::Equal) + CRU_DEFINE_KEYCODE_MAP('\\', KeyCode::BackSlash) + CRU_DEFINE_KEYCODE_MAP(0xFF1B, KeyCode::Escape) + CRU_DEFINE_KEYCODE_MAP(0xFF09, KeyCode::Tab) + CRU_DEFINE_KEYCODE_MAP(0xFFE5, KeyCode::CapsLock) + CRU_DEFINE_KEYCODE_MAP(0xFFE1, KeyCode::LeftShift) + CRU_DEFINE_KEYCODE_MAP(0xFFE2, KeyCode::RightShift) + CRU_DEFINE_KEYCODE_MAP(0xFFE3, KeyCode::LeftCtrl) + CRU_DEFINE_KEYCODE_MAP(0xFFE4, KeyCode::RightCtrl) + CRU_DEFINE_KEYCODE_MAP(0xFFE9, KeyCode::LeftAlt) + CRU_DEFINE_KEYCODE_MAP(0xFFEA, KeyCode::RightAlt) + CRU_DEFINE_KEYCODE_MAP(0xFF08, KeyCode::Backspace) + CRU_DEFINE_KEYCODE_MAP(0xFF0D, KeyCode::Return) + CRU_DEFINE_KEYCODE_MAP(0xFFFF, KeyCode::Delete) + CRU_DEFINE_KEYCODE_MAP(0xFF50, KeyCode::Home) + CRU_DEFINE_KEYCODE_MAP(0xFF57, KeyCode::End) + CRU_DEFINE_KEYCODE_MAP(0xFF55, KeyCode::PageUp) + CRU_DEFINE_KEYCODE_MAP(0xFF56, KeyCode::PageDown) + CRU_DEFINE_KEYCODE_MAP(0xFF51, KeyCode::Left) + CRU_DEFINE_KEYCODE_MAP(0xFF53, KeyCode::Right) + CRU_DEFINE_KEYCODE_MAP(0xFF52, KeyCode::Up) + CRU_DEFINE_KEYCODE_MAP(0xFF54, KeyCode::Down) + CRU_DEFINE_KEYCODE_MAP(' ', KeyCode::Space) + default: + return KeyCode::Unknown; + } +} + +std::vector XorgKeycodeToKeysyms(XcbUiApplication *application, + xcb_keycode_t keycode) { + auto connection = application->GetXcbConnection(); + auto setup = xcb_get_setup(connection); + auto min_keycode = setup->min_keycode; + auto max_keycode = setup->max_keycode; + + // Get keyboard mapping + auto mapping_cookie = xcb_get_keyboard_mapping(connection, keycode, 1); + auto mapping_reply = FreeLater( + xcb_get_keyboard_mapping_reply(connection, mapping_cookie, NULL)); + + if (!mapping_reply) { + throw XcbException("Cannot get keyboard mapping."); + } + + auto keysyms_per_keycode = mapping_reply->keysyms_per_keycode; + auto *keysyms = xcb_get_keyboard_mapping_keysyms(mapping_reply); + + std::vector result; + for (int i = 0; i < keysyms_per_keycode; i++) { + result.push_back(keysyms[i]); + } + return result; +} + +KeyCode XorgKeycodeToCruKeyCode(XcbUiApplication *application, + xcb_keycode_t keycode) { + auto keysyms = XorgKeycodeToKeysyms(application, keycode); + + for (auto keysym : keysyms) { + auto result = XorgKeysymToCruKeyCode(keysym); + if (result != KeyCode::Unknown) return result; + } + + return KeyCode::Unknown; +} + +namespace { +using KeymapBitset = + std::bitset().keys) * + CHAR_BIT>; + +KeymapBitset GetXorgKeymap(xcb_connection_t *connection) { + auto keymap_cookie = xcb_query_keymap(connection); + auto keymap_reply = + FreeLater(xcb_query_keymap_reply(connection, keymap_cookie, NULL)); + + if (!keymap_reply) { + throw XcbException("Cannot get keymap."); + } + + KeymapBitset result; + int counter = 0; + for (auto member : keymap_reply->keys) { + for (int i = 0; i < sizeof(member); i++) { + result[counter] = member & (1 << i); + counter++; + } + } + + return result; +} +} // namespace + +std::unordered_map GetKeyboardState( + XcbUiApplication *application) { + auto connection = application->GetXcbConnection(); + auto setup = xcb_get_setup(connection); + auto min_keycode = setup->min_keycode; + auto max_keycode = setup->max_keycode; + + // Get keyboard mapping + auto mapping_cookie = xcb_get_keyboard_mapping(connection, min_keycode, + max_keycode - min_keycode + 1); + auto mapping_reply = FreeLater( + xcb_get_keyboard_mapping_reply(connection, mapping_cookie, NULL)); + + if (!mapping_reply) { + throw XcbException("Cannot get keyboard mapping."); + } + + auto keysyms_per_keycode = mapping_reply->keysyms_per_keycode; + auto *keysyms = xcb_get_keyboard_mapping_keysyms(mapping_reply); + + auto keymap = GetXorgKeymap(connection); + + std::unordered_map result; + + for (xcb_keycode_t i = min_keycode; i <= max_keycode; i++) { + auto keysyms_for_this = keysyms + (i - min_keycode) * keysyms_per_keycode; + for (int j = 0; j < keysyms_per_keycode; j++) { + auto keycode = XorgKeysymToCruKeyCode(keysyms_for_this[j]); + if (keycode != KeyCode::Unknown) { + result[keycode] = keymap[i]; + } + } + } + + return result; +} + +// Though X provides GetModifierMapping, it cannot get ALT state. +KeyModifier GetCurrentKeyModifiers(XcbUiApplication *application) { + KeyModifier result{}; + auto state = GetKeyboardState(application); + if (state[KeyCode::LeftShift] || state[KeyCode::RightShift]) { + result |= KeyModifiers::Shift; + } + if (state[KeyCode::LeftCtrl] || state[KeyCode::RightCtrl]) { + result |= KeyModifiers::Ctrl; + } + if (state[KeyCode::LeftAlt] || state[KeyCode::RightAlt]) { + result |= KeyModifiers::Alt; + } + return result; +} + +KeyModifier ConvertModifiersOfEvent(uint32_t mask) { + // const char *MODIFIERS[] = { + // "Shift", "Lock", "Ctrl", "Alt", "Mod2", "Mod3", "Mod4", + // "Mod5", "Button1", "Button2", "Button3", "Button4", "Button5"}; + constexpr KeyModifier MODIFIERS[] = { + KeyModifiers::Shift, KeyModifiers::None, KeyModifiers::Ctrl, + KeyModifiers::Alt, KeyModifiers::None, KeyModifiers::None, + KeyModifiers::None, KeyModifiers::None, KeyModifiers::None, + KeyModifiers::None, KeyModifiers::None, KeyModifiers::None, + KeyModifiers::None, + }; + + KeyModifier result; + for (auto iter = std::begin(MODIFIERS); mask; mask >>= 1, ++iter) { + if (mask & 1) { + result |= *iter; + } + } + return result; +} + +XcbKeyboardManager::XcbKeyboardManager(XcbUiApplication *application) + : application_(application) { + xkb_x11_setup_xkb_extension( + application->GetXcbConnection(), XKB_X11_MIN_MAJOR_XKB_VERSION, + XKB_X11_MIN_MINOR_XKB_VERSION, XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, + nullptr, nullptr, nullptr, nullptr); + + xkb_context_ = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if (!xkb_context_) { + throw PlatformException("Failed to call xkb_context_new."); + } + + auto device_id = + xkb_x11_get_core_keyboard_device_id(application->GetXcbConnection()); + if (device_id == -1) { + throw PlatformException( + "Failed to call xkb_x11_get_core_keyboard_device_id."); + } + + xkb_keymap_ = xkb_x11_keymap_new_from_device( + xkb_context_, application->GetXcbConnection(), device_id, + XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!xkb_keymap_) { + throw PlatformException("Failed to call xkb_x11_keymap_new_from_device."); + } + + xkb_state_ = xkb_x11_state_new_from_device( + xkb_keymap_, application->GetXcbConnection(), device_id); + if (!xkb_state_) { + throw PlatformException("Failed to call xkb_x11_state_new_from_device."); + } +} + +XcbKeyboardManager::~XcbKeyboardManager() { + xkb_state_unref(xkb_state_); + xkb_keymap_unref(xkb_keymap_); + xkb_context_unref(xkb_context_); +} + +std::string XcbKeyboardManager::KeycodeToUtf8(xcb_keycode_t keycode) { + auto size = xkb_state_key_get_utf8(xkb_state_, keycode, NULL, 0); + if (size <= 0) { + return {}; + } + std::string buffer(size + 1, 0); + xkb_state_key_get_utf8(xkb_state_, keycode, buffer.data(), size + 1); + buffer.resize(size); + return buffer; +} + +std::string XcbKeyboardManager::KeysymToUtf8(xcb_keysym_t keysym) { + auto size = xkb_keysym_to_utf8(keysym, NULL, 0); + if (size <= 0) { + return {}; + } + std::string buffer(size + 1, 0); + xkb_keysym_to_utf8(keysym, buffer.data(), size + 1); + buffer.resize(size); + return buffer; +} + +} // namespace cru::platform::gui::xcb diff --git a/src/platform/gui/xcb/InputMethod.cpp b/src/platform/gui/xcb/InputMethod.cpp index 16d6b4bd..5ee06ab4 100644 --- a/src/platform/gui/xcb/InputMethod.cpp +++ b/src/platform/gui/xcb/InputMethod.cpp @@ -1,10 +1,7 @@ #include "cru/platform/gui/xcb/InputMethod.h" #include "cru/base/log/Logger.h" #include "cru/platform/Check.h" -#include "cru/platform/gui/InputMethod.h" -#include "cru/platform/gui/Keyboard.h" -#include "cru/platform/gui/Window.h" -#include "cru/platform/gui/xcb/Keyboard.h" +#include "cru/platform/gui/xcb/Input.h" #include "cru/platform/gui/xcb/UiApplication.h" #include "cru/platform/gui/xcb/Window.h" @@ -99,7 +96,7 @@ void XcbXimInputMethodManager::DispatchCommit(xcb_xim_t *im, xcb_xic_t ic, if (focus_context_) { focus_context_->composition_event_.Raise(nullptr); focus_context_->composition_end_event_.Raise(nullptr); - focus_context_->text_event_.Raise(String::FromUtf8(text)); + focus_context_->text_event_.Raise(std::move(text)); } } @@ -135,7 +132,7 @@ XcbXimInputMethodContext::XcbXimInputMethodContext( window->FocusEvent()->AddHandler([this, window](FocusChangeType type) { auto context = CheckPlatform( - window->GetInputMethodContext(), GetPlatformIdUtf8()); + window->GetInputMethodContext(), GetPlatformId()); if (type == FocusChangeType::Gain) { SetFocus(); } @@ -208,7 +205,7 @@ IEvent *XcbXimInputMethodContext::CompositionEvent() { return &composition_event_; } -IEvent *XcbXimInputMethodContext::TextEvent() { +IEvent *XcbXimInputMethodContext::TextEvent() { return &text_event_; } diff --git a/src/platform/gui/xcb/Keyboard.cpp b/src/platform/gui/xcb/Keyboard.cpp deleted file mode 100644 index 4bfc448c..00000000 --- a/src/platform/gui/xcb/Keyboard.cpp +++ /dev/null @@ -1,280 +0,0 @@ -#include "cru/platform/gui/xcb/Keyboard.h" -#include "cru/base/Exception.h" -#include "cru/base/Guard.h" -#include "cru/platform/gui/Keyboard.h" -#include "cru/platform/gui/xcb/UiApplication.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace cru::platform::gui::xcb { -// Refer to -// https://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html#keysym_encoding -KeyCode XorgKeysymToCruKeyCode(xcb_keysym_t keysym) { - if (keysym >= 'A' && keysym <= 'Z') { - return KeyCode(static_cast(KeyCode::A) + (keysym - 'A')); - } - - if (keysym >= 'a' && keysym <= 'z') { - return KeyCode(static_cast(KeyCode::A) + (keysym - 'a')); - } - - if (keysym >= '0' && keysym <= '9') { - return KeyCode(static_cast(KeyCode::N0) + (keysym - '0')); - } - - if (keysym >= 0xFFB0 && keysym <= 0xFFB9) { - return KeyCode(static_cast(KeyCode::NumPad0) + (keysym - 0xFFB0)); - } - - if (keysym >= 0xFFBE && keysym <= 0xFFC9) { - return KeyCode(static_cast(KeyCode::F1) + (keysym - 0xFFBE)); - } - - switch (keysym) { -#define CRU_DEFINE_KEYCODE_MAP(keysym, cru) \ - case keysym: \ - return cru; - - CRU_DEFINE_KEYCODE_MAP(',', KeyCode::Comma) - CRU_DEFINE_KEYCODE_MAP('.', KeyCode::Period) - CRU_DEFINE_KEYCODE_MAP('/', KeyCode::Slash) - CRU_DEFINE_KEYCODE_MAP(';', KeyCode::Semicolon) - CRU_DEFINE_KEYCODE_MAP('\'', KeyCode::Quote) - CRU_DEFINE_KEYCODE_MAP('{', KeyCode::LeftSquareBracket) - CRU_DEFINE_KEYCODE_MAP('}', KeyCode::RightSquareBracket) - CRU_DEFINE_KEYCODE_MAP('-', KeyCode::Minus) - CRU_DEFINE_KEYCODE_MAP('=', KeyCode::Equal) - CRU_DEFINE_KEYCODE_MAP('\\', KeyCode::BackSlash) - CRU_DEFINE_KEYCODE_MAP(0xFF1B, KeyCode::Escape) - CRU_DEFINE_KEYCODE_MAP(0xFF09, KeyCode::Tab) - CRU_DEFINE_KEYCODE_MAP(0xFFE5, KeyCode::CapsLock) - CRU_DEFINE_KEYCODE_MAP(0xFFE1, KeyCode::LeftShift) - CRU_DEFINE_KEYCODE_MAP(0xFFE2, KeyCode::RightShift) - CRU_DEFINE_KEYCODE_MAP(0xFFE3, KeyCode::LeftCtrl) - CRU_DEFINE_KEYCODE_MAP(0xFFE4, KeyCode::RightCtrl) - CRU_DEFINE_KEYCODE_MAP(0xFFE9, KeyCode::LeftAlt) - CRU_DEFINE_KEYCODE_MAP(0xFFEA, KeyCode::RightAlt) - CRU_DEFINE_KEYCODE_MAP(0xFF08, KeyCode::Backspace) - CRU_DEFINE_KEYCODE_MAP(0xFF0D, KeyCode::Return) - CRU_DEFINE_KEYCODE_MAP(0xFFFF, KeyCode::Delete) - CRU_DEFINE_KEYCODE_MAP(0xFF50, KeyCode::Home) - CRU_DEFINE_KEYCODE_MAP(0xFF57, KeyCode::End) - CRU_DEFINE_KEYCODE_MAP(0xFF55, KeyCode::PageUp) - CRU_DEFINE_KEYCODE_MAP(0xFF56, KeyCode::PageDown) - CRU_DEFINE_KEYCODE_MAP(0xFF51, KeyCode::Left) - CRU_DEFINE_KEYCODE_MAP(0xFF53, KeyCode::Right) - CRU_DEFINE_KEYCODE_MAP(0xFF52, KeyCode::Up) - CRU_DEFINE_KEYCODE_MAP(0xFF54, KeyCode::Down) - CRU_DEFINE_KEYCODE_MAP(' ', KeyCode::Space) - default: - return KeyCode::Unknown; - } -} - -std::vector XorgKeycodeToKeysyms(XcbUiApplication *application, - xcb_keycode_t keycode) { - auto connection = application->GetXcbConnection(); - auto setup = xcb_get_setup(connection); - auto min_keycode = setup->min_keycode; - auto max_keycode = setup->max_keycode; - - // Get keyboard mapping - auto mapping_cookie = xcb_get_keyboard_mapping(connection, keycode, 1); - auto mapping_reply = FreeLater( - xcb_get_keyboard_mapping_reply(connection, mapping_cookie, NULL)); - - if (!mapping_reply) { - throw XcbException("Cannot get keyboard mapping."); - } - - auto keysyms_per_keycode = mapping_reply->keysyms_per_keycode; - auto *keysyms = xcb_get_keyboard_mapping_keysyms(mapping_reply); - - std::vector result; - for (int i = 0; i < keysyms_per_keycode; i++) { - result.push_back(keysyms[i]); - } - return result; -} - -KeyCode XorgKeycodeToCruKeyCode(XcbUiApplication *application, - xcb_keycode_t keycode) { - auto keysyms = XorgKeycodeToKeysyms(application, keycode); - - for (auto keysym : keysyms) { - auto result = XorgKeysymToCruKeyCode(keysym); - if (result != KeyCode::Unknown) return result; - } - - return KeyCode::Unknown; -} - -namespace { -using KeymapBitset = - std::bitset().keys) * - CHAR_BIT>; - -KeymapBitset GetXorgKeymap(xcb_connection_t *connection) { - auto keymap_cookie = xcb_query_keymap(connection); - auto keymap_reply = - FreeLater(xcb_query_keymap_reply(connection, keymap_cookie, NULL)); - - if (!keymap_reply) { - throw XcbException("Cannot get keymap."); - } - - KeymapBitset result; - int counter = 0; - for (auto member : keymap_reply->keys) { - for (int i = 0; i < sizeof(member); i++) { - result[counter] = member & (1 << i); - counter++; - } - } - - return result; -} -} // namespace - -std::unordered_map GetKeyboardState( - XcbUiApplication *application) { - auto connection = application->GetXcbConnection(); - auto setup = xcb_get_setup(connection); - auto min_keycode = setup->min_keycode; - auto max_keycode = setup->max_keycode; - - // Get keyboard mapping - auto mapping_cookie = xcb_get_keyboard_mapping(connection, min_keycode, - max_keycode - min_keycode + 1); - auto mapping_reply = FreeLater( - xcb_get_keyboard_mapping_reply(connection, mapping_cookie, NULL)); - - if (!mapping_reply) { - throw XcbException("Cannot get keyboard mapping."); - } - - auto keysyms_per_keycode = mapping_reply->keysyms_per_keycode; - auto *keysyms = xcb_get_keyboard_mapping_keysyms(mapping_reply); - - auto keymap = GetXorgKeymap(connection); - - std::unordered_map result; - - for (xcb_keycode_t i = min_keycode; i <= max_keycode; i++) { - auto keysyms_for_this = keysyms + (i - min_keycode) * keysyms_per_keycode; - for (int j = 0; j < keysyms_per_keycode; j++) { - auto keycode = XorgKeysymToCruKeyCode(keysyms_for_this[j]); - if (keycode != KeyCode::Unknown) { - result[keycode] = keymap[i]; - } - } - } - - return result; -} - -// Though X provides GetModifierMapping, it cannot get ALT state. -KeyModifier GetCurrentKeyModifiers(XcbUiApplication *application) { - KeyModifier result{}; - auto state = GetKeyboardState(application); - if (state[KeyCode::LeftShift] || state[KeyCode::RightShift]) { - result |= KeyModifiers::Shift; - } - if (state[KeyCode::LeftCtrl] || state[KeyCode::RightCtrl]) { - result |= KeyModifiers::Ctrl; - } - if (state[KeyCode::LeftAlt] || state[KeyCode::RightAlt]) { - result |= KeyModifiers::Alt; - } - return result; -} - -KeyModifier ConvertModifiersOfEvent(uint32_t mask) { - // const char *MODIFIERS[] = { - // "Shift", "Lock", "Ctrl", "Alt", "Mod2", "Mod3", "Mod4", - // "Mod5", "Button1", "Button2", "Button3", "Button4", "Button5"}; - constexpr KeyModifier MODIFIERS[] = { - KeyModifiers::Shift, KeyModifiers::none, KeyModifiers::Ctrl, - KeyModifiers::Alt, KeyModifiers::none, KeyModifiers::none, - KeyModifiers::none, KeyModifiers::none, KeyModifiers::none, - KeyModifiers::none, KeyModifiers::none, KeyModifiers::none, - KeyModifiers::none, - }; - - KeyModifier result; - for (auto iter = std::begin(MODIFIERS); mask; mask >>= 1, ++iter) { - if (mask & 1) { - result |= *iter; - } - } - return result; -} - -XcbKeyboardManager::XcbKeyboardManager(XcbUiApplication *application) - : application_(application) { - xkb_x11_setup_xkb_extension( - application->GetXcbConnection(), XKB_X11_MIN_MAJOR_XKB_VERSION, - XKB_X11_MIN_MINOR_XKB_VERSION, XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, - nullptr, nullptr, nullptr, nullptr); - - xkb_context_ = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - if (!xkb_context_) { - throw PlatformException("Failed to call xkb_context_new."); - } - - auto device_id = - xkb_x11_get_core_keyboard_device_id(application->GetXcbConnection()); - if (device_id == -1) { - throw PlatformException( - "Failed to call xkb_x11_get_core_keyboard_device_id."); - } - - xkb_keymap_ = xkb_x11_keymap_new_from_device( - xkb_context_, application->GetXcbConnection(), device_id, - XKB_KEYMAP_COMPILE_NO_FLAGS); - if (!xkb_keymap_) { - throw PlatformException("Failed to call xkb_x11_keymap_new_from_device."); - } - - xkb_state_ = xkb_x11_state_new_from_device( - xkb_keymap_, application->GetXcbConnection(), device_id); - if (!xkb_state_) { - throw PlatformException("Failed to call xkb_x11_state_new_from_device."); - } -} - -XcbKeyboardManager::~XcbKeyboardManager() { - xkb_state_unref(xkb_state_); - xkb_keymap_unref(xkb_keymap_); - xkb_context_unref(xkb_context_); -} - -std::string XcbKeyboardManager::KeycodeToUtf8(xcb_keycode_t keycode) { - auto size = xkb_state_key_get_utf8(xkb_state_, keycode, NULL, 0); - if (size <= 0) { - return {}; - } - std::string buffer(size + 1, 0); - xkb_state_key_get_utf8(xkb_state_, keycode, buffer.data(), size + 1); - buffer.resize(size); - return buffer; -} - -std::string XcbKeyboardManager::KeysymToUtf8(xcb_keysym_t keysym) { - auto size = xkb_keysym_to_utf8(keysym, NULL, 0); - if (size <= 0) { - return {}; - } - std::string buffer(size + 1, 0); - xkb_keysym_to_utf8(keysym, buffer.data(), size + 1); - buffer.resize(size); - return buffer; -} - -} // namespace cru::platform::gui::xcb diff --git a/src/platform/gui/xcb/UiApplication.cpp b/src/platform/gui/xcb/UiApplication.cpp index a0a949b7..436bb335 100644 --- a/src/platform/gui/xcb/UiApplication.cpp +++ b/src/platform/gui/xcb/UiApplication.cpp @@ -1,13 +1,12 @@ #include "cru/platform/gui/xcb/UiApplication.h" -#include "cru/base/Base.h" #include "cru/base/Guard.h" #include "cru/platform/graphics/cairo/CairoGraphicsFactory.h" #include "cru/platform/gui/Window.h" #include "cru/platform/gui/xcb/Clipboard.h" #include "cru/platform/gui/xcb/Cursor.h" +#include "cru/platform/gui/xcb/Input.h" #include "cru/platform/gui/xcb/InputMethod.h" -#include "cru/platform/gui/xcb/Keyboard.h" #include "cru/platform/gui/xcb/Window.h" #include diff --git a/src/platform/gui/xcb/Window.cpp b/src/platform/gui/xcb/Window.cpp index 6458046b..003afc40 100644 --- a/src/platform/gui/xcb/Window.cpp +++ b/src/platform/gui/xcb/Window.cpp @@ -7,12 +7,9 @@ #include "cru/platform/graphics/NullPainter.h" #include "cru/platform/graphics/Painter.h" #include "cru/platform/graphics/cairo/CairoPainter.h" -#include "cru/platform/gui/Base.h" -#include "cru/platform/gui/Keyboard.h" -#include "cru/platform/gui/Window.h" #include "cru/platform/gui/xcb/Cursor.h" +#include "cru/platform/gui/xcb/Input.h" #include "cru/platform/gui/xcb/InputMethod.h" -#include "cru/platform/gui/xcb/Keyboard.h" #include "cru/platform/gui/xcb/UiApplication.h" #include @@ -73,7 +70,7 @@ void XcbWindow::Close() { INativeWindow *XcbWindow::GetParent() { return parent_; } void XcbWindow::SetParent(INativeWindow *parent) { - parent_ = CheckPlatform(parent, GetPlatformIdUtf8()); + parent_ = CheckPlatform(parent, GetPlatformId()); if (xcb_window_) { DoSetParent(*xcb_window_); } @@ -90,10 +87,10 @@ void XcbWindow::SetStyleFlag(WindowStyleFlag flag) { application_->XcbFlush(); } -String XcbWindow::GetTitle() { return String::FromUtf8(title_); } +std::string XcbWindow::GetTitle() { return title_; } -void XcbWindow::SetTitle(String title) { - title_ = title.ToUtf8(); +void XcbWindow::SetTitle(std::string title) { + title_ = std::move(title); if (xcb_window_) { DoSetTitle(*xcb_window_); } @@ -271,7 +268,7 @@ bool XcbWindow::ReleaseMouse() { void XcbWindow::SetCursor(std::shared_ptr cursor) { if (!xcb_window_) return; - auto xcb_cursor = CheckPlatform(cursor, GetPlatformIdUtf8()); + auto xcb_cursor = CheckPlatform(cursor, GetPlatformId()); cursor_ = xcb_cursor; DoSetCursor(*xcb_window_, xcb_cursor.get()); } -- cgit v1.2.3