18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms. 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful, 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details. 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/ 120e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner#include "hw/android/goldfish/device.h" 1328a09b6fe8d8f3e92ffee9263609a6da881b8818David 'Digit' Turner#include "migration/qemu-file.h" 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/hw-events.h" 15b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project#include "android/charmap.h" 16b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project#include "android/globals.h" /* for android_hw */ 178dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine#include "android/multitouch-screen.h" 189b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner#include "exec/cpu-common.h" 199b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner#include "exec/hwaddr.h" 200e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner#include "hw/hw.h" 212ec695af7284adbedcdbc08a22d818b6bdd8990cDavid 'Digit' Turner#include "hw/irq.h" 22d4e803c5e928790b14704ae7f0b048da7ba47fabDavid 'Digit' Turner#include "android/user-events.h" 231c31e3e43ce4cca85a707dfff631e5e102fdecedDavid 'Digit' Turner#include "ui/console.h" 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MAX_EVENTS 256*4 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectenum { 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project REG_READ = 0x00, 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project REG_SET_PAGE = 0x00, 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project REG_LEN = 0x04, 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project REG_DATA = 0x08, 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PAGE_NAME = 0x00000, 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PAGE_EVBITS = 0x10000, 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PAGE_ABSDATA = 0x20000 | EV_ABS, 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3880bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner/* These corresponds to the state of the driver. 3980bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner * Unfortunately, we have to buffer events coming 4080bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner * from the UI, since the kernel driver is not 4180bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner * capable of receiving them until XXXXXX 4280bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner */ 4380bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turnerenum { 4480bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner STATE_INIT = 0, /* The device is initialized */ 4580bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner STATE_BUFFERED, /* Events have been buffered, but no IRQ raised yet */ 4680bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner STATE_LIVE /* Events can be sent directly to the kernel */ 4780bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner}; 4880bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner 49b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project/* NOTE: The ev_bits arrays are used to indicate to the kernel 50b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * which events can be sent by the emulated hardware. 51b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project */ 52b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t base; 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_irq irq; 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int pending; 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int page; 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned events[MAX_EVENTS]; 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned first; 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned last; 6380bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner unsigned state; 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *name; 66b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct { 68b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project size_t len; 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *bits; 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } ev_bits[EV_MAX + 1]; 71b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int32_t *abs_info; 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project size_t abs_info_count; 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} events_state; 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 768dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine/* An entry in the array of ABS_XXX values */ 778dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkinetypedef struct ABSEntry { 788dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine /* Minimum ABS_XXX value. */ 798dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine uint32_t min; 808dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine /* Maximum ABS_XXX value. */ 818dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine uint32_t max; 828dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine /* 'fuzz;, and 'flat' ABS_XXX values are always zero here. */ 838dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine uint32_t fuzz; 848dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine uint32_t flat; 858dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine} ABSEntry; 868dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine 878dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* modify this each time you change the events_device structure. you 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * will also need to upadte events_state_load and events_state_save 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 9180bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner#define EVENTS_STATE_SAVE_VERSION 2 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef QFIELD_STRUCT 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define QFIELD_STRUCT events_state 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectQFIELD_BEGIN(events_state_fields) 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QFIELD_INT32(pending), 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QFIELD_INT32(page), 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QFIELD_BUFFER(events), 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QFIELD_INT32(first), 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QFIELD_INT32(last), 10280bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner QFIELD_INT32(state), 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectQFIELD_END 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void events_state_save(QEMUFile* f, void* opaque) 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events_state* s = opaque; 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_put_struct(f, events_state_fields, s); 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int events_state_load(QEMUFile* f, void* opaque, int version_id) 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events_state* s = opaque; 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (version_id != EVENTS_STATE_SAVE_VERSION) 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return qemu_get_struct(f, events_state_fields, s); 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void enqueue_event(events_state *s, unsigned int type, unsigned int code, int value) 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int enqueued = s->last - s->first; 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (enqueued < 0) 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project enqueued += MAX_EVENTS; 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12980bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner if (enqueued + 3 > MAX_EVENTS) { 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr, "##KBD: Full queue, lose event\n"); 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 134055ae42d36d9d78a7920f66ee2df485d81d24264David 'Digit' Turner if(s->first == s->last) { 13580bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner if (s->state == STATE_LIVE) 13680bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner qemu_irq_raise(s->irq); 13780bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner else { 13880bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner s->state = STATE_BUFFERED; 13980bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner } 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project //fprintf(stderr, "##KBD: type=%d code=%d value=%d\n", type, code, value); 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->events[s->last] = type; 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->last = (s->last + 1) & (MAX_EVENTS-1); 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->events[s->last] = code; 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->last = (s->last + 1) & (MAX_EVENTS-1); 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->events[s->last] = value; 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->last = (s->last + 1) & (MAX_EVENTS-1); 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned dequeue_event(events_state *s) 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned n; 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(s->first == s->last) { 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project n = s->events[s->first]; 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->first = (s->first + 1) & (MAX_EVENTS - 1); 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(s->first == s->last) { 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_irq_lower(s->irq); 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 167334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima#ifdef TARGET_I386 168334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima /* 169334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima * Adding the logic to handle edge-triggered interrupts for x86 170334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima * because the exisiting goldfish events device basically provides 171334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima * level-trigger interrupts only. 172334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima * 173334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima * Logic: When an event (including the type/code/value) is fetched 174334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima * by the driver, if there is still another event in the event 175334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima * queue, the goldfish event device will re-assert the IRQ so that 176334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima * the driver can be notified to fetch the event again. 177334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima */ 178334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima else if (((s->first + 2) & (MAX_EVENTS - 1)) < s->last || 179334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima (s->first & (MAX_EVENTS - 1)) > s->last) { /* if there still is an event */ 180334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima qemu_irq_lower(s->irq); 181334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima qemu_irq_raise(s->irq); 182334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima } 183334ab475d2f27dbf6fbf836c2d4fb86dbb02a15cJun Nakajima#endif 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return n; 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int get_page_len(events_state *s) 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int page = s->page; 1900158ea3220978ecc0fa1738e4a0bdae83fa36175David 'Digit' Turner if (page == PAGE_NAME) { 19172d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet const char* name = s->name; 1920158ea3220978ecc0fa1738e4a0bdae83fa36175David 'Digit' Turner return strlen(name); 1930158ea3220978ecc0fa1738e4a0bdae83fa36175David 'Digit' Turner } if (page >= PAGE_EVBITS && page <= PAGE_EVBITS + EV_MAX) 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return s->ev_bits[page - PAGE_EVBITS].len; 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (page == PAGE_ABSDATA) 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return s->abs_info_count * sizeof(s->abs_info[0]); 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int get_page_data(events_state *s, int offset) 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int page_len = get_page_len(s); 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int page = s->page; 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (offset > page_len) 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 2060158ea3220978ecc0fa1738e4a0bdae83fa36175David 'Digit' Turner if (page == PAGE_NAME) { 20772d561178e62b74923cfe3bc0faa59bcb07c57c3Xavier Ducrohet const char* name = s->name; 2080158ea3220978ecc0fa1738e4a0bdae83fa36175David 'Digit' Turner return name[offset]; 2090158ea3220978ecc0fa1738e4a0bdae83fa36175David 'Digit' Turner } if (page >= PAGE_EVBITS && page <= PAGE_EVBITS + EV_MAX) 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return s->ev_bits[page - PAGE_EVBITS].bits[offset]; 21180bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner if (page == PAGE_ABSDATA) { 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return s->abs_info[offset / sizeof(s->abs_info[0])]; 21380bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner } 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 217bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turnerstatic uint32_t events_read(void *x, hwaddr off) 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events_state *s = (events_state *) x; 2205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int offset = off; // - s->base; 22180bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner 22280bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner /* This gross hack below is used to ensure that we 22380bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner * only raise the IRQ when the kernel driver is 22480bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner * properly ready! If done before this, the driver 22580bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner * becomes confused and ignores all input events 22680bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner * as soon as one was buffered! 22780bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner */ 22880bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner if (offset == REG_LEN && s->page == PAGE_ABSDATA) { 22980bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner if (s->state == STATE_BUFFERED) 23080bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner qemu_irq_raise(s->irq); 23180bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner s->state = STATE_LIVE; 23280bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner } 23380bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (offset == REG_READ) 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return dequeue_event(s); 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (offset == REG_LEN) 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return get_page_len(s); 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else if (offset >= REG_DATA) 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return get_page_data(s, offset - REG_DATA); 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; // this shouldn't happen, if the driver does the right thing 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 243bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turnerstatic void events_write(void *x, hwaddr off, uint32_t val) 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events_state *s = (events_state *) x; 2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int offset = off; // - s->base; 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (offset == REG_SET_PAGE) 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->page = val; 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic CPUReadMemoryFunc *events_readfn[] = { 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events_read, 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events_read, 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events_read 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic CPUWriteMemoryFunc *events_writefn[] = { 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events_write, 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events_write, 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events_write 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void events_put_keycode(void *x, int keycode) 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events_state *s = (events_state *) x; 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project enqueue_event(s, EV_KEY, keycode&0x1ff, (keycode&0x200) ? 1 : 0); 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void events_put_mouse(void *opaque, int dx, int dy, int dz, int buttons_state) 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events_state *s = (events_state *) opaque; 273b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project /* in the Android emulator, we use dz == 0 for touchscreen events, 274b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * and dz == 1 for trackball events. See the kbd_mouse_event calls 275b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * in android/skin/trackball.c and android/skin/window.c 276b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project */ 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (dz == 0) { 278863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine if (androidHwConfig_isScreenMultiTouch(android_hw)) { 2798dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine /* Convert mouse event into multi-touch event */ 2808dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine multitouch_update_pointer(MTES_MOUSE, 0, dx, dy, 2818dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine (buttons_state & 1) ? 0x81 : 0); 282863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine } else if (androidHwConfig_isScreenTouch(android_hw)) { 2838dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine enqueue_event(s, EV_ABS, ABS_X, dx); 2848dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine enqueue_event(s, EV_ABS, ABS_Y, dy); 2858dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine enqueue_event(s, EV_ABS, ABS_Z, dz); 2868dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine enqueue_event(s, EV_KEY, BTN_TOUCH, buttons_state&1); 2878dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine enqueue_event(s, EV_SYN, 0, 0); 2888dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine } 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project enqueue_event(s, EV_REL, REL_X, dx); 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project enqueue_event(s, EV_REL, REL_Y, dy); 2928dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine enqueue_event(s, EV_SYN, 0, 0); 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void events_put_generic(void* opaque, int type, int code, int value) 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2988dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine events_state *s = (events_state *) opaque; 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project enqueue_event(s, type, code, value); 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 303b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project/* set bits [bitl..bith] in the ev_bits[type] array 304b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project */ 305b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Projectstatic void 306b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Projectevents_set_bits(events_state *s, int type, int bitl, int bith) 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *bits; 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t maskl, maskh; 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int il, ih; 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project il = bitl / 8; 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ih = bith / 8; 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ih >= s->ev_bits[type].len) { 314aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner bits = g_malloc0(ih + 1); 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bits == NULL) 316b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project return; 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(bits, s->ev_bits[type].bits, s->ev_bits[type].len); 318aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free(s->ev_bits[type].bits); 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->ev_bits[type].bits = bits; 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->ev_bits[type].len = ih + 1; 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits = s->ev_bits[type].bits; 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project maskl = 0xffU << (bitl & 7); 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project maskh = 0xffU >> (7 - (bith & 7)); 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (il >= ih) 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project maskh &= maskl; 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits[il] |= maskl; 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (++il < ih) 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits[il] = 0xff; 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits[ih] |= maskh; 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 336b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Projectstatic void 337b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Projectevents_set_bit(events_state* s, int type, int bit) 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 339b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bits(s, type, bit, bit); 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 342799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turnerstatic void 343799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turnerevents_clr_bit(events_state* s, int type, int bit) 344799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner{ 345799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner int ii = bit / 8; 346799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner if (ii < s->ev_bits[type].len) { 347799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner uint8_t* bits = s->ev_bits[type].bits; 348799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner uint8_t mask = 0x01U << (bit & 7); 349799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner bits[ii] &= ~mask; 350799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner } 351799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner} 352799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid events_dev_init(uint32_t base, qemu_irq irq) 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project events_state *s; 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int iomemtype; 357b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project AndroidHwConfig* config = android_hw; 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 359aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner s = (events_state *) g_malloc0(sizeof(events_state)); 3600158ea3220978ecc0fa1738e4a0bdae83fa36175David 'Digit' Turner 361b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project /* now set the events capability bits depending on hardware configuration */ 362b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project /* apparently, the EV_SYN array is used to indicate which other 363b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * event classes to consider. 364b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project */ 365b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project 366b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project /* configure EV_KEY array 367b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * 368b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * All Android devices must have the following keys: 369b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * KEY_HOME, KEY_BACK, KEY_SEND (Call), KEY_END (EndCall), 370b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * KEY_SOFT1 (Menu), VOLUME_UP, VOLUME_DOWN 371b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * 372b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * Note that previous models also had a KEY_SOFT2, 373b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * and a KEY_POWER which we still support here. 374b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * 3753d2300cb2f8f575d9e0c553c88790b5d79dda1b6David 'Digit' Turner * Newer models have a KEY_SEARCH key, which we always 3763d2300cb2f8f575d9e0c553c88790b5d79dda1b6David 'Digit' Turner * enable here. 3773d2300cb2f8f575d9e0c553c88790b5d79dda1b6David 'Digit' Turner * 378b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * A Dpad will send: KEY_DOWN / UP / LEFT / RIGHT / CENTER 379b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * 380b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * The KEY_CAMERA button isn't very useful if there is no camera. 381b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * 382b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * BTN_MOUSE is sent when the trackball is pressed 383b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * BTN_TOUCH is sent when the touchscreen is pressed 384b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project */ 385b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit (s, EV_SYN, EV_KEY ); 386b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project 387b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_HOME); 388b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_BACK); 389b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_SEND); 390b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_END); 391b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_SOFT1); 392b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_VOLUMEUP); 393b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_VOLUMEDOWN); 394b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_SOFT2); 395b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_POWER); 3963d2300cb2f8f575d9e0c553c88790b5d79dda1b6David 'Digit' Turner events_set_bit(s, EV_KEY, KEY_SEARCH); 397b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project 398b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project if (config->hw_dPad) { 399b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_DOWN); 400b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_UP); 401b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_LEFT); 402b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_RIGHT); 403b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_CENTER); 404b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project } 405b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project 406b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project if (config->hw_trackBall) { 407b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, BTN_MOUSE); 408b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project } 409863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine if (androidHwConfig_isScreenTouch(config)) { 410b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, BTN_TOUCH); 411b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project } 412b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project 4137485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine if (strcmp(config->hw_camera_back, "none") || 4147485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine strcmp(config->hw_camera_front, "none")) { 4157485c2989d727a1d0c14a66fb75e140f885a1583Vladimir Chtchetkine /* Camera emulation is enabled. */ 416b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_KEY, KEY_CAMERA); 417b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project } 418b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project 419b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project if (config->hw_keyboard) { 420b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project /* since we want to implement Unicode reverse-mapping 421b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * allow any kind of key, even those not available on 422b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * the skin. 423b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * 424b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * the previous code did set the [1..0x1ff] range, but 425b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * we don't want to enable certain bits in the middle 426b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * of the range that are registered for mouse/trackball/joystick 427b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * events. 428b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * 429b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * see "linux_keycodes.h" for the list of events codes. 430b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project */ 431b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bits(s, EV_KEY, 1, 0xff); 432b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bits(s, EV_KEY, 0x160, 0x1ff); 433799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner 434799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner /* If there is a keyboard, but no DPad, we need to clear the 435799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner * corresponding bits. Doing this is simpler than trying to exclude 436799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner * the DPad values from the ranges above. 437799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner */ 438799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner if (!config->hw_dPad) { 439799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner events_clr_bit(s, EV_KEY, KEY_DOWN); 440799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner events_clr_bit(s, EV_KEY, KEY_UP); 441799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner events_clr_bit(s, EV_KEY, KEY_LEFT); 442799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner events_clr_bit(s, EV_KEY, KEY_RIGHT); 443799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner events_clr_bit(s, EV_KEY, KEY_CENTER); 444799c6c0ecab548cf4716d14d1f077819cdde8e10David 'Digit' Turner } 445b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project } 446b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project 447b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project /* configure EV_REL array 448b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * 449b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * EV_REL events are sent when the trackball is moved 450b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project */ 451b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project if (config->hw_trackBall) { 452b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit (s, EV_SYN, EV_REL ); 453b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bits(s, EV_REL, REL_X, REL_Y); 454b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project } 455b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project 456b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project /* configure EV_ABS array. 457b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * 458b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * EV_ABS events are sent when the touchscreen is pressed 459b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project */ 460863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine if (!androidHwConfig_isScreenNoTouch(config)) { 4618dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine ABSEntry* abs_values; 46231203e4ba2e7b91aabe077aa9cac9158dd480775Xavier Ducrohet 463b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit (s, EV_SYN, EV_ABS ); 464b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bits(s, EV_ABS, ABS_X, ABS_Z); 46531203e4ba2e7b91aabe077aa9cac9158dd480775Xavier Ducrohet /* Allocate the absinfo to report the min/max bounds for each 4668dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine * absolute dimension. The array must contain 3, or ABS_MAX tuples 46731203e4ba2e7b91aabe077aa9cac9158dd480775Xavier Ducrohet * of (min,max,fuzz,flat) 32-bit values. 46831203e4ba2e7b91aabe077aa9cac9158dd480775Xavier Ducrohet * 46931203e4ba2e7b91aabe077aa9cac9158dd480775Xavier Ducrohet * min and max are the bounds 47031203e4ba2e7b91aabe077aa9cac9158dd480775Xavier Ducrohet * fuzz corresponds to the device's fuziness, we set it to 0 47131203e4ba2e7b91aabe077aa9cac9158dd480775Xavier Ducrohet * flat corresponds to the flat position for JOEYDEV devices, 47231203e4ba2e7b91aabe077aa9cac9158dd480775Xavier Ducrohet * we also set it to 0. 47331203e4ba2e7b91aabe077aa9cac9158dd480775Xavier Ducrohet * 47431203e4ba2e7b91aabe077aa9cac9158dd480775Xavier Ducrohet * There is no need to save/restore this array in a snapshot 47531203e4ba2e7b91aabe077aa9cac9158dd480775Xavier Ducrohet * since the values only depend on the hardware configuration. 47631203e4ba2e7b91aabe077aa9cac9158dd480775Xavier Ducrohet */ 477863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine s->abs_info_count = androidHwConfig_isScreenMultiTouch(config) ? ABS_MAX * 4 : 3 * 4; 4788dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine const int abs_size = sizeof(uint32_t) * s->abs_info_count; 4798dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine s->abs_info = malloc(abs_size); 4808dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine memset(s->abs_info, 0, abs_size); 4818dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine abs_values = (ABSEntry*)s->abs_info; 4828dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine 4838dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine abs_values[ABS_X].max = config->hw_lcd_width-1; 4848dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine abs_values[ABS_Y].max = config->hw_lcd_height-1; 4858dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine abs_values[ABS_Z].max = 1; 4868dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine 487863d1010d9c8fa4342b1b0ea860bcfb096806accVladimir Chtchetkine if (androidHwConfig_isScreenMultiTouch(config)) { 4888dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine /* 4898dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine * Setup multitouch. 4908dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine */ 4918dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine events_set_bit(s, EV_ABS, ABS_MT_SLOT); 4928dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine events_set_bit(s, EV_ABS, ABS_MT_POSITION_X); 4938dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine events_set_bit(s, EV_ABS, ABS_MT_POSITION_Y); 4948dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine events_set_bit(s, EV_ABS, ABS_MT_TRACKING_ID); 4958dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine events_set_bit(s, EV_ABS, ABS_MT_TOUCH_MAJOR); 4968dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine events_set_bit(s, EV_ABS, ABS_MT_PRESSURE); 4978dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine 4988dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine abs_values[ABS_MT_SLOT].max = multitouch_get_max_slot(); 4998dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine abs_values[ABS_MT_TRACKING_ID].max = abs_values[ABS_MT_SLOT].max + 1; 5008dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine abs_values[ABS_MT_POSITION_X].max = abs_values[ABS_X].max; 5018dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine abs_values[ABS_MT_POSITION_Y].max = abs_values[ABS_Y].max; 5028dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine abs_values[ABS_MT_TOUCH_MAJOR].max = 0x7fffffff; // TODO: Make it less random 5038dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine abs_values[ABS_MT_PRESSURE].max = 0x100; // TODO: Make it less random 5048dd31e8e10fc3ca10192368acf19d2345eeddde7Vladimir Chtchetkine } 505b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project } 506b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project 507b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project /* configure EV_SW array 508b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * 50971bc069784aa4e4e78a83f03d73622f3d4af6250SeongJae Park * EV_SW events are sent to indicate that the keyboard lid 510b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * was closed or opened (done when we switch layouts through 511b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * KP-7 or KP-9). 512b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project * 5138b9887163ce94928aec159956d1a61fc93bb949dDavid 'Digit' Turner * We only support this when hw.keyboard.lid is true. 514b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project */ 5158b9887163ce94928aec159956d1a61fc93bb949dDavid 'Digit' Turner if (config->hw_keyboard && config->hw_keyboard_lid) { 516b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_SYN, EV_SW); 517b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project events_set_bit(s, EV_SW, 0); 518b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project } 519b059facee5eb498c78c573617c62cc13eddc8644The Android Open Source Project 5205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner iomemtype = cpu_register_io_memory(events_readfn, events_writefn, s); 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_register_physical_memory(base, 0xfff, iomemtype); 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_add_kbd_event_handler(events_put_keycode, s); 5255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_add_mouse_event_handler(events_put_mouse, s, 1, "goldfish-events"); 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->base = base; 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->irq = irq; 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->first = 0; 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s->last = 0; 53280bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner s->state = STATE_INIT; 533aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner s->name = g_strdup(config->hw_keyboard_charmap); 53480bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner 53580bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner /* This function migh fire buffered events to the device, so 53680bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner * ensure that it is called after initialization is complete 53780bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner */ 53880bc5c8c7b9c50e8f302c22c2fba42dd6e8aa2dfDavid 'Digit' Turner user_event_register_generic(s, events_put_generic); 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5405cb5c0b8c5145dc0002b24e1421a3fa7a697475eDavid 'Digit' Turner register_savevm(NULL, 5415cb5c0b8c5145dc0002b24e1421a3fa7a697475eDavid 'Digit' Turner "events_state", 5425cb5c0b8c5145dc0002b24e1421a3fa7a697475eDavid 'Digit' Turner 0, 5435cb5c0b8c5145dc0002b24e1421a3fa7a697475eDavid 'Digit' Turner EVENTS_STATE_SAVE_VERSION, 5445cb5c0b8c5145dc0002b24e1421a3fa7a697475eDavid 'Digit' Turner events_state_save, 5455cb5c0b8c5145dc0002b24e1421a3fa7a697475eDavid 'Digit' Turner events_state_load, 5465cb5c0b8c5145dc0002b24e1421a3fa7a697475eDavid 'Digit' Turner s); 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 548