How to get current Input Language?


#1

Hi,

I would like to set up a MidiKeyboardComponent to catch my KeyPresses in such way that the ‘a’,‘s’,‘d’,‘f’,… row on the keyboard mimics the first white notes on the midi piano.
My problem is: how do I cope with the different input languages that my users might have? In French and German for instance, the keyboard layouts are quite different and the keycodes will be different.

How can I at least get the current input method so that I can change the keyboard mapping accordingly? (then I will have another problem of knowing how the other keyboards look like, but I guess resources can be found on the internet for that…).


#2

I don’t think it is possible without hacking the juce code. You have to retrieve the key virtual scancode, which is independent of the local keyboard layout , see for example what is mentionned here:

http://www.rawmaterialsoftware.com/viewtopic.php?f=2&t=7754&p=43769#p43769

I have defined a global int variable “GLOBAL_keycode_of_last_event” that is written into each time a key is released or pressed . Its value can be checked in the keyPressed / keyStateChanged callback of your component.

--- modules.orig/juce_gui_basics/native/juce_linux_Windowing.cpp  2012-02-17 09:50:23.000000000 +0100
+++ modules/juce_gui_basics/native/juce_linux_Windowing.cpp       2012-02-17 09:50:27.000000000 +0100
@@ -736,6 +736,7 @@
     }
 }

+int GLOBAL_keycode_of_last_event; 

 //==============================================================================
 class LinuxComponentPeer  : public ComponentPeer
@@ -1254,6 +1255,7 @@
         bool keyDownChange = false;
         KeySym sym;

+        GLOBAL_keycode_of_last_event = keyEvent->keycode; 
         {
             ScopedXLock xlock;
             updateKeyStates (keyEvent->keycode, true);
@@ -1365,6 +1367,7 @@
     {
         if (! isKeyReleasePartOfAutoRepeat (keyEvent))
         {
+            GLOBAL_keycode_of_last_event = keyEvent->keycode; 
             updateKeyStates (keyEvent->keycode, false);
             KeySym sym;

@@ -2715,6 +2718,11 @@
     }
 }

--- modules.orig/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm   2012-02-14 23:41:24.000000000 +0100
+++ modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm        2012-02-17 09:50:27.000000000 +0100
@@ -1378,6 +1378,8 @@
 {
 }

+int GLOBAL_keycode_of_last_event; // horrible hack to provide a low-level keycode info.
+
 bool NSViewComponentPeer::handleKeyEvent (NSEvent* ev, bool isKeyDown)
 {
     String unicode (nsStringToJuce ([ev characters]));
@@ -1387,6 +1389,8 @@
     //DBG ("unicode: " + unicode + " " + String::toHexString ((int) unicode[0]));
     //DBG ("unmodified: " + unmodified + " " + String::toHexString ((int) unmodified[0]));

+    GLOBAL_keycode_of_last_event = [ev keyCode];
+
     if (unicode.isNotEmpty() || keyCode != 0)
     {
         if (isKeyDown)
@@ -1412,6 +1416,10 @@
             if (handleKeyUpOrDown (false))
                 return true;
         }
+    } else {
+        if (handleKeyUpOrDown (isKeyDown))
+            return true;
     }

     return false;
@@ -1446,6 +1454,8 @@

 void NSViewComponentPeer::redirectModKeyChange (NSEvent* ev)
 {
+    GLOBAL_keycode_of_last_event = [ev keyCode];
+
     keysCurrentlyDown.clear();
     handleKeyUpOrDown (true);

--- modules.orig/juce_gui_basics/native/juce_win32_Windowing.cpp  2012-02-14 23:41:25.000000000 +0100
+++ modules/juce_gui_basics/native/juce_win32_Windowing.cpp       2012-02-14 23:41:32.000000000 +0100
@@ -192,6 +192,7 @@
 const int KeyPress::fastForwardKey          = 0x30002;
 const int KeyPress::rewindKey               = 0x30003;

+int GLOBAL_keycode_of_last_event; // horrible hack to provide a low-level keycode info.

 //==============================================================================
 class WindowsBitmapImage  : public ImagePixelData
@@ -2223,6 +2224,7 @@
             //==============================================================================
             case WM_KEYDOWN:
             case WM_SYSKEYDOWN:
+                GLOBAL_keycode_of_last_event = ((lParam & 0xFF0000) >> 16); 
                 if (doKeyDown (wParam))
                     return 0;

@@ -2231,6 +2233,7 @@

             case WM_KEYUP:
             case WM_SYSKEYUP:
+                GLOBAL_keycode_of_last_event = ((lParam & 0xFF0000) >> 16); 
                 if (doKeyUp (wParam))
                     return 0;

Definitively not elegant but it does work very well. The mapping keycode <-> physical key is OS-dependant, though