Commit 2b0140a91f2ec32f674957068cdf7ead053e6e05

Sam Lantinga 2015-10-27T11:17:32

Add a new SDL_KEYMAPCHANGED SDL event to abstract notification of keyboard layout or input language changes.

diff --git a/include/SDL_events.h b/include/SDL_events.h
index 2ccb101..8a364c2 100644
--- a/include/SDL_events.h
+++ b/include/SDL_events.h
@@ -94,6 +94,9 @@ typedef enum
     SDL_KEYUP,                  /**< Key released */
     SDL_TEXTEDITING,            /**< Keyboard text editing (composition) */
     SDL_TEXTINPUT,              /**< Keyboard text input */
+    SDL_KEYMAPCHANGED,          /**< Keymap changed due to a system event such as an
+                                     input language or keyboard layout change.
+                                */
 
     /* Mouse events */
     SDL_MOUSEMOTION    = 0x400, /**< Mouse moved */
diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c
index 4f5bb2d..513cb55 100644
--- a/src/events/SDL_events.c
+++ b/src/events/SDL_events.c
@@ -649,4 +649,10 @@ SDL_SendSysWMEvent(SDL_SysWMmsg * message)
     return (posted);
 }
 
+int
+SDL_SendKeymapChangedEvent(void)
+{
+    return SDL_SendAppEvent(SDL_KEYMAPCHANGED);
+}
+
 /* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/events/SDL_events_c.h b/src/events/SDL_events_c.h
index ebd983d..0ead5f3 100644
--- a/src/events/SDL_events_c.h
+++ b/src/events/SDL_events_c.h
@@ -38,6 +38,7 @@ extern void SDL_QuitInterrupt(void);
 
 extern int SDL_SendAppEvent(SDL_EventType eventType);
 extern int SDL_SendSysWMEvent(SDL_SysWMmsg * message);
+extern int SDL_SendKeymapChangedEvent(void);
 
 extern int SDL_QuitInit(void);
 extern int SDL_SendQuit(void);
diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m
index 41ecf1f..9abca97 100644
--- a/src/video/cocoa/SDL_cocoakeyboard.m
+++ b/src/video/cocoa/SDL_cocoakeyboard.m
@@ -398,7 +398,7 @@ HandleModifiers(_THIS, unsigned short scancode, unsigned int modifierFlags)
 }
 
 static void
-UpdateKeymap(SDL_VideoData *data)
+UpdateKeymap(SDL_VideoData *data, SDL_bool send_event)
 {
     TISInputSourceRef key_layout;
     const void *chr_data;
@@ -454,6 +454,9 @@ UpdateKeymap(SDL_VideoData *data)
             }
         }
         SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
+        if (send_event) {
+            SDL_SendKeymapChangedEvent();
+        }
         return;
     }
 
@@ -466,7 +469,7 @@ Cocoa_InitKeyboard(_THIS)
 {
     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
 
-    UpdateKeymap(data);
+    UpdateKeymap(data, SDL_FALSE);
 
     /* Set our own names for the platform-dependent but layout-independent keys */
     /* This key is NumLock on the MacBook keyboard. :) */
@@ -564,7 +567,7 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
     case NSKeyDown:
         if (![event isARepeat]) {
             /* See if we need to rebuild the keyboard layout */
-            UpdateKeymap(data);
+            UpdateKeymap(data, SDL_TRUE);
         }
 
         SDL_SendKeyboardKey(SDL_PRESSED, code);
diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index bb99f29..3ce8291 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -626,6 +626,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
     case WM_INPUTLANGCHANGE:
         {
             WIN_UpdateKeymap();
+            SDL_SendKeymapChangedEvent();
         }
         returnCode = 1;
         break;
diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c
index 7ec4edf..2f730c4 100644
--- a/src/video/x11/SDL_x11events.c
+++ b/src/video/x11/SDL_x11events.c
@@ -625,6 +625,7 @@ X11_DispatchEvent(_THIS)
             }
 
             X11_UpdateKeymap(_this);
+            SDL_SendKeymapChangedEvent();
         }
         return;
     }
@@ -1143,6 +1144,7 @@ X11_DispatchEvent(_THIS)
                    notice and reinit our keymap here. This might not be the
                    right approach, but it seems to work. */
                 X11_UpdateKeymap(_this);
+                SDL_SendKeymapChangedEvent();
             }
         }
         break;