diff options
author | Thomas Martitz <kugel@rockbox.org> | 2010-10-31 15:32:57 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2010-10-31 15:32:57 +0000 |
commit | 49f1ec8e8ad0b4c06df01fcdd4b18037fbe3ebcc (patch) | |
tree | b185e604dcea64865389f5b149e754ba8ffd3f75 | |
parent | dbe2ac1ec6f4ed88f267d2a4df024b6dc42a87ff (diff) | |
download | rockbox-49f1ec8e8ad0b4c06df01fcdd4b18037fbe3ebcc.tar.gz rockbox-49f1ec8e8ad0b4c06df01fcdd4b18037fbe3ebcc.zip |
Add support multimedia keys/buttons to the core, and adapt Rockbox on android for it (multimedia buttons are found on wired headsets and the lock screen in cyanogenmod).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28421 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | android/AndroidManifest.xml | 11 | ||||
-rw-r--r-- | android/src/org/rockbox/Helper/MediaButtonReceiver.java | 164 | ||||
-rw-r--r-- | android/src/org/rockbox/RockboxFramebuffer.java | 11 | ||||
-rw-r--r-- | android/src/org/rockbox/RockboxService.java | 2 | ||||
-rw-r--r-- | apps/action.c | 5 | ||||
-rw-r--r-- | apps/gui/wps.c | 14 | ||||
-rw-r--r-- | apps/menu.c | 16 | ||||
-rw-r--r-- | apps/misc.c | 37 | ||||
-rw-r--r-- | firmware/export/button.h | 15 | ||||
-rw-r--r-- | firmware/export/config/application.h | 1 | ||||
-rw-r--r-- | firmware/target/hosted/android/app/button-application.c | 21 | ||||
-rw-r--r-- | firmware/target/hosted/android/app/button-target.h | 1 | ||||
-rw-r--r-- | firmware/target/hosted/android/button-android.c | 19 |
13 files changed, 300 insertions, 17 deletions
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index c52d83fd2c..06a13ddb40 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml | |||
@@ -16,10 +16,21 @@ | |||
16 | </intent-filter> | 16 | </intent-filter> |
17 | </activity> | 17 | </activity> |
18 | <service android:name=".RockboxService"/> | 18 | <service android:name=".RockboxService"/> |
19 | <receiver android:name=".Helper.MediaButtonReceiver$MediaReceiver" | ||
20 | android:enabled="true" | ||
21 | android:exported="true"> | ||
22 | <intent-filter> | ||
23 | <action android:name="android.intent.action.MEDIA_BUTTON" /> | ||
24 | </intent-filter> | ||
25 | </receiver> | ||
19 | 26 | ||
20 | <activity android:name="KeyboardActivity"></activity> | 27 | <activity android:name="KeyboardActivity"></activity> |
21 | <activity android:name="YesnoActivity"></activity> | 28 | <activity android:name="YesnoActivity"></activity> |
22 | </application> | 29 | </application> |
23 | <uses-sdk android:minSdkVersion="4" /> | 30 | <uses-sdk android:minSdkVersion="4" /> |
24 | <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> | 31 | <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> |
32 | |||
33 | |||
34 | |||
35 | |||
25 | </manifest> | 36 | </manifest> |
diff --git a/android/src/org/rockbox/Helper/MediaButtonReceiver.java b/android/src/org/rockbox/Helper/MediaButtonReceiver.java new file mode 100644 index 0000000000..3749cec32a --- /dev/null +++ b/android/src/org/rockbox/Helper/MediaButtonReceiver.java | |||
@@ -0,0 +1,164 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 Thomas Martitz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | package org.rockbox.Helper; | ||
23 | |||
24 | import java.lang.reflect.Method; | ||
25 | |||
26 | import org.rockbox.RockboxService; | ||
27 | |||
28 | import android.content.BroadcastReceiver; | ||
29 | import android.content.ComponentName; | ||
30 | import android.content.Context; | ||
31 | import android.content.Intent; | ||
32 | import android.content.IntentFilter; | ||
33 | import android.media.AudioManager; | ||
34 | import android.view.KeyEvent; | ||
35 | |||
36 | public class MediaButtonReceiver | ||
37 | { | ||
38 | /* A note on the API being used. 2.2 introduces a new and sane API | ||
39 | * for handling multimedia button presses | ||
40 | * http://android-developers.blogspot.com/2010/06/allowing-applications-to-play-nicer.html | ||
41 | * | ||
42 | * the old API is flawed. It doesn't have management for | ||
43 | * concurrent media apps | ||
44 | * | ||
45 | * if multiple media apps are running | ||
46 | * probably all of them want to respond to media keys | ||
47 | * | ||
48 | * it's not clear which app wins, it depends on the | ||
49 | * priority set for the IntentFilter (see below) | ||
50 | * | ||
51 | * so this all might or might not work on < 2.2 */ | ||
52 | |||
53 | IMultiMediaReceiver api; | ||
54 | |||
55 | public MediaButtonReceiver(Context c) | ||
56 | { | ||
57 | try { | ||
58 | api = new NewApi(c); | ||
59 | } catch (Exception e) { | ||
60 | api = new OldApi(c); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | public void register() | ||
65 | { | ||
66 | api.register(); | ||
67 | } | ||
68 | |||
69 | public void unregister() | ||
70 | { | ||
71 | api.register(); | ||
72 | } | ||
73 | |||
74 | /* helper class for the manifest */ | ||
75 | public static class MediaReceiver extends BroadcastReceiver | ||
76 | { | ||
77 | @Override | ||
78 | public void onReceive(Context context, Intent intent) | ||
79 | { | ||
80 | if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) | ||
81 | { | ||
82 | KeyEvent key = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); | ||
83 | if (key.getAction() == KeyEvent.ACTION_UP) | ||
84 | { /* pass the pressed key to Rockbox */ | ||
85 | if (RockboxService.get_instance().get_fb().dispatchKeyEvent(key)) | ||
86 | abortBroadcast(); | ||
87 | } | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
92 | private interface IMultiMediaReceiver | ||
93 | { | ||
94 | void register(); | ||
95 | void unregister(); | ||
96 | } | ||
97 | |||
98 | private static class NewApi implements IMultiMediaReceiver | ||
99 | { | ||
100 | private Method register_method; | ||
101 | private Method unregister_method; | ||
102 | private AudioManager audio_manager; | ||
103 | private ComponentName receiver_name; | ||
104 | /* the constructor gets the methods through reflection so that | ||
105 | * this compiles on pre-2.2 devices */ | ||
106 | NewApi(Context c) throws SecurityException, NoSuchMethodException | ||
107 | { | ||
108 | register_method = AudioManager.class.getMethod( | ||
109 | "registerMediaButtonEventReceiver", | ||
110 | new Class[] { ComponentName.class } ); | ||
111 | unregister_method = AudioManager.class.getMethod( | ||
112 | "unregisterMediaButtonEventReceiver", | ||
113 | new Class[] { ComponentName.class } ); | ||
114 | |||
115 | audio_manager = (AudioManager)c.getSystemService(Context.AUDIO_SERVICE); | ||
116 | receiver_name = new ComponentName(c, MediaReceiver.class); | ||
117 | } | ||
118 | public void register() | ||
119 | { | ||
120 | try { | ||
121 | register_method.invoke(audio_manager, receiver_name); | ||
122 | } catch (Exception e) { | ||
123 | // Nothing | ||
124 | e.printStackTrace(); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | public void unregister() | ||
129 | { | ||
130 | try | ||
131 | { | ||
132 | unregister_method.invoke(audio_manager, receiver_name); | ||
133 | } catch (Exception e) { | ||
134 | // Nothing | ||
135 | e.printStackTrace(); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | } | ||
140 | |||
141 | private static class OldApi implements IMultiMediaReceiver | ||
142 | { | ||
143 | private static final IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON); | ||
144 | private MediaReceiver receiver; | ||
145 | private Context context; | ||
146 | OldApi(Context c) | ||
147 | { | ||
148 | filter.setPriority(1); /* 1 higher than the built-in media player */ | ||
149 | receiver = new MediaReceiver(); | ||
150 | context = c; | ||
151 | } | ||
152 | |||
153 | public void register() | ||
154 | { | ||
155 | context.registerReceiver(receiver, filter); | ||
156 | } | ||
157 | |||
158 | public void unregister() | ||
159 | { | ||
160 | context.unregisterReceiver(receiver); | ||
161 | } | ||
162 | |||
163 | } | ||
164 | } | ||
diff --git a/android/src/org/rockbox/RockboxFramebuffer.java b/android/src/org/rockbox/RockboxFramebuffer.java index 0daeffe265..84974d627a 100644 --- a/android/src/org/rockbox/RockboxFramebuffer.java +++ b/android/src/org/rockbox/RockboxFramebuffer.java | |||
@@ -23,6 +23,8 @@ package org.rockbox; | |||
23 | 23 | ||
24 | import java.nio.ByteBuffer; | 24 | import java.nio.ByteBuffer; |
25 | 25 | ||
26 | import org.rockbox.Helper.MediaButtonReceiver; | ||
27 | |||
26 | import android.content.Context; | 28 | import android.content.Context; |
27 | import android.graphics.Bitmap; | 29 | import android.graphics.Bitmap; |
28 | import android.graphics.Canvas; | 30 | import android.graphics.Canvas; |
@@ -35,6 +37,7 @@ public class RockboxFramebuffer extends View | |||
35 | { | 37 | { |
36 | private Bitmap btm; | 38 | private Bitmap btm; |
37 | private ByteBuffer native_buf; | 39 | private ByteBuffer native_buf; |
40 | private MediaButtonReceiver media_monitor; | ||
38 | 41 | ||
39 | public RockboxFramebuffer(Context c, int lcd_width, | 42 | public RockboxFramebuffer(Context c, int lcd_width, |
40 | int lcd_height, ByteBuffer native_fb) | 43 | int lcd_height, ByteBuffer native_fb) |
@@ -47,6 +50,8 @@ public class RockboxFramebuffer extends View | |||
47 | btm = Bitmap.createBitmap(lcd_width, lcd_height, Bitmap.Config.RGB_565); | 50 | btm = Bitmap.createBitmap(lcd_width, lcd_height, Bitmap.Config.RGB_565); |
48 | native_buf = native_fb; | 51 | native_buf = native_fb; |
49 | requestFocus(); | 52 | requestFocus(); |
53 | media_monitor = new MediaButtonReceiver(c); | ||
54 | media_monitor.register(); | ||
50 | /* the service needs to know the about us */ | 55 | /* the service needs to know the about us */ |
51 | ((RockboxService)c).set_fb(this); | 56 | ((RockboxService)c).set_fb(this); |
52 | } | 57 | } |
@@ -122,6 +127,12 @@ public class RockboxFramebuffer extends View | |||
122 | set_lcd_active(1); | 127 | set_lcd_active(1); |
123 | } | 128 | } |
124 | 129 | ||
130 | public void destroy() | ||
131 | { | ||
132 | suspend(); | ||
133 | media_monitor.unregister(); | ||
134 | } | ||
135 | |||
125 | public native void set_lcd_active(int active); | 136 | public native void set_lcd_active(int active); |
126 | public native void touchHandler(boolean down, int x, int y); | 137 | public native void touchHandler(boolean down, int x, int y); |
127 | public native boolean buttonHandler(int keycode, boolean state); | 138 | public native boolean buttonHandler(int keycode, boolean state); |
diff --git a/android/src/org/rockbox/RockboxService.java b/android/src/org/rockbox/RockboxService.java index b841bc5d7f..8989271b9f 100644 --- a/android/src/org/rockbox/RockboxService.java +++ b/android/src/org/rockbox/RockboxService.java | |||
@@ -139,6 +139,7 @@ public class RockboxService extends Service | |||
139 | { | 139 | { |
140 | public void run() | 140 | public void run() |
141 | { | 141 | { |
142 | LOG("main"); | ||
142 | /* the following block unzips libmisc.so, which contains the files | 143 | /* the following block unzips libmisc.so, which contains the files |
143 | * we ship, such as themes. It's needed to put it into a .so file | 144 | * we ship, such as themes. It's needed to put it into a .so file |
144 | * because there's no other way to ship files and have access | 145 | * because there's no other way to ship files and have access |
@@ -276,6 +277,7 @@ public class RockboxService extends Service | |||
276 | public void onDestroy() | 277 | public void onDestroy() |
277 | { | 278 | { |
278 | super.onDestroy(); | 279 | super.onDestroy(); |
280 | fb.destroy(); | ||
279 | /* Make sure our notification is gone. */ | 281 | /* Make sure our notification is gone. */ |
280 | stopForeground(); | 282 | stopForeground(); |
281 | } | 283 | } |
diff --git a/apps/action.c b/apps/action.c index 8f427c8d68..d61930a08c 100644 --- a/apps/action.c +++ b/apps/action.c | |||
@@ -183,8 +183,9 @@ static int get_action_worker(int context, int timeout, | |||
183 | else | 183 | else |
184 | button = button_get_w_tmo(timeout); | 184 | button = button_get_w_tmo(timeout); |
185 | 185 | ||
186 | /* Data from sys events can be pulled with button_get_data */ | 186 | /* Data from sys events can be pulled with button_get_data |
187 | if (button == BUTTON_NONE || button & SYS_EVENT) | 187 | * multimedia button presses don't go through the action system */ |
188 | if (button == BUTTON_NONE || button & (SYS_EVENT|BUTTON_MULTIMEDIA)) | ||
188 | return button; | 189 | return button; |
189 | /* Don't send any buttons through untill we see the release event */ | 190 | /* Don't send any buttons through untill we see the release event */ |
190 | if (wait_for_release) | 191 | if (wait_for_release) |
diff --git a/apps/gui/wps.c b/apps/gui/wps.c index a5fe304d21..7d633ad4e8 100644 --- a/apps/gui/wps.c +++ b/apps/gui/wps.c | |||
@@ -1045,18 +1045,18 @@ long gui_wps_show(void) | |||
1045 | exit = true; | 1045 | exit = true; |
1046 | break; | 1046 | break; |
1047 | #endif | 1047 | #endif |
1048 | case SYS_POWEROFF: | ||
1049 | default_event_handler(SYS_POWEROFF); | ||
1050 | break; | ||
1051 | case ACTION_WPS_VIEW_PLAYLIST: | 1048 | case ACTION_WPS_VIEW_PLAYLIST: |
1052 | gwps_leave_wps(); | 1049 | gwps_leave_wps(); |
1053 | return GO_TO_PLAYLIST_VIEWER; | 1050 | return GO_TO_PLAYLIST_VIEWER; |
1054 | break; | 1051 | break; |
1055 | default: | 1052 | default: |
1056 | if(default_event_handler(button) == SYS_USB_CONNECTED) | 1053 | switch(default_event_handler(button)) |
1057 | { | 1054 | { /* music has been stopped by the default handler */ |
1058 | gwps_leave_wps(); | 1055 | case SYS_USB_CONNECTED: |
1059 | return GO_TO_ROOT; | 1056 | case SYS_CALL_INCOMING: |
1057 | case BUTTON_MULTIMEDIA_STOP: | ||
1058 | gwps_leave_wps(); | ||
1059 | return GO_TO_ROOT; | ||
1060 | } | 1060 | } |
1061 | update = true; | 1061 | update = true; |
1062 | break; | 1062 | break; |
diff --git a/apps/menu.c b/apps/menu.c index 9d67c7b03e..5839a51c21 100644 --- a/apps/menu.c +++ b/apps/menu.c | |||
@@ -650,10 +650,20 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected, | |||
650 | } | 650 | } |
651 | #endif | 651 | #endif |
652 | } | 652 | } |
653 | else if(default_event_handler(action) == SYS_USB_CONNECTED) | 653 | else |
654 | { | 654 | { |
655 | ret = MENU_ATTACHED_USB; | 655 | switch(default_event_handler(action)) |
656 | done = true; | 656 | { |
657 | case SYS_USB_CONNECTED: | ||
658 | ret = MENU_ATTACHED_USB; | ||
659 | done = true; | ||
660 | break; | ||
661 | case SYS_CALL_HUNG_UP: | ||
662 | case BUTTON_MULTIMEDIA_PLAYPAUSE: | ||
663 | /* remove splash from playlist_resume() */ | ||
664 | redraw_lists = true; | ||
665 | break; | ||
666 | } | ||
657 | } | 667 | } |
658 | 668 | ||
659 | if (redraw_lists && !done) | 669 | if (redraw_lists && !done) |
diff --git a/apps/misc.c b/apps/misc.c index 8d0ca7922f..c41f63456c 100644 --- a/apps/misc.c +++ b/apps/misc.c | |||
@@ -529,6 +529,7 @@ long default_event_handler_ex(long event, void (*callback)(void *), void *parame | |||
529 | #if CONFIG_PLATFORM & PLATFORM_ANDROID | 529 | #if CONFIG_PLATFORM & PLATFORM_ANDROID |
530 | static bool resume = false; | 530 | static bool resume = false; |
531 | #endif | 531 | #endif |
532 | |||
532 | switch(event) | 533 | switch(event) |
533 | { | 534 | { |
534 | case SYS_BATTERY_UPDATE: | 535 | case SYS_BATTERY_UPDATE: |
@@ -629,11 +630,45 @@ long default_event_handler_ex(long event, void (*callback)(void *), void *parame | |||
629 | if (resume && playlist_resume() != -1) | 630 | if (resume && playlist_resume() != -1) |
630 | { | 631 | { |
631 | playlist_start(global_status.resume_index, | 632 | playlist_start(global_status.resume_index, |
632 | global_status.resume_offset); | 633 | global_status.resume_offset); |
633 | } | 634 | } |
634 | resume = false; | 635 | resume = false; |
635 | return SYS_CALL_HUNG_UP; | 636 | return SYS_CALL_HUNG_UP; |
636 | #endif | 637 | #endif |
638 | #ifdef HAVE_MULTIMEDIA_KEYS | ||
639 | /* multimedia keys on keyboards, headsets */ | ||
640 | case BUTTON_MULTIMEDIA_PLAYPAUSE: | ||
641 | { | ||
642 | int status = audio_status(); | ||
643 | if (status & AUDIO_STATUS_PLAY) | ||
644 | { | ||
645 | if (status & AUDIO_STATUS_PAUSE) | ||
646 | audio_resume(); | ||
647 | else | ||
648 | audio_pause(); | ||
649 | } | ||
650 | else | ||
651 | if (playlist_resume() != -1) | ||
652 | { | ||
653 | playlist_start(global_status.resume_index, | ||
654 | global_status.resume_offset); | ||
655 | } | ||
656 | return event; | ||
657 | } | ||
658 | case BUTTON_MULTIMEDIA_NEXT: | ||
659 | audio_next(); | ||
660 | return event; | ||
661 | case BUTTON_MULTIMEDIA_PREV: | ||
662 | audio_prev(); | ||
663 | return event; | ||
664 | case BUTTON_MULTIMEDIA_STOP: | ||
665 | list_stop_handler(); | ||
666 | return event; | ||
667 | case BUTTON_MULTIMEDIA_REW: | ||
668 | case BUTTON_MULTIMEDIA_FFWD: | ||
669 | /* not supported yet, needs to be done in the WPS */ | ||
670 | return 0; | ||
671 | #endif | ||
637 | } | 672 | } |
638 | return 0; | 673 | return 0; |
639 | } | 674 | } |
diff --git a/firmware/export/button.h b/firmware/export/button.h index 097f50a9d5..3847d2ac9f 100644 --- a/firmware/export/button.h +++ b/firmware/export/button.h | |||
@@ -69,6 +69,21 @@ int button_apply_acceleration(const unsigned int data); | |||
69 | #define BUTTON_REL 0x02000000 | 69 | #define BUTTON_REL 0x02000000 |
70 | #define BUTTON_REPEAT 0x04000000 | 70 | #define BUTTON_REPEAT 0x04000000 |
71 | #define BUTTON_TOUCHSCREEN 0x08000000 | 71 | #define BUTTON_TOUCHSCREEN 0x08000000 |
72 | #define BUTTON_MULTIMEDIA 0x10000000 | ||
73 | |||
74 | #define BUTTON_MULTIMEDIA_PLAYPAUSE (BUTTON_MULTIMEDIA|0x01) | ||
75 | #define BUTTON_MULTIMEDIA_STOP (BUTTON_MULTIMEDIA|0x02) | ||
76 | #define BUTTON_MULTIMEDIA_PREV (BUTTON_MULTIMEDIA|0x04) | ||
77 | #define BUTTON_MULTIMEDIA_NEXT (BUTTON_MULTIMEDIA|0x08) | ||
78 | #define BUTTON_MULTIMEDIA_REW (BUTTON_MULTIMEDIA|0x10) | ||
79 | #define BUTTON_MULTIMEDIA_FFWD (BUTTON_MULTIMEDIA|0x20) | ||
80 | |||
81 | #define BUTTON_MULTIMEDIA_ALL (BUTTON_MULTIMEDIA_PLAYPAUSE| \ | ||
82 | BUTTON_MULTIMEDIA_STOP| \ | ||
83 | BUTTON_MULTIMEDIA_PREV| \ | ||
84 | BUTTON_MULTIMEDIA_NEXT| \ | ||
85 | BUTTON_MULTIMEDIA_REW | \ | ||
86 | BUTTON_MULTIMEDIA_FFWD) | ||
72 | 87 | ||
73 | #ifdef HAVE_TOUCHSCREEN | 88 | #ifdef HAVE_TOUCHSCREEN |
74 | int touchscreen_last_touch(void); | 89 | int touchscreen_last_touch(void); |
diff --git a/firmware/export/config/application.h b/firmware/export/config/application.h index 4dc34c14fa..b731f0cf76 100644 --- a/firmware/export/config/application.h +++ b/firmware/export/config/application.h | |||
@@ -77,6 +77,7 @@ | |||
77 | 77 | ||
78 | #if (CONFIG_PLATFORM & PLATFORM_ANDROID) | 78 | #if (CONFIG_PLATFORM & PLATFORM_ANDROID) |
79 | #define CONFIG_KEYPAD ANDROID_PAD | 79 | #define CONFIG_KEYPAD ANDROID_PAD |
80 | #define HAVE_MULTIMEDIA_KEYS | ||
80 | #elif (CONFIG_PLATFORM & PLATFORM_SDL) | 81 | #elif (CONFIG_PLATFORM & PLATFORM_SDL) |
81 | #define HAVE_SCROLLWHEEL | 82 | #define HAVE_SCROLLWHEEL |
82 | #define CONFIG_KEYPAD SDL_PAD | 83 | #define CONFIG_KEYPAD SDL_PAD |
diff --git a/firmware/target/hosted/android/app/button-application.c b/firmware/target/hosted/android/app/button-application.c index 47798a6096..a7d75ef172 100644 --- a/firmware/target/hosted/android/app/button-application.c +++ b/firmware/target/hosted/android/app/button-application.c | |||
@@ -45,3 +45,24 @@ int key_to_button(int keyboard_key) | |||
45 | return BUTTON_MENU; | 45 | return BUTTON_MENU; |
46 | } | 46 | } |
47 | } | 47 | } |
48 | |||
49 | unsigned multimedia_to_button(int keyboard_key) | ||
50 | { | ||
51 | switch (keyboard_key) | ||
52 | { | ||
53 | case KEYCODE_MEDIA_PLAY_PAUSE: | ||
54 | return BUTTON_MULTIMEDIA_PLAYPAUSE; | ||
55 | case KEYCODE_MEDIA_STOP: | ||
56 | return BUTTON_MULTIMEDIA_STOP; | ||
57 | case KEYCODE_MEDIA_NEXT: | ||
58 | return BUTTON_MULTIMEDIA_NEXT; | ||
59 | case KEYCODE_MEDIA_PREVIOUS: | ||
60 | return BUTTON_MULTIMEDIA_PREV; | ||
61 | case KEYCODE_MEDIA_REWIND: | ||
62 | return BUTTON_MULTIMEDIA_REW; | ||
63 | case KEYCODE_MEDIA_FAST_FORWARD: | ||
64 | return BUTTON_MULTIMEDIA_FFWD; | ||
65 | default: | ||
66 | return 0; | ||
67 | } | ||
68 | } | ||
diff --git a/firmware/target/hosted/android/app/button-target.h b/firmware/target/hosted/android/app/button-target.h index 6c7bd271e9..ca306d4fef 100644 --- a/firmware/target/hosted/android/app/button-target.h +++ b/firmware/target/hosted/android/app/button-target.h | |||
@@ -28,6 +28,7 @@ | |||
28 | #undef button_init_device | 28 | #undef button_init_device |
29 | void button_init_device(void); | 29 | void button_init_device(void); |
30 | int button_read_device(int *data); | 30 | int button_read_device(int *data); |
31 | unsigned multimedia_to_button(int keyboard_key); | ||
31 | 32 | ||
32 | /* Main unit's buttons */ | 33 | /* Main unit's buttons */ |
33 | #define BUTTON_MENU 0x00000001 | 34 | #define BUTTON_MENU 0x00000001 |
diff --git a/firmware/target/hosted/android/button-android.c b/firmware/target/hosted/android/button-android.c index c072e3e38b..9bf15c25a2 100644 --- a/firmware/target/hosted/android/button-android.c +++ b/firmware/target/hosted/android/button-android.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include "kernel.h" | 28 | #include "kernel.h" |
29 | #include "system.h" | 29 | #include "system.h" |
30 | #include "touchscreen.h" | 30 | #include "touchscreen.h" |
31 | 31 | #include "debug.h" | |
32 | static int last_y, last_x; | 32 | static int last_y, last_x; |
33 | static int last_btns; | 33 | static int last_btns; |
34 | static long last_button_tick; | 34 | static long last_button_tick; |
@@ -44,7 +44,7 @@ static enum { | |||
44 | * began or stopped the touch action + where (pixel coordinates) */ | 44 | * began or stopped the touch action + where (pixel coordinates) */ |
45 | JNIEXPORT void JNICALL | 45 | JNIEXPORT void JNICALL |
46 | Java_org_rockbox_RockboxFramebuffer_touchHandler(JNIEnv*env, jobject this, | 46 | Java_org_rockbox_RockboxFramebuffer_touchHandler(JNIEnv*env, jobject this, |
47 | bool down, int x, int y) | 47 | jboolean down, jint x, jint y) |
48 | { | 48 | { |
49 | (void)env; | 49 | (void)env; |
50 | (void)this; | 50 | (void)this; |
@@ -63,12 +63,23 @@ Java_org_rockbox_RockboxFramebuffer_touchHandler(JNIEnv*env, jobject this, | |||
63 | * generated by pressing/releasing them to a variable */ | 63 | * generated by pressing/releasing them to a variable */ |
64 | JNIEXPORT bool JNICALL | 64 | JNIEXPORT bool JNICALL |
65 | Java_org_rockbox_RockboxFramebuffer_buttonHandler(JNIEnv*env, jobject this, | 65 | Java_org_rockbox_RockboxFramebuffer_buttonHandler(JNIEnv*env, jobject this, |
66 | int keycode, bool state) | 66 | jint keycode, jboolean state) |
67 | { | 67 | { |
68 | (void)env; | 68 | (void)env; |
69 | (void)this; | 69 | (void)this; |
70 | 70 | ||
71 | int button = key_to_button(keycode); | 71 | unsigned button = 0; |
72 | |||
73 | if (!state) | ||
74 | button = multimedia_to_button((int)keycode); | ||
75 | |||
76 | if (button) | ||
77 | { /* multimeida buttons are handled differently */ | ||
78 | queue_post(&button_queue, button, 0); | ||
79 | return true; | ||
80 | } | ||
81 | |||
82 | button = key_to_button(keycode); | ||
72 | 83 | ||
73 | if (button == BUTTON_NONE) | 84 | if (button == BUTTON_NONE) |
74 | return false; | 85 | return false; |