|
@@ -440,194 +440,216 @@ static char** parseUriList(char* text, int* count)
|
|
return paths;
|
|
return paths;
|
|
}
|
|
}
|
|
|
|
|
|
-// Update cursor position to decide candidate window
|
|
|
|
-static void _ximChangeCursorPosition(XIC xic, _GLFWwindow* window)
|
|
|
|
|
|
+// Update caret position to decide candidate window
|
|
|
|
+//
|
|
|
|
+static void updateCaretPosition(_GLFWwindow* window, XIC xic)
|
|
{
|
|
{
|
|
- XVaNestedList preedit_attr;
|
|
|
|
- XPoint spot;
|
|
|
|
|
|
+ XVaNestedList attributes;
|
|
|
|
+ XPoint spot;
|
|
|
|
|
|
spot.x = window->preeditCursorPosX;
|
|
spot.x = window->preeditCursorPosX;
|
|
spot.y = window->preeditCursorPosY + window->preeditCursorHeight;
|
|
spot.y = window->preeditCursorPosY + window->preeditCursorHeight;
|
|
- preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
|
|
|
|
- XSetICValues(xic, XNPreeditAttributes, preedit_attr, NULL);
|
|
|
|
- XFree(preedit_attr);
|
|
|
|
|
|
+ attributes = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
|
|
|
|
+ XSetICValues(xic, XNPreeditAttributes, attributes, NULL);
|
|
|
|
+ XFree(attributes);
|
|
}
|
|
}
|
|
|
|
|
|
-// IME Start callback (do nothing)
|
|
|
|
-static void _ximPreeditStartCallback(XIC xic, XPointer clientData, XPointer callData)
|
|
|
|
|
|
+// IME start callback (do nothing)
|
|
|
|
+//
|
|
|
|
+static void preeditStartCallback(XIC xic, XPointer clientData, XPointer callData)
|
|
{
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
-// IME Done callback (do nothing)
|
|
|
|
-static void _ximPreeditDoneCallback(XIC xic, XPointer clientData, XPointer callData)
|
|
|
|
|
|
+// IME done callback (do nothing)
|
|
|
|
+//
|
|
|
|
+static void preeditDoneCallback(XIC xic, XPointer clientData, XPointer callData)
|
|
{
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
-// IME Draw callback
|
|
|
|
-static void _ximPreeditDrawCallback(XIC xic, XPointer clientData, XIMPreeditDrawCallbackStruct *callData)
|
|
|
|
|
|
+// IME draw callback
|
|
|
|
+//
|
|
|
|
+static void preeditDrawCallback(XIC xic, XPointer clientData, XIMPreeditDrawCallbackStruct* callData)
|
|
{
|
|
{
|
|
- int i, j, length, ctext, rstart, rend;
|
|
|
|
|
|
+ int i, j, length, rstart, rend;
|
|
XIMText* text;
|
|
XIMText* text;
|
|
const char* src;
|
|
const char* src;
|
|
unsigned int codePoint;
|
|
unsigned int codePoint;
|
|
unsigned int* preeditText;
|
|
unsigned int* preeditText;
|
|
XIMFeedback f;
|
|
XIMFeedback f;
|
|
- _GLFWwindow* window = (_GLFWwindow*)clientData;
|
|
|
|
|
|
+ _GLFWwindow* window = (_GLFWwindow*) clientData;
|
|
|
|
|
|
// keep cursor position to reduce API call
|
|
// keep cursor position to reduce API call
|
|
int cursorX = window->preeditCursorPosX;
|
|
int cursorX = window->preeditCursorPosX;
|
|
int cursorY = window->preeditCursorPosY;
|
|
int cursorY = window->preeditCursorPosY;
|
|
int cursorHeight = window->preeditCursorHeight;
|
|
int cursorHeight = window->preeditCursorHeight;
|
|
|
|
|
|
- if (!callData->text) {
|
|
|
|
- // preedit text is empty
|
|
|
|
- window->ntext = 0;
|
|
|
|
- window->nblocks = 0;
|
|
|
|
|
|
+ if (!callData->text)
|
|
|
|
+ {
|
|
|
|
+ // Composition string is empty
|
|
|
|
+ window->preeditBlockCount = 0;
|
|
_glfwInputPreedit(window, 0);
|
|
_glfwInputPreedit(window, 0);
|
|
return;
|
|
return;
|
|
- } else {
|
|
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
text = callData->text;
|
|
text = callData->text;
|
|
length = callData->chg_length;
|
|
length = callData->chg_length;
|
|
- if (text->encoding_is_wchar) {
|
|
|
|
|
|
+ if (text->encoding_is_wchar)
|
|
|
|
+ {
|
|
// wchar is not supported
|
|
// wchar is not supported
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- ctext = window->ctext;
|
|
|
|
- while (ctext < length+1) {
|
|
|
|
- ctext = (ctext == 0) ? 1 : ctext * 2;
|
|
|
|
- }
|
|
|
|
- if (ctext != window->ctext) {
|
|
|
|
- preeditText = realloc(window->preeditText, sizeof(unsigned int)*ctext);
|
|
|
|
- if (preeditText == NULL) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- window->preeditText = preeditText;
|
|
|
|
- window->ctext = ctext;
|
|
|
|
- }
|
|
|
|
- window->ntext = length;
|
|
|
|
- window->preeditText[length] = 0;
|
|
|
|
- if (window->cblocks == 0) {
|
|
|
|
- window->preeditAttributeBlocks = malloc(sizeof(int)*4);
|
|
|
|
- window->cblocks = 4;
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ free(window->preeditText);
|
|
|
|
+ window->preeditText = calloc(length + 1, sizeof(unsigned int));
|
|
|
|
+
|
|
|
|
+ if (!window->preeditBlocks)
|
|
|
|
+ window->preeditBlocks = calloc(4, sizeof(int));
|
|
|
|
+
|
|
src = text->string.multi_byte;
|
|
src = text->string.multi_byte;
|
|
rend = 0;
|
|
rend = 0;
|
|
rstart = length;
|
|
rstart = length;
|
|
- for (i = 0, j = 0; i < text->length; i++) {
|
|
|
|
- #if defined(X_HAVE_UTF8_STRING)
|
|
|
|
|
|
+
|
|
|
|
+ for (i = 0, j = 0; i < text->length; i++)
|
|
|
|
+ {
|
|
|
|
+#if defined(X_HAVE_UTF8_STRING)
|
|
codePoint = decodeUTF8(&src);
|
|
codePoint = decodeUTF8(&src);
|
|
- #else
|
|
|
|
|
|
+#else
|
|
codePoint = *src;
|
|
codePoint = *src;
|
|
src++;
|
|
src++;
|
|
- #endif
|
|
|
|
- if (i < callData->chg_first || callData->chg_first+length < i) {
|
|
|
|
|
|
+#endif
|
|
|
|
+ if (i < callData->chg_first || callData->chg_first + length < i)
|
|
continue;
|
|
continue;
|
|
- }
|
|
|
|
|
|
+
|
|
window->preeditText[j++] = codePoint;
|
|
window->preeditText[j++] = codePoint;
|
|
f = text->feedback[i];
|
|
f = text->feedback[i];
|
|
- if ((f & XIMReverse) || (f & XIMHighlight)) {
|
|
|
|
|
|
+
|
|
|
|
+ if ((f & XIMReverse) || (f & XIMHighlight))
|
|
|
|
+ {
|
|
rend = i;
|
|
rend = i;
|
|
- if (i < rstart) {
|
|
|
|
|
|
+ if (i < rstart)
|
|
rstart = i;
|
|
rstart = i;
|
|
- }
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if (rstart == length) {
|
|
|
|
- window->nblocks = 1;
|
|
|
|
- window->preeditAttributeBlocks[0] = length;
|
|
|
|
- window->preeditAttributeBlocks[1] = 0;
|
|
|
|
|
|
+
|
|
|
|
+ if (rstart == length)
|
|
|
|
+ {
|
|
|
|
+ window->preeditBlockCount = 1;
|
|
|
|
+ window->preeditBlocks[0] = length;
|
|
|
|
+ window->preeditBlocks[1] = 0;
|
|
_glfwInputPreedit(window, 0);
|
|
_glfwInputPreedit(window, 0);
|
|
- } else if (rstart == 0) {
|
|
|
|
- if (rend == length -1) {
|
|
|
|
- window->nblocks = 1;
|
|
|
|
- window->preeditAttributeBlocks[0] = length;
|
|
|
|
- window->preeditAttributeBlocks[1] = 0;
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (rstart == 0)
|
|
|
|
+ {
|
|
|
|
+ if (rend == length -1)
|
|
|
|
+ {
|
|
|
|
+ window->preeditBlockCount = 1;
|
|
|
|
+ window->preeditBlocks[0] = length;
|
|
|
|
+ window->preeditBlocks[1] = 0;
|
|
_glfwInputPreedit(window, 0);
|
|
_glfwInputPreedit(window, 0);
|
|
- } else {
|
|
|
|
- window->nblocks = 2;
|
|
|
|
- window->preeditAttributeBlocks[0] = rend + 1;
|
|
|
|
- window->preeditAttributeBlocks[1] = length - rend - 1;
|
|
|
|
- window->preeditAttributeBlocks[2] = 0;
|
|
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ window->preeditBlockCount = 2;
|
|
|
|
+ window->preeditBlocks[0] = rend + 1;
|
|
|
|
+ window->preeditBlocks[1] = length - rend - 1;
|
|
|
|
+ window->preeditBlocks[2] = 0;
|
|
_glfwInputPreedit(window, 0);
|
|
_glfwInputPreedit(window, 0);
|
|
}
|
|
}
|
|
- } else if (rend == length -1) {
|
|
|
|
- window->nblocks = 2;
|
|
|
|
- window->preeditAttributeBlocks[0] = rstart;
|
|
|
|
- window->preeditAttributeBlocks[1] = length - rstart;
|
|
|
|
- window->preeditAttributeBlocks[2] = 0;
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (rend == length -1)
|
|
|
|
+ {
|
|
|
|
+ window->preeditBlockCount = 2;
|
|
|
|
+ window->preeditBlocks[0] = rstart;
|
|
|
|
+ window->preeditBlocks[1] = length - rstart;
|
|
|
|
+ window->preeditBlocks[2] = 0;
|
|
_glfwInputPreedit(window, 1);
|
|
_glfwInputPreedit(window, 1);
|
|
- } else {
|
|
|
|
- window->nblocks = 3;
|
|
|
|
- window->preeditAttributeBlocks[0] = rstart;
|
|
|
|
- window->preeditAttributeBlocks[1] = rend - rstart + 1;
|
|
|
|
- window->preeditAttributeBlocks[2] = length - rend - 1;
|
|
|
|
- window->preeditAttributeBlocks[3] = 0;
|
|
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ window->preeditBlockCount = 3;
|
|
|
|
+ window->preeditBlocks[0] = rstart;
|
|
|
|
+ window->preeditBlocks[1] = rend - rstart + 1;
|
|
|
|
+ window->preeditBlocks[2] = length - rend - 1;
|
|
|
|
+ window->preeditBlocks[3] = 0;
|
|
_glfwInputPreedit(window, 1);
|
|
_glfwInputPreedit(window, 1);
|
|
}
|
|
}
|
|
- if ((cursorX != window->preeditCursorPosX)
|
|
|
|
- || (cursorY != window->preeditCursorPosY)
|
|
|
|
- || (cursorHeight != window->preeditCursorHeight)) {
|
|
|
|
- _ximChangeCursorPosition(xic, window);
|
|
|
|
|
|
+
|
|
|
|
+ if ((caretX != window->preeditCaretPosX) ||
|
|
|
|
+ (caretY != window->preeditCaretPosY) ||
|
|
|
|
+ (caretHeight != window->preeditCaretHeight))
|
|
|
|
+ {
|
|
|
|
+ updateCaretPosition(window, xic);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// IME Caret callback (do nothing)
|
|
// IME Caret callback (do nothing)
|
|
-static void _ximPreeditCaretCallback(XIC xic, XPointer clientData, XPointer callData)
|
|
|
|
|
|
+//
|
|
|
|
+static void preeditCaretCallback(XIC xic, XPointer clientData, XPointer callData)
|
|
{
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
-static void _ximStatusStartCallback(XIC xic, XPointer clientData, XPointer callData)
|
|
|
|
|
|
+static void statusStartCallback(XIC xic, XPointer clientData, XPointer callData)
|
|
{
|
|
{
|
|
- _GLFWwindow* window = (_GLFWwindow*)clientData;
|
|
|
|
|
|
+ _GLFWwindow* window = (_GLFWwindow*) clientData;
|
|
window->x11.imeFocus = GLFW_TRUE;
|
|
window->x11.imeFocus = GLFW_TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
-static void _ximStatusDoneCallback(XIC xic, XPointer clientData, XPointer callData)
|
|
|
|
|
|
+static void statusDoneCallback(XIC xic, XPointer clientData, XPointer callData)
|
|
{
|
|
{
|
|
- _GLFWwindow* window = (_GLFWwindow*)clientData;
|
|
|
|
|
|
+ _GLFWwindow* window = (_GLFWwindow*) clientData;
|
|
window->x11.imeFocus = GLFW_FALSE;
|
|
window->x11.imeFocus = GLFW_FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
-static void _ximStatusDrawCallback(XIC xic, XPointer clientData, XIMStatusDrawCallbackStruct* callData)
|
|
|
|
|
|
+static void statusDrawCallback(XIC xic, XPointer clientData, XIMStatusDrawCallbackStruct* callData)
|
|
{
|
|
{
|
|
- _GLFWwindow* window = (_GLFWwindow*)clientData;
|
|
|
|
|
|
+ _GLFWwindow* window = (_GLFWwindow*) clientData;
|
|
_glfwInputIMEStatus(window);
|
|
_glfwInputIMEStatus(window);
|
|
}
|
|
}
|
|
|
|
|
|
// Create XIM Preedit callback
|
|
// Create XIM Preedit callback
|
|
|
|
+//
|
|
static XVaNestedList _createXIMPreeditCallbacks(_GLFWwindow* window)
|
|
static XVaNestedList _createXIMPreeditCallbacks(_GLFWwindow* window)
|
|
{
|
|
{
|
|
window->x11.preeditStartCallback.client_data = (XPointer)window;
|
|
window->x11.preeditStartCallback.client_data = (XPointer)window;
|
|
- window->x11.preeditStartCallback.callback = (XIMProc)_ximPreeditStartCallback;
|
|
|
|
|
|
+ window->x11.preeditStartCallback.callback = (XIMProc) preeditStartCallback;
|
|
window->x11.preeditDoneCallback.client_data = (XPointer)window;
|
|
window->x11.preeditDoneCallback.client_data = (XPointer)window;
|
|
- window->x11.preeditDoneCallback.callback = (XIMProc)_ximPreeditDoneCallback;
|
|
|
|
|
|
+ window->x11.preeditDoneCallback.callback = (XIMProc) preeditDoneCallback;
|
|
window->x11.preeditDrawCallback.client_data = (XPointer)window;
|
|
window->x11.preeditDrawCallback.client_data = (XPointer)window;
|
|
- window->x11.preeditDrawCallback.callback = (XIMProc)_ximPreeditDrawCallback;
|
|
|
|
|
|
+ window->x11.preeditDrawCallback.callback = (XIMProc) preeditDrawCallback;
|
|
window->x11.preeditCaretCallback.client_data = (XPointer)window;
|
|
window->x11.preeditCaretCallback.client_data = (XPointer)window;
|
|
- window->x11.preeditCaretCallback.callback = (XIMProc)_ximPreeditCaretCallback;
|
|
|
|
- return XVaCreateNestedList (0,
|
|
|
|
- XNPreeditStartCallback, &window->x11.preeditStartCallback.client_data,
|
|
|
|
- XNPreeditDoneCallback, &window->x11.preeditDoneCallback.client_data,
|
|
|
|
- XNPreeditDrawCallback, &window->x11.preeditDrawCallback.client_data,
|
|
|
|
- XNPreeditCaretCallback, &window->x11.preeditCaretCallback.client_data,
|
|
|
|
- NULL);
|
|
|
|
|
|
+ window->x11.preeditCaretCallback.callback = (XIMProc) preeditCaretCallback;
|
|
|
|
+ return XVaCreateNestedList(0,
|
|
|
|
+ XNPreeditStartCallback,
|
|
|
|
+ &window->x11.preeditStartCallback.client_data,
|
|
|
|
+ XNPreeditDoneCallback,
|
|
|
|
+ &window->x11.preeditDoneCallback.client_data,
|
|
|
|
+ XNPreeditDrawCallback,
|
|
|
|
+ &window->x11.preeditDrawCallback.client_data,
|
|
|
|
+ XNPreeditCaretCallback,
|
|
|
|
+ &window->x11.preeditCaretCallback.client_data,
|
|
|
|
+ NULL);
|
|
}
|
|
}
|
|
|
|
|
|
// Create XIM status callback
|
|
// Create XIM status callback
|
|
|
|
+//
|
|
static XVaNestedList _createXIMStatusCallbacks(_GLFWwindow* window)
|
|
static XVaNestedList _createXIMStatusCallbacks(_GLFWwindow* window)
|
|
{
|
|
{
|
|
window->x11.statusStartCallback.client_data = (XPointer)window;
|
|
window->x11.statusStartCallback.client_data = (XPointer)window;
|
|
- window->x11.statusStartCallback.callback = (XIMProc)_ximStatusStartCallback;
|
|
|
|
|
|
+ window->x11.statusStartCallback.callback = (XIMProc) statusStartCallback;
|
|
window->x11.statusDoneCallback.client_data = (XPointer)window;
|
|
window->x11.statusDoneCallback.client_data = (XPointer)window;
|
|
- window->x11.statusDoneCallback.callback = (XIMProc)_ximStatusDoneCallback;
|
|
|
|
|
|
+ window->x11.statusDoneCallback.callback = (XIMProc) statusDoneCallback;
|
|
window->x11.statusDrawCallback.client_data = (XPointer)window;
|
|
window->x11.statusDrawCallback.client_data = (XPointer)window;
|
|
- window->x11.statusDrawCallback.callback = (XIMProc)_ximStatusDrawCallback;
|
|
|
|
- return XVaCreateNestedList (0,
|
|
|
|
- XNStatusStartCallback, &window->x11.statusStartCallback.client_data,
|
|
|
|
- XNStatusDoneCallback, &window->x11.statusDoneCallback.client_data,
|
|
|
|
- XNStatusDrawCallback, &window->x11.statusDrawCallback.client_data,
|
|
|
|
- NULL);
|
|
|
|
|
|
+ window->x11.statusDrawCallback.callback = (XIMProc) statusDrawCallback;
|
|
|
|
+ return XVaCreateNestedList(0,
|
|
|
|
+ XNStatusStartCallback,
|
|
|
|
+ &window->x11.statusStartCallback.client_data,
|
|
|
|
+ XNStatusDoneCallback,
|
|
|
|
+ &window->x11.statusDoneCallback.client_data,
|
|
|
|
+ XNStatusDrawCallback,
|
|
|
|
+ &window->x11.statusDrawCallback.client_data,
|
|
|
|
+ NULL);
|
|
}
|
|
}
|
|
|
|
|
|
// Centers the cursor over the window client area
|
|
// Centers the cursor over the window client area
|
|
@@ -2682,47 +2704,46 @@ VkResult _glfwPlatformCreateWindowSurface(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;
|
|
|
|
|
|
+void _glfwPlatformResetPreeditText(_GLFWwindow* window)
|
|
|
|
+{
|
|
|
|
+ // Restore conversion state after resetting ic later
|
|
|
|
+ XIMPreeditState state = XIMPreeditUnKnown;
|
|
|
|
+ XVaNestedList attributes;
|
|
char* result;
|
|
char* result;
|
|
|
|
|
|
- if (window->ntext == 0)
|
|
|
|
|
|
+ if (*window->preeditText == 0)
|
|
return;
|
|
return;
|
|
|
|
|
|
- preedit_attr = XVaCreateNestedList(0, XNPreeditState, &preedit_state, NULL);
|
|
|
|
- XGetICValues(ic, XNPreeditAttributes, preedit_attr, NULL);
|
|
|
|
- XFree(preedit_attr);
|
|
|
|
|
|
+ attributes = XVaCreateNestedList(0, XNPreeditState, &state, NULL);
|
|
|
|
+ XGetICValues(window->x11.ic, XNPreeditAttributes, attributes, NULL);
|
|
|
|
+ XFree(attributes);
|
|
|
|
|
|
- result = XmbResetIC(ic);
|
|
|
|
|
|
+ result = XmbResetIC(window->x11.ic);
|
|
|
|
|
|
- preedit_attr = XVaCreateNestedList(0, XNPreeditState, preedit_state, NULL);
|
|
|
|
- XSetICValues(ic, XNPreeditAttributes, preedit_attr, NULL);
|
|
|
|
- XFree(preedit_attr);
|
|
|
|
|
|
+ attributes = XVaCreateNestedList(0, XNPreeditState, state, NULL);
|
|
|
|
+ XSetICValues(window->x11.ic, XNPreeditAttributes, attributes, NULL);
|
|
|
|
+ XFree(attributes);
|
|
|
|
|
|
- window->ntext = 0;
|
|
|
|
- window->nblocks = 0;
|
|
|
|
|
|
+ window->preeditBlockCount = 0;
|
|
_glfwInputPreedit(window, 0);
|
|
_glfwInputPreedit(window, 0);
|
|
|
|
|
|
- XFree (result);
|
|
|
|
|
|
+ XFree(result);
|
|
}
|
|
}
|
|
|
|
|
|
-void _glfwPlatformSetIMEStatus(_GLFWwindow* window, int active) {
|
|
|
|
- XIC ic = window->x11.ic;
|
|
|
|
- if (active) {
|
|
|
|
- XSetICFocus(ic);
|
|
|
|
- } else {
|
|
|
|
- XUnsetICFocus(ic);
|
|
|
|
- }
|
|
|
|
|
|
+void _glfwPlatformSetIMEStatus(_GLFWwindow* window, int active)
|
|
|
|
+{
|
|
|
|
+ if (active)
|
|
|
|
+ XSetICFocus(window->x11.ic);
|
|
|
|
+ else
|
|
|
|
+ XUnsetICFocus(window->x11.ic);
|
|
}
|
|
}
|
|
|
|
|
|
-int _glfwPlatformGetIMEStatus(_GLFWwindow* window) {
|
|
|
|
|
|
+int _glfwPlatformGetIMEStatus(_GLFWwindow* window)
|
|
|
|
+{
|
|
return window->x11.imeFocus;
|
|
return window->x11.imeFocus;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
////// GLFW native API //////
|
|
////// GLFW native API //////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|