1/* Copyright (C) 2010 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
13/* Initialization of the Android-specific DisplayState.
14 * Read docs/DISPLAY-STATE.TXT to understand what this
15 * is supposed to do.
16 */
17#include "android/display.h"
18#include "android/utils/system.h"
19
20/*
21
22TECHNICAL NOTE:
23
24DisplayState <--> QFrameBuffer <--> QEmulator/SDL
25
26*/
27
28/* QFrameBuffer producer callbacks */
29
30/* this is called periodically by the GUI timer to check for updates
31 * and poll user events. Use vga_hw_update().
32 */
33static void
34android_display_producer_check(void *opaque)
35{
36    /* core: call vga_hw_update(). this will eventually
37     * lead to calls to android_display_update()
38     */
39    (void)opaque;
40    vga_hw_update();
41}
42
43static void
44android_display_producer_invalidate(void *opaque)
45{
46    (void)opaque;
47    vga_hw_invalidate();
48}
49
50/* QFrameBuffer client callbacks */
51
52/* this is called from dpy_update() each time a hardware framebuffer
53 * rectangular update was detected. Send this to the QFrameBuffer.
54 */
55static void
56android_display_update(DisplayState *ds, int x, int y, int w, int h)
57{
58    QFrameBuffer* qfbuff = ds->opaque;
59    qframebuffer_update(qfbuff, x, y, w, h);
60}
61
62static void
63android_display_resize(DisplayState *ds)
64{
65    QFrameBuffer* qfbuff = ds->opaque;
66    qframebuffer_rotate(qfbuff, 0);
67}
68
69static void
70android_display_refresh(DisplayState *ds)
71{
72    QFrameBuffer* qfbuff = ds->opaque;
73    qframebuffer_poll(qfbuff);
74}
75
76
77void android_display_init(DisplayState* ds, QFrameBuffer* qf)
78{
79    DisplayChangeListener* dcl;
80
81    qframebuffer_set_producer(qf, ds,
82                              android_display_producer_check,
83                              android_display_producer_invalidate,
84                              NULL); // detach
85
86    /* Replace the display surface with one with the right dimensions */
87    qemu_free_displaysurface(ds);
88    ds->opaque    = qf;
89    ds->surface   = qemu_create_displaysurface_from(qf->width,
90                                                    qf->height,
91                                                    qf->bits_per_pixel,
92                                                    qf->pitch,
93                                                    qf->pixels);
94
95    /* Register a change listener for it */
96    ANEW0(dcl);
97    dcl->dpy_update      = android_display_update;
98    dcl->dpy_resize      = android_display_resize;
99    dcl->dpy_refresh     = android_display_refresh;
100    dcl->dpy_text_cursor = NULL;
101
102    register_displaychangelistener(ds, dcl);
103}
104