From 95219897ff4e6d0502b920c521fccc612ad913dd Mon Sep 17 00:00:00 2001 From: pbrook Date: Sun, 9 Apr 2006 01:06:34 +0000 Subject: [PATCH] Allow multiple graphics devices. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1803 c046a42c-6fe2-441c-8c8c-71466251a162 --- cocoa.m | 13 ++++------ console.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++------- hw/integratorcp.c | 18 +------------ hw/pl110.c | 11 +++++--- hw/sun4m.c | 19 +------------- hw/tcx.c | 17 +++++++----- hw/vga.c | 20 ++++++++------ monitor.c | 2 +- sdl.c | 16 +++++------- vl.c | 5 +--- vl.h | 29 +++++++++++---------- 11 files changed, 125 insertions(+), 100 deletions(-) diff --git a/cocoa.m b/cocoa.m index 27773e9..2e2908f 100644 --- a/cocoa.m +++ b/cocoa.m @@ -365,8 +365,8 @@ static void cocoa_refresh(DisplayState *ds) pool = [ [ NSAutoreleasePool alloc ] init ]; distantPast = [ NSDate distantPast ]; - if (is_active_console(vga_console)) - vga_update_display(); + vga_hw_update(); + do { event = [ NSApp nextEventMatchingMask:NSAnyEventMask untilDate:distantPast inMode: NSDefaultRunLoopMode dequeue:YES ]; @@ -382,7 +382,7 @@ static void cocoa_refresh(DisplayState *ds) /* emulate caps lock and num lock keydown and keyup */ kbd_put_keycode(keycode); kbd_put_keycode(keycode | 0x80); - } else if (is_active_console(vga_console)) { + } else if (is_graphic_console()) { if (keycode & 0x80) kbd_put_keycode(0xe0); if (modifiers_state[keycode] == 0) { @@ -429,15 +429,12 @@ static void cocoa_refresh(DisplayState *ds) /* toggle Monitor */ case 0x02 ... 0x0a: /* '1' to '9' keys */ console_select(keycode - 0x02); - if (is_active_console(vga_console)) { - /* tell the vga console to redisplay itself */ - vga_invalidate_display(); break; } } } else { /* handle standard key events */ - if (is_active_console(vga_console)) { + if (is_graphic_console()) { if (keycode & 0x80) //check bit for e0 in front kbd_put_keycode(0xe0); kbd_put_keycode(keycode & 0x7f); //remove e0 bit in front @@ -468,7 +465,7 @@ static void cocoa_refresh(DisplayState *ds) case NSKeyUp: { int keycode = cocoa_keycode_to_qemu([event keyCode]); - if (is_active_console(vga_console)) { + if (is_graphic_console()) { if (keycode & 0x80) kbd_put_keycode(0xe0); kbd_put_keycode(keycode | 0x80); //add 128 to signal release of key diff --git a/console.c b/console.c index d1eb406..6f9dc1f 100644 --- a/console.c +++ b/console.c @@ -53,10 +53,17 @@ enum TTYState { TTY_STATE_CSI, }; - +/* ??? This is mis-named. + It is used for both text and graphical consoles. */ struct TextConsole { int text_console; /* true if text console */ 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; + void *hw; + int g_width, g_height; int width; int height; @@ -82,6 +89,26 @@ static TextConsole *active_console; static TextConsole *consoles[MAX_CONSOLES]; static int nb_consoles = 0; +void vga_hw_update(void) +{ + if (active_console->hw_update) + active_console->hw_update(active_console->hw); +} + +void vga_hw_invalidate(void) +{ + if (active_console->hw_invalidate) + active_console->hw_invalidate(active_console->hw); +} + +void vga_hw_screen_dump(const char *filename) +{ + /* There is currently no was of specifying which screen we want to dump, + so always dump the dirst one. */ + if (consoles[0]->hw_screen_dump) + consoles[0]->hw_screen_dump(consoles[0]->hw, filename); +} + /* convert a RGBA color to a color index usable in graphic primitives */ static unsigned int vga_get_color(DisplayState *ds, unsigned int rgba) { @@ -782,8 +809,10 @@ void console_select(unsigned int index) s->g_width = s->ds->width; s->g_height = s->ds->height; text_console_resize(s); - } + } console_refresh(s); + } else { + vga_hw_invalidate(); } } } @@ -874,9 +903,10 @@ void kbd_put_keysym(int keysym) } } -TextConsole *graphic_console_init(DisplayState *ds) +static TextConsole *new_console(DisplayState *ds, int text) { TextConsole *s; + int i; if (nb_consoles >= MAX_CONSOLES) return NULL; @@ -884,16 +914,44 @@ TextConsole *graphic_console_init(DisplayState *ds) if (!s) { return NULL; } - if (!active_console) + if (!active_console || (active_console->text_console && !text)) active_console = s; s->ds = ds; - consoles[nb_consoles++] = s; + s->text_console = text; + if (text) { + consoles[nb_consoles++] = s; + } else { + /* HACK: Put graphical consoles before text consoles. */ + for (i = nb_consoles; i > 0; i--) { + if (!consoles[i - 1]->text_console) + break; + consoles[i] = consoles[i - 1]; + } + consoles[i] = s; + } + return s; +} + +TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update, + vga_hw_invalidate_ptr invalidate, + vga_hw_screen_dump_ptr screen_dump, + void *opaque) +{ + TextConsole *s; + + s = new_console(ds, 0); + if (!s) + return NULL; + s->hw_update = update; + s->hw_invalidate = invalidate; + s->hw_screen_dump = screen_dump; + s->hw = opaque; return s; } -int is_active_console(TextConsole *s) +int is_graphic_console(void) { - return s == active_console; + return !active_console->text_console; } CharDriverState *text_console_init(DisplayState *ds) @@ -906,12 +964,11 @@ CharDriverState *text_console_init(DisplayState *ds) chr = qemu_mallocz(sizeof(CharDriverState)); if (!chr) return NULL; - s = graphic_console_init(ds); + s = new_console(ds, 1); if (!s) { free(chr); return NULL; } - s->text_console = 1; chr->opaque = s; chr->chr_write = console_puts; chr->chr_add_read_handler = console_chr_add_read_handler; diff --git a/hw/integratorcp.c b/hw/integratorcp.c index db73efd..1bcd734 100644 --- a/hw/integratorcp.c +++ b/hw/integratorcp.c @@ -27,22 +27,6 @@ void irq_info(void) { } -static void *lcd; - -void vga_update_display(void) -{ - pl110_update_display(lcd); -} - -void vga_screen_dump(const char *filename) -{ -} - -void vga_invalidate_display(void) -{ - pl110_invalidate_display(lcd); -} - void DMA_run (void) { } @@ -1210,7 +1194,7 @@ static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device, exit (1); } } - lcd = pl110_init(ds, 0xc0000000, pic, 22); + pl110_init(ds, 0xc0000000, pic, 22, 0); /* Load the kernel. */ if (!kernel_filename) { diff --git a/hw/pl110.c b/hw/pl110.c index 2506dfd..839f103 100644 --- a/hw/pl110.c +++ b/hw/pl110.c @@ -89,7 +89,7 @@ static int pl110_enabled(pl110_state *s) return (s->cr & PL110_CR_EN) && (s->cr & PL110_CR_PWR); } -void pl110_update_display(void *opaque) +static void pl110_update_display(void *opaque) { pl110_state *s = (pl110_state *)opaque; drawfn* fntable; @@ -205,7 +205,7 @@ void pl110_update_display(void *opaque) dpy_update(s->ds, 0, first, s->cols, last - first + 1); } -void pl110_invalidate_display(void * opaque) +static void pl110_invalidate_display(void * opaque) { pl110_state *s = (pl110_state *)opaque; s->invalidate = 1; @@ -378,7 +378,8 @@ static CPUWriteMemoryFunc *pl110_writefn[] = { pl110_write }; -void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq) +void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq, + int versatile) { pl110_state *s; int iomemtype; @@ -386,11 +387,13 @@ void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq) s = (pl110_state *)qemu_mallocz(sizeof(pl110_state)); iomemtype = cpu_register_io_memory(0, pl110_readfn, pl110_writefn, s); - cpu_register_physical_memory(base, 0x007fffff, iomemtype); + cpu_register_physical_memory(base, 0x00000fff, iomemtype); s->base = base; s->ds = ds; s->pic = pic; s->irq = irq; + graphic_console_init(ds, pl110_update_display, pl110_invalidate_display, + NULL, s); /* ??? Save/restore. */ return s; } diff --git a/hw/sun4m.c b/hw/sun4m.c index b41ee25..435ac02 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -187,23 +187,6 @@ void pic_set_irq_cpu(int irq, int level, unsigned int cpu) slavio_pic_set_irq_cpu(slavio_intctl, irq, level, cpu); } -static void *tcx; - -void vga_update_display() -{ - tcx_update_display(tcx); -} - -void vga_invalidate_display() -{ - tcx_invalidate_display(tcx); -} - -void vga_screen_dump(const char *filename) -{ - tcx_screen_dump(tcx, filename); -} - static void *iommu; uint32_t iommu_translate(uint32_t addr) @@ -256,7 +239,7 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, slavio_intctl_set_cpu(slavio_intctl, i, envs[i]); } - tcx = tcx_init(ds, PHYS_JJ_TCX_FB, phys_ram_base + ram_size, ram_size, vram_size, graphic_width, graphic_height); + tcx_init(ds, PHYS_JJ_TCX_FB, phys_ram_base + ram_size, ram_size, vram_size, graphic_width, graphic_height); if (nd_table[0].vlan) { if (nd_table[0].model == NULL || strcmp(nd_table[0].model, "lance") == 0) { diff --git a/hw/tcx.c b/hw/tcx.c index c0fddf3..a3a2114 100644 --- a/hw/tcx.c +++ b/hw/tcx.c @@ -37,6 +37,8 @@ typedef struct TCXState { uint8_t dac_index, dac_state; } TCXState; +static void tcx_screen_dump(void *opaque, const char *filename); + static void tcx_draw_line32(TCXState *s1, uint8_t *d, const uint8_t *s, int width) { @@ -81,7 +83,7 @@ static void tcx_draw_line8(TCXState *s1, uint8_t *d, /* Fixed line length 1024 allows us to do nice tricks not possible on VGA... */ -void tcx_update_display(void *opaque) +static void tcx_update_display(void *opaque) { TCXState *ts = opaque; uint32_t page; @@ -158,7 +160,7 @@ void tcx_update_display(void *opaque) } } -void tcx_invalidate_display(void *opaque) +static void tcx_invalidate_display(void *opaque) { TCXState *s = opaque; int i; @@ -269,15 +271,15 @@ static CPUWriteMemoryFunc *tcx_dac_write[3] = { tcx_dac_writel, }; -void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base, - unsigned long vram_offset, int vram_size, int width, int height) +void tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base, + unsigned long vram_offset, int vram_size, int width, int height) { TCXState *s; int io_memory; s = qemu_mallocz(sizeof(TCXState)); if (!s) - return NULL; + return; s->ds = ds; s->addr = addr; s->vram = vram_base; @@ -289,14 +291,15 @@ void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base, io_memory = cpu_register_io_memory(0, tcx_dac_read, tcx_dac_write, s); cpu_register_physical_memory(addr + 0x200000, TCX_DAC_NREGS, io_memory); + graphic_console_init(s->ds, tcx_update_display, tcx_invalidate_display, + tcx_screen_dump, s); register_savevm("tcx", addr, 1, tcx_save, tcx_load, s); qemu_register_reset(tcx_reset, s); tcx_reset(s); dpy_resize(s->ds, width, height); - return s; } -void tcx_screen_dump(void *opaque, const char *filename) +static void tcx_screen_dump(void *opaque, const char *filename) { TCXState *s = opaque; FILE *f; diff --git a/hw/vga.c b/hw/vga.c index 49e5b21..a712790 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -146,6 +146,8 @@ static uint8_t expand4to8[16]; VGAState *vga_state; int vga_io_memory; +static void vga_screen_dump(void *opaque, const char *filename); + static uint32_t vga_ioport_read(void *opaque, uint32_t addr) { VGAState *s = opaque; @@ -1482,9 +1484,9 @@ static void vga_draw_blank(VGAState *s, int full_update) #define GMODE_GRAPH 1 #define GMODE_BLANK 2 -void vga_update_display(void) +static void vga_update_display(void *opaque) { - VGAState *s = vga_state; + VGAState *s = (VGAState *)opaque; int full_update, graphic_mode; if (s->ds->depth == 0) { @@ -1532,9 +1534,9 @@ void vga_update_display(void) } /* force a full display refresh */ -void vga_invalidate_display(void) +static void vga_invalidate_display(void *opaque) { - VGAState *s = vga_state; + VGAState *s = (VGAState *)opaque; s->last_width = -1; s->last_height = -1; @@ -1698,6 +1700,8 @@ void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, s->get_bpp = vga_get_bpp; s->get_offsets = vga_get_offsets; s->get_resolution = vga_get_resolution; + graphic_console_init(s->ds, vga_update_display, vga_invalidate_display, + vga_screen_dump, s); /* XXX: currently needed for display */ vga_state = s; } @@ -1854,13 +1858,13 @@ static int ppm_save(const char *filename, uint8_t *data, /* save the vga display in a PPM image even if no display is available */ -void vga_screen_dump(const char *filename) +static void vga_screen_dump(void *opaque, const char *filename) { - VGAState *s = vga_state; + VGAState *s = (VGAState *)opaque; DisplayState *saved_ds, ds1, *ds = &ds1; /* XXX: this is a little hackish */ - vga_invalidate_display(); + vga_invalidate_display(s); saved_ds = s->ds; memset(ds, 0, sizeof(DisplayState)); @@ -1871,7 +1875,7 @@ void vga_screen_dump(const char *filename) s->ds = ds; s->graphic_mode = -1; - vga_update_display(); + vga_update_display(s); if (ds->data) { ppm_save(filename, ds->data, vga_save_w, vga_save_h, diff --git a/monitor.c b/monitor.c index 6b98cf1..3078b1d 100644 --- a/monitor.c +++ b/monitor.c @@ -356,7 +356,7 @@ static void do_change(const char *device, const char *filename) static void do_screen_dump(const char *filename) { - vga_screen_dump(filename); + vga_hw_screen_dump(filename); } static void do_log(const char *items) diff --git a/sdl.c b/sdl.c index d53f3e9..b8c82fd 100644 --- a/sdl.c +++ b/sdl.c @@ -314,8 +314,8 @@ static void toggle_full_screen(DisplayState *ds) if (!gui_saved_grab) sdl_grab_end(); } - vga_invalidate_display(); - vga_update_display(); + vga_hw_invalidate(); + vga_hw_update(); } static void sdl_refresh(DisplayState *ds) @@ -328,8 +328,7 @@ static void sdl_refresh(DisplayState *ds) sdl_update_caption(); } - if (is_active_console(vga_console)) - vga_update_display(); + vga_hw_update(); while (SDL_PollEvent(ev)) { switch (ev->type) { @@ -352,10 +351,7 @@ static void sdl_refresh(DisplayState *ds) break; case 0x02 ... 0x0a: /* '1' to '9' keys */ console_select(keycode - 0x02); - if (is_active_console(vga_console)) { - /* tell the vga console to redisplay itself */ - vga_invalidate_display(); - } else { + if (!is_graphic_console()) { /* display grab if going to a text console */ if (gui_grab) sdl_grab_end(); @@ -365,7 +361,7 @@ static void sdl_refresh(DisplayState *ds) default: break; } - } else if (!is_active_console(vga_console)) { + } else if (!is_graphic_console()) { int keysym; keysym = 0; if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) { @@ -420,7 +416,7 @@ static void sdl_refresh(DisplayState *ds) } } } - if (is_active_console(vga_console)) + if (is_graphic_console()) sdl_process_key(&ev->key); break; case SDL_QUIT: diff --git a/vl.c b/vl.c index 3a99cbd..ed59988 100644 --- a/vl.c +++ b/vl.c @@ -137,7 +137,6 @@ int graphic_height = 600; #endif int graphic_depth = 15; int full_screen = 0; -TextConsole *vga_console; CharDriverState *serial_hds[MAX_SERIAL_PORTS]; CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; #ifdef TARGET_I386 @@ -2994,7 +2993,7 @@ static void dumb_resize(DisplayState *ds, int w, int h) static void dumb_refresh(DisplayState *ds) { - vga_update_display(); + vga_hw_update(); } void dumb_display_init(DisplayState *ds) @@ -5123,8 +5122,6 @@ int main(int argc, char **argv) #endif } - vga_console = graphic_console_init(ds); - monitor_hd = qemu_chr_open(monitor_device); if (!monitor_hd) { fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device); diff --git a/vl.h b/vl.h index ada0788..0c6f013 100644 --- a/vl.h +++ b/vl.h @@ -254,10 +254,19 @@ int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg); typedef struct DisplayState DisplayState; typedef struct TextConsole TextConsole; -extern TextConsole *vga_console; - -TextConsole *graphic_console_init(DisplayState *ds); -int is_active_console(TextConsole *s); +typedef void (*vga_hw_update_ptr)(void *); +typedef void (*vga_hw_invalidate_ptr)(void *); +typedef void (*vga_hw_screen_dump_ptr)(void *, const char *); + +TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update, + vga_hw_invalidate_ptr invalidate, + vga_hw_screen_dump_ptr screen_dump, + void *opaque); +void vga_hw_update(void); +void vga_hw_invalidate(void); +void vga_hw_screen_dump(const char *filename); + +int is_graphic_console(void); CharDriverState *text_console_init(DisplayState *ds); void console_select(unsigned int index); @@ -673,9 +682,6 @@ static inline void dpy_resize(DisplayState *s, int w, int h) int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, unsigned long vga_ram_offset, int vga_ram_size, unsigned long vga_bios_offset, int vga_bios_size); -void vga_update_display(void); -void vga_invalidate_display(void); -void vga_screen_dump(const char *filename); /* cirrus_vga.c */ void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, @@ -844,11 +850,8 @@ uint32_t iommu_translate_local(void *opaque, uint32_t addr); void lance_init(NICInfo *nd, int irq, uint32_t leaddr, uint32_t ledaddr); /* tcx.c */ -void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base, +void tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base, unsigned long vram_offset, int vram_size, int width, int height); -void tcx_update_display(void *opaque); -void tcx_invalidate_display(void *opaque); -void tcx_screen_dump(void *opaque, const char *filename); /* slavio_intctl.c */ void *slavio_intctl_init(); @@ -976,9 +979,7 @@ void ps2_keyboard_set_translation(void *opaque, int mode); void smc91c111_init(NICInfo *, uint32_t, void *, int); /* pl110.c */ -void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq); -void pl110_update_display(void *opaque); -void pl110_invalidate_display(void *opaque); +void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq, int); #endif /* defined(QEMU_TOOL) */ -- 1.7.9.5