goldfish_events_device.c revision 055ae42d36d9d78a7920f66ee2df485d81d24264
1/* Copyright (C) 2007-2008 The Android Open Source Project 2** 3** This software is licensed under the terms of the GNU General Public 4** License version 2, as published by the Free Software Foundation, and 5** may be copied, distributed, and modified under those terms. 6** 7** This program is distributed in the hope that it will be useful, 8** but WITHOUT ANY WARRANTY; without even the implied warranty of 9** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10** GNU General Public License for more details. 11*/ 12#include "qemu_file.h" 13#include "android/hw-events.h" 14#include "android/charmap.h" 15#include "android/globals.h" /* for android_hw */ 16#include "irq.h" 17#include "user-events.h" 18 19#define MAX_EVENTS 256*4 20 21enum { 22 REG_READ = 0x00, 23 REG_SET_PAGE = 0x00, 24 REG_LEN = 0x04, 25 REG_DATA = 0x08, 26 27 PAGE_NAME = 0x00000, 28 PAGE_EVBITS = 0x10000, 29 PAGE_ABSDATA = 0x20000 | EV_ABS, 30}; 31 32/* NOTE: The ev_bits arrays are used to indicate to the kernel 33 * which events can be sent by the emulated hardware. 34 */ 35 36typedef struct 37{ 38 uint32_t base; 39 qemu_irq irq; 40 int pending; 41 int page; 42 43 unsigned events[MAX_EVENTS]; 44 unsigned first; 45 unsigned last; 46 47 const char *name; 48 49 struct { 50 size_t len; 51 uint8_t *bits; 52 } ev_bits[EV_MAX + 1]; 53 54 int32_t *abs_info; 55 size_t abs_info_count; 56} events_state; 57 58/* modify this each time you change the events_device structure. you 59 * will also need to upadte events_state_load and events_state_save 60 */ 61#define EVENTS_STATE_SAVE_VERSION 1 62 63#undef QFIELD_STRUCT 64#define QFIELD_STRUCT events_state 65 66QFIELD_BEGIN(events_state_fields) 67 QFIELD_INT32(pending), 68 QFIELD_INT32(page), 69 QFIELD_BUFFER(events), 70 QFIELD_INT32(first), 71 QFIELD_INT32(last), 72QFIELD_END 73 74static void events_state_save(QEMUFile* f, void* opaque) 75{ 76 events_state* s = opaque; 77 78 qemu_put_struct(f, events_state_fields, s); 79} 80 81static int events_state_load(QEMUFile* f, void* opaque, int version_id) 82{ 83 events_state* s = opaque; 84 85 if (version_id != EVENTS_STATE_SAVE_VERSION) 86 return -1; 87 88 return qemu_get_struct(f, events_state_fields, s); 89} 90 91extern const char* android_skin_keycharmap; 92 93static void enqueue_event(events_state *s, unsigned int type, unsigned int code, int value) 94{ 95 int enqueued = s->last - s->first; 96 97 if (enqueued < 0) 98 enqueued += MAX_EVENTS; 99 100 if (enqueued + 3 >= MAX_EVENTS-1) { 101 fprintf(stderr, "##KBD: Full queue, lose event\n"); 102 return; 103 } 104 105 if(s->first == s->last) { 106 qemu_irq_raise(s->irq); 107 } 108 109 //fprintf(stderr, "##KBD: type=%d code=%d value=%d\n", type, code, value); 110 111 s->events[s->last] = type; 112 s->last = (s->last + 1) & (MAX_EVENTS-1); 113 s->events[s->last] = code; 114 s->last = (s->last + 1) & (MAX_EVENTS-1); 115 s->events[s->last] = value; 116 s->last = (s->last + 1) & (MAX_EVENTS-1); 117} 118 119static unsigned dequeue_event(events_state *s) 120{ 121 unsigned n; 122 123 if(s->first == s->last) { 124 return 0; 125 } 126 127 n = s->events[s->first]; 128 129 s->first = (s->first + 1) & (MAX_EVENTS - 1); 130 131 if(s->first == s->last) { 132 qemu_irq_lower(s->irq); 133 } 134 135 return n; 136} 137 138static int get_page_len(events_state *s) 139{ 140 int page = s->page; 141 if (page == PAGE_NAME) 142 return strlen(s->name); 143 if (page >= PAGE_EVBITS && page <= PAGE_EVBITS + EV_MAX) 144 return s->ev_bits[page - PAGE_EVBITS].len; 145 if (page == PAGE_ABSDATA) 146 return s->abs_info_count * sizeof(s->abs_info[0]); 147 return 0; 148} 149 150static int get_page_data(events_state *s, int offset) 151{ 152 int page_len = get_page_len(s); 153 int page = s->page; 154 if (offset > page_len) 155 return 0; 156 if (page == PAGE_NAME) 157 return s->name[offset]; 158 if (page >= PAGE_EVBITS && page <= PAGE_EVBITS + EV_MAX) 159 return s->ev_bits[page - PAGE_EVBITS].bits[offset]; 160 if (page == PAGE_ABSDATA) 161 return s->abs_info[offset / sizeof(s->abs_info[0])]; 162 return 0; 163} 164 165static uint32_t events_read(void *x, target_phys_addr_t off) 166{ 167 events_state *s = (events_state *) x; 168 int offset = off; // - s->base; 169 if (offset == REG_READ) 170 return dequeue_event(s); 171 else if (offset == REG_LEN) 172 return get_page_len(s); 173 else if (offset >= REG_DATA) 174 return get_page_data(s, offset - REG_DATA); 175 return 0; // this shouldn't happen, if the driver does the right thing 176} 177 178static void events_write(void *x, target_phys_addr_t off, uint32_t val) 179{ 180 events_state *s = (events_state *) x; 181 int offset = off; // - s->base; 182 if (offset == REG_SET_PAGE) 183 s->page = val; 184} 185 186static CPUReadMemoryFunc *events_readfn[] = { 187 events_read, 188 events_read, 189 events_read 190}; 191 192static CPUWriteMemoryFunc *events_writefn[] = { 193 events_write, 194 events_write, 195 events_write 196}; 197 198static void events_put_keycode(void *x, int keycode) 199{ 200 events_state *s = (events_state *) x; 201 202 enqueue_event(s, EV_KEY, keycode&0x1ff, (keycode&0x200) ? 1 : 0); 203} 204 205static void events_put_mouse(void *opaque, int dx, int dy, int dz, int buttons_state) 206{ 207 events_state *s = (events_state *) opaque; 208 /* in the Android emulator, we use dz == 0 for touchscreen events, 209 * and dz == 1 for trackball events. See the kbd_mouse_event calls 210 * in android/skin/trackball.c and android/skin/window.c 211 */ 212 if (dz == 0) { 213 enqueue_event(s, EV_ABS, ABS_X, dx); 214 enqueue_event(s, EV_ABS, ABS_Y, dy); 215 enqueue_event(s, EV_ABS, ABS_Z, dz); 216 enqueue_event(s, EV_KEY, BTN_TOUCH, buttons_state&1); 217 } else { 218 enqueue_event(s, EV_REL, REL_X, dx); 219 enqueue_event(s, EV_REL, REL_Y, dy); 220 } 221 enqueue_event(s, EV_SYN, 0, 0); 222} 223 224static void events_put_generic(void* opaque, int type, int code, int value) 225{ 226 events_state *s = (events_state *) opaque; 227 228 enqueue_event(s, type, code, value); 229} 230 231/* set bits [bitl..bith] in the ev_bits[type] array 232 */ 233static void 234events_set_bits(events_state *s, int type, int bitl, int bith) 235{ 236 uint8_t *bits; 237 uint8_t maskl, maskh; 238 int il, ih; 239 il = bitl / 8; 240 ih = bith / 8; 241 if (ih >= s->ev_bits[type].len) { 242 bits = qemu_mallocz(ih + 1); 243 if (bits == NULL) 244 return; 245 memcpy(bits, s->ev_bits[type].bits, s->ev_bits[type].len); 246 qemu_free(s->ev_bits[type].bits); 247 s->ev_bits[type].bits = bits; 248 s->ev_bits[type].len = ih + 1; 249 } 250 else 251 bits = s->ev_bits[type].bits; 252 maskl = 0xffU << (bitl & 7); 253 maskh = 0xffU >> (7 - (bith & 7)); 254 if (il >= ih) 255 maskh &= maskl; 256 else { 257 bits[il] |= maskl; 258 while (++il < ih) 259 bits[il] = 0xff; 260 } 261 bits[ih] |= maskh; 262} 263 264static void 265events_set_bit(events_state* s, int type, int bit) 266{ 267 events_set_bits(s, type, bit, bit); 268} 269 270void events_dev_init(uint32_t base, qemu_irq irq) 271{ 272 events_state *s; 273 int iomemtype; 274 AndroidHwConfig* config = android_hw; 275 276 s = (events_state *) qemu_mallocz(sizeof(events_state)); 277 // Use name of the default charmap. 278 s->name = android_get_default_charmap_name(); 279 280 /* now set the events capability bits depending on hardware configuration */ 281 /* apparently, the EV_SYN array is used to indicate which other 282 * event classes to consider. 283 */ 284 285 /* configure EV_KEY array 286 * 287 * All Android devices must have the following keys: 288 * KEY_HOME, KEY_BACK, KEY_SEND (Call), KEY_END (EndCall), 289 * KEY_SOFT1 (Menu), VOLUME_UP, VOLUME_DOWN 290 * 291 * Note that previous models also had a KEY_SOFT2, 292 * and a KEY_POWER which we still support here. 293 * 294 * Newer models have a KEY_SEARCH key, which we always 295 * enable here. 296 * 297 * A Dpad will send: KEY_DOWN / UP / LEFT / RIGHT / CENTER 298 * 299 * The KEY_CAMERA button isn't very useful if there is no camera. 300 * 301 * BTN_MOUSE is sent when the trackball is pressed 302 * BTN_TOUCH is sent when the touchscreen is pressed 303 */ 304 events_set_bit (s, EV_SYN, EV_KEY ); 305 306 events_set_bit(s, EV_KEY, KEY_HOME); 307 events_set_bit(s, EV_KEY, KEY_BACK); 308 events_set_bit(s, EV_KEY, KEY_SEND); 309 events_set_bit(s, EV_KEY, KEY_END); 310 events_set_bit(s, EV_KEY, KEY_SOFT1); 311 events_set_bit(s, EV_KEY, KEY_VOLUMEUP); 312 events_set_bit(s, EV_KEY, KEY_VOLUMEDOWN); 313 events_set_bit(s, EV_KEY, KEY_SOFT2); 314 events_set_bit(s, EV_KEY, KEY_POWER); 315 events_set_bit(s, EV_KEY, KEY_SEARCH); 316 317 if (config->hw_dPad) { 318 events_set_bit(s, EV_KEY, KEY_DOWN); 319 events_set_bit(s, EV_KEY, KEY_UP); 320 events_set_bit(s, EV_KEY, KEY_LEFT); 321 events_set_bit(s, EV_KEY, KEY_RIGHT); 322 events_set_bit(s, EV_KEY, KEY_CENTER); 323 } 324 325 if (config->hw_trackBall) { 326 events_set_bit(s, EV_KEY, BTN_MOUSE); 327 } 328 if (config->hw_touchScreen) { 329 events_set_bit(s, EV_KEY, BTN_TOUCH); 330 } 331 332 if (config->hw_camera) { 333 events_set_bit(s, EV_KEY, KEY_CAMERA); 334 } 335 336 if (config->hw_keyboard) { 337 /* since we want to implement Unicode reverse-mapping 338 * allow any kind of key, even those not available on 339 * the skin. 340 * 341 * the previous code did set the [1..0x1ff] range, but 342 * we don't want to enable certain bits in the middle 343 * of the range that are registered for mouse/trackball/joystick 344 * events. 345 * 346 * see "linux_keycodes.h" for the list of events codes. 347 */ 348 events_set_bits(s, EV_KEY, 1, 0xff); 349 events_set_bits(s, EV_KEY, 0x160, 0x1ff); 350 } 351 352 /* configure EV_REL array 353 * 354 * EV_REL events are sent when the trackball is moved 355 */ 356 if (config->hw_trackBall) { 357 events_set_bit (s, EV_SYN, EV_REL ); 358 events_set_bits(s, EV_REL, REL_X, REL_Y); 359 } 360 361 /* configure EV_ABS array. 362 * 363 * EV_ABS events are sent when the touchscreen is pressed 364 */ 365 if (config->hw_touchScreen) { 366 events_set_bit (s, EV_SYN, EV_ABS ); 367 events_set_bits(s, EV_ABS, ABS_X, ABS_Z); 368 } 369 370 /* configure EV_SW array 371 * 372 * EW_SW events are sent to indicate that the keyboard lid 373 * was closed or opened (done when we switch layouts through 374 * KP-7 or KP-9). 375 * 376 * We only support this when there is a real keyboard, which 377 * we assume can be hidden/revealed. 378 */ 379 if (config->hw_keyboard) { 380 events_set_bit(s, EV_SYN, EV_SW); 381 events_set_bit(s, EV_SW, 0); 382 } 383 384 iomemtype = cpu_register_io_memory(events_readfn, events_writefn, s); 385 386 cpu_register_physical_memory(base, 0xfff, iomemtype); 387 388 qemu_add_kbd_event_handler(events_put_keycode, s); 389 qemu_add_mouse_event_handler(events_put_mouse, s, 1, "goldfish-events"); 390 user_event_register_generic(s, events_put_generic); 391 392 s->base = base; 393 s->irq = irq; 394 395 s->first = 0; 396 s->last = 0; 397 398 register_savevm( "events_state", 0, EVENTS_STATE_SAVE_VERSION, 399 events_state_save, events_state_load, s ); 400} 401 402