mirror of
https://github.com/libsdl-org/SDL.git
synced 2024-11-23 19:03:27 +08:00
Dynamically allocate long text for SDL_EVENT_TEXT_INPUT events
This prevents input text from being split across Unicode combining or modifier characters, and in practice allocations will rarely happen.
This commit is contained in:
parent
2a1660ab51
commit
75ea3a8d32
@ -298,7 +298,7 @@ The timestamp_us member of the sensor events has been renamed sensor_timestamp a
|
|||||||
|
|
||||||
You should set the event.common.timestamp field before passing an event to SDL_PushEvent(). If the timestamp is 0 it will be filled in with SDL_GetTicksNS().
|
You should set the event.common.timestamp field before passing an event to SDL_PushEvent(). If the timestamp is 0 it will be filled in with SDL_GetTicksNS().
|
||||||
|
|
||||||
You should call SDL_CleanupEvent() after handling SDL_EVENT_DROP_FILE, SDL_EVENT_DROP_TEXT, SDL_EVENT_SYSWM, and SDL_EVENT_TEXT_EDITING. This cleans up the memory associated with those events, and you no longer have to free the data yourself.
|
You should call SDL_CleanupEvent() after handling SDL_EVENT_DROP_FILE, SDL_EVENT_DROP_TEXT, SDL_EVENT_SYSWM, SDL_EVENT_TEXT_EDITING, and SDL_EVENT_TEXT_INPUT. This cleans up the memory associated with those events, and you no longer have to free the data yourself.
|
||||||
|
|
||||||
Mouse events use floating point values for mouse coordinates and relative motion values. You can get sub-pixel motion depending on the platform and display scaling.
|
Mouse events use floating point values for mouse coordinates and relative motion values. You can get sub-pixel motion depending on the platform and display scaling.
|
||||||
|
|
||||||
|
@ -284,7 +284,8 @@ typedef struct SDL_TextInputEvent
|
|||||||
Uint32 type; /**< ::SDL_EVENT_TEXT_INPUT */
|
Uint32 type; /**< ::SDL_EVENT_TEXT_INPUT */
|
||||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||||
SDL_WindowID windowID; /**< The window with keyboard focus, if any */
|
SDL_WindowID windowID; /**< The window with keyboard focus, if any */
|
||||||
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; /**< The input text */
|
char *text; /**< The input text */
|
||||||
|
char short_text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< Memory space for short input text, use 'text' instead */
|
||||||
} SDL_TextInputEvent;
|
} SDL_TextInputEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -470,11 +470,13 @@ static void SDL_LogEvent(const SDL_Event *event)
|
|||||||
|
|
||||||
static void SDL_CopyEvent(SDL_Event *dst, SDL_Event *src)
|
static void SDL_CopyEvent(SDL_Event *dst, SDL_Event *src)
|
||||||
{
|
{
|
||||||
*dst = *src;
|
SDL_copyp(dst, src);
|
||||||
|
|
||||||
/* Pointers to internal static data must be updated when copying. */
|
/* Pointers to internal static data must be updated when copying. */
|
||||||
if (src->type == SDL_EVENT_TEXT_EDITING && src->edit.text == src->edit.short_text) {
|
if (src->type == SDL_EVENT_TEXT_EDITING && src->edit.text == src->edit.short_text) {
|
||||||
dst->edit.text = dst->edit.short_text;
|
dst->edit.text = dst->edit.short_text;
|
||||||
|
} else if (src->type == SDL_EVENT_TEXT_INPUT && src->text.text == src->text.short_text) {
|
||||||
|
dst->text.text = dst->text.short_text;
|
||||||
} else if (src->type == SDL_EVENT_DROP_TEXT && src->drop.data == src->drop.short_data) {
|
} else if (src->type == SDL_EVENT_DROP_TEXT && src->drop.data == src->drop.short_data) {
|
||||||
dst->drop.data = dst->drop.short_data;
|
dst->drop.data = dst->drop.short_data;
|
||||||
}
|
}
|
||||||
@ -1106,6 +1108,12 @@ void SDL_CleanupEvent(SDL_Event *event)
|
|||||||
event->edit.text = NULL;
|
event->edit.text = NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SDL_EVENT_TEXT_INPUT:
|
||||||
|
if (event->text.text && event->text.text != event->text.short_text) {
|
||||||
|
SDL_free(event->text.text);
|
||||||
|
event->text.text = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1071,19 +1071,19 @@ int SDL_SendKeyboardText(const char *text)
|
|||||||
posted = 0;
|
posted = 0;
|
||||||
if (SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) {
|
if (SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
size_t pos = 0, advance, length = SDL_strlen(text);
|
|
||||||
|
|
||||||
event.type = SDL_EVENT_TEXT_INPUT;
|
event.type = SDL_EVENT_TEXT_INPUT;
|
||||||
event.common.timestamp = 0;
|
event.common.timestamp = 0;
|
||||||
event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
|
event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
|
||||||
while (pos < length) {
|
|
||||||
advance = SDL_utf8strlcpy(event.text.text, text + pos, SDL_arraysize(event.text.text));
|
size_t len = SDL_strlen(text);
|
||||||
if (!advance) {
|
if (len < sizeof(event.text.short_text)) {
|
||||||
break;
|
SDL_memcpy(event.text.short_text, text, len + 1);
|
||||||
}
|
event.text.text = event.text.short_text;
|
||||||
pos += advance;
|
} else {
|
||||||
posted |= (SDL_PushEvent(&event) > 0);
|
event.text.text = SDL_strdup(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
posted = (SDL_PushEvent(&event) > 0);
|
||||||
}
|
}
|
||||||
return posted;
|
return posted;
|
||||||
}
|
}
|
||||||
|
@ -186,6 +186,7 @@ static void loop(void)
|
|||||||
case SDL_EVENT_TEXT_INPUT:
|
case SDL_EVENT_TEXT_INPUT:
|
||||||
PrintText("INPUT", event.text.text);
|
PrintText("INPUT", event.text.text);
|
||||||
SDLTest_TextWindowAddText(textwin, "%s", event.text.text);
|
SDLTest_TextWindowAddText(textwin, "%s", event.text.text);
|
||||||
|
SDL_CleanupEvent(&event);
|
||||||
break;
|
break;
|
||||||
case SDL_EVENT_FINGER_DOWN:
|
case SDL_EVENT_FINGER_DOWN:
|
||||||
if (SDL_TextInputActive()) {
|
if (SDL_TextInputActive()) {
|
||||||
|
@ -187,6 +187,7 @@ static void loop(void)
|
|||||||
break;
|
break;
|
||||||
case SDL_EVENT_TEXT_INPUT:
|
case SDL_EVENT_TEXT_INPUT:
|
||||||
PrintText("INPUT", event.text.text);
|
PrintText("INPUT", event.text.text);
|
||||||
|
SDL_CleanupEvent(&event);
|
||||||
break;
|
break;
|
||||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||||
/* Left button quits the app, other buttons toggles text input */
|
/* Left button quits the app, other buttons toggles text input */
|
||||||
|
@ -1728,6 +1728,7 @@ static void loop(void *arg)
|
|||||||
AddControllerNameText(event.text.text);
|
AddControllerNameText(event.text.text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SDL_CleanupEvent(&event);
|
||||||
break;
|
break;
|
||||||
case SDL_EVENT_QUIT:
|
case SDL_EVENT_QUIT:
|
||||||
done = SDL_TRUE;
|
done = SDL_TRUE;
|
||||||
|
@ -770,6 +770,7 @@ int main(int argc, char *argv[])
|
|||||||
/* is committed */
|
/* is committed */
|
||||||
markedText[0] = 0;
|
markedText[0] = 0;
|
||||||
Redraw();
|
Redraw();
|
||||||
|
SDL_CleanupEvent(&event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SDL_EVENT_TEXT_EDITING:
|
case SDL_EVENT_TEXT_EDITING:
|
||||||
|
Loading…
Reference in New Issue
Block a user