From 934a5a5808c7a0b0dff469ad2c3a523e78a4ef4b Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Mon, 16 Aug 2010 20:12:06 +0000 Subject: Android port: add support for hardware keys * Forward Java KeyEvents to C layer and translate them to Rockbox BUTTON_*. * Add a basic Android keymap git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27832 a1c6a512-1295-4272-9138-f99709370657 --- android/src/org/rockbox/RockboxFramebuffer.java | 24 ++- apps/SOURCES | 2 + apps/keymaps/keymap-android.c | 198 +++++++++++++++++++++ firmware/SOURCES | 3 + firmware/export/config.h | 1 + firmware/export/config/application.h | 4 + .../target/hosted/android/app/android_keyevents.h | 97 ++++++++++ .../target/hosted/android/app/android_keyevents.sh | 9 + .../target/hosted/android/app/button-application.c | 24 ++- firmware/target/hosted/android/app/button-target.h | 43 +++-- firmware/target/hosted/android/button-android.c | 42 ++++- 11 files changed, 413 insertions(+), 34 deletions(-) create mode 100644 apps/keymaps/keymap-android.c create mode 100644 firmware/target/hosted/android/app/android_keyevents.h create mode 100755 firmware/target/hosted/android/app/android_keyevents.sh diff --git a/android/src/org/rockbox/RockboxFramebuffer.java b/android/src/org/rockbox/RockboxFramebuffer.java index 32fbfef111..1734b4fab1 100644 --- a/android/src/org/rockbox/RockboxFramebuffer.java +++ b/android/src/org/rockbox/RockboxFramebuffer.java @@ -22,23 +22,28 @@ package org.rockbox; import java.nio.ByteBuffer; + import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.util.Log; +import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; -public class RockboxFramebuffer extends View +public class RockboxFramebuffer extends View { private Bitmap btm; private ByteBuffer native_buf; - public RockboxFramebuffer(Context c) { super(c); btm = null; + + /* Needed so we can catch KeyEvents */ + setFocusable(true); + requestFocus(); } public void onDraw(Canvas c) @@ -55,7 +60,6 @@ public class RockboxFramebuffer extends View public void java_lcd_update() { - btm.copyPixelsFromBuffer(native_buf); postInvalidate(); } @@ -64,6 +68,7 @@ public class RockboxFramebuffer extends View { /* can't copy a partial buffer */ btm.copyPixelsFromBuffer(native_buf); + postInvalidate(x, y, x+w, y+h); } @@ -90,7 +95,17 @@ public class RockboxFramebuffer extends View pixelHandler((int)me.getX(), (int)me.getY()); return true; } - + + public boolean onKeyDown(int keyCode, KeyEvent event) + { + return buttonHandler(keyCode, true); + } + + public boolean onKeyUp(int keyCode, KeyEvent event) + { + return buttonHandler(keyCode, false); + } + /* the two below should only be called from the activity thread */ public void suspend() { /* suspend, Rockbox will not make any lcd updates */ @@ -105,4 +120,5 @@ public class RockboxFramebuffer extends View public native void set_lcd_active(int active); public native void pixelHandler(int x, int y); public native void touchHandler(int down); + public native boolean buttonHandler(int keycode, boolean state); } diff --git a/apps/SOURCES b/apps/SOURCES index d15ba5bf6a..a00239428c 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -293,4 +293,6 @@ keymaps/keymap-mini2440.c keymaps/keymap-vibe500.c #elif CONFIG_KEYPAD == MPIO_HD200_PAD keymaps/keymap-mpio-hd200.c +#elif CONFIG_KEYPAD == ANDROID_PAD +keymaps/keymap-android.c #endif diff --git a/apps/keymaps/keymap-android.c b/apps/keymaps/keymap-android.c new file mode 100644 index 0000000000..cbc20c3e67 --- /dev/null +++ b/apps/keymaps/keymap-android.c @@ -0,0 +1,198 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Maurus Cuelenaere + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* Button Code Definitions for Android targets */ + +#include +#include +#include + +#include "config.h" +#include "action.h" +#include "button.h" +#include "settings.h" + +/* + * The format of the list is as follows + * { Action Code, Button code, Prereq button code } + * if there's no need to check the previous button's value, use BUTTON_NONE + * Insert LAST_ITEM_IN_LIST at the end of each mapping + */ + +static const struct button_mapping button_context_standard[] = { + { ACTION_STD_PREV, BUTTON_DPAD_UP, BUTTON_NONE }, + { ACTION_STD_PREVREPEAT, BUTTON_DPAD_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_NEXT, BUTTON_DPAD_DOWN, BUTTON_NONE }, + { ACTION_STD_NEXTREPEAT, BUTTON_DPAD_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + + { ACTION_STD_OK, BUTTON_DPAD_CENTER|BUTTON_REL, BUTTON_DPAD_CENTER }, + { ACTION_STD_OK, BUTTON_DPAD_RIGHT|BUTTON_REL, BUTTON_DPAD_RIGHT }, + { ACTION_STD_CANCEL, BUTTON_BACK, BUTTON_NONE }, + { ACTION_STD_CANCEL, BUTTON_DPAD_LEFT|BUTTON_REL, BUTTON_DPAD_LEFT }, + + { ACTION_STD_CONTEXT, BUTTON_MENU, BUTTON_NONE }, + + LAST_ITEM_IN_LIST +}; /* button_context_standard */ + +static const struct button_mapping button_context_wps[] = { + { ACTION_WPS_BROWSE, BUTTON_BACK, BUTTON_NONE }, + { ACTION_WPS_MENU, BUTTON_MENU|BUTTON_REL, BUTTON_MENU }, + { ACTION_WPS_CONTEXT, BUTTON_MENU|BUTTON_REPEAT, BUTTON_MENU }, + + LAST_ITEM_IN_LIST +}; /* button_context_wps */ + +static const struct button_mapping button_context_list[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_list */ + +static const struct button_mapping button_context_tree[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST) +}; /* button_context_tree */ + +static const struct button_mapping button_context_listtree_scroll_with_combo[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE), +}; + +static const struct button_mapping button_context_listtree_scroll_without_combo[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_TREE), +}; + +static const struct button_mapping button_context_settings[] = { + { ACTION_SETTINGS_INC, BUTTON_DPAD_RIGHT, BUTTON_NONE }, + { ACTION_SETTINGS_INCREPEAT, BUTTON_DPAD_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_SETTINGS_DEC, BUTTON_DPAD_LEFT, BUTTON_NONE }, + { ACTION_SETTINGS_DECREPEAT, BUTTON_DPAD_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_OK, BUTTON_DPAD_CENTER, BUTTON_NONE }, + { ACTION_STD_CANCEL, BUTTON_BACK, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_settings */ + +static const struct button_mapping button_context_settings_right_is_inc[] = { + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_settingsgraphical */ + +static const struct button_mapping button_context_yesno[] = { + { ACTION_YESNO_ACCEPT, BUTTON_DPAD_CENTER, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_settings_yesno */ + +static const struct button_mapping button_context_colorchooser[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS), +}; /* button_context_colorchooser */ + +static const struct button_mapping button_context_eq[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS), +}; /* button_context_eq */ + +/** Bookmark Screen **/ +static const struct button_mapping button_context_bmark[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST), +}; /* button_context_bmark */ + +static const struct button_mapping button_context_time[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS), +}; /* button_context_time */ + +static const struct button_mapping button_context_quickscreen[] = { + { ACTION_STD_CANCEL, BUTTON_BACK|BUTTON_REL, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_quickscreen */ + +static const struct button_mapping button_context_pitchscreen[] = { + + { ACTION_PS_INC_SMALL, BUTTON_DPAD_RIGHT, BUTTON_NONE }, + { ACTION_PS_INC_BIG, BUTTON_DPAD_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_PS_DEC_SMALL, BUTTON_DPAD_LEFT, BUTTON_NONE }, + { ACTION_PS_DEC_BIG, BUTTON_DPAD_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_PS_EXIT, BUTTON_BACK, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_pitchcreen */ + +static const struct button_mapping button_context_keyboard[] = { + { ACTION_KBD_PAGE_FLIP, BUTTON_MENU, BUTTON_NONE }, + { ACTION_KBD_CURSOR_LEFT, BUTTON_DPAD_LEFT, BUTTON_NONE }, + { ACTION_KBD_CURSOR_LEFT, BUTTON_DPAD_LEFT|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_KBD_CURSOR_RIGHT, BUTTON_DPAD_RIGHT, BUTTON_NONE }, + { ACTION_KBD_CURSOR_RIGHT, BUTTON_DPAD_RIGHT|BUTTON_REPEAT, BUTTON_NONE }, + + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) +}; /* button_context_keyboard */ + +static const struct button_mapping button_context_radio[] = { + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS) +}; /* button_context_radio */ + +const struct button_mapping* target_get_context_mapping(int context) +{ + switch (context) + { + case CONTEXT_STD: + return button_context_standard; + case CONTEXT_WPS: + return button_context_wps; + + case CONTEXT_LIST: + return button_context_list; + case CONTEXT_MAINMENU: + case CONTEXT_TREE: + if (global_settings.hold_lr_for_scroll_in_list) + return button_context_listtree_scroll_without_combo; + else + return button_context_listtree_scroll_with_combo; + case CONTEXT_CUSTOM|CONTEXT_TREE: + return button_context_tree; + + case CONTEXT_SETTINGS: + return button_context_settings; + case CONTEXT_CUSTOM|CONTEXT_SETTINGS: + case CONTEXT_SETTINGS_RECTRIGGER: + return button_context_settings_right_is_inc; + + case CONTEXT_SETTINGS_COLOURCHOOSER: + return button_context_colorchooser; + case CONTEXT_SETTINGS_EQ: + return button_context_eq; + + case CONTEXT_SETTINGS_TIME: + return button_context_time; + + case CONTEXT_YESNOSCREEN: + return button_context_yesno; + case CONTEXT_FM: + return button_context_radio; + case CONTEXT_BOOKMARKSCREEN: + return button_context_bmark; + case CONTEXT_QUICKSCREEN: + return button_context_quickscreen; + case CONTEXT_PITCHSCREEN: + return button_context_pitchscreen; + case CONTEXT_KEYBOARD: + return button_context_keyboard; + } + return button_context_standard; +} diff --git a/firmware/SOURCES b/firmware/SOURCES index f27a7dd140..19e51ac948 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1708,6 +1708,9 @@ target/hosted/android/button-android.c target/hosted/android/kernel-android.c target/hosted/android/pcm-android.c target/hosted/android/system-android.c +#ifdef APPLICATION +target/hosted/android/app/button-application.c +#endif drivers/audio/android.c thread.c #endif diff --git a/firmware/export/config.h b/firmware/export/config.h index 3b59004549..409c9d9965 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -128,6 +128,7 @@ #define PHILIPS_HDD6330_PAD 42 #define PBELL_VIBE500_PAD 43 #define MPIO_HD200_PAD 44 +#define ANDROID_PAD 45 /* CONFIG_REMOTE_KEYPAD */ #define H100_REMOTE 1 diff --git a/firmware/export/config/application.h b/firmware/export/config/application.h index 71ee62356b..6a87d5f62a 100644 --- a/firmware/export/config/application.h +++ b/firmware/export/config/application.h @@ -75,7 +75,11 @@ /* Define this if you do software codec */ #define CONFIG_CODEC SWCODEC +#ifdef ANDROID +#define CONFIG_KEYPAD ANDROID_PAD +#else #define CONFIG_KEYPAD COWON_D2_PAD +#endif #if (CONFIG_PLATFORM & PLATFORM_SDL) /* Use SDL audio/pcm in a SDL app build */ diff --git a/firmware/target/hosted/android/app/android_keyevents.h b/firmware/target/hosted/android/app/android_keyevents.h new file mode 100644 index 0000000000..82c525f396 --- /dev/null +++ b/firmware/target/hosted/android/app/android_keyevents.h @@ -0,0 +1,97 @@ +/* Ripped from http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob_plain;f=core/java/android/view/KeyEvent.java;hb=HEAD */ +#define KEYCODE_UNKNOWN 0 +#define KEYCODE_SOFT_LEFT 1 +#define KEYCODE_SOFT_RIGHT 2 +#define KEYCODE_HOME 3 +#define KEYCODE_BACK 4 +#define KEYCODE_CALL 5 +#define KEYCODE_ENDCALL 6 +#define KEYCODE_0 7 +#define KEYCODE_1 8 +#define KEYCODE_2 9 +#define KEYCODE_3 10 +#define KEYCODE_4 11 +#define KEYCODE_5 12 +#define KEYCODE_6 13 +#define KEYCODE_7 14 +#define KEYCODE_8 15 +#define KEYCODE_9 16 +#define KEYCODE_STAR 17 +#define KEYCODE_POUND 18 +#define KEYCODE_DPAD_UP 19 +#define KEYCODE_DPAD_DOWN 20 +#define KEYCODE_DPAD_LEFT 21 +#define KEYCODE_DPAD_RIGHT 22 +#define KEYCODE_DPAD_CENTER 23 +#define KEYCODE_VOLUME_UP 24 +#define KEYCODE_VOLUME_DOWN 25 +#define KEYCODE_POWER 26 +#define KEYCODE_CAMERA 27 +#define KEYCODE_CLEAR 28 +#define KEYCODE_A 29 +#define KEYCODE_B 30 +#define KEYCODE_C 31 +#define KEYCODE_D 32 +#define KEYCODE_E 33 +#define KEYCODE_F 34 +#define KEYCODE_G 35 +#define KEYCODE_H 36 +#define KEYCODE_I 37 +#define KEYCODE_J 38 +#define KEYCODE_K 39 +#define KEYCODE_L 40 +#define KEYCODE_M 41 +#define KEYCODE_N 42 +#define KEYCODE_O 43 +#define KEYCODE_P 44 +#define KEYCODE_Q 45 +#define KEYCODE_R 46 +#define KEYCODE_S 47 +#define KEYCODE_T 48 +#define KEYCODE_U 49 +#define KEYCODE_V 50 +#define KEYCODE_W 51 +#define KEYCODE_X 52 +#define KEYCODE_Y 53 +#define KEYCODE_Z 54 +#define KEYCODE_COMMA 55 +#define KEYCODE_PERIOD 56 +#define KEYCODE_ALT_LEFT 57 +#define KEYCODE_ALT_RIGHT 58 +#define KEYCODE_SHIFT_LEFT 59 +#define KEYCODE_SHIFT_RIGHT 60 +#define KEYCODE_TAB 61 +#define KEYCODE_SPACE 62 +#define KEYCODE_SYM 63 +#define KEYCODE_EXPLORER 64 +#define KEYCODE_ENVELOPE 65 +#define KEYCODE_ENTER 66 +#define KEYCODE_DEL 67 +#define KEYCODE_GRAVE 68 +#define KEYCODE_MINUS 69 +#define KEYCODE_EQUALS 70 +#define KEYCODE_LEFT_BRACKET 71 +#define KEYCODE_RIGHT_BRACKET 72 +#define KEYCODE_BACKSLASH 73 +#define KEYCODE_SEMICOLON 74 +#define KEYCODE_APOSTROPHE 75 +#define KEYCODE_SLASH 76 +#define KEYCODE_AT 77 +#define KEYCODE_NUM 78 +#define KEYCODE_HEADSETHOOK 79 +#define KEYCODE_FOCUS 80 +#define KEYCODE_PLUS 81 +#define KEYCODE_MENU 82 +#define KEYCODE_NOTIFICATION 83 +#define KEYCODE_SEARCH 84 +#define KEYCODE_MEDIA_PLAY_PAUSE 85 +#define KEYCODE_MEDIA_STOP 86 +#define KEYCODE_MEDIA_NEXT 87 +#define KEYCODE_MEDIA_PREVIOUS 88 +#define KEYCODE_MEDIA_REWIND 89 +#define KEYCODE_MEDIA_FAST_FORWARD 90 +#define KEYCODE_MUTE 91 +#define KEYCODE_PAGE_UP 92 +#define KEYCODE_PAGE_DOWN 93 +#define KEYCODE_PICTSYMBOLS 94 +#define KEYCODE_SWITCH_CHARSET 95 diff --git a/firmware/target/hosted/android/app/android_keyevents.sh b/firmware/target/hosted/android/app/android_keyevents.sh new file mode 100755 index 0000000000..cd654ad01e --- /dev/null +++ b/firmware/target/hosted/android/app/android_keyevents.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# Simple script that converts Android's KEYCODE_* ints to preprocessor #defines + +URL="http://android.git.kernel.org/?p=platform/frameworks/base.git;a=blob_plain;f=core/java/android/view/KeyEvent.java;hb=HEAD" + +echo "Processing $URL..." +(echo "/* Ripped from $URL */"; + curl $URL | grep "public static final int KEYCODE" | sed 's/^.*public static final int \(KEYCODE_.*\) *= *\([0-9]*\).*$/#define \1 \2/' +) > `dirname $0`/android_keyevents.h diff --git a/firmware/target/hosted/android/app/button-application.c b/firmware/target/hosted/android/app/button-application.c index a27f769718..47798a6096 100644 --- a/firmware/target/hosted/android/app/button-application.c +++ b/firmware/target/hosted/android/app/button-application.c @@ -17,13 +17,31 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - ***************************************************9*************************/ + *****************************************************************************/ #include "button.h" +#include "android_keyevents.h" int key_to_button(int keyboard_key) { - (void)keyboard_key; - return BUTTON_NONE; + switch (keyboard_key) + { + default: + return BUTTON_NONE; + case KEYCODE_BACK: + return BUTTON_BACK; + case KEYCODE_DPAD_UP: + return BUTTON_DPAD_UP; + case KEYCODE_DPAD_DOWN: + return BUTTON_DPAD_DOWN; + case KEYCODE_DPAD_LEFT: + return BUTTON_DPAD_LEFT; + case KEYCODE_DPAD_RIGHT: + return BUTTON_DPAD_RIGHT; + case KEYCODE_DPAD_CENTER: + return BUTTON_DPAD_CENTER; + case KEYCODE_MENU: + return BUTTON_MENU; + } } diff --git a/firmware/target/hosted/android/app/button-target.h b/firmware/target/hosted/android/app/button-target.h index 329ed651af..6c7bd271e9 100644 --- a/firmware/target/hosted/android/app/button-target.h +++ b/firmware/target/hosted/android/app/button-target.h @@ -30,35 +30,32 @@ void button_init_device(void); int button_read_device(int *data); /* Main unit's buttons */ -#define BUTTON_POWER 0x00000001 -#define BUTTON_PLUS 0x00000002 -#define BUTTON_MINUS 0x00000004 -#define BUTTON_MENU 0x00000008 +#define BUTTON_MENU 0x00000001 +#define BUTTON_BACK 0x00000002 +#define BUTTON_DPAD_LEFT 0x00000004 +#define BUTTON_DPAD_RIGHT 0x00000008 +#define BUTTON_DPAD_UP 0x00000010 +#define BUTTON_DPAD_DOWN 0x00000020 +#define BUTTON_DPAD_CENTER 0x00000040 /* Compatibility hacks for flipping. Needs a somewhat better fix. */ -#define BUTTON_LEFT BUTTON_MIDLEFT -#define BUTTON_RIGHT BUTTON_MIDRIGHT -#define BUTTON_UP BUTTON_TOPMIDDLE -#define BUTTON_DOWN BUTTON_BOTTOMMIDDLE +#define BUTTON_LEFT BUTTON_DPAD_LEFT +#define BUTTON_RIGHT BUTTON_DPAD_RIGHT +#define BUTTON_UP BUTTON_DPAD_UP +#define BUTTON_DOWN BUTTON_DPAD_DOWN /* Touch Screen Area Buttons */ -#define BUTTON_TOPLEFT 0x00000010 -#define BUTTON_TOPMIDDLE 0x00000020 -#define BUTTON_TOPRIGHT 0x00000040 -#define BUTTON_MIDLEFT 0x00000080 -#define BUTTON_CENTER 0x00000100 -#define BUTTON_MIDRIGHT 0x00000200 -#define BUTTON_BOTTOMLEFT 0x00000400 -#define BUTTON_BOTTOMMIDDLE 0x00000800 -#define BUTTON_BOTTOMRIGHT 0x00001000 - -#define BUTTON_MAIN 0x1FFF +#define BUTTON_TOPLEFT 0x00001000 +#define BUTTON_TOPMIDDLE 0x00002000 +#define BUTTON_TOPRIGHT 0x00004000 +#define BUTTON_MIDLEFT 0x00008000 +#define BUTTON_CENTER 0x00010000 +#define BUTTON_MIDRIGHT 0x00020000 +#define BUTTON_BOTTOMLEFT 0x00040000 +#define BUTTON_BOTTOMMIDDLE 0x00080000 +#define BUTTON_BOTTOMRIGHT 0x00100000 /* No remote */ #define BUTTON_REMOTE 0 - -/* Software power-off */ -#define POWEROFF_BUTTON BUTTON_POWER -#define POWEROFF_COUNT 10 #endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/hosted/android/button-android.c b/firmware/target/hosted/android/button-android.c index 1172880908..50e347e714 100644 --- a/firmware/target/hosted/android/button-android.c +++ b/firmware/target/hosted/android/button-android.c @@ -22,12 +22,15 @@ #include #include +#include "button.h" +#include "buttonmap.h" #include "config.h" #include "kernel.h" #include "system.h" #include "touchscreen.h" static int last_y, last_x; +static int last_btns; static enum { STATE_UNKNOWN, @@ -35,7 +38,6 @@ static enum { STATE_DOWN, } last_state = STATE_UNKNOWN; - /* * this writes in an interrupt-like fashion the last pixel coordinates * that the user pressed on the screen */ @@ -64,13 +66,45 @@ Java_org_rockbox_RockboxFramebuffer_touchHandler(JNIEnv*env, jobject this, last_state = STATE_UP; } +/* + * this writes in an interrupt-like fashion the button events that the user + * generated by pressing/releasing them to a variable */ +JNIEXPORT bool JNICALL +Java_org_rockbox_RockboxFramebuffer_buttonHandler(JNIEnv*env, jobject this, + int keycode, bool state) +{ + (void)env; + (void)this; + + int button = key_to_button(keycode); + + if (button == BUTTON_NONE) + return false; + + if (state) + last_btns |= button; + else + last_btns &= ~button; + + return true; +} + void button_init_device(void) { } int button_read_device(int *data) { - /* get grid button/coordinates based on the current touchscreen mode */ - int btn = touchscreen_to_pixels(last_x, last_y, data); - return (last_state == STATE_DOWN ? btn : 0); + int btn = last_btns; + /* Get grid button/coordinates based on the current touchscreen mode + * + * Caveat: the caller seemingly depends on *data always being filled with + * the last known touchscreen position, so always call + * touchscreen_to_pixels() */ + int touch = touchscreen_to_pixels(last_x, last_y, data); + + if (last_state == STATE_DOWN) + btn |= touch; + + return btn; } -- cgit