diff options
Diffstat (limited to 'firmware/target/hosted/android')
-rw-r--r-- | firmware/target/hosted/android/app/button-target.h | 2 | ||||
-rw-r--r-- | firmware/target/hosted/android/lcd-android.c | 140 |
2 files changed, 61 insertions, 81 deletions
diff --git a/firmware/target/hosted/android/app/button-target.h b/firmware/target/hosted/android/app/button-target.h index 6106b612f9..3b6028739c 100644 --- a/firmware/target/hosted/android/app/button-target.h +++ b/firmware/target/hosted/android/app/button-target.h | |||
@@ -58,6 +58,8 @@ void android_ignore_back_button(bool yes); | |||
58 | #define BUTTON_BOTTOMMIDDLE 0x00080000 | 58 | #define BUTTON_BOTTOMMIDDLE 0x00080000 |
59 | #define BUTTON_BOTTOMRIGHT 0x00100000 | 59 | #define BUTTON_BOTTOMRIGHT 0x00100000 |
60 | 60 | ||
61 | #define BUTTON_FORCE_REDRAW 0x00200000 | ||
62 | |||
61 | /* No remote */ | 63 | /* No remote */ |
62 | #define BUTTON_REMOTE 0 | 64 | #define BUTTON_REMOTE 0 |
63 | 65 | ||
diff --git a/firmware/target/hosted/android/lcd-android.c b/firmware/target/hosted/android/lcd-android.c index 92e8f5b96f..f719329819 100644 --- a/firmware/target/hosted/android/lcd-android.c +++ b/firmware/target/hosted/android/lcd-android.c | |||
@@ -21,10 +21,12 @@ | |||
21 | 21 | ||
22 | 22 | ||
23 | #include <jni.h> | 23 | #include <jni.h> |
24 | #include <string.h> | ||
24 | #include "config.h" | 25 | #include "config.h" |
25 | #include "system.h" | 26 | #include "system.h" |
26 | #include "kernel.h" | 27 | #include "kernel.h" |
27 | #include "lcd.h" | 28 | #include "lcd.h" |
29 | #include "button.h" | ||
28 | 30 | ||
29 | extern JNIEnv *env_ptr; | 31 | extern JNIEnv *env_ptr; |
30 | extern jclass RockboxService_class; | 32 | extern jclass RockboxService_class; |
@@ -32,57 +34,48 @@ extern jobject RockboxService_instance; | |||
32 | 34 | ||
33 | static jclass RockboxFramebuffer_class; | 35 | static jclass RockboxFramebuffer_class; |
34 | static jobject RockboxFramebuffer_instance; | 36 | static jobject RockboxFramebuffer_instance; |
35 | static jmethodID postInvalidate1; | 37 | static jmethodID java_lcd_update; |
36 | static jmethodID postInvalidate2; | 38 | static jmethodID java_lcd_update_rect; |
37 | 39 | ||
38 | static bool display_on; | ||
39 | static int dpi; | 40 | static int dpi; |
40 | static int scroll_threshold; | 41 | static int scroll_threshold; |
41 | static struct wakeup lcd_wakeup; | 42 | static bool display_on; |
42 | static struct mutex lcd_mtx; | ||
43 | 43 | ||
44 | void lcd_init_device(void) | 44 | void lcd_init_device(void) |
45 | { | 45 | { |
46 | JNIEnv e = *env_ptr; | 46 | JNIEnv e = *env_ptr; |
47 | wakeup_init(&lcd_wakeup); | 47 | /* get existing instance from the Service */ |
48 | mutex_init(&lcd_mtx); | 48 | jmethodID get_fb = e->GetMethodID(env_ptr, RockboxService_class, "get_fb", |
49 | RockboxFramebuffer_class = e->FindClass(env_ptr, | 49 | "()Lorg/rockbox/RockboxFramebuffer;"); |
50 | "org/rockbox/RockboxFramebuffer"); | 50 | RockboxFramebuffer_instance = e->CallObjectMethod(env_ptr, |
51 | /* instantiate a RockboxFramebuffer instance | 51 | RockboxService_instance, |
52 | * | 52 | get_fb); |
53 | * Pass lcd width and height and our framebuffer so the java layer | 53 | RockboxFramebuffer_class = (*env_ptr)->GetObjectClass(env_ptr, |
54 | * can create a Bitmap which directly maps to it | 54 | RockboxFramebuffer_instance); |
55 | **/ | 55 | |
56 | 56 | /* Get init function and set up what's left from the constructor */ | |
57 | /* map the framebuffer to a ByteBuffer, this way lcd updates will | 57 | jmethodID java_lcd_init = (*env_ptr)->GetMethodID(env_ptr, |
58 | * be directly feched from the framebuffer */ | 58 | RockboxFramebuffer_class, |
59 | "java_lcd_init", | ||
60 | "(IILjava/nio/ByteBuffer;)V"); | ||
61 | |||
59 | jobject buf = e->NewDirectByteBuffer(env_ptr, | 62 | jobject buf = e->NewDirectByteBuffer(env_ptr, |
60 | lcd_framebuffer, | 63 | lcd_framebuffer, |
61 | (jlong)sizeof(lcd_framebuffer)); | 64 | (jlong)sizeof(lcd_framebuffer)); |
62 | 65 | ||
63 | jmethodID constructor = e->GetMethodID(env_ptr, | 66 | e->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, java_lcd_init, |
64 | RockboxFramebuffer_class, | ||
65 | "<init>", | ||
66 | "(Landroid/content/Context;" /* Service */ | ||
67 | "II" /* lcd width/height */ | ||
68 | "Ljava/nio/ByteBuffer;)V"); /* ByteBuffer */ | ||
69 | |||
70 | RockboxFramebuffer_instance = e->NewObject(env_ptr, | ||
71 | RockboxFramebuffer_class, | ||
72 | constructor, | ||
73 | RockboxService_instance, | ||
74 | (jint)LCD_WIDTH, | 67 | (jint)LCD_WIDTH, |
75 | (jint)LCD_HEIGHT, | 68 | (jint)LCD_HEIGHT, |
76 | buf); | 69 | buf); |
77 | 70 | ||
78 | /* cache update functions */ | 71 | /* cache update functions */ |
79 | postInvalidate1 = (*env_ptr)->GetMethodID(env_ptr, | 72 | java_lcd_update = (*env_ptr)->GetMethodID(env_ptr, |
80 | RockboxFramebuffer_class, | 73 | RockboxFramebuffer_class, |
81 | "postInvalidate", | 74 | "java_lcd_update", |
82 | "()V"); | 75 | "()V"); |
83 | postInvalidate2 = (*env_ptr)->GetMethodID(env_ptr, | 76 | java_lcd_update_rect = (*env_ptr)->GetMethodID(env_ptr, |
84 | RockboxFramebuffer_class, | 77 | RockboxFramebuffer_class, |
85 | "postInvalidate", | 78 | "java_lcd_update_rect", |
86 | "(IIII)V"); | 79 | "(IIII)V"); |
87 | 80 | ||
88 | jmethodID get_dpi = e->GetMethodID(env_ptr, | 81 | jmethodID get_dpi = e->GetMethodID(env_ptr, |
@@ -98,49 +91,54 @@ void lcd_init_device(void) | |||
98 | get_dpi); | 91 | get_dpi); |
99 | scroll_threshold = e->CallIntMethod(env_ptr, RockboxFramebuffer_instance, | 92 | scroll_threshold = e->CallIntMethod(env_ptr, RockboxFramebuffer_instance, |
100 | get_scroll_threshold); | 93 | get_scroll_threshold); |
101 | display_on = true; | 94 | /* must not draw until surface is created */ |
95 | display_on = false; | ||
102 | } | 96 | } |
103 | 97 | ||
104 | /* the update mechanism is asynchronous since | ||
105 | * onDraw() must be called from the UI thread | ||
106 | * | ||
107 | * The Rockbox thread calling lcd_update() has to wait | ||
108 | * for the update to complete, so that it's synchronous, | ||
109 | * and we need to notify it (we could wait in the java layer, but | ||
110 | * that'd block the other Rockbox threads too) | ||
111 | * | ||
112 | * That should give more smoonth animations | ||
113 | */ | ||
114 | void lcd_update(void) | 98 | void lcd_update(void) |
115 | { | 99 | { |
116 | /* tell the system we're ready for drawing */ | ||
117 | if (display_on) | 100 | if (display_on) |
118 | { | 101 | (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, |
119 | mutex_lock(&lcd_mtx); | 102 | java_lcd_update); |
120 | (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, postInvalidate1); | ||
121 | wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK); | ||
122 | mutex_unlock(&lcd_mtx); | ||
123 | } | ||
124 | } | 103 | } |
125 | 104 | ||
126 | void lcd_update_rect(int x, int y, int width, int height) | 105 | void lcd_update_rect(int x, int y, int width, int height) |
127 | { | 106 | { |
128 | if (display_on) | 107 | if (display_on) |
129 | { | 108 | (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, |
130 | mutex_lock(&lcd_mtx); | 109 | java_lcd_update_rect, x, y, width, height); |
131 | (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, postInvalidate2, | 110 | } |
132 | (jint)x, (jint)y, (jint)x+width, (jint)y+height); | 111 | |
133 | wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK); | 112 | /* |
134 | mutex_unlock(&lcd_mtx); | 113 | * this is called when the surface is created, which called is everytime |
135 | } | 114 | * the activity is brought in front and the RockboxFramebuffer gains focus |
115 | * | ||
116 | * Note this is considered interrupt context | ||
117 | */ | ||
118 | JNIEXPORT void JNICALL | ||
119 | Java_org_rockbox_RockboxFramebuffer_surfaceCreated(JNIEnv *e, jobject this, | ||
120 | jobject surfaceholder) | ||
121 | { | ||
122 | (void)e; (void)this; (void)surfaceholder; | ||
123 | |||
124 | display_on = true; | ||
125 | send_event(LCD_EVENT_ACTIVATION, NULL); | ||
126 | /* Force an update, since the newly created surface is initially black | ||
127 | * waiting for the next normal update results in a longish black screen */ | ||
128 | queue_post(&button_queue, BUTTON_FORCE_REDRAW, 0); | ||
136 | } | 129 | } |
137 | 130 | ||
131 | /* | ||
132 | * the surface is destroyed everytime the RockboxFramebuffer loses focus and | ||
133 | * goes invisible | ||
134 | */ | ||
138 | JNIEXPORT void JNICALL | 135 | JNIEXPORT void JNICALL |
139 | Java_org_rockbox_RockboxFramebuffer_post_1update_1done(JNIEnv *e, jobject this) | 136 | Java_org_rockbox_RockboxFramebuffer_surfaceDestroyed(JNIEnv *e, jobject this, |
137 | jobject surfaceholder) | ||
140 | { | 138 | { |
141 | (void)e; | 139 | (void)e; (void)this; (void)surfaceholder; |
142 | (void)this; | 140 | |
143 | wakeup_signal(&lcd_wakeup); | 141 | display_on = false; |
144 | } | 142 | } |
145 | 143 | ||
146 | bool lcd_active(void) | 144 | bool lcd_active(void) |
@@ -158,26 +156,6 @@ int touchscreen_get_scroll_threshold(void) | |||
158 | return scroll_threshold; | 156 | return scroll_threshold; |
159 | } | 157 | } |
160 | 158 | ||
161 | /* | ||
162 | * (un)block lcd updates. | ||
163 | * | ||
164 | * Notice: This is called from the activity thread, so take it | ||
165 | * as interrupt context and take care what the event callback does | ||
166 | * (it shouldn't block in particular | ||
167 | * | ||
168 | * the 1s are needed due to strange naming conventions... | ||
169 | **/ | ||
170 | JNIEXPORT void JNICALL | ||
171 | Java_org_rockbox_RockboxFramebuffer_set_1lcd_1active(JNIEnv *e, | ||
172 | jobject this, | ||
173 | jint active) | ||
174 | { | ||
175 | (void)e; | ||
176 | (void)this; | ||
177 | display_on = active != 0; | ||
178 | if (active) | ||
179 | send_event(LCD_EVENT_ACTIVATION, NULL); | ||
180 | } | ||
181 | /* below is a plain copy from lcd-sdl.c */ | 159 | /* below is a plain copy from lcd-sdl.c */ |
182 | 160 | ||
183 | /** | 161 | /** |