aboutsummaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/goldfish_events_device.c96
-rw-r--r--hw/goldfish_fb.c21
-rw-r--r--hw/goldfish_nand.c4
3 files changed, 80 insertions, 41 deletions
diff --git a/hw/goldfish_events_device.c b/hw/goldfish_events_device.c
index a5b2a21..dad76ad 100644
--- a/hw/goldfish_events_device.c
+++ b/hw/goldfish_events_device.c
@@ -13,6 +13,7 @@
#include "android/hw-events.h"
#include "android/charmap.h"
#include "android/globals.h" /* for android_hw */
+#include "android/multitouch-screen.h"
#include "irq.h"
#include "user-events.h"
#include "console.h"
@@ -68,6 +69,18 @@ typedef struct
size_t abs_info_count;
} events_state;
+/* An entry in the array of ABS_XXX values */
+typedef struct ABSEntry {
+ /* Minimum ABS_XXX value. */
+ uint32_t min;
+ /* Maximum ABS_XXX value. */
+ uint32_t max;
+ /* 'fuzz;, and 'flat' ABS_XXX values are always zero here. */
+ uint32_t fuzz;
+ uint32_t flat;
+} ABSEntry;
+
+
/* modify this each time you change the events_device structure. you
* will also need to upadte events_state_load and events_state_save
*/
@@ -258,20 +271,27 @@ static void events_put_mouse(void *opaque, int dx, int dy, int dz, int buttons_s
* in android/skin/trackball.c and android/skin/window.c
*/
if (dz == 0) {
- enqueue_event(s, EV_ABS, ABS_X, dx);
- enqueue_event(s, EV_ABS, ABS_Y, dy);
- enqueue_event(s, EV_ABS, ABS_Z, dz);
- enqueue_event(s, EV_KEY, BTN_TOUCH, buttons_state&1);
+ if (androidHwConfig_isScreenMultiTouch(android_hw)) {
+ /* Convert mouse event into multi-touch event */
+ multitouch_update_pointer(MTES_MOUSE, 0, dx, dy,
+ (buttons_state & 1) ? 0x81 : 0);
+ } else if (androidHwConfig_isScreenTouch(android_hw)) {
+ enqueue_event(s, EV_ABS, ABS_X, dx);
+ enqueue_event(s, EV_ABS, ABS_Y, dy);
+ enqueue_event(s, EV_ABS, ABS_Z, dz);
+ enqueue_event(s, EV_KEY, BTN_TOUCH, buttons_state&1);
+ enqueue_event(s, EV_SYN, 0, 0);
+ }
} else {
enqueue_event(s, EV_REL, REL_X, dx);
enqueue_event(s, EV_REL, REL_Y, dy);
+ enqueue_event(s, EV_SYN, 0, 0);
}
- enqueue_event(s, EV_SYN, 0, 0);
}
static void events_put_generic(void* opaque, int type, int code, int value)
{
- events_state *s = (events_state *) opaque;
+ events_state *s = (events_state *) opaque;
enqueue_event(s, type, code, value);
}
@@ -382,11 +402,13 @@ void events_dev_init(uint32_t base, qemu_irq irq)
if (config->hw_trackBall) {
events_set_bit(s, EV_KEY, BTN_MOUSE);
}
- if (config->hw_touchScreen) {
+ if (androidHwConfig_isScreenTouch(config)) {
events_set_bit(s, EV_KEY, BTN_TOUCH);
}
- if (config->hw_camera) {
+ if (strcmp(config->hw_camera_back, "none") ||
+ strcmp(config->hw_camera_front, "none")) {
+ /* Camera emulation is enabled. */
events_set_bit(s, EV_KEY, KEY_CAMERA);
}
@@ -431,13 +453,13 @@ void events_dev_init(uint32_t base, qemu_irq irq)
*
* EV_ABS events are sent when the touchscreen is pressed
*/
- if (config->hw_touchScreen) {
- int32_t* values;
+ if (!androidHwConfig_isScreenNoTouch(config)) {
+ ABSEntry* abs_values;
events_set_bit (s, EV_SYN, EV_ABS );
events_set_bits(s, EV_ABS, ABS_X, ABS_Z);
/* Allocate the absinfo to report the min/max bounds for each
- * absolute dimension. The array must contain 3 tuples
+ * absolute dimension. The array must contain 3, or ABS_MAX tuples
* of (min,max,fuzz,flat) 32-bit values.
*
* min and max are the bounds
@@ -448,33 +470,39 @@ void events_dev_init(uint32_t base, qemu_irq irq)
* There is no need to save/restore this array in a snapshot
* since the values only depend on the hardware configuration.
*/
- s->abs_info_count = 3*4;
- s->abs_info = values = malloc(sizeof(uint32_t)*s->abs_info_count);
-
- /* ABS_X min/max/fuzz/flat */
- values[0] = 0;
- values[1] = config->hw_lcd_width-1;
- values[2] = 0;
- values[3] = 0;
- values += 4;
-
- /* ABS_Y */
- values[0] = 0;
- values[1] = config->hw_lcd_height-1;
- values[2] = 0;
- values[3] = 0;
- values += 4;
-
- /* ABS_Z */
- values[0] = 0;
- values[1] = 1;
- values[2] = 0;
- values[3] = 0;
+ s->abs_info_count = androidHwConfig_isScreenMultiTouch(config) ? ABS_MAX * 4 : 3 * 4;
+ const int abs_size = sizeof(uint32_t) * s->abs_info_count;
+ s->abs_info = malloc(abs_size);
+ memset(s->abs_info, 0, abs_size);
+ abs_values = (ABSEntry*)s->abs_info;
+
+ abs_values[ABS_X].max = config->hw_lcd_width-1;
+ abs_values[ABS_Y].max = config->hw_lcd_height-1;
+ abs_values[ABS_Z].max = 1;
+
+ if (androidHwConfig_isScreenMultiTouch(config)) {
+ /*
+ * Setup multitouch.
+ */
+ events_set_bit(s, EV_ABS, ABS_MT_SLOT);
+ events_set_bit(s, EV_ABS, ABS_MT_POSITION_X);
+ events_set_bit(s, EV_ABS, ABS_MT_POSITION_Y);
+ events_set_bit(s, EV_ABS, ABS_MT_TRACKING_ID);
+ events_set_bit(s, EV_ABS, ABS_MT_TOUCH_MAJOR);
+ events_set_bit(s, EV_ABS, ABS_MT_PRESSURE);
+
+ abs_values[ABS_MT_SLOT].max = multitouch_get_max_slot();
+ abs_values[ABS_MT_TRACKING_ID].max = abs_values[ABS_MT_SLOT].max + 1;
+ abs_values[ABS_MT_POSITION_X].max = abs_values[ABS_X].max;
+ abs_values[ABS_MT_POSITION_Y].max = abs_values[ABS_Y].max;
+ abs_values[ABS_MT_TOUCH_MAJOR].max = 0x7fffffff; // TODO: Make it less random
+ abs_values[ABS_MT_PRESSURE].max = 0x100; // TODO: Make it less random
+ }
}
/* configure EV_SW array
*
- * EW_SW events are sent to indicate that the keyboard lid
+ * EV_SW events are sent to indicate that the keyboard lid
* was closed or opened (done when we switch layouts through
* KP-7 or KP-9).
*
diff --git a/hw/goldfish_fb.c b/hw/goldfish_fb.c
index d74d797..16450b3 100644
--- a/hw/goldfish_fb.c
+++ b/hw/goldfish_fb.c
@@ -319,7 +319,11 @@ compute_fb_update_rect_linear(FbUpdateState* fbs,
xx1 = 0;
DUFF4(width, {
- if (src[xx1] != dst[xx1])
+ uint16_t spix = src[xx1];
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+ spix = (uint16_t)((spix << 8) | (spix >> 8));
+#endif
+ if (spix != dst[xx1])
break;
xx1++;
});
@@ -332,8 +336,8 @@ compute_fb_update_rect_linear(FbUpdateState* fbs,
break;
xx2--;
});
-#if HOST_WORDS_BIGENDIAN
- /* Convert the guest little-endian pixels into big-endian ones */
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+ /* Convert the guest pixels into host ones */
int xx = xx1;
DUFF4(xx2-xx1+1,{
unsigned spix = src[xx];
@@ -382,7 +386,12 @@ compute_fb_update_rect_linear(FbUpdateState* fbs,
xx1 = 0;
DUFF4(width, {
- if (src[xx1] != dst[xx1]) {
+ uint32_t spix = src[xx1];
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+ spix = (spix << 16) | (spix >> 16);
+ spix = ((spix << 8) & 0xff00ff00) | ((spix >> 8) & 0x00ff00ff);
+#endif
+ if (spix != dst[xx1]) {
break;
}
xx1++;
@@ -397,8 +406,8 @@ compute_fb_update_rect_linear(FbUpdateState* fbs,
}
xx2--;
});
-#if HOST_WORDS_BIGENDIAN
- /* Convert the guest little-endian pixels into big-endian ones */
+#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+ /* Convert the guest pixels into host ones */
int xx = xx1;
DUFF4(xx2-xx1+1,{
uint32_t spix = src[xx];
diff --git a/hw/goldfish_nand.c b/hw/goldfish_nand.c
index 31e814b..55f77f6 100644
--- a/hw/goldfish_nand.c
+++ b/hw/goldfish_nand.c
@@ -140,7 +140,7 @@ typedef struct {
* 2: saving actual disk contents as well
* 3: use the correct data length and truncate to avoid padding.
*/
-#define NAND_DEV_STATE_SAVE_VERSION 3
+#define NAND_DEV_STATE_SAVE_VERSION 4
#define QFIELD_STRUCT nand_dev_controller_state
QFIELD_BEGIN(nand_dev_controller_state_fields)
@@ -149,6 +149,8 @@ QFIELD_BEGIN(nand_dev_controller_state_fields)
QFIELD_INT32(addr_high),
QFIELD_INT32(transfer_size),
QFIELD_INT32(data),
+ QFIELD_INT32(batch_addr_low),
+ QFIELD_INT32(batch_addr_high),
QFIELD_INT32(result),
QFIELD_END