aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/cru/base/Bitmask.h4
-rw-r--r--include/cru/base/StringToNumberConverter.h10
-rw-r--r--include/cru/platform/gui/Keyboard.h10
-rw-r--r--include/cru/platform/gui/xcb/InputMethod.h77
-rw-r--r--include/cru/platform/gui/xcb/UiApplication.h4
-rw-r--r--include/cru/platform/gui/xcb/Window.h4
6 files changed, 98 insertions, 11 deletions
diff --git a/include/cru/base/Bitmask.h b/include/cru/base/Bitmask.h
index 9b6b8957..7606f784 100644
--- a/include/cru/base/Bitmask.h
+++ b/include/cru/base/Bitmask.h
@@ -10,8 +10,10 @@ struct Bitmask final {
constexpr Bitmask() : value(0) {}
constexpr explicit Bitmask(TUnderlying value) : value(value) {}
+ // Start from 1.
static constexpr Bitmask FromOffset(int offset) {
- return Bitmask(static_cast<TUnderlying>(1u << offset));
+ if (offset == 0) return {};
+ return Bitmask(static_cast<TUnderlying>(1u << (offset - 1)));
}
constexpr bool Has(Bitmask rhs) const { return (value & rhs.value) != 0; }
diff --git a/include/cru/base/StringToNumberConverter.h b/include/cru/base/StringToNumberConverter.h
index 051f44d0..64c29971 100644
--- a/include/cru/base/StringToNumberConverter.h
+++ b/include/cru/base/StringToNumberConverter.h
@@ -14,15 +14,15 @@ using StringToNumberFlag = Bitmask<details::StringToNumberFlagTag>;
struct StringToNumberFlags {
constexpr static StringToNumberFlag kAllowLeadingSpaces =
- StringToNumberFlag::FromOffset(0);
- constexpr static StringToNumberFlag kAllowTrailingSpaces =
StringToNumberFlag::FromOffset(1);
- constexpr static StringToNumberFlag kAllowTrailingJunk =
+ constexpr static StringToNumberFlag kAllowTrailingSpaces =
StringToNumberFlag::FromOffset(2);
- constexpr static StringToNumberFlag kAllowLeadingZeroForInteger =
+ constexpr static StringToNumberFlag kAllowTrailingJunk =
StringToNumberFlag::FromOffset(3);
- constexpr static StringToNumberFlag kThrowOnError =
+ constexpr static StringToNumberFlag kAllowLeadingZeroForInteger =
StringToNumberFlag::FromOffset(4);
+ constexpr static StringToNumberFlag kThrowOnError =
+ StringToNumberFlag::FromOffset(5);
};
template <typename TResult>
diff --git a/include/cru/platform/gui/Keyboard.h b/include/cru/platform/gui/Keyboard.h
index eb1cc76e..97665e41 100644
--- a/include/cru/platform/gui/Keyboard.h
+++ b/include/cru/platform/gui/Keyboard.h
@@ -118,16 +118,16 @@ struct TagKeyModifier {};
using KeyModifier = Bitmask<details::TagKeyModifier>;
struct KeyModifiers {
- static constexpr KeyModifier none{0};
- static constexpr KeyModifier shift{0b1};
- static constexpr KeyModifier ctrl{0b10};
- static constexpr KeyModifier alt{0b100};
- static constexpr KeyModifier command{0b1000};
static constexpr KeyModifier None = KeyModifier::FromOffset(0);
static constexpr KeyModifier Shift = KeyModifier::FromOffset(1);
static constexpr KeyModifier Ctrl = KeyModifier::FromOffset(2);
static constexpr KeyModifier Alt = KeyModifier::FromOffset(3);
static constexpr KeyModifier Command = KeyModifier::FromOffset(4);
+ static constexpr KeyModifier none = None;
+ static constexpr KeyModifier shift = Shift;
+ static constexpr KeyModifier ctrl = Ctrl;
+ static constexpr KeyModifier alt = Alt;
+ static constexpr KeyModifier command = Command;
};
#ifdef CRU_PLATFORM_OSX
diff --git a/include/cru/platform/gui/xcb/InputMethod.h b/include/cru/platform/gui/xcb/InputMethod.h
new file mode 100644
index 00000000..286f3158
--- /dev/null
+++ b/include/cru/platform/gui/xcb/InputMethod.h
@@ -0,0 +1,77 @@
+#pragma once
+
+#include "../InputMethod.h"
+#include "Base.h"
+
+#include <xcb-imdkit/imclient.h>
+#include <xcb/xcb.h>
+#include <optional>
+
+namespace cru::platform::gui::xcb {
+class XcbUiApplication;
+class XcbWindow;
+
+class XcbXimInputMethodManager : public XcbResource {
+ friend XcbUiApplication;
+
+ public:
+ XcbXimInputMethodManager(XcbUiApplication* application);
+ ~XcbXimInputMethodManager() override;
+
+ xcb_xim_t* GetXcbXim();
+
+ private:
+ void DispatchCommit(xcb_xim_t* im, xcb_xic_t ic, std::string text);
+ void DispatchComposition(xcb_xim_t* im, xcb_xic_t ic, CompositionText text);
+
+ bool HandleXEvent(xcb_generic_event_t* event);
+
+ private:
+ XcbUiApplication* application_;
+ xcb_xim_t* im_;
+};
+
+class XcbXimInputMethodContext : public XcbResource,
+ public virtual IInputMethodContext {
+ friend XcbXimInputMethodManager;
+
+ public:
+ XcbXimInputMethodContext(XcbXimInputMethodManager* manager,
+ XcbWindow* window);
+ ~XcbXimInputMethodContext() override;
+
+ bool ShouldManuallyDrawCompositionText() override;
+
+ void EnableIME() override;
+ void DisableIME() override;
+
+ void CompleteComposition() override;
+ void CancelComposition() override;
+ CompositionText GetCompositionText() override;
+
+ // Set the candidate window left-top. Relative to window left-top. Use this
+ // method to prepare typing.
+ void SetCandidateWindowPosition(const Point& point) override;
+
+ IEvent<std::nullptr_t>* CompositionStartEvent() override;
+ IEvent<std::nullptr_t>* CompositionEndEvent() override;
+ IEvent<std::nullptr_t>* CompositionEvent() override;
+ IEvent<StringView>* TextEvent() override;
+
+ private:
+ void CreateIc(xcb_window_t window);
+ void DestroyIc();
+
+ private:
+ XcbXimInputMethodManager* manager_;
+ XcbWindow* window_;
+ bool enabled_;
+ std::optional<xcb_xic_t> ic_;
+ CompositionText composition_text_;
+
+ Event<std::nullptr_t> composition_start_event_;
+ Event<std::nullptr_t> composition_end_event_;
+ Event<std::nullptr_t> composition_event_;
+ Event<StringView> text_event_;
+};
+} // namespace cru::platform::gui::xcb
diff --git a/include/cru/platform/gui/xcb/UiApplication.h b/include/cru/platform/gui/xcb/UiApplication.h
index b8de86f2..d6971099 100644
--- a/include/cru/platform/gui/xcb/UiApplication.h
+++ b/include/cru/platform/gui/xcb/UiApplication.h
@@ -13,6 +13,7 @@
namespace cru::platform::gui::xcb {
class XcbWindow;
class XcbCursorManager;
+class XcbXimInputMethodManager;
class XcbUiApplication : public XcbResource, public virtual IUiApplication {
friend XcbWindow;
@@ -49,6 +50,8 @@ class XcbUiApplication : public XcbResource, public virtual IUiApplication {
#undef CRU_XCB_UI_APPLICATION_DEFINE_XCB_ATOM
+ XcbXimInputMethodManager* GetXcbXimInputMethodManager();
+
public:
int Run() override;
@@ -100,5 +103,6 @@ class XcbUiApplication : public XcbResource, public virtual IUiApplication {
std::vector<XcbWindow*> windows_;
XcbCursorManager* cursor_manager_;
+ XcbXimInputMethodManager* input_method_manager_;
};
} // namespace cru::platform::gui::xcb
diff --git a/include/cru/platform/gui/xcb/Window.h b/include/cru/platform/gui/xcb/Window.h
index 61e4b616..e330ba7c 100644
--- a/include/cru/platform/gui/xcb/Window.h
+++ b/include/cru/platform/gui/xcb/Window.h
@@ -12,6 +12,7 @@
namespace cru::platform::gui::xcb {
class XcbUiApplication;
class XcbCursor;
+class XcbXimInputMethodContext;
class XcbWindow : public XcbResource, public virtual INativeWindow {
friend XcbUiApplication;
@@ -79,6 +80,8 @@ class XcbWindow : public XcbResource, public virtual INativeWindow {
public:
std::optional<xcb_window_t> GetXcbWindow();
+ XcbUiApplication* GetXcbUiApplication();
+ bool HasFocus();
private:
xcb_window_t DoCreateWindow();
@@ -112,6 +115,7 @@ class XcbWindow : public XcbResource, public virtual INativeWindow {
std::shared_ptr<XcbCursor> cursor_;
XcbWindow* parent_;
+ XcbXimInputMethodContext* input_method_;
Event<std::nullptr_t> create_event_;
Event<std::nullptr_t> destroy_event_;