From 09d51dcd84b787326bdce08faaeed4a8fd1119c5 Mon Sep 17 00:00:00 2001 From: Daijiro Fukuda Date: Thu, 28 Apr 2022 15:15:27 +0900 Subject: [PATCH] Move new platform APIs to _GLFWplatform The following APIs should be generalized to _GLFWplatform. * _glfwPlatformResetPreeditText * _glfwPlatformSetIMEStatus * _glfwPlatformGetIMEStatus --- src/cocoa_init.m | 3 + src/cocoa_platform.h | 4 ++ src/cocoa_window.m | 130 +++++++++++++++++++++---------------------- src/input.c | 6 +- src/internal.h | 7 +-- src/null_init.c | 3 + src/null_platform.h | 4 ++ src/null_window.c | 13 +++++ src/win32_init.c | 3 + src/win32_platform.h | 4 ++ src/win32_window.c | 50 ++++++++--------- src/wl_init.c | 3 + src/wl_platform.h | 4 ++ src/wl_window.c | 13 +++++ src/x11_init.c | 3 + src/x11_platform.h | 4 ++ src/x11_window.c | 112 ++++++++++++++++++------------------- 17 files changed, 213 insertions(+), 153 deletions(-) diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 6bc6496a..e547859f 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -500,6 +500,9 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform) _glfwGetKeyScancodeCocoa, _glfwSetClipboardStringCocoa, _glfwGetClipboardStringCocoa, + _glfwResetPreeditTextCocoa, + _glfwSetIMEStatusCocoa, + _glfwGetIMEStatusCocoa, _glfwInitJoysticksCocoa, _glfwTerminateJoysticksCocoa, _glfwPollJoystickCocoa, diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 9259b195..9361de93 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -268,6 +268,10 @@ void _glfwSetCursorCocoa(_GLFWwindow* window, _GLFWcursor* cursor); void _glfwSetClipboardStringCocoa(const char* string); const char* _glfwGetClipboardStringCocoa(void); +void _glfwResetPreeditTextCocoa(_GLFWwindow* window); +void _glfwSetIMEStatusCocoa(_GLFWwindow* window, int active); +int _glfwGetIMEStatusCocoa(_GLFWwindow* window); + EGLenum _glfwGetEGLPlatformCocoa(EGLint** attribs); EGLNativeDisplayType _glfwGetEGLNativeDisplayCocoa(void); EGLNativeWindowType _glfwGetEGLNativeWindowCocoa(_GLFWwindow* window); diff --git a/src/cocoa_window.m b/src/cocoa_window.m index b37bd3c7..33576d65 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1858,6 +1858,71 @@ const char* _glfwGetClipboardStringCocoa(void) } // autoreleasepool } +void _glfwResetPreeditTextCocoa(_GLFWwindow* window) +{ + NSTextInputContext* context = [NSTextInputContext currentInputContext]; + [context discardMarkedText]; + [window->ns.view unmarkText]; +} + +void _glfwSetIMEStatusCocoa(_GLFWwindow* window, int active) +{ + // Mac OS has several input sources. + // this code assumes input methods not in ascii capable inputs using IME. + NSArray* asciiInputSources = + CFBridgingRelease(TISCreateASCIICapableInputSourceList()); + TISInputSourceRef asciiSource = + (__bridge TISInputSourceRef) [asciiInputSources firstObject]; + if (active) + { + NSArray* allInputSources = + CFBridgingRelease(TISCreateInputSourceList(NULL, false)); + NSString* asciiSourceID = + (__bridge NSString *) TISGetInputSourceProperty(asciiSource, + kTISPropertyInputSourceID); + int i; + int count = [allInputSources count]; + for (i = 0; i < count; i++) + { + TISInputSourceRef source = + (__bridge TISInputSourceRef) [allInputSources objectAtIndex:i]; + NSString* sourceID = + (__bridge NSString *) TISGetInputSourceProperty(source, + kTISPropertyInputSourceID); + if ([asciiSourceID compare:sourceID] != NSOrderedSame) + { + TISSelectInputSource(source); + break; + } + } + } + else if (asciiSource) + { + TISSelectInputSource(asciiSource); + } +} + +int _glfwGetIMEStatusCocoa(_GLFWwindow* window) +{ + TISInputSourceRef currentSource = TISCopyCurrentKeyboardInputSource(); + NSString* currentSourceID = + (__bridge NSString *) TISGetInputSourceProperty(currentSource, + kTISPropertyInputSourceID); + NSArray* asciiInputSources = + CFBridgingRelease(TISCreateASCIICapableInputSourceList()); + TISInputSourceRef asciiSource = + (__bridge TISInputSourceRef) [asciiInputSources firstObject]; + if (asciiSource) + { + NSString* asciiSourceID = + (__bridge NSString *) TISGetInputSourceProperty(asciiSource, + kTISPropertyInputSourceID); + return [asciiSourceID compare:currentSourceID] == NSOrderedSame + ? GLFW_FALSE : GLFW_TRUE; + } + return GLFW_FALSE; +} + EGLenum _glfwGetEGLPlatformCocoa(EGLint** attribs) { if (_glfw.egl.ANGLE_platform_angle) @@ -2011,71 +2076,6 @@ VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, } // autoreleasepool } -void _glfwPlatformResetPreeditText(_GLFWwindow* window) -{ - NSTextInputContext* context = [NSTextInputContext currentInputContext]; - [context discardMarkedText]; - [window->ns.view unmarkText]; -} - -void _glfwPlatformSetIMEStatus(_GLFWwindow* window, int active) -{ - // Mac OS has several input sources. - // this code assumes input methods not in ascii capable inputs using IME. - NSArray* asciiInputSources = - CFBridgingRelease(TISCreateASCIICapableInputSourceList()); - TISInputSourceRef asciiSource = - (__bridge TISInputSourceRef) [asciiInputSources firstObject]; - if (active) - { - NSArray* allInputSources = - CFBridgingRelease(TISCreateInputSourceList(NULL, false)); - NSString* asciiSourceID = - (__bridge NSString *) TISGetInputSourceProperty(asciiSource, - kTISPropertyInputSourceID); - int i; - int count = [allInputSources count]; - for (i = 0; i < count; i++) - { - TISInputSourceRef source = - (__bridge TISInputSourceRef) [allInputSources objectAtIndex:i]; - NSString* sourceID = - (__bridge NSString *) TISGetInputSourceProperty(source, - kTISPropertyInputSourceID); - if ([asciiSourceID compare:sourceID] != NSOrderedSame) - { - TISSelectInputSource(source); - break; - } - } - } - else if (asciiSource) - { - TISSelectInputSource(asciiSource); - } -} - -int _glfwPlatformGetIMEStatus(_GLFWwindow* window) -{ - TISInputSourceRef currentSource = TISCopyCurrentKeyboardInputSource(); - NSString* currentSourceID = - (__bridge NSString *) TISGetInputSourceProperty(currentSource, - kTISPropertyInputSourceID); - NSArray* asciiInputSources = - CFBridgingRelease(TISCreateASCIICapableInputSourceList()); - TISInputSourceRef asciiSource = - (__bridge TISInputSourceRef) [asciiInputSources firstObject]; - if (asciiSource) - { - NSString* asciiSourceID = - (__bridge NSString *) TISGetInputSourceProperty(asciiSource, - kTISPropertyInputSourceID); - return [asciiSourceID compare:currentSourceID] == NSOrderedSame - ? GLFW_FALSE : GLFW_TRUE; - } - return GLFW_FALSE; -} - ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// ////////////////////////////////////////////////////////////////////////// diff --git a/src/input.c b/src/input.c index 8743a86a..cbd15330 100644 --- a/src/input.c +++ b/src/input.c @@ -526,7 +526,7 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode) case GLFW_RAW_MOUSE_MOTION: return window->rawMouseMotion; case GLFW_IME: - return _glfwPlatformGetIMEStatus(window); + return _glfw.platform.getIMEStatus(window); } _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode); @@ -636,7 +636,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value) case GLFW_IME: { - _glfwPlatformSetIMEStatus(window, value ? GLFW_TRUE : GLFW_FALSE); + _glfw.platform.setIMEStatus(window, value ? GLFW_TRUE : GLFW_FALSE); return; } } @@ -915,7 +915,7 @@ GLFWAPI void glfwSetPreeditCursorPos(GLFWwindow* handle, int x, int y, int h) GLFWAPI void glfwResetPreeditText(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; - _glfwPlatformResetPreeditText(window); + _glfw.platform.resetPreeditText(window); } GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) diff --git a/src/internal.h b/src/internal.h index 15224c66..b23e4b98 100644 --- a/src/internal.h +++ b/src/internal.h @@ -699,6 +699,9 @@ struct _GLFWplatform int (*getKeyScancode)(int); void (*setClipboardString)(const char*); const char* (*getClipboardString)(void); + void (*resetPreeditText)(_GLFWwindow*); + void (*setIMEStatus)(_GLFWwindow*,int); + int (*getIMEStatus)(_GLFWwindow*); GLFWbool (*initJoysticks)(void); void (*terminateJoysticks)(void); int (*pollJoystick)(_GLFWjoystick*,int); @@ -953,10 +956,6 @@ void _glfwInputError(int code, const char* format, ...) void _glfwInputError(int code, const char* format, ...); #endif -void _glfwPlatformResetPreeditText(_GLFWwindow* window); -void _glfwPlatformSetIMEStatus(_GLFWwindow* window, int active); -int _glfwPlatformGetIMEStatus(_GLFWwindow* window); - ////////////////////////////////////////////////////////////////////////// ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// diff --git a/src/null_init.c b/src/null_init.c index de4b28f3..b5b9beec 100644 --- a/src/null_init.c +++ b/src/null_init.c @@ -56,6 +56,9 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform) _glfwGetKeyScancodeNull, _glfwSetClipboardStringNull, _glfwGetClipboardStringNull, + _glfwResetPreeditTextNull, + _glfwSetIMEStatusNull, + _glfwGetIMEStatusNull, _glfwInitJoysticksNull, _glfwTerminateJoysticksNull, _glfwPollJoystickNull, diff --git a/src/null_platform.h b/src/null_platform.h index fca7c11f..9c439a2d 100644 --- a/src/null_platform.h +++ b/src/null_platform.h @@ -137,6 +137,10 @@ const char* _glfwGetClipboardStringNull(void); const char* _glfwGetScancodeNameNull(int scancode); int _glfwGetKeyScancodeNull(int key); +void _glfwResetPreeditTextNull(_GLFWwindow* window); +void _glfwSetIMEStatusNull(_GLFWwindow* window, int active); +int _glfwGetIMEStatusNull(_GLFWwindow* window); + EGLenum _glfwGetEGLPlatformNull(EGLint** attribs); EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void); EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window); diff --git a/src/null_window.c b/src/null_window.c index b40110b8..a1ae6e9d 100644 --- a/src/null_window.c +++ b/src/null_window.c @@ -542,6 +542,19 @@ const char* _glfwGetClipboardStringNull(void) return _glfw.null.clipboardString; } +void _glfwResetPreeditTextNull(_GLFWwindow* window) +{ +} + +void _glfwSetIMEStatusNull(_GLFWwindow* window, int active) +{ +} + +int _glfwGetIMEStatusNull(_GLFWwindow* window) +{ + return GLFW_FALSE; +} + EGLenum _glfwGetEGLPlatformNull(EGLint** attribs) { return 0; diff --git a/src/win32_init.c b/src/win32_init.c index cbfa40d4..62821932 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -596,6 +596,9 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform) _glfwGetKeyScancodeWin32, _glfwSetClipboardStringWin32, _glfwGetClipboardStringWin32, + _glfwResetPreeditTextWin32, + _glfwSetIMEStatusWin32, + _glfwGetIMEStatusWin32, _glfwInitJoysticksWin32, _glfwTerminateJoysticksWin32, _glfwPollJoystickWin32, diff --git a/src/win32_platform.h b/src/win32_platform.h index e5fdc8a0..81f18477 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -629,6 +629,10 @@ void _glfwSetCursorWin32(_GLFWwindow* window, _GLFWcursor* cursor); void _glfwSetClipboardStringWin32(const char* string); const char* _glfwGetClipboardStringWin32(void); +void _glfwResetPreeditTextWin32(_GLFWwindow* window); +void _glfwSetIMEStatusWin32(_GLFWwindow* window, int active); +int _glfwGetIMEStatusWin32(_GLFWwindow* window); + EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs); EGLNativeDisplayType _glfwGetEGLNativeDisplayWin32(void); EGLNativeWindowType _glfwGetEGLNativeWindowWin32(_GLFWwindow* window); diff --git a/src/win32_window.c b/src/win32_window.c index ebbbbf42..8d355b9b 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -2524,6 +2524,31 @@ const char* _glfwGetClipboardStringWin32(void) return _glfw.win32.clipboardString; } +void _glfwResetPreeditTextWin32(_GLFWwindow* window) +{ + HWND hWnd = window->win32.handle; + HIMC hIMC = ImmGetContext(hWnd); + ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0); + ImmReleaseContext(hWnd, hIMC); +} + +void _glfwSetIMEStatusWin32(_GLFWwindow* window, int active) +{ + HWND hWnd = window->win32.handle; + HIMC hIMC = ImmGetContext(hWnd); + ImmSetOpenStatus(hIMC, active ? TRUE : FALSE); + ImmReleaseContext(hWnd, hIMC); +} + +int _glfwGetIMEStatusWin32(_GLFWwindow* window) +{ + HWND hWnd = window->win32.handle; + HIMC hIMC = ImmGetContext(hWnd); + BOOL result = ImmGetOpenStatus(hIMC); + ImmReleaseContext(hWnd, hIMC); + return result ? GLFW_TRUE : GLFW_FALSE; +} + EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs) { if (_glfw.egl.ANGLE_platform_angle) @@ -2636,31 +2661,6 @@ VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance, return err; } -void _glfwPlatformResetPreeditText(_GLFWwindow* window) -{ - HWND hWnd = window->win32.handle; - HIMC hIMC = ImmGetContext(hWnd); - ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0); - ImmReleaseContext(hWnd, hIMC); -} - -void _glfwPlatformSetIMEStatus(_GLFWwindow* window, int active) -{ - HWND hWnd = window->win32.handle; - HIMC hIMC = ImmGetContext(hWnd); - ImmSetOpenStatus(hIMC, active ? TRUE : FALSE); - ImmReleaseContext(hWnd, hIMC); -} - -int _glfwPlatformGetIMEStatus(_GLFWwindow* window) -{ - HWND hWnd = window->win32.handle; - HIMC hIMC = ImmGetContext(hWnd); - BOOL result = ImmGetOpenStatus(hIMC); - ImmReleaseContext(hWnd, hIMC); - return result ? GLFW_TRUE : GLFW_FALSE; -} - GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle) { _GLFWwindow* window = (_GLFWwindow*) handle; diff --git a/src/wl_init.c b/src/wl_init.c index c232ce79..7e55de56 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -362,6 +362,9 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform) _glfwGetKeyScancodeWayland, _glfwSetClipboardStringWayland, _glfwGetClipboardStringWayland, + _glfwResetPreeditTextWayland, + _glfwSetIMEStatusWayland, + _glfwGetIMEStatusWayland, #if defined(__linux__) _glfwInitJoysticksLinux, _glfwTerminateJoysticksLinux, diff --git a/src/wl_platform.h b/src/wl_platform.h index d6c8c4da..8b7db75d 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -490,6 +490,10 @@ void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor); void _glfwSetClipboardStringWayland(const char* string); const char* _glfwGetClipboardStringWayland(void); +void _glfwResetPreeditTextWayland(_GLFWwindow* window); +void _glfwSetIMEStatusWayland(_GLFWwindow* window, int active); +int _glfwGetIMEStatusWayland(_GLFWwindow* window); + EGLenum _glfwGetEGLPlatformWayland(EGLint** attribs); EGLNativeDisplayType _glfwGetEGLNativeDisplayWayland(void); EGLNativeWindowType _glfwGetEGLNativeWindowWayland(_GLFWwindow* window); diff --git a/src/wl_window.c b/src/wl_window.c index a1f93185..b4b6dc01 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2592,6 +2592,19 @@ const char* _glfwGetClipboardStringWayland(void) return _glfw.wl.clipboardString; } +void _glfwResetPreeditTextWayland(_GLFWwindow* window) +{ +} + +void _glfwSetIMEStatusWayland(_GLFWwindow* window, int active) +{ +} + +int _glfwGetIMEStatusWayland(_GLFWwindow* window) +{ + return GLFW_FALSE; +} + EGLenum _glfwGetEGLPlatformWayland(EGLint** attribs) { if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_wayland) diff --git a/src/x11_init.c b/src/x11_init.c index 2fbde908..bc53e6c4 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -1184,6 +1184,9 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform) _glfwGetKeyScancodeX11, _glfwSetClipboardStringX11, _glfwGetClipboardStringX11, + _glfwResetPreeditTextX11, + _glfwSetIMEStatusX11, + _glfwGetIMEStatusX11, #if defined(__linux__) _glfwInitJoysticksLinux, _glfwTerminateJoysticksLinux, diff --git a/src/x11_platform.h b/src/x11_platform.h index 2bd88744..1abde8a0 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -979,6 +979,10 @@ void _glfwSetCursorX11(_GLFWwindow* window, _GLFWcursor* cursor); void _glfwSetClipboardStringX11(const char* string); const char* _glfwGetClipboardStringX11(void); +void _glfwResetPreeditTextX11(_GLFWwindow* window); +void _glfwSetIMEStatusX11(_GLFWwindow* window, int active); +int _glfwGetIMEStatusX11(_GLFWwindow* window); + EGLenum _glfwGetEGLPlatformX11(EGLint** attribs); EGLNativeDisplayType _glfwGetEGLNativeDisplayX11(void); EGLNativeWindowType _glfwGetEGLNativeWindowX11(_GLFWwindow* window); diff --git a/src/x11_window.c b/src/x11_window.c index f20c2af4..b0c3607e 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -3259,6 +3259,62 @@ const char* _glfwGetClipboardStringX11(void) return getSelectionString(_glfw.x11.CLIPBOARD); } +void _glfwResetPreeditTextX11(_GLFWwindow* window) +{ + XIC ic = window->x11.ic; + + /* restore conversion state after resetting ic later */ + XIMPreeditState preedit_state = XIMPreeditUnKnown; + XVaNestedList preedit_attr; + char* result; + + // Can not manage IME in the case of over-the-spot. + if (_glfw.x11.imStyle == STYLE_OVERTHESPOT) + return; + + if (window->ntext == 0) + return; + + preedit_attr = XVaCreateNestedList(0, XNPreeditState, &preedit_state, NULL); + XGetICValues(ic, XNPreeditAttributes, preedit_attr, NULL); + XFree(preedit_attr); + + result = XmbResetIC(ic); + + preedit_attr = XVaCreateNestedList(0, XNPreeditState, preedit_state, NULL); + XSetICValues(ic, XNPreeditAttributes, preedit_attr, NULL); + XFree(preedit_attr); + + window->ntext = 0; + window->nblocks = 0; + _glfwInputPreedit(window, 0); + + XFree (result); +} + +void _glfwSetIMEStatusX11(_GLFWwindow* window, int active) +{ + XIC ic = window->x11.ic; + + // Can not manage IME in the case of over-the-spot. + if (_glfw.x11.imStyle == STYLE_OVERTHESPOT) + return; + + if (active) + XSetICFocus(ic); + else + XUnsetICFocus(ic); +} + +int _glfwGetIMEStatusX11(_GLFWwindow* window) +{ + // Can not manage IME in the case of over-the-spot. + if (_glfw.x11.imStyle == STYLE_OVERTHESPOT) + return GLFW_FALSE; + + return window->x11.imeFocus; +} + EGLenum _glfwGetEGLPlatformX11(EGLint** attribs) { if (_glfw.egl.ANGLE_platform_angle) @@ -3457,62 +3513,6 @@ VkResult _glfwCreateWindowSurfaceX11(VkInstance instance, } } -void _glfwPlatformResetPreeditText(_GLFWwindow* window) -{ - XIC ic = window->x11.ic; - - /* restore conversion state after resetting ic later */ - XIMPreeditState preedit_state = XIMPreeditUnKnown; - XVaNestedList preedit_attr; - char* result; - - // Can not manage IME in the case of over-the-spot. - if (_glfw.x11.imStyle == STYLE_OVERTHESPOT) - return; - - if (window->ntext == 0) - return; - - preedit_attr = XVaCreateNestedList(0, XNPreeditState, &preedit_state, NULL); - XGetICValues(ic, XNPreeditAttributes, preedit_attr, NULL); - XFree(preedit_attr); - - result = XmbResetIC(ic); - - preedit_attr = XVaCreateNestedList(0, XNPreeditState, preedit_state, NULL); - XSetICValues(ic, XNPreeditAttributes, preedit_attr, NULL); - XFree(preedit_attr); - - window->ntext = 0; - window->nblocks = 0; - _glfwInputPreedit(window, 0); - - XFree (result); -} - -void _glfwPlatformSetIMEStatus(_GLFWwindow* window, int active) -{ - XIC ic = window->x11.ic; - - // Can not manage IME in the case of over-the-spot. - if (_glfw.x11.imStyle == STYLE_OVERTHESPOT) - return; - - if (active) - XSetICFocus(ic); - else - XUnsetICFocus(ic); -} - -int _glfwPlatformGetIMEStatus(_GLFWwindow* window) -{ - // Can not manage IME in the case of over-the-spot. - if (_glfw.x11.imStyle == STYLE_OVERTHESPOT) - return GLFW_FALSE; - - return window->x11.imeFocus; -} - ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// //////////////////////////////////////////////////////////////////////////