diff options
-rw-r--r-- | Makefile.android | 5 | ||||
-rw-r--r-- | android/framebuffer.c | 9 | ||||
-rw-r--r-- | android/framebuffer.h | 9 | ||||
-rw-r--r-- | android/looper-generic.c | 2 | ||||
-rw-r--r-- | android/main-common.c | 2 | ||||
-rw-r--r-- | android/main-ui.c | 11 | ||||
-rw-r--r-- | android/protocol/ui-commands-impl.c | 4 | ||||
-rw-r--r-- | android/qemulator.c | 6 | ||||
-rw-r--r-- | console-ui.c | 715 | ||||
-rw-r--r-- | qemu-timer-ui.c | 2 | ||||
-rw-r--r-- | vl-android-ui.c | 495 |
11 files changed, 108 insertions, 1152 deletions
diff --git a/Makefile.android b/Makefile.android index 1e103fd..7ddff81 100644 --- a/Makefile.android +++ b/Makefile.android @@ -690,7 +690,6 @@ CORE_MISC_SOURCES = vl-android.c \ module.c \ qemu-timer.c \ android/boot-properties.c \ - android/display.c \ android/hw-kmsg.c \ android/hw-lcd.c \ android/gps.c \ @@ -876,6 +875,7 @@ endif VL_SOURCES := android/framebuffer.c \ user-events-qemu.c \ android/cmdline-option.c \ + android/display.c \ android/looper-qemu.c \ android/protocol/ui-commands-qemu.c \ android/protocol/core-commands-qemu.c \ @@ -1209,14 +1209,11 @@ endif VL_SOURCES := android/framebuffer.c \ android/cmdline-option.c \ android/config.c \ - android/display.c \ android/looper-generic.c \ android/snapshot.c \ android/main-common.c \ android/main-ui.c \ - qemu-timer-ui.c \ vl-android-ui.c \ - console-ui.c \ iolooper-select.c \ android/protocol/core-connection.c \ android/protocol/attach-ui-impl.c \ diff --git a/android/framebuffer.c b/android/framebuffer.c index 53c6a48..b9b968e 100644 --- a/android/framebuffer.c +++ b/android/framebuffer.c @@ -281,6 +281,15 @@ qframebuffer_check_updates( void ) } void +qframebuffer_pulse( void ) +{ + int nn; + for (nn = 0; nn < framebuffer_fifo_count; nn++) { + qframebuffer_poll(framebuffer_fifo[nn]); + } +} + +void qframebuffer_invalidate_all( void ) { int nn; diff --git a/android/framebuffer.h b/android/framebuffer.h index 9d1f626..faf2f41 100644 --- a/android/framebuffer.h +++ b/android/framebuffer.h @@ -172,6 +172,10 @@ qframebuffer_update( QFrameBuffer* qfbuff, int x, int y, int w, int h ); extern void qframebuffer_rotate( QFrameBuffer* qfbuff, int rotation ); +/* this function is used to poll a framebuffer's client for input + * events. Should be called either explicitely, or through qframebuffer_pulse() + * periodically. + */ extern void qframebuffer_poll( QFrameBuffer* qfbuff ); @@ -188,6 +192,11 @@ qframebuffer_done( QFrameBuffer* qfbuff ); extern void qframebuffer_check_updates( void ); +/* call this function periodically to force a poll on all franebuffers + */ +extern void +qframebuffer_pulse( void ); + /* this is called by the emulator. for each registered framebuffer, call * its producer's Invalidate method, if any */ diff --git a/android/looper-generic.c b/android/looper-generic.c index 6ec0db4..d75fbff 100644 --- a/android/looper-generic.c +++ b/android/looper-generic.c @@ -289,7 +289,7 @@ glooper_addActiveTimer(GLooper* looper, GLoopTimer* tt) pnode = &node->activeNext; } tt->activeNext = *pnode; - *pnode = tt->activeNext; + *pnode = tt; } static void diff --git a/android/main-common.c b/android/main-common.c index 23ba5b9..bcae501 100644 --- a/android/main-common.c +++ b/android/main-common.c @@ -315,7 +315,9 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) } snprintf(buf, sizeof buf, "width=%d,height=%d", width, height); +#if !defined(CONFIG_STANDALONE_UI) && !defined(CONFIG_STANDALONE_CORE) android_display_init(ds, qframebuffer_fifo_get()); +#endif } /* list of skin aliases */ diff --git a/android/main-ui.c b/android/main-ui.c index 9981b76..daf71cb 100644 --- a/android/main-ui.c +++ b/android/main-ui.c @@ -1507,16 +1507,5 @@ int main(int argc, char **argv) } } - // Connect to the core's framebuffer service - if (implFb_create(attachUiImpl_get_console_socket(), "-raw", - qemulator_get_first_framebuffer(qemulator_get()))) { - return -1; - } - - // Attach the recepient of UI commands. - if (uiCmdImpl_create(attachUiImpl_get_console_socket())) { - return -1; - } - return qemu_main(n, args); } diff --git a/android/protocol/ui-commands-impl.c b/android/protocol/ui-commands-impl.c index f265514..2ca4194 100644 --- a/android/protocol/ui-commands-impl.c +++ b/android/protocol/ui-commands-impl.c @@ -124,7 +124,7 @@ _uiCmdImpl_io_read(void* opaque) status = read(uicmd->sock, uicmd->reader_buffer + uicmd->reader_offset, uicmd->reader_bytes - uicmd->reader_offset); if (status == 0) { - /* Disconnection, meaning that the core process got termonated. */ + /* Disconnection, meaning that the core process got terminated. */ fprintf(stderr, "core-ui-control service got disconnected\n"); uiCmdImpl_destroy(); return; @@ -201,7 +201,7 @@ uiCmdImpl_create(SockAddress* console_socket) return -1; } - // Initialze UI command reader. + // Initialize UI command reader. _uiCmdImpl.sock = core_connection_get_socket(_uiCmdImpl.core_connection); if (qemu_set_fd_handler(_uiCmdImpl.sock, _uiCmdImpl_io_read, NULL, &_uiCmdImpl)) { diff --git a/android/qemulator.c b/android/qemulator.c index 36a9ec8..c90a674 100644 --- a/android/qemulator.c +++ b/android/qemulator.c @@ -97,8 +97,10 @@ qemulator_fb_update( void* _emulator, int x, int y, int w, int h ) { QEmulator* emulator = _emulator; - if (emulator->window) - skin_window_update_display( emulator->window, x, y, w, h ); + if (!emulator->window) { + qemulator_setup( emulator ); + } + skin_window_update_display( emulator->window, x, y, w, h ); } static void diff --git a/console-ui.c b/console-ui.c deleted file mode 100644 index 42a5cb3..0000000 --- a/console-ui.c +++ /dev/null @@ -1,715 +0,0 @@ -/* - * QEMU graphical console - * - * Copyright (c) 2004 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "qemu-common.h" -#include "console.h" -#include "qemu-timer.h" -#include "android/utils/system.h" - -//#define DEBUG_CONSOLE -#define DEFAULT_BACKSCROLL 512 -#define MAX_CONSOLES 12 - -#define QEMU_RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) -#define QEMU_RGB(r, g, b) QEMU_RGBA(r, g, b, 0xff) - -typedef struct TextAttributes { - uint8_t fgcol:4; - uint8_t bgcol:4; - uint8_t bold:1; - uint8_t uline:1; - uint8_t blink:1; - uint8_t invers:1; - uint8_t unvisible:1; -} TextAttributes; - -typedef struct TextCell { - uint8_t ch; - TextAttributes t_attrib; -} TextCell; - -#define MAX_ESC_PARAMS 3 - -enum TTYState { - TTY_STATE_NORM, - TTY_STATE_ESC, - TTY_STATE_CSI, -}; - -typedef struct QEMUFIFO { - uint8_t *buf; - int buf_size; - int count, wptr, rptr; -} QEMUFIFO; - -typedef enum { - GRAPHIC_CONSOLE, - TEXT_CONSOLE, - TEXT_CONSOLE_FIXED_SIZE -} console_type_t; - -/* ??? This is mis-named. - It is used for both text and graphical consoles. */ -struct TextConsole { - console_type_t console_type; - DisplayState *ds; - /* Graphic console state. */ - vga_hw_update_ptr hw_update; - vga_hw_invalidate_ptr hw_invalidate; - vga_hw_screen_dump_ptr hw_screen_dump; - vga_hw_text_update_ptr hw_text_update; - void *hw; - - int g_width, g_height; - int width; - int height; - int total_height; - int backscroll_height; - int x, y; - int x_saved, y_saved; - int y_displayed; - int y_base; - TextAttributes t_attrib_default; /* default text attributes */ - TextAttributes t_attrib; /* currently active text attributes */ - TextCell *cells; - int text_x[2], text_y[2], cursor_invalidate; - - int update_x0; - int update_y0; - int update_x1; - int update_y1; - - enum TTYState state; - int esc_params[MAX_ESC_PARAMS]; - int nb_esc_params; - - /* fifo for key pressed */ - QEMUFIFO out_fifo; - uint8_t out_fifo_buf[16]; - QEMUTimer *kbd_timer; -}; - -static DisplayState *display_state; -static TextConsole *active_console; -static TextConsole *consoles[MAX_CONSOLES]; -static int nb_consoles = 0; - -#ifdef CONFIG_ANDROID -/* Graphic console width, height and bits per pixel. - * These default values can be changed with the "-android-gui" option. - */ -int android_display_width = 640; -int android_display_height = 480; -int android_display_bpp = 32; -#endif - -void vga_hw_update(void) -{ - if (active_console && active_console->hw_update) - active_console->hw_update(active_console->hw); -} - -void vga_hw_invalidate(void) -{ - if (active_console && active_console->hw_invalidate) - active_console->hw_invalidate(active_console->hw); -} - -void vga_hw_screen_dump(const char *filename) -{ - TextConsole *previous_active_console; - - previous_active_console = active_console; - active_console = consoles[0]; - /* There is currently no way of specifying which screen we want to dump, - so always dump the first one. */ - if (consoles[0]->hw_screen_dump) - consoles[0]->hw_screen_dump(consoles[0]->hw, filename); - active_console = previous_active_console; -} - -void vga_hw_text_update(console_ch_t *chardata) -{ - if (active_console && active_console->hw_text_update) - active_console->hw_text_update(active_console->hw, chardata); -} - -/* convert a RGBA color to a color index usable in graphic primitives */ -static unsigned int vga_get_color(DisplayState *ds, unsigned int rgba) -{ - unsigned int r, g, b, color; - - switch(ds_get_bits_per_pixel(ds)) { -#if 0 - case 8: - r = (rgba >> 16) & 0xff; - g = (rgba >> 8) & 0xff; - b = (rgba) & 0xff; - color = (rgb_to_index[r] * 6 * 6) + - (rgb_to_index[g] * 6) + - (rgb_to_index[b]); - break; -#endif - case 15: - r = (rgba >> 16) & 0xff; - g = (rgba >> 8) & 0xff; - b = (rgba) & 0xff; - color = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3); - break; - case 16: - r = (rgba >> 16) & 0xff; - g = (rgba >> 8) & 0xff; - b = (rgba) & 0xff; - color = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); - break; - case 32: - default: - color = rgba; - break; - } - return color; -} - -/***********************************************************/ -/* basic char display */ - -#define FONT_HEIGHT 16 -#define FONT_WIDTH 8 - -#include "vgafont.h" - -#define cbswap_32(__x) \ -((uint32_t)( \ - (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \ - (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \ - (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \ - (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )) - -#ifdef HOST_WORDS_BIGENDIAN -#define PAT(x) x -#else -#define PAT(x) cbswap_32(x) -#endif - -static const uint32_t dmask16[16] = { - PAT(0x00000000), - PAT(0x000000ff), - PAT(0x0000ff00), - PAT(0x0000ffff), - PAT(0x00ff0000), - PAT(0x00ff00ff), - PAT(0x00ffff00), - PAT(0x00ffffff), - PAT(0xff000000), - PAT(0xff0000ff), - PAT(0xff00ff00), - PAT(0xff00ffff), - PAT(0xffff0000), - PAT(0xffff00ff), - PAT(0xffffff00), - PAT(0xffffffff), -}; - -static const uint32_t dmask4[4] = { - PAT(0x00000000), - PAT(0x0000ffff), - PAT(0xffff0000), - PAT(0xffffffff), -}; - -static uint32_t color_table[2][8]; - -enum color_names { - COLOR_BLACK = 0, - COLOR_RED = 1, - COLOR_GREEN = 2, - COLOR_YELLOW = 3, - COLOR_BLUE = 4, - COLOR_MAGENTA = 5, - COLOR_CYAN = 6, - COLOR_WHITE = 7 -}; - -static const uint32_t color_table_rgb[2][8] = { - { /* dark */ - QEMU_RGB(0x00, 0x00, 0x00), /* black */ - QEMU_RGB(0xaa, 0x00, 0x00), /* red */ - QEMU_RGB(0x00, 0xaa, 0x00), /* green */ - QEMU_RGB(0xaa, 0xaa, 0x00), /* yellow */ - QEMU_RGB(0x00, 0x00, 0xaa), /* blue */ - QEMU_RGB(0xaa, 0x00, 0xaa), /* magenta */ - QEMU_RGB(0x00, 0xaa, 0xaa), /* cyan */ - QEMU_RGB(0xaa, 0xaa, 0xaa), /* white */ - }, - { /* bright */ - QEMU_RGB(0x00, 0x00, 0x00), /* black */ - QEMU_RGB(0xff, 0x00, 0x00), /* red */ - QEMU_RGB(0x00, 0xff, 0x00), /* green */ - QEMU_RGB(0xff, 0xff, 0x00), /* yellow */ - QEMU_RGB(0x00, 0x00, 0xff), /* blue */ - QEMU_RGB(0xff, 0x00, 0xff), /* magenta */ - QEMU_RGB(0x00, 0xff, 0xff), /* cyan */ - QEMU_RGB(0xff, 0xff, 0xff), /* white */ - } -}; - -static inline unsigned int col_expand(DisplayState *ds, unsigned int col) -{ - switch(ds_get_bits_per_pixel(ds)) { - case 8: - col |= col << 8; - col |= col << 16; - break; - case 15: - case 16: - col |= col << 16; - break; - default: - break; - } - - return col; -} -#ifdef DEBUG_CONSOLE -static void console_print_text_attributes(TextAttributes *t_attrib, char ch) -{ - if (t_attrib->bold) { - printf("b"); - } else { - printf(" "); - } - if (t_attrib->uline) { - printf("u"); - } else { - printf(" "); - } - if (t_attrib->blink) { - printf("l"); - } else { - printf(" "); - } - if (t_attrib->invers) { - printf("i"); - } else { - printf(" "); - } - if (t_attrib->unvisible) { - printf("n"); - } else { - printf(" "); - } - - printf(" fg: %d bg: %d ch:'%2X' '%c'\n", t_attrib->fgcol, t_attrib->bgcol, ch, ch); -} -#endif - -void console_select(unsigned int index) -{ - TextConsole *s; - - if (index >= MAX_CONSOLES) - return; - active_console->g_width = ds_get_width(active_console->ds); - active_console->g_height = ds_get_height(active_console->ds); - s = consoles[index]; - if (s) { - DisplayState *ds = s->ds; - active_console = s; - if (ds_get_bits_per_pixel(s->ds)) { - ds->surface = qemu_resize_displaysurface(ds, s->g_width, s->g_height); - } else { - s->ds->surface->width = s->width; - s->ds->surface->height = s->height; - } - dpy_resize(s->ds); - vga_hw_invalidate(); - } -} - -static TextConsole *get_graphic_console(DisplayState *ds) -{ - int i; - TextConsole *s; - for (i = 0; i < nb_consoles; i++) { - s = consoles[i]; - if (s->console_type == GRAPHIC_CONSOLE && s->ds == ds) - return s; - } - return NULL; -} - -static TextConsole *new_console(DisplayState *ds, console_type_t console_type) -{ - TextConsole *s; - int i; - - if (nb_consoles >= MAX_CONSOLES) - return NULL; - ANEW0(s); - if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) && - (console_type == GRAPHIC_CONSOLE))) { - active_console = s; - } - s->ds = ds; - s->console_type = console_type; - if (console_type != GRAPHIC_CONSOLE) { - consoles[nb_consoles++] = s; - } else { - /* HACK: Put graphical consoles before text consoles. */ - for (i = nb_consoles; i > 0; i--) { - if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE) - break; - consoles[i] = consoles[i - 1]; - } - consoles[i] = s; - nb_consoles++; - } - return s; -} - -static DisplaySurface* defaultallocator_create_displaysurface(int width, int height) -{ - DisplaySurface *surface; - - ANEW0(surface); - surface->width = width; - surface->height = height; - surface->linesize = width * 4; - surface->pf = qemu_default_pixelformat(32); -#ifdef HOST_WORDS_BIGENDIAN - surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG; -#else - surface->flags = QEMU_ALLOCATED_FLAG; -#endif - surface->data = (uint8_t*) android_alloc0(surface->linesize * surface->height); - - return surface; -} - -static DisplaySurface* defaultallocator_resize_displaysurface(DisplaySurface *surface, - int width, int height) -{ - surface->width = width; - surface->height = height; - surface->linesize = width * 4; - surface->pf = qemu_default_pixelformat(32); - if (surface->flags & QEMU_ALLOCATED_FLAG) - surface->data = (uint8_t*) android_realloc(surface->data, surface->linesize * surface->height); - else - surface->data = (uint8_t*) android_alloc(surface->linesize * surface->height); -#ifdef HOST_WORDS_BIGENDIAN - surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG; -#else - surface->flags = QEMU_ALLOCATED_FLAG; -#endif - - return surface; -} - -DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp, - int linesize, uint8_t *data) -{ - DisplaySurface *surface; - - ANEW0(surface); - surface->width = width; - surface->height = height; - surface->linesize = linesize; - surface->pf = qemu_default_pixelformat(bpp); -#ifdef HOST_WORDS_BIGENDIAN - surface->flags = QEMU_BIG_ENDIAN_FLAG; -#endif - surface->data = data; - - return surface; -} - -static void defaultallocator_free_displaysurface(DisplaySurface *surface) -{ - if (surface == NULL) - return; - if (surface->flags & QEMU_ALLOCATED_FLAG) - AFREE(surface->data); - AFREE(surface); -} - -static struct DisplayAllocator default_allocator = { - defaultallocator_create_displaysurface, - defaultallocator_resize_displaysurface, - defaultallocator_free_displaysurface -}; - -static void dumb_display_init(void) -{ - DisplayState *ds; - ANEW0(ds); - ds->allocator = &default_allocator; - ds->surface = qemu_create_displaysurface(ds, 640, 480); - register_displaystate(ds); -} - -/***********************************************************/ -/* register display */ - -void register_displaystate(DisplayState *ds) -{ - DisplayState **s; - s = &display_state; - while (*s != NULL) - s = &(*s)->next; - ds->next = NULL; - *s = ds; -} - -DisplayState *get_displaystate(void) -{ - if (!display_state) { - dumb_display_init (); - } - return display_state; -} - -DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da) -{ - if(ds->allocator == &default_allocator) { - DisplaySurface *surf; - surf = da->create_displaysurface(ds_get_width(ds), ds_get_height(ds)); - defaultallocator_free_displaysurface(ds->surface); - ds->surface = surf; - ds->allocator = da; - } - return ds->allocator; -} - -DisplayState *graphic_console_init(vga_hw_update_ptr update, - vga_hw_invalidate_ptr invalidate, - vga_hw_screen_dump_ptr screen_dump, - vga_hw_text_update_ptr text_update, - void *opaque) -{ - TextConsole *s; - DisplayState *ds; - - ANEW0(ds); - ds->allocator = &default_allocator; -#ifdef CONFIG_ANDROID - ds->surface = qemu_create_displaysurface(ds, android_display_width, android_display_height); -#else - ds->surface = qemu_create_displaysurface(ds, 640, 480); -#endif - - s = new_console(ds, GRAPHIC_CONSOLE); - if (s == NULL) { - qemu_free_displaysurface(ds); - AFREE(ds); - return NULL; - } - s->hw_update = update; - s->hw_invalidate = invalidate; - s->hw_screen_dump = screen_dump; - s->hw_text_update = text_update; - s->hw = opaque; - - register_displaystate(ds); - return ds; -} - -int is_graphic_console(void) -{ - return active_console && active_console->console_type == GRAPHIC_CONSOLE; -} - -int is_fixedsize_console(void) -{ - return active_console && active_console->console_type != TEXT_CONSOLE; -} - -void console_color_init(DisplayState *ds) -{ - int i, j; - for (j = 0; j < 2; j++) { - for (i = 0; i < 8; i++) { - color_table[j][i] = col_expand(ds, - vga_get_color(ds, color_table_rgb[j][i])); - } - } -} - -void qemu_console_resize(DisplayState *ds, int width, int height) -{ - TextConsole *s = get_graphic_console(ds); - if (!s) return; - - s->g_width = width; - s->g_height = height; - if (is_graphic_console()) { - ds->surface = qemu_resize_displaysurface(ds, width, height); - dpy_resize(ds); - } -} - -void qemu_console_copy(DisplayState *ds, int src_x, int src_y, - int dst_x, int dst_y, int w, int h) -{ - if (is_graphic_console()) { - dpy_copy(ds, src_x, src_y, dst_x, dst_y, w, h); - } -} - -PixelFormat qemu_different_endianness_pixelformat(int bpp) -{ - PixelFormat pf; - - memset(&pf, 0x00, sizeof(PixelFormat)); - - pf.bits_per_pixel = bpp; - pf.bytes_per_pixel = bpp / 8; - pf.depth = bpp == 32 ? 24 : bpp; - - switch (bpp) { - case 24: - pf.rmask = 0x000000FF; - pf.gmask = 0x0000FF00; - pf.bmask = 0x00FF0000; - pf.rmax = 255; - pf.gmax = 255; - pf.bmax = 255; - pf.rshift = 0; - pf.gshift = 8; - pf.bshift = 16; - pf.rbits = 8; - pf.gbits = 8; - pf.bbits = 8; - break; - case 32: - pf.rmask = 0x0000FF00; - pf.gmask = 0x00FF0000; - pf.bmask = 0xFF000000; - pf.amask = 0x00000000; - pf.amax = 255; - pf.rmax = 255; - pf.gmax = 255; - pf.bmax = 255; - pf.ashift = 0; - pf.rshift = 8; - pf.gshift = 16; - pf.bshift = 24; - pf.rbits = 8; - pf.gbits = 8; - pf.bbits = 8; - pf.abits = 8; - break; - default: - break; - } - return pf; -} - -PixelFormat qemu_default_pixelformat(int bpp) -{ - PixelFormat pf; - - memset(&pf, 0x00, sizeof(PixelFormat)); - - pf.bits_per_pixel = bpp; - pf.bytes_per_pixel = bpp / 8; - pf.depth = bpp == 32 ? 24 : bpp; - - switch (bpp) { - case 15: - pf.bits_per_pixel = 16; - pf.bytes_per_pixel = 2; - pf.rmask = 0x00007c00; - pf.gmask = 0x000003E0; - pf.bmask = 0x0000001F; - pf.rmax = 31; - pf.gmax = 31; - pf.bmax = 31; - pf.rshift = 10; - pf.gshift = 5; - pf.bshift = 0; - pf.rbits = 5; - pf.gbits = 5; - pf.bbits = 5; - break; - case 16: - pf.rmask = 0x0000F800; - pf.gmask = 0x000007E0; - pf.bmask = 0x0000001F; - pf.rmax = 31; - pf.gmax = 63; - pf.bmax = 31; - pf.rshift = 11; - pf.gshift = 5; - pf.bshift = 0; - pf.rbits = 5; - pf.gbits = 6; - pf.bbits = 5; - break; - case 24: - pf.rmask = 0x00FF0000; - pf.gmask = 0x0000FF00; - pf.bmask = 0x000000FF; - pf.rmax = 255; - pf.gmax = 255; - pf.bmax = 255; - pf.rshift = 16; - pf.gshift = 8; - pf.bshift = 0; - pf.rbits = 8; - pf.gbits = 8; - pf.bbits = 8; - case 32: - pf.rmask = 0x00FF0000; - pf.gmask = 0x0000FF00; - pf.bmask = 0x000000FF; - pf.amax = 255; - pf.rmax = 255; - pf.gmax = 255; - pf.bmax = 255; - pf.ashift = 24; - pf.rshift = 16; - pf.gshift = 8; - pf.bshift = 0; - pf.rbits = 8; - pf.gbits = 8; - pf.bbits = 8; - pf.abits = 8; - break; - default: - break; - } - return pf; -} - -#ifdef CONFIG_ANDROID -void -android_display_init_from(int width, int height, int rotation, int bpp) -{ - DisplayState *ds; - ANEW0(ds); - ds->allocator = &default_allocator; - ds->surface = qemu_create_displaysurface(ds, width, height); - register_displaystate(ds); -} -#endif diff --git a/qemu-timer-ui.c b/qemu-timer-ui.c index ae85509..095036d 100644 --- a/qemu-timer-ui.c +++ b/qemu-timer-ui.c @@ -49,6 +49,8 @@ extern QEMUClock* rtc_clock; #include "qemu-timer.h" +QEMUClock *rtc_clock; + /***********************************************************/ /* real time host monotonic timer */ diff --git a/vl-android-ui.c b/vl-android-ui.c index c4a396c..91a7764 100644 --- a/vl-android-ui.c +++ b/vl-android-ui.c @@ -27,6 +27,8 @@ #define _GNU_SOURCE 1 #endif +#include <sys/wait.h> + #include "qemu-common.h" #include "net.h" #include "console.h" @@ -47,217 +49,46 @@ #include "android/protocol/user-events-proxy.h" #include "android/protocol/core-commands-proxy.h" #include "android/protocol/ui-commands-impl.h" +#include "android/qemulator.h" -#ifdef CONFIG_MEMCHECK -#include "memcheck/memcheck.h" -#endif // CONFIG_MEMCHECK - -#include <unistd.h> -#include <fcntl.h> -#include <signal.h> -#include <time.h> -#include <errno.h> -#include <sys/time.h> -#include <zlib.h> - -/* Needed early for CONFIG_BSD etc. */ -#include "config-host.h" - -#ifndef _WIN32 -#include <libgen.h> -#include <pwd.h> -#include <sys/times.h> -#include <sys/wait.h> -#include <termios.h> -#include <sys/mman.h> -#include <sys/ioctl.h> -#include <sys/resource.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <net/if.h> -#if defined(__NetBSD__) -#include <net/if_tap.h> -#endif -#ifdef __linux__ -#include <linux/if_tun.h> -#endif -#include <arpa/inet.h> -#include <dirent.h> -#include <netdb.h> -#include <sys/select.h> -#ifdef CONFIG_BSD -#include <sys/stat.h> -#if defined(__FreeBSD__) || defined(__DragonFly__) -#include <libutil.h> -#else -#include <util.h> -#endif -#elif defined (__GLIBC__) && defined (__FreeBSD_kernel__) -#include <freebsd/stdlib.h> -#else -#ifdef __linux__ -#include <pty.h> -#include <malloc.h> -#include <linux/rtc.h> - -/* For the benefit of older linux systems which don't supply it, - we use a local copy of hpet.h. */ -/* #include <linux/hpet.h> */ -#include "hpet.h" - -#include <linux/ppdev.h> -#include <linux/parport.h> -#endif -#ifdef __sun__ -#include <sys/stat.h> -#include <sys/ethernet.h> -#include <sys/sockio.h> -#include <netinet/arp.h> -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/ip_icmp.h> // must come after ip.h -#include <netinet/udp.h> -#include <netinet/tcp.h> -#include <net/if.h> -#include <syslog.h> -#include <stropts.h> -#endif -#endif -#endif - -#if defined(__OpenBSD__) -#include <util.h> -#endif - -#if defined(CONFIG_VDE) -#include <libvdeplug.h> -#endif - -#ifdef _WIN32 -#include <windows.h> -#include <malloc.h> -#include <sys/timeb.h> -#include <mmsystem.h> -#define getopt_long_only getopt_long -#define memalign(align, size) malloc(size) -#endif - - -#ifdef CONFIG_COCOA -#undef main -#define main qemu_main -#endif /* CONFIG_COCOA */ - -#include "qemu-timer.h" -#include "qemu-char.h" - -#if defined(CONFIG_SKINS) && !defined(CONFIG_STANDALONE_CORE) -#undef main -#define main qemu_main -#endif - -#include "qemu_socket.h" - -static const char *data_dir; - -static DisplayState *display_state; -DisplayType display_type = DT_DEFAULT; -const char* keyboard_layout = NULL; -int64_t ticks_per_sec; -int vm_running; -static int autostart; -QEMUClock *rtc_clock; -#ifdef TARGET_SPARC -int graphic_width = 1024; -int graphic_height = 768; -int graphic_depth = 8; -#else -int graphic_width = 800; -int graphic_height = 600; -int graphic_depth = 15; -#endif -static int full_screen = 0; -#ifdef CONFIG_SDL -static int no_frame = 0; -#endif -int no_quit = 0; -int smp_cpus = 1; -const char *vnc_display; -int acpi_enabled = 1; -int no_reboot = 0; -int no_shutdown = 0; -int cursor_hide = 1; -int graphic_rotate = 0; -#ifndef _WIN32 -int daemonize = 0; -#endif -#ifdef TARGET_ARM -int old_param = 0; -#endif -const char *qemu_name; -int alt_grab = 0; - -static QEMUTimer *nographic_timer; - -uint8_t qemu_uuid[16]; - -extern int android_display_width; -extern int android_display_height; -extern int android_display_bpp; - -extern void dprint( const char* format, ... ); - -#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) - -/* compute with 96 bit intermediate result: (a*b)/c */ -uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) -{ - union { - uint64_t ll; - struct { -#ifdef HOST_WORDS_BIGENDIAN - uint32_t high, low; -#else - uint32_t low, high; -#endif - } l; - } u, res; - uint64_t rl, rh; - - u.ll = a; - rl = (uint64_t)u.l.low * (uint64_t)b; - rh = (uint64_t)u.l.high * (uint64_t)b; - rh += (rl >> 32); - res.l.high = rh / c; - res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c; - return res.ll; -} +static Looper* mainLooper; /***********************************************************/ /* I/O handling */ typedef struct IOHandlerRecord { - int fd; - IOCanReadHandler *fd_read_poll; - IOHandler *fd_read; - IOHandler *fd_write; - int deleted; - void *opaque; - /* temporary data */ - struct pollfd *ufd; + LoopIo io[1]; + IOHandler* fd_read; + IOHandler* fd_write; + int running; + int deleted; + void* opaque; struct IOHandlerRecord *next; } IOHandlerRecord; static IOHandlerRecord *first_io_handler; -/* XXX: fd_read_poll should be suppressed, but an API change is - necessary in the character devices to suppress fd_can_read(). */ -int qemu_set_fd_handler2(int fd, - IOCanReadHandler *fd_read_poll, - IOHandler *fd_read, - IOHandler *fd_write, - void *opaque) +static void ioh_callback(void* opaque, int fd, unsigned events) +{ + IOHandlerRecord* ioh = opaque; + ioh->running = 1; + if ((events & LOOP_IO_READ) != 0) { + ioh->fd_read(ioh->opaque); + } + if (!ioh->deleted && (events & LOOP_IO_WRITE) != 0) { + ioh->fd_write(ioh->opaque); + } + ioh->running = 0; + if (ioh->deleted) { + loopIo_done(ioh->io); + free(ioh); + } +} + +int qemu_set_fd_handler(int fd, + IOHandler *fd_read, + IOHandler *fd_write, + void *opaque) { IOHandlerRecord **pioh, *ioh; @@ -266,175 +97,76 @@ int qemu_set_fd_handler2(int fd, for(;;) { ioh = *pioh; if (ioh == NULL) - break; - if (ioh->fd == fd) { - ioh->deleted = 1; + return 0; + if (ioh->io->fd == fd) { break; } pioh = &ioh->next; } + if (ioh->running) { + ioh->deleted = 1; + } else { + *pioh = ioh->next; + loopIo_done(ioh->io); + free(ioh); + } } else { for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { - if (ioh->fd == fd) + if (ioh->io->fd == fd) goto found; } ANEW0(ioh); ioh->next = first_io_handler; first_io_handler = ioh; + loopIo_init(ioh->io, mainLooper, fd, ioh_callback, ioh); found: - ioh->fd = fd; - ioh->fd_read_poll = fd_read_poll; - ioh->fd_read = fd_read; + ioh->fd_read = fd_read; ioh->fd_write = fd_write; - ioh->opaque = opaque; - ioh->deleted = 0; + ioh->opaque = opaque; + + if (fd_read != NULL) + loopIo_wantRead(ioh->io); + else + loopIo_dontWantRead(ioh->io); + + if (fd_write != NULL) + loopIo_wantWrite(ioh->io); + else + loopIo_dontWantWrite(ioh->io); } return 0; } -int qemu_set_fd_handler(int fd, - IOHandler *fd_read, - IOHandler *fd_write, - void *opaque) -{ - return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque); -} - /***********************************************************/ /* main execution loop */ +static LoopTimer gui_timer[1]; + static void gui_update(void *opaque) { - uint64_t interval = GUI_REFRESH_INTERVAL; - DisplayState *ds = opaque; - DisplayChangeListener *dcl = ds->listeners; - - dpy_refresh(ds); - - while (dcl != NULL) { - if (dcl->gui_timer_interval && - dcl->gui_timer_interval < interval) - interval = dcl->gui_timer_interval; - dcl = dcl->next; - } - qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock)); + LoopTimer* timer = opaque; + qframebuffer_pulse(); + loopTimer_startRelative(timer, GUI_REFRESH_INTERVAL); } -static void nographic_update(void *opaque) +static void init_gui_timer(Looper* looper) { - uint64_t interval = GUI_REFRESH_INTERVAL; - - qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock)); + loopTimer_init(gui_timer, looper, gui_update, gui_timer); + loopTimer_startRelative(gui_timer, 0); + qframebuffer_invalidate_all(); } -static int shutdown_requested = 0; - +/* Called from qemulator.c */ void qemu_system_shutdown_request(void) { - shutdown_requested = 1; -} - - - -static int qemu_event_init(void) -{ - return 0; -} - -static int qemu_init_main_loop(void) -{ - return qemu_event_init(); -} - -#define qemu_mutex_lock_iothread() do { } while (0) -#define qemu_mutex_unlock_iothread() do { } while (0) - - -#ifdef _WIN32 -static void host_main_loop_wait(int *timeout) -{ -} -#else -static void host_main_loop_wait(int *timeout) -{ -} -#endif - -void main_loop_wait(int timeout) -{ - IOHandlerRecord *ioh; - fd_set rfds, wfds, xfds; - int ret, nfds; - struct timeval tv; - - host_main_loop_wait(&timeout); - - /* poll any events */ - /* XXX: separate device handlers from system ones */ - nfds = -1; - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); - for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { - if (ioh->deleted) - continue; - if (ioh->fd_read && - (!ioh->fd_read_poll || - ioh->fd_read_poll(ioh->opaque) != 0)) { - FD_SET(ioh->fd, &rfds); - if (ioh->fd > nfds) - nfds = ioh->fd; - } - if (ioh->fd_write) { - FD_SET(ioh->fd, &wfds); - if (ioh->fd > nfds) - nfds = ioh->fd; - } - } - - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - - ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); - if (ret > 0) { - IOHandlerRecord **pioh; - - for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { - if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) { - ioh->fd_read(ioh->opaque); - } - if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) { - ioh->fd_write(ioh->opaque); - } - } - - /* remove deleted IO handlers */ - pioh = &first_io_handler; - while (*pioh) { - ioh = *pioh; - if (ioh->deleted) { - *pioh = ioh->next; - AFREE(ioh); - } else - pioh = &ioh->next; - } - } - - qemu_run_all_timers(); -} - -static void main_loop(void) -{ - while (!shutdown_requested) { - main_loop_wait(qemu_calculate_timeout()); - } + looper_forceQuit(mainLooper); } #ifndef _WIN32 static void termsig_handler(int signal) { - /* qemu_system_shutdown_request(); */ + qemu_system_shutdown_request(); } static void sigchld_handler(int signal) @@ -459,40 +191,6 @@ static void sighandler_setup(void) #endif -#define QEMU_FILE_TYPE_BIOS 0 -#define QEMU_FILE_TYPE_KEYMAP 1 - -char *qemu_find_file(int type, const char *name) -{ - int len; - const char *subdir; - char *buf; - - /* If name contains path separators then try it as a straight path. */ - if ((strchr(name, '/') || strchr(name, '\\')) - && access(name, R_OK) == 0) { - return strdup(name); - } - switch (type) { - case QEMU_FILE_TYPE_BIOS: - subdir = ""; - break; - case QEMU_FILE_TYPE_KEYMAP: - subdir = "keymaps/"; - break; - default: - abort(); - } - len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2; - buf = android_alloc0(len); - snprintf(buf, len, "%s/%s%s", data_dir, subdir, name); - if (access(buf, R_OK)) { - AFREE(buf); - return NULL; - } - return buf; -} - #ifdef _WIN32 static BOOL WINAPI qemu_ctrl_handler(DWORD type) { @@ -501,13 +199,8 @@ static BOOL WINAPI qemu_ctrl_handler(DWORD type) } #endif -int main(int argc, char **argv, char **envp) +int qemu_main(int argc, char **argv, char **envp) { - DisplayState *ds; - DisplayChangeListener *dcl; - - init_clocks(); - #ifndef _WIN32 { struct sigaction act; @@ -538,18 +231,6 @@ int main(int argc, char **argv, char **envp) } #endif - autostart= 1; - - if (qemu_init_main_loop()) { - fprintf(stderr, "qemu_init_main_loop failed\n"); - exit(1); - } - - if (init_timer_alarm() < 0) { - fprintf(stderr, "could not initialize alarm timer\n"); - exit(1); - } - #ifdef _WIN32 socket_init(); #endif @@ -559,42 +240,23 @@ int main(int argc, char **argv, char **envp) sighandler_setup(); #endif - /* just use the first displaystate for the moment */ - ds = display_state = get_displaystate(); - - if (display_type == DT_DEFAULT) { - display_type = DT_SDL; - } - + mainLooper = looper_newGeneric(); - switch (display_type) { - case DT_NOGRAPHIC: - break; - case DT_SDL: - sdl_display_init(ds, full_screen, no_frame); - break; - default: - break; - } - dpy_resize(ds); + /* Register a timer to call qframebuffer_pulse periodically */ + init_gui_timer(mainLooper); - dcl = ds->listeners; - while (dcl != NULL) { - if (dcl->dpy_refresh != NULL) { - ds->gui_timer = qemu_new_timer(rt_clock, gui_update, ds); - qemu_mod_timer(ds->gui_timer, qemu_get_clock(rt_clock)); - } - dcl = dcl->next; + // Connect to the core's framebuffer service + if (implFb_create(attachUiImpl_get_console_socket(), "-raw", + qemulator_get_first_framebuffer(qemulator_get()))) { + return -1; } - if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) { - nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL); - qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock)); + // Attach the recepient of UI commands. + if (uiCmdImpl_create(attachUiImpl_get_console_socket())) { + return -1; } - //qemu_chr_initial_reset(); - - main_loop(); + looper_run(mainLooper); implFb_destroy(); userEventsProxy_destroy(); @@ -602,6 +264,5 @@ int main(int argc, char **argv, char **envp) uiCmdImpl_destroy(); attachUiImpl_destroy(); - quit_timers(); return 0; } |