Browse Source

x11: Fail gracefully on keymap creation failure

Frank Praznik 6 ngày trước cách đây
mục cha
commit
8c4e048a68
1 tập tin đã thay đổi với 24 bổ sung11 xóa
  1. 24 11
      src/video/x11/SDL_x11keyboard.c

+ 24 - 11
src/video/x11/SDL_x11keyboard.c

@@ -307,14 +307,12 @@ static unsigned int X11_GetXkbVirtualModifierMask(SDL_VideoDevice *_this, const
     SDL_VideoData *videodata = _this->internal;
     unsigned int mod_mask = 0;
 
-    if (videodata->keyboard.xkb_enabled) {
-        Atom vmod = X11_XInternAtom(videodata->display, vmod_name, True);
-        if (vmod != None) {
-            for (int i = 0; i < XkbNumVirtualMods; ++i) {
-                if (vmod == videodata->keyboard.xkb.desc_ptr->names->vmods[i]) {
-                    mod_mask = videodata->keyboard.xkb.desc_ptr->server->vmods[i];
-                    break;
-                }
+    const Atom vmod = X11_XInternAtom(videodata->display, vmod_name, True);
+    if (vmod != None) {
+        for (int i = 0; i < XkbNumVirtualMods; ++i) {
+            if (vmod == videodata->keyboard.xkb.desc_ptr->names->vmods[i]) {
+                mod_mask = videodata->keyboard.xkb.desc_ptr->server->vmods[i];
+                break;
             }
         }
     }
@@ -382,7 +380,7 @@ void X11_UpdateKeymap(SDL_VideoDevice *_this, bool send_event)
 
         for (unsigned int i = 0; i < XkbNumKbdGroups; ++i) {
             SDL_DestroyKeymap(data->keyboard.xkb.keymaps[i]);
-            data->keyboard.xkb.keymaps[i] = SDL_CreateKeymap(false);
+            data->keyboard.xkb.keymaps[i] = NULL;
         }
 
         X11_XkbGetNames(data->display, XkbVirtualModNamesMask, data->keyboard.xkb.desc_ptr);
@@ -402,6 +400,18 @@ void X11_UpdateKeymap(SDL_VideoDevice *_this, bool send_event)
         data->keyboard.numlock_mask = X11_GetXkbVirtualModifierMask(_this, "NumLock");
         data->keyboard.scrolllock_mask = X11_GetXkbVirtualModifierMask(_this, "ScrollLock");
 
+        for (unsigned int i = 0; i < XkbNumKbdGroups; ++i) {
+            data->keyboard.xkb.keymaps[i] = SDL_CreateKeymap(false);
+            if (!data->keyboard.xkb.keymaps[i]) {
+                for (unsigned int j = 0; j < i; ++j) {
+                    SDL_DestroyKeymap(data->keyboard.xkb.keymaps[i]);
+                    data->keyboard.xkb.keymaps[j] = NULL;
+                }
+
+                return;
+            }
+        }
+
         const Uint32 valid_mod_mask = ShiftMask | LockMask | data->keyboard.alt_mask | data->keyboard.level3_mask | data->keyboard.level5_mask;
 
         for (Uint32 xkeycode = data->keyboard.xkb.desc_ptr->min_key_code; xkeycode < data->keyboard.xkb.desc_ptr->max_key_code; ++xkeycode) {
@@ -474,6 +484,9 @@ void X11_UpdateKeymap(SDL_VideoDevice *_this, bool send_event)
 #endif
     {
         SDL_Keymap *keymap = SDL_CreateKeymap(true);
+        if (!keymap) {
+            return;
+        }
 
         if (send_event) {
             if (data->keyboard.core.keysym_map) {
@@ -481,8 +494,8 @@ void X11_UpdateKeymap(SDL_VideoDevice *_this, bool send_event)
             }
             X11_XDisplayKeycodes(data->display, &data->keyboard.core.min_keycode, &data->keyboard.core.max_keycode);
             data->keyboard.core.keysym_map = X11_XGetKeyboardMapping(data->display, data->keyboard.core.min_keycode,
-                                                                  data->keyboard.core.max_keycode - data->keyboard.core.min_keycode,
-                                                                  &data->keyboard.core.keysyms_per_key);
+                                                                     data->keyboard.core.max_keycode - data->keyboard.core.min_keycode,
+                                                                     &data->keyboard.core.keysyms_per_key);
         }
 
         for (Uint32 xkeycode = data->keyboard.core.min_keycode; xkeycode <= data->keyboard.core.max_keycode; ++xkeycode) {