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
22 TECHNICAL NOTE:
23
24 DisplayState <--> 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 */
33 static void
android_display_producer_check(void * opaque)34 android_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
43 static void
android_display_producer_invalidate(void * opaque)44 android_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 */
55 static void
android_display_update(DisplayState * ds,int x,int y,int w,int h)56 android_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
62 static void
android_display_resize(DisplayState * ds)63 android_display_resize(DisplayState *ds)
64 {
65 QFrameBuffer* qfbuff = ds->opaque;
66 qframebuffer_rotate(qfbuff, 0);
67 }
68
69 static void
android_display_refresh(DisplayState * ds)70 android_display_refresh(DisplayState *ds)
71 {
72 QFrameBuffer* qfbuff = ds->opaque;
73 qframebuffer_poll(qfbuff);
74 }
75
76
android_display_init(DisplayState * ds,QFrameBuffer * qf)77 void 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