blob: 90559f3e50b3d9a2222724eb57b6b1a9dcbfda4a [file] [log] [blame]
/* Copyright (C) 2010 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
*/
/* Initialization of the Android-specific DisplayState.
* Read docs/DISPLAY-STATE.TXT to understand what this
* is supposed to do.
*/
#include "android-qemu1-glue/display.h"
#include "android/emulator-window.h"
#include "android/utils/system.h"
/*
TECHNICAL NOTE:
DisplayState <--> QFrameBuffer <--> QEmulator/SDL
*/
/* QFrameBuffer producer callbacks */
/* this is called periodically by the GUI timer to check for updates
* and poll user events. Use vga_hw_update().
*/
static void
android_display_producer_check(void *opaque)
{
/* core: call vga_hw_update(). this will eventually
* lead to calls to android_display_update()
*/
(void)opaque;
vga_hw_update();
}
static void
android_display_producer_invalidate(void *opaque)
{
(void)opaque;
vga_hw_invalidate();
}
static void
android_display_producer_detach(void* opaque)
{
DisplayState* ds = (DisplayState*)opaque;
if (ds) {
// clean the framebuffer pointer on shutdown
ds->opaque = NULL;
}
}
/* QFrameBuffer client callbacks */
/* this is called from dpy_update() each time a hardware framebuffer
* rectangular update was detected. Send this to the QFrameBuffer.
*/
static void
android_display_update(DisplayState *ds, int x, int y, int w, int h)
{
QFrameBuffer* qfbuff = ds->opaque;
if (qfbuff) {
qframebuffer_update(qfbuff, x, y, w, h);
}
}
static void
android_display_resize(DisplayState *ds)
{
QFrameBuffer* qfbuff = ds->opaque;
if (qfbuff) {
qframebuffer_rotate(qfbuff, 0);
}
}
static void
android_display_refresh(DisplayState *ds)
{
QFrameBuffer* qfbuff = ds->opaque;
if (qfbuff) {
qframebuffer_poll(qfbuff);
}
}
void android_display_init(DisplayState* ds, QFrameBuffer* qf)
{
DisplayChangeListener* dcl;
qframebuffer_set_producer(qf, ds,
android_display_producer_check,
android_display_producer_invalidate,
android_display_producer_detach);
/* Replace the display surface with one with the right dimensions */
qemu_free_displaysurface(ds);
ds->opaque = qf;
ds->surface = qemu_create_displaysurface_from(qf->width,
qf->height,
qf->bits_per_pixel,
qf->pitch,
qf->pixels);
/* Register a change listener for it */
ANEW0(dcl);
dcl->dpy_update = android_display_update;
dcl->dpy_resize = android_display_resize;
dcl->dpy_refresh = android_display_refresh;
dcl->dpy_text_cursor = NULL;
register_displaychangelistener(ds, dcl);
}
void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
{
int width = 0;
int height = 0;
char buf[128] = { 0 };
EmulatorWindow* emulator = emulator_window_get();
SkinLayout* skin_layout = emulator_window_get_layout(emulator);
if(skin_layout == NULL) {
// running in no-window mode
return;
}
SkinDisplay* disp = skin_layout_get_display(skin_layout);
if (disp->rotation & 1) {
width = disp->rect.size.h;
height = disp->rect.size.w;
} else {
width = disp->rect.size.w;
height = disp->rect.size.h;
}
snprintf(buf, sizeof buf, "width=%d,height=%d", width, height);
android_display_init(ds, qframebuffer_fifo_get());
}