We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2948

Summary: [Android] Arrow keys from external keyboard are not received
Product: SDL Reporter: Sylvain <sylvain.becker>
Component: joystickAssignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2    
Version: 2.0.3   
Hardware: ARM   
OS: Android (All)   
Attachments: patch

Description Sylvain 2015-04-17 12:47:26 UTC
http://developer.android.com/reference/android/view/InputDevice.html
 int SOURCE_CLASS_JOYSTICK   Constant Value: 16       (0x00000010) 

 int SOURCE_JOYSTICK         Constant Value: 16777232 (0x01000010) 
 int SOURCE_KEYBOARD         Constant Value: 257      (0x00000101) 
 int SOURCE_GAMEPAD          Constant Value: 1025     (0x00000401) 
 int SOURCE_DPAD             Constant Value:  513     (0x00000201) 


I have an a PC keyboard that I connect to an android device.
The issue is that "arrow" keys gets lost.

More explanation: 

This device gets detected twice by the java "pollInputDevices()" both as SOURCE_KEYBOARD and as a composite (0x1000311 == SOURCE_JOYSTICK | SOURCE_KEYBOARD | SOURCE_DPAD).
Because of being a SOURCE_CLASS_JOYSTICK, only the second entry is registered, and I opened it.


When I press one arrow key, the java method "onKey(...)" is called.
The Source "event.getSource()" is "SOURCE_KEYBOARD", so it enters this conditions : 

   if ( (event.getSource() & InputDevice.SOURCE_GAMEPAD) != 0 || 
      (event.getSource() & InputDevice.SOURCE_DPAD) != 0 ) {


And then, it enters : 
	
   SDLActivity.onNativePadDown() (native code in "SDL_sysjoystick.c")


Since the "arrows" are viewed as "D-PAD", it gets translated : 
   
   int button = keycode_to_SDL(keycode);


But the android-java "event.getDeviceId()" is wrong: this is the one from the Keyboard, and not the one from the Joystick that I have opened.
So I don't get them through the Joystick interface.


And since, the keycode has been translated, it returns 0 and assume it was consumed.
So I lost the key in the function "Android_OnPadDown()" 


Notice, It won't happen with other normal "letters" keys because they does not get translated by "keycode_to_SDL", so "Android_OnPadDown()" returns -1. 
And then java code send the keys to "SDLActivity.onNativeKeyDown()".




Possible patch on "Android_OnPadDown" and also "Android_OnPadUp" (and maybe other functons): 

85 int
186 Android_OnPadDown(int device_id, int keycode)
187 {
188     SDL_joylist_item *item;
189     int button = keycode_to_SDL(keycode);
190     if (button >= 0) {
191         item = JoystickByDeviceId(device_id);
192         if (item && item->joystick) {
193             SDL_PrivateJoystickButton(item->joystick, button , SDL_PRESSED);
194         } 
+           else return -1;
195         return 0;
196     }
197 
198     return -1;
199 }

It would allow the java caller function to send the key to "SDLActivity.onNativeKeyDown();"



Another solution, would be to replace: 

 if ( (event.getSource() & InputDevice.SOURCE_GAMEPAD) != 0 || 
      (event.getSource() & InputDevice.SOURCE_DPAD) != 0 ) {

by 

 if ( (event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0)

Because only "SOURCE_CLASS_JOYSTICK" devices are registered/opened.


Thanks
Comment 1 Sylvain 2015-04-17 18:18:08 UTC
See also: https://bugzilla.libsdl.org/show_bug.cgi?id=2949
Comment 2 Sam Lantinga 2015-06-17 05:19:10 UTC
Can you provide a tested patch for this issue?

Thanks!
Comment 3 Sylvain 2015-06-17 06:26:12 UTC
Created attachment 2180 [details]
patch

Here's a patch !

(maybe we could have the same process for onNativeHat)
Comment 4 Sam Lantinga 2015-06-17 07:01:16 UTC
Fixed, thanks!
https://hg.libsdl.org/SDL/rev/47ae0a3aa68f