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