mirror of
https://github.com/glfw/glfw.git
synced 2024-11-26 06:14:35 +00:00
Apply shibukawa's fix of GLFW for Windows
This fix is based on shibukawa's fix:
https://github.com/glfw/glfw/pull/658
d36a164423
Some minor coding style changes are made, but not yet follow glfw's one,
and some comments doesn't follow recent changes. So further work is
needed.
Co-authored-by: Yoshiki Shibukawa <yoshiki@shibu.jp>
Co-authored-by: Takuro Ashie <ashie@clear-code.com>
This commit is contained in:
parent
228e58262e
commit
2e30ad17fe
@ -1155,6 +1155,7 @@ extern "C" {
|
|||||||
#define GLFW_LOCK_KEY_MODS 0x00033004
|
#define GLFW_LOCK_KEY_MODS 0x00033004
|
||||||
#define GLFW_RAW_MOUSE_MOTION 0x00033005
|
#define GLFW_RAW_MOUSE_MOTION 0x00033005
|
||||||
#define GLFW_UNLIMITED_MOUSE_BUTTONS 0x00033006
|
#define GLFW_UNLIMITED_MOUSE_BUTTONS 0x00033006
|
||||||
|
#define GLFW_IME 0x00033007
|
||||||
|
|
||||||
#define GLFW_CURSOR_NORMAL 0x00034001
|
#define GLFW_CURSOR_NORMAL 0x00034001
|
||||||
#define GLFW_CURSOR_HIDDEN 0x00034002
|
#define GLFW_CURSOR_HIDDEN 0x00034002
|
||||||
@ -1945,6 +1946,37 @@ typedef void (* GLFWcharfun)(GLFWwindow* window, unsigned int codepoint);
|
|||||||
*/
|
*/
|
||||||
typedef void (* GLFWcharmodsfun)(GLFWwindow* window, unsigned int codepoint, int mods);
|
typedef void (* GLFWcharmodsfun)(GLFWwindow* window, unsigned int codepoint, int mods);
|
||||||
|
|
||||||
|
/*! @brief The function signature for preedit callbacks.
|
||||||
|
*
|
||||||
|
* This is the function signature for preedit callback functions.
|
||||||
|
*
|
||||||
|
* @param[in] window The window that received the event.
|
||||||
|
* @param[in] length Preedit string length.
|
||||||
|
* @param[in] string Preedit string.
|
||||||
|
* @param[in] count Attributed block count.
|
||||||
|
* @param[in] blocksizes List of attributed block size.
|
||||||
|
* @param[in] focusedblock Focused block index.
|
||||||
|
*
|
||||||
|
* @sa @ref preedit
|
||||||
|
* @sa glfwSetPreeditCallback
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
typedef void (* GLFWpreeditfun)(GLFWwindow*,int,unsigned int*,int,int*,int);
|
||||||
|
|
||||||
|
/*! @brief The function signature for IME status change callbacks.
|
||||||
|
*
|
||||||
|
* This is the function signature for IME status change callback functions.
|
||||||
|
*
|
||||||
|
* @param[in] window The window that received the event.
|
||||||
|
*
|
||||||
|
* @sa @ref preedit
|
||||||
|
* @sa glfwSetIMEStatusCallback
|
||||||
|
*
|
||||||
|
* @ingroup monitor
|
||||||
|
*/
|
||||||
|
typedef void (* GLFWimestatusfun)(GLFWwindow*);
|
||||||
|
|
||||||
/*! @brief The function pointer type for path drop callbacks.
|
/*! @brief The function pointer type for path drop callbacks.
|
||||||
*
|
*
|
||||||
* This is the function pointer type for path drop callbacks. A path drop
|
* This is the function pointer type for path drop callbacks. A path drop
|
||||||
@ -4652,8 +4684,8 @@ GLFWAPI void glfwPostEmptyEvent(void);
|
|||||||
*
|
*
|
||||||
* This function returns the value of an input option for the specified window.
|
* This function returns the value of an input option for the specified window.
|
||||||
* The mode must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS,
|
* The mode must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS,
|
||||||
* @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or
|
* @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS,
|
||||||
* @ref GLFW_RAW_MOUSE_MOTION.
|
* @ref GLFW_RAW_MOUSE_MOTION or @ref GLFW_IME.
|
||||||
*
|
*
|
||||||
* @param[in] window The window to query.
|
* @param[in] window The window to query.
|
||||||
* @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`,
|
* @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`,
|
||||||
@ -4677,8 +4709,9 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
|
|||||||
*
|
*
|
||||||
* This function sets an input mode option for the specified window. The mode
|
* This function sets an input mode option for the specified window. The mode
|
||||||
* must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS,
|
* must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS,
|
||||||
* @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS
|
* @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS,
|
||||||
* @ref GLFW_RAW_MOUSE_MOTION, or @ref GLFW_UNLIMITED_MOUSE_BUTTONS.
|
* @ref GLFW_RAW_MOUSE_MOTION, @ref GLFW_UNLIMITED_MOUSE_BUTTONS,
|
||||||
|
* @ref GLFW_IME.
|
||||||
*
|
*
|
||||||
* If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
|
* If the mode is `GLFW_CURSOR`, the value must be one of the following cursor
|
||||||
* modes:
|
* modes:
|
||||||
@ -4723,10 +4756,13 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
|
|||||||
* callback, or `GLFW_FALSE` to limit the mouse buttons sent to the callback
|
* callback, or `GLFW_FALSE` to limit the mouse buttons sent to the callback
|
||||||
* to the mouse button token values up to `GLFW_MOUSE_BUTTON_LAST`.
|
* to the mouse button token values up to `GLFW_MOUSE_BUTTON_LAST`.
|
||||||
*
|
*
|
||||||
|
* If the mode is `GLFW_IME`, the value must be either `GLFW_TRUE` to turn on
|
||||||
|
* IME, or `GLFW_FALSE` to turn off it.
|
||||||
|
*
|
||||||
* @param[in] window The window whose input mode to set.
|
* @param[in] window The window whose input mode to set.
|
||||||
* @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`,
|
* @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`,
|
||||||
* `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or
|
* `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS`,
|
||||||
* `GLFW_RAW_MOUSE_MOTION`.
|
* `GLFW_RAW_MOUSE_MOTION` or `GLFW_IME`.
|
||||||
* @param[in] value The new value of the specified input mode.
|
* @param[in] value The new value of the specified input mode.
|
||||||
*
|
*
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
@ -5156,6 +5192,67 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);
|
|||||||
*/
|
*/
|
||||||
GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
|
GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
|
||||||
|
|
||||||
|
/*! @brief Retrieves the position of the text cursor relative to the client area of window.
|
||||||
|
*
|
||||||
|
* This function returns position hint to decide the candidate window.
|
||||||
|
*
|
||||||
|
* @param[in] window The window to set the text cursor for.
|
||||||
|
* @param[out] x The text cursor x position (relative position from window coordinates).
|
||||||
|
* @param[out] y The text cursor y position (relative position from window coordinates).
|
||||||
|
* @param[out] h The text cursor height.
|
||||||
|
*
|
||||||
|
* @par Thread Safety
|
||||||
|
* This function may only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref input_char
|
||||||
|
*
|
||||||
|
* @since Added in GLFW 3.X.
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
GLFWAPI void glfwGetPreeditCursorPos(GLFWwindow* window, int *x, int *y, int *h);
|
||||||
|
|
||||||
|
/*! @brief Notify the text cursor position to window system to decide the candidate window position.
|
||||||
|
*
|
||||||
|
* This function teach position hint to decide the candidate window. The candidate window
|
||||||
|
* is a part of IME(Input Method Editor) and show several candidate strings.
|
||||||
|
*
|
||||||
|
* Windows sytems decide proper pisition from text cursor geometry.
|
||||||
|
* You should call this function in preedit callback.
|
||||||
|
*
|
||||||
|
* @param[in] window The window to set the text cursor for.
|
||||||
|
* @param[in] x The text cursor x position (relative position from window coordinates).
|
||||||
|
* @param[in] y The text cursor y position (relative position from window coordinates).
|
||||||
|
* @param[in] h The text cursor height.
|
||||||
|
*
|
||||||
|
* @par Thread Safety
|
||||||
|
* This function may only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref input_char
|
||||||
|
*
|
||||||
|
* @since Added in GLFW 3.X.
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
GLFWAPI void glfwSetPreeditCursorPos(GLFWwindow* window, int x, int y, int h);
|
||||||
|
|
||||||
|
/*! @brief Reset IME input status.
|
||||||
|
*
|
||||||
|
* This function resets IME's preedit text.
|
||||||
|
*
|
||||||
|
* @param[in] window The window.
|
||||||
|
*
|
||||||
|
* @par Thread Safety
|
||||||
|
* This function may only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref preedit
|
||||||
|
*
|
||||||
|
* @since Added in GLFW 3.X.
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
GLFWAPI void glfwResetPreeditText(GLFWwindow* window);
|
||||||
|
|
||||||
/*! @brief Sets the key callback.
|
/*! @brief Sets the key callback.
|
||||||
*
|
*
|
||||||
* This function sets the key callback of the specified window, which is called
|
* This function sets the key callback of the specified window, which is called
|
||||||
@ -5291,6 +5388,58 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun callback
|
|||||||
*/
|
*/
|
||||||
GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun callback);
|
GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun callback);
|
||||||
|
|
||||||
|
/*! @brief Sets the preedit callback.
|
||||||
|
*
|
||||||
|
* This function sets the preedit callback of the specified
|
||||||
|
* window, which is called when an IME is processing text before commited.
|
||||||
|
*
|
||||||
|
* Callback receives relative position of input cursor inside preedit text and
|
||||||
|
* attributed text blocks. This callback is used for on-the-spot text editing
|
||||||
|
* with IME.
|
||||||
|
*
|
||||||
|
* @param[in] window The window whose callback to set.
|
||||||
|
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
|
||||||
|
* callback.
|
||||||
|
* @return The previously set callback, or `NULL` if no callback was set or an
|
||||||
|
* error occurred.
|
||||||
|
*
|
||||||
|
* @par Thread Safety
|
||||||
|
* This function may only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref input_char
|
||||||
|
*
|
||||||
|
* @since Added in GLFW 3.X
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
GLFWAPI GLFWpreeditfun glfwSetPreeditCallback(GLFWwindow* window, GLFWpreeditfun cbfun);
|
||||||
|
|
||||||
|
/*! @brief Sets the IME status change callback.
|
||||||
|
*
|
||||||
|
* This function sets the preedit callback of the specified
|
||||||
|
* window, which is called when an IME is processing text before commited.
|
||||||
|
*
|
||||||
|
* Callback receives relative position of input cursor inside preedit text and
|
||||||
|
* attributed text blocks. This callback is used for on-the-spot text editing
|
||||||
|
* with IME.
|
||||||
|
*
|
||||||
|
* @param[in] window The window whose callback to set.
|
||||||
|
* @param[in] cbfun The new callback, or `NULL` to remove the currently set
|
||||||
|
* callback.
|
||||||
|
* @return The previously set callback, or `NULL` if no callback was set or an
|
||||||
|
* error occurred.
|
||||||
|
*
|
||||||
|
* @par Thread Safety
|
||||||
|
* This function may only be called from the main thread.
|
||||||
|
*
|
||||||
|
* @sa @ref input_char
|
||||||
|
*
|
||||||
|
* @since Added in GLFW 3.X
|
||||||
|
*
|
||||||
|
* @ingroup input
|
||||||
|
*/
|
||||||
|
GLFWAPI GLFWimestatusfun glfwSetIMEStatusCallback(GLFWwindow* window, GLFWimestatusfun cbfun);
|
||||||
|
|
||||||
/*! @brief Sets the mouse button callback.
|
/*! @brief Sets the mouse button callback.
|
||||||
*
|
*
|
||||||
* This function sets the mouse button callback of the specified window, which
|
* This function sets the mouse button callback of the specified window, which
|
||||||
|
@ -146,6 +146,7 @@ endif()
|
|||||||
|
|
||||||
if (GLFW_BUILD_WIN32)
|
if (GLFW_BUILD_WIN32)
|
||||||
list(APPEND glfw_PKG_LIBS "-lgdi32")
|
list(APPEND glfw_PKG_LIBS "-lgdi32")
|
||||||
|
list(APPEND glfw_LIBRARIES "imm32")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (GLFW_BUILD_COCOA)
|
if (GLFW_BUILD_COCOA)
|
||||||
|
62
src/input.c
62
src/input.c
@ -328,6 +328,20 @@ void _glfwInputChar(_GLFWwindow* window, uint32_t codepoint, int mods, GLFWbool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwInputPreedit(_GLFWwindow* window, int focusedBlock)
|
||||||
|
{
|
||||||
|
if (window->callbacks.preedit) {
|
||||||
|
window->callbacks.preedit((GLFWwindow*) window, window->ntext, window->preeditText, window->nblocks, window->preeditAttributeBlocks, focusedBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwInputIMEStatus(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (window->callbacks.imestatus) {
|
||||||
|
window->callbacks.imestatus((GLFWwindow*) window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Notifies shared code of a scroll event
|
// Notifies shared code of a scroll event
|
||||||
//
|
//
|
||||||
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
|
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
|
||||||
@ -580,6 +594,8 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
|
|||||||
return window->rawMouseMotion;
|
return window->rawMouseMotion;
|
||||||
case GLFW_UNLIMITED_MOUSE_BUTTONS:
|
case GLFW_UNLIMITED_MOUSE_BUTTONS:
|
||||||
return window->disableMouseButtonLimit;
|
return window->disableMouseButtonLimit;
|
||||||
|
case GLFW_IME:
|
||||||
|
return _glfwPlatformGetIMEStatus(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
||||||
@ -693,6 +709,12 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
|||||||
window->disableMouseButtonLimit = value ? GLFW_TRUE : GLFW_FALSE;
|
window->disableMouseButtonLimit = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GLFW_IME:
|
||||||
|
{
|
||||||
|
_glfwPlatformSetIMEStatus(window, value ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
||||||
@ -953,6 +975,30 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
|
|||||||
_glfw.platform.setCursor(window, cursor);
|
_glfw.platform.setCursor(window, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwGetPreeditCursorPos(GLFWwindow* handle, int *x, int *y, int *h)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
if (x)
|
||||||
|
*x = window->preeditCursorPosX;
|
||||||
|
if (y)
|
||||||
|
*y = window->preeditCursorPosY;
|
||||||
|
if (h)
|
||||||
|
*h = window->preeditCursorHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwSetPreeditCursorPos(GLFWwindow* handle, int x, int y, int h)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
window->preeditCursorPosX = x;
|
||||||
|
window->preeditCursorPosY = y;
|
||||||
|
window->preeditCursorHeight = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwResetPreeditText(GLFWwindow* handle) {
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
_glfwPlatformResetPreeditText(window);
|
||||||
|
}
|
||||||
|
|
||||||
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
|
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
|
||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
@ -986,6 +1032,22 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmods
|
|||||||
return cbfun;
|
return cbfun;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWpreeditfun glfwSetPreeditCallback(GLFWwindow* handle, GLFWpreeditfun cbfun)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
_GLFW_SWAP(GLFWpreeditfun, window->callbacks.preedit, cbfun);
|
||||||
|
return cbfun;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWimestatusfun glfwSetIMEStatusCallback(GLFWwindow* handle, GLFWimestatusfun cbfun)
|
||||||
|
{
|
||||||
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
_GLFW_SWAP(GLFWimestatusfun, window->callbacks.imestatus, cbfun);
|
||||||
|
return cbfun;
|
||||||
|
}
|
||||||
|
|
||||||
GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
|
GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
|
||||||
GLFWmousebuttonfun cbfun)
|
GLFWmousebuttonfun cbfun)
|
||||||
{
|
{
|
||||||
|
@ -561,6 +561,15 @@ struct _GLFWwindow
|
|||||||
double virtualCursorPosX, virtualCursorPosY;
|
double virtualCursorPosX, virtualCursorPosY;
|
||||||
GLFWbool rawMouseMotion;
|
GLFWbool rawMouseMotion;
|
||||||
|
|
||||||
|
// Preedit texts
|
||||||
|
unsigned int* preeditText;
|
||||||
|
int ntext;
|
||||||
|
int ctext;
|
||||||
|
int* preeditAttributeBlocks;
|
||||||
|
int nblocks;
|
||||||
|
int cblocks;
|
||||||
|
int preeditCursorPosX, preeditCursorPosY, preeditCursorHeight;
|
||||||
|
|
||||||
_GLFWcontext context;
|
_GLFWcontext context;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -580,6 +589,8 @@ struct _GLFWwindow
|
|||||||
GLFWkeyfun key;
|
GLFWkeyfun key;
|
||||||
GLFWcharfun character;
|
GLFWcharfun character;
|
||||||
GLFWcharmodsfun charmods;
|
GLFWcharmodsfun charmods;
|
||||||
|
GLFWpreeditfun preedit;
|
||||||
|
GLFWimestatusfun imestatus;
|
||||||
GLFWdropfun drop;
|
GLFWdropfun drop;
|
||||||
} callbacks;
|
} callbacks;
|
||||||
|
|
||||||
@ -934,6 +945,8 @@ void _glfwInputKey(_GLFWwindow* window,
|
|||||||
int key, int scancode, int action, int mods);
|
int key, int scancode, int action, int mods);
|
||||||
void _glfwInputChar(_GLFWwindow* window,
|
void _glfwInputChar(_GLFWwindow* window,
|
||||||
uint32_t codepoint, int mods, GLFWbool plain);
|
uint32_t codepoint, int mods, GLFWbool plain);
|
||||||
|
void _glfwInputPreedit(_GLFWwindow* window, int focusedBlock);
|
||||||
|
void _glfwInputIMEStatus(_GLFWwindow* window);
|
||||||
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset);
|
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset);
|
||||||
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
||||||
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
||||||
@ -954,6 +967,9 @@ void _glfwInputError(int code, const char* format, ...)
|
|||||||
void _glfwInputError(int code, const char* format, ...);
|
void _glfwInputError(int code, const char* format, ...);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void _glfwPlatformResetPreeditText(_GLFWwindow* window);
|
||||||
|
void _glfwPlatformSetIMEStatus(_GLFWwindow* window, int active);
|
||||||
|
int _glfwPlatformGetIMEStatus(_GLFWwindow* window);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
|
#include <imm.h>
|
||||||
|
|
||||||
// Returns the window style for the specified window
|
// Returns the window style for the specified window
|
||||||
//
|
//
|
||||||
@ -529,6 +530,15 @@ static void maximizeWindowManually(_GLFWwindow* window)
|
|||||||
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set cursor position to decide candidate window
|
||||||
|
static void _win32ChangeCursorPosition(HIMC hIMC, _GLFWwindow* window) {
|
||||||
|
int x = window->preeditCursorPosX;
|
||||||
|
int y = window->preeditCursorPosY;
|
||||||
|
int h = window->preeditCursorHeight;
|
||||||
|
CANDIDATEFORM excludeRect = {0, CFS_EXCLUDE, {x, y}, {x, y, x, y+h}};
|
||||||
|
ImmSetCandidateWindow(hIMC, &excludeRect);
|
||||||
|
}
|
||||||
|
|
||||||
// Window procedure for user-created windows
|
// Window procedure for user-created windows
|
||||||
//
|
//
|
||||||
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
@ -800,6 +810,93 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_IME_COMPOSITION:
|
||||||
|
{
|
||||||
|
if (lParam & GCS_RESULTSTR) {
|
||||||
|
window->nblocks = 0;
|
||||||
|
window->ntext = 0;
|
||||||
|
_glfwInputPreedit(window, 0);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (lParam & GCS_COMPSTR) {
|
||||||
|
HIMC hIMC = ImmGetContext(hWnd);
|
||||||
|
// get preedit data sizes
|
||||||
|
LONG preeditTextLength = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, NULL, 0);
|
||||||
|
LONG attrLength = ImmGetCompositionString(hIMC, GCS_COMPATTR, NULL, 0);
|
||||||
|
LONG clauseLength = ImmGetCompositionString(hIMC, GCS_COMPCLAUSE, NULL, 0);
|
||||||
|
if (preeditTextLength > 0) {
|
||||||
|
// get preedit data
|
||||||
|
int length = preeditTextLength/sizeof(WCHAR);
|
||||||
|
LPWSTR buffer = (LPWSTR)_glfw_calloc(preeditTextLength, sizeof(WCHAR));
|
||||||
|
LPSTR attributes = (LPSTR)_glfw_calloc(attrLength, 1);
|
||||||
|
DWORD *clauses = (DWORD*)_glfw_calloc(clauseLength, 1);
|
||||||
|
ImmGetCompositionStringW(hIMC, GCS_COMPSTR, buffer, preeditTextLength);
|
||||||
|
ImmGetCompositionString(hIMC, GCS_COMPATTR, attributes, attrLength);
|
||||||
|
ImmGetCompositionString(hIMC, GCS_COMPCLAUSE, clauses, clauseLength);
|
||||||
|
// store preedit text
|
||||||
|
int ctext = window->ctext;
|
||||||
|
while (ctext < length+1) {
|
||||||
|
ctext = (ctext == 0) ? 1 : ctext*2;
|
||||||
|
}
|
||||||
|
if (ctext != window->ctext) {
|
||||||
|
unsigned int* preeditText = _glfw_realloc(window->preeditText, sizeof(unsigned int)*ctext);
|
||||||
|
if (preeditText == NULL) {
|
||||||
|
return 0;
|
||||||
|
_glfw_free(buffer);
|
||||||
|
_glfw_free(attributes);
|
||||||
|
_glfw_free(clauses);
|
||||||
|
}
|
||||||
|
window->preeditText = preeditText;
|
||||||
|
window->ctext = ctext;
|
||||||
|
}
|
||||||
|
window->ntext = length;
|
||||||
|
window->preeditText[length] = 0;
|
||||||
|
int i;
|
||||||
|
for (i=0; i < length; i++) {
|
||||||
|
window->preeditText[i] = buffer[i];
|
||||||
|
}
|
||||||
|
// store blocks
|
||||||
|
window->nblocks = clauseLength/sizeof(DWORD)-1;
|
||||||
|
// last element of clauses is a block count, but
|
||||||
|
// text length is convenient.
|
||||||
|
clauses[window->nblocks] = length;
|
||||||
|
int cblocks = window->cblocks;
|
||||||
|
while (cblocks < window->nblocks) {
|
||||||
|
cblocks = (cblocks == 0) ? 1 : cblocks*2;
|
||||||
|
}
|
||||||
|
if (cblocks != window->cblocks) {
|
||||||
|
int* blocks = _glfw_realloc(window->preeditAttributeBlocks, sizeof(int)*cblocks);
|
||||||
|
if (blocks == NULL) {
|
||||||
|
return 0;
|
||||||
|
_glfw_free(buffer);
|
||||||
|
_glfw_free(attributes);
|
||||||
|
_glfw_free(clauses);
|
||||||
|
}
|
||||||
|
window->preeditAttributeBlocks = blocks;
|
||||||
|
window->cblocks = cblocks;
|
||||||
|
}
|
||||||
|
int focusedBlock = 0;
|
||||||
|
for (i=0; i < window->nblocks; i++) {
|
||||||
|
window->preeditAttributeBlocks[i] = clauses[i+1]-clauses[i];
|
||||||
|
if (attributes[clauses[i]] != ATTR_CONVERTED) {
|
||||||
|
focusedBlock = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_glfw_free(buffer);
|
||||||
|
_glfw_free(attributes);
|
||||||
|
_glfw_free(clauses);
|
||||||
|
_glfwInputPreedit(window, focusedBlock);
|
||||||
|
_win32ChangeCursorPosition(hIMC, window);
|
||||||
|
}
|
||||||
|
ImmReleaseContext(hWnd, hIMC);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_IME_NOTIFY:
|
||||||
|
if (wParam == IMN_SETOPENSTATUS)
|
||||||
|
_glfwInputIMEStatus(window);
|
||||||
|
break;
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
case WM_RBUTTONDOWN:
|
case WM_RBUTTONDOWN:
|
||||||
case WM_MBUTTONDOWN:
|
case WM_MBUTTONDOWN:
|
||||||
@ -2575,6 +2672,31 @@ VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance,
|
|||||||
return err;
|
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)
|
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
|
||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
@ -495,6 +495,11 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
|
|||||||
*prev = window->next;
|
*prev = window->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear memory for preedit text
|
||||||
|
if (window->preeditText)
|
||||||
|
_glfw_free(window->preeditText);
|
||||||
|
if (window->preeditAttributeBlocks)
|
||||||
|
_glfw_free(window->preeditAttributeBlocks);
|
||||||
_glfw_free(window->title);
|
_glfw_free(window->title);
|
||||||
_glfw_free(window);
|
_glfw_free(window);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user