diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/goldfish_events_device.c | 96 | ||||
-rw-r--r-- | hw/goldfish_fb.c | 21 | ||||
-rw-r--r-- | hw/goldfish_nand.c | 4 |
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 |