Bladeren bron

The candidates in SDL_EVENT_TEXT_EDITING_CANDIDATES should be a single allocation

Sam Lantinga 9 maanden geleden
bovenliggende
commit
a340de6196
2 gewijzigde bestanden met toevoegingen van 40 en 26 verwijderingen
  1. 32 5
      src/events/SDL_keyboard.c
  2. 8 21
      test/testime.c

+ 32 - 5
src/events/SDL_keyboard.c

@@ -760,6 +760,37 @@ int SDL_SendEditingText(const char *text, int start, int length)
     return posted;
 }
 
+static const char * const *CreateCandidatesForEvent(char **candidates, int num_candidates)
+{
+    const char **event_candidates;
+    int i;
+    char *ptr;
+    size_t total_length = (num_candidates + 1) * sizeof(*event_candidates);
+
+    for (i = 0; i < num_candidates; ++i) {
+        size_t length = SDL_strlen(candidates[i]) + 1;
+
+        total_length += length;
+    }
+
+    event_candidates = (const char **)SDL_malloc(total_length);
+    if (!event_candidates) {
+        return NULL;
+    }
+    ptr = (char *)(event_candidates + (num_candidates + 1));
+
+    for (i = 0; i < num_candidates; ++i) {
+        size_t length = SDL_strlen(candidates[i]) + 1;
+
+        event_candidates[i] = ptr;
+        SDL_memcpy(ptr, candidates[i], length);
+        ptr += length;
+    }
+    event_candidates[i] = NULL;
+
+    return SDL_FreeLater(event_candidates);
+}
+
 int SDL_SendEditingTextCandidates(char **candidates, int num_candidates, int selected_candidate, SDL_bool horizontal)
 {
     SDL_Keyboard *keyboard = &SDL_keyboard;
@@ -778,14 +809,10 @@ int SDL_SendEditingTextCandidates(char **candidates, int num_candidates, int sel
         event.common.timestamp = 0;
         event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0;
         if (num_candidates > 0) {
-            const char **event_candidates = (const char **)SDL_AllocateTemporaryMemory((num_candidates + 1) * sizeof(*event_candidates));
+            const char * const *event_candidates = CreateCandidatesForEvent(candidates, num_candidates);
             if (!event_candidates) {
                 return 0;
             }
-            for (int i = 0; i < num_candidates; ++i) {
-                event_candidates[i] = SDL_CreateTemporaryString(candidates[i]);
-            }
-            event_candidates[num_candidates] = NULL;
             event.edit_candidates.candidates = event_candidates;
             event.edit_candidates.num_candidates = num_candidates;
             event.edit_candidates.selected_candidate = selected_candidate;

+ 8 - 21
test/testime.c

@@ -53,7 +53,7 @@ static int cursor_length = 0;
 static SDL_bool cursor_visible;
 static Uint64 last_cursor_change;
 static SDL_BlendMode highlight_mode;
-static char **candidates;
+static const char **candidates;
 static int num_candidates;
 static int selected_candidate;
 static SDL_bool horizontal_candidates;
@@ -431,7 +431,7 @@ static char *utf8_advance(char *p, size_t distance)
 }
 #endif
 
-static Uint32 utf8_decode(char *p, size_t len)
+static Uint32 utf8_decode(const char *p, size_t len)
 {
     Uint32 codepoint = 0;
     size_t i = 0;
@@ -476,11 +476,6 @@ static void InitInput(void)
 
 static void ClearCandidates(void)
 {
-    int i;
-
-    for (i = 0; i < num_candidates; ++i) {
-        SDL_free(candidates[i]);
-    }
     SDL_free(candidates);
     candidates = NULL;
     num_candidates = 0;
@@ -488,20 +483,12 @@ static void ClearCandidates(void)
 
 static void SaveCandidates(SDL_Event *event)
 {
-    int i;
-
     ClearCandidates();
 
     num_candidates = event->edit_candidates.num_candidates;
     if (num_candidates > 0) {
-        candidates = (char **)SDL_malloc(num_candidates * sizeof(*candidates));
-        if (!candidates) {
-            num_candidates = 0;
-            return;
-        }
-        for (i = 0; i < num_candidates; ++i) {
-            candidates[i] = SDL_strdup(event->edit_candidates.candidates[i]);
-        }
+        candidates = (const char **)SDL_ClaimTemporaryMemory(event->edit_candidates.candidates);
+        SDL_assert(candidates);
         selected_candidate = event->edit_candidates.selected_candidate;
         horizontal_candidates = event->edit_candidates.horizontal;
     }
@@ -529,7 +516,7 @@ static void DrawCandidates(int rendererID, SDL_FRect *cursorRect)
         /* FIXME */
 #else
         if (horizontal_candidates) {
-            char *utext = candidates[i];
+            const char *utext = candidates[i];
             Uint32 codepoint;
             size_t len;
             float advance = 0.0f;
@@ -544,7 +531,7 @@ static void DrawCandidates(int rendererID, SDL_FRect *cursorRect)
             w += advance;
             h = UNIFONT_GLYPH_SIZE * UNIFONT_DRAW_SCALE;
         } else {
-            char *utext = candidates[i];
+            const char *utext = candidates[i];
             Uint32 codepoint;
             size_t len;
             float advance = 0.0f;
@@ -596,7 +583,7 @@ static void DrawCandidates(int rendererID, SDL_FRect *cursorRect)
         dstRect.h = UNIFONT_GLYPH_SIZE * UNIFONT_DRAW_SCALE;
 
         if (horizontal_candidates) {
-            char *utext = candidates[i];
+            const char *utext = candidates[i];
             Uint32 codepoint;
             size_t len;
             float start;
@@ -621,7 +608,7 @@ static void DrawCandidates(int rendererID, SDL_FRect *cursorRect)
                 SDL_RenderFillRect(renderer, &underlineRect);
             }
         } else {
-            char *utext = candidates[i];
+            const char *utext = candidates[i];
             Uint32 codepoint;
             size_t len;
             float start;