char: allocate CharDriverState as a single object

Use a single allocation for CharDriverState, this avoids extra
allocations & pointers, and is a step towards more object-oriented
CharDriver.

Gtk console is a bit peculiar, gd_vc_chr_set_echo() used to have a
temporary VirtualConsole to save the echo bit. Instead now, we consider
whether vcd->console is set or not, and restore the echo bit saved in
VCDriverState when calling gd_vc_vte_init().

The casts added are temporary, they are replaced with QOM type-safe
macros in a later patch in this series.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Marc-André Lureau 2016-10-21 23:44:44 +03:00 committed by Paolo Bonzini
parent 5ebd67030c
commit 41ac54b253
10 changed files with 230 additions and 214 deletions

View File

@ -85,7 +85,7 @@
#define BUF_SIZE 256 #define BUF_SIZE 256
typedef struct { typedef struct {
CharDriverState *chr; CharDriverState parent;
brlapi_handle_t *brlapi; brlapi_handle_t *brlapi;
int brlapi_fd; int brlapi_fd;
@ -255,7 +255,7 @@ static int baum_deferred_init(BaumDriverState *baum)
/* The serial port can receive more of our data */ /* The serial port can receive more of our data */
static void baum_accept_input(struct CharDriverState *chr) static void baum_accept_input(struct CharDriverState *chr)
{ {
BaumDriverState *baum = chr->opaque; BaumDriverState *baum = (BaumDriverState *)chr;
int room, first; int room, first;
if (!baum->out_buf_used) if (!baum->out_buf_used)
@ -281,22 +281,23 @@ static void baum_accept_input(struct CharDriverState *chr)
/* We want to send a packet */ /* We want to send a packet */
static void baum_write_packet(BaumDriverState *baum, const uint8_t *buf, int len) static void baum_write_packet(BaumDriverState *baum, const uint8_t *buf, int len)
{ {
CharDriverState *chr = (CharDriverState *)baum;
uint8_t io_buf[1 + 2 * len], *cur = io_buf; uint8_t io_buf[1 + 2 * len], *cur = io_buf;
int room; int room;
*cur++ = ESC; *cur++ = ESC;
while (len--) while (len--)
if ((*cur++ = *buf++) == ESC) if ((*cur++ = *buf++) == ESC)
*cur++ = ESC; *cur++ = ESC;
room = qemu_chr_be_can_write(baum->chr); room = qemu_chr_be_can_write(chr);
len = cur - io_buf; len = cur - io_buf;
if (len <= room) { if (len <= room) {
/* Fits */ /* Fits */
qemu_chr_be_write(baum->chr, io_buf, len); qemu_chr_be_write(chr, io_buf, len);
} else { } else {
int first; int first;
uint8_t out; uint8_t out;
/* Can't fit all, send what can be, and store the rest. */ /* Can't fit all, send what can be, and store the rest. */
qemu_chr_be_write(baum->chr, io_buf, room); qemu_chr_be_write(chr, io_buf, room);
len -= room; len -= room;
cur = io_buf + room; cur = io_buf + room;
if (len > BUF_SIZE - baum->out_buf_used) { if (len > BUF_SIZE - baum->out_buf_used) {
@ -471,7 +472,7 @@ static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len)
/* The other end is writing some data. Store it and try to interpret */ /* The other end is writing some data. Store it and try to interpret */
static int baum_write(CharDriverState *chr, const uint8_t *buf, int len) static int baum_write(CharDriverState *chr, const uint8_t *buf, int len)
{ {
BaumDriverState *baum = chr->opaque; BaumDriverState *baum = (BaumDriverState *)chr;
int tocopy, cur, eaten, orig_len = len; int tocopy, cur, eaten, orig_len = len;
if (!len) if (!len)
@ -612,14 +613,13 @@ static void baum_chr_read(void *opaque)
static void baum_free(struct CharDriverState *chr) static void baum_free(struct CharDriverState *chr)
{ {
BaumDriverState *baum = chr->opaque; BaumDriverState *baum = (BaumDriverState *)chr;
timer_free(baum->cellCount_timer); timer_free(baum->cellCount_timer);
if (baum->brlapi) { if (baum->brlapi) {
brlapi__closeConnection(baum->brlapi); brlapi__closeConnection(baum->brlapi);
g_free(baum->brlapi); g_free(baum->brlapi);
} }
g_free(baum);
} }
static CharDriverState *chr_baum_init(const CharDriver *driver, static CharDriverState *chr_baum_init(const CharDriver *driver,
@ -638,10 +638,7 @@ static CharDriverState *chr_baum_init(const CharDriver *driver,
if (!chr) { if (!chr) {
return NULL; return NULL;
} }
baum = g_malloc0(sizeof(BaumDriverState)); baum = (BaumDriverState *)chr;
baum->chr = chr;
chr->opaque = baum;
handle = g_malloc0(brlapi_getHandleSize()); handle = g_malloc0(brlapi_getHandleSize());
baum->brlapi = handle; baum->brlapi = handle;
@ -663,13 +660,13 @@ static CharDriverState *chr_baum_init(const CharDriver *driver,
fail_handle: fail_handle:
g_free(handle); g_free(handle);
g_free(chr); g_free(chr);
g_free(baum);
return NULL; return NULL;
} }
static void register_types(void) static void register_types(void)
{ {
static const CharDriver driver = { static const CharDriver driver = {
.instance_size = sizeof(BaumDriverState),
.kind = CHARDEV_BACKEND_KIND_BRAILLE, .kind = CHARDEV_BACKEND_KIND_BRAILLE,
.create = chr_baum_init, .create = chr_baum_init,
.chr_write = baum_write, .chr_write = baum_write,

View File

@ -31,7 +31,8 @@
#define MSMOUSE_HI2(n) (((n) & 0xc0) >> 6) #define MSMOUSE_HI2(n) (((n) & 0xc0) >> 6)
typedef struct { typedef struct {
CharDriverState *chr; CharDriverState parent;
QemuInputHandlerState *hs; QemuInputHandlerState *hs;
int axis[INPUT_AXIS__MAX]; int axis[INPUT_AXIS__MAX];
bool btns[INPUT_BUTTON__MAX]; bool btns[INPUT_BUTTON__MAX];
@ -42,7 +43,7 @@ typedef struct {
static void msmouse_chr_accept_input(CharDriverState *chr) static void msmouse_chr_accept_input(CharDriverState *chr)
{ {
MouseState *mouse = chr->opaque; MouseState *mouse = (MouseState *)chr;
int len; int len;
len = qemu_chr_be_can_write(chr); len = qemu_chr_be_can_write(chr);
@ -122,9 +123,10 @@ static void msmouse_input_event(DeviceState *dev, QemuConsole *src,
static void msmouse_input_sync(DeviceState *dev) static void msmouse_input_sync(DeviceState *dev)
{ {
MouseState *mouse = (MouseState *)dev; MouseState *mouse = (MouseState *)dev;
CharDriverState *chr = (CharDriverState *)dev;
msmouse_queue_event(mouse); msmouse_queue_event(mouse);
msmouse_chr_accept_input(mouse->chr); msmouse_chr_accept_input(chr);
} }
static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int len) static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int len)
@ -135,10 +137,9 @@ static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int
static void msmouse_chr_free(struct CharDriverState *chr) static void msmouse_chr_free(struct CharDriverState *chr)
{ {
MouseState *mouse = chr->opaque; MouseState *mouse = (MouseState *)chr;
qemu_input_handler_unregister(mouse->hs); qemu_input_handler_unregister(mouse->hs);
g_free(mouse);
} }
static QemuInputHandler msmouse_handler = { static QemuInputHandler msmouse_handler = {
@ -165,12 +166,10 @@ static CharDriverState *qemu_chr_open_msmouse(const CharDriver *driver,
} }
*be_opened = false; *be_opened = false;
mouse = g_new0(MouseState, 1); mouse = (MouseState *)chr;
mouse->hs = qemu_input_handler_register((DeviceState *)mouse, mouse->hs = qemu_input_handler_register((DeviceState *)mouse,
&msmouse_handler); &msmouse_handler);
mouse->chr = chr;
chr->opaque = mouse;
return chr; return chr;
} }
@ -178,6 +177,7 @@ static CharDriverState *qemu_chr_open_msmouse(const CharDriver *driver,
static void register_types(void) static void register_types(void)
{ {
static const CharDriver driver = { static const CharDriver driver = {
.instance_size = sizeof(MouseState),
.kind = CHARDEV_BACKEND_KIND_MSMOUSE, .kind = CHARDEV_BACKEND_KIND_MSMOUSE,
.create = qemu_chr_open_msmouse, .create = qemu_chr_open_msmouse,
.chr_write = msmouse_chr_write, .chr_write = msmouse_chr_write,

View File

@ -30,7 +30,8 @@
#define BUF_SIZE 32 #define BUF_SIZE 32
typedef struct { typedef struct {
CharDriverState *chr; CharDriverState parent;
uint8_t in_buf[32]; uint8_t in_buf[32];
int in_buf_used; int in_buf_used;
} TestdevCharState; } TestdevCharState;
@ -79,7 +80,7 @@ static int testdev_eat_packet(TestdevCharState *testdev)
/* The other end is writing some data. Store it and try to interpret */ /* The other end is writing some data. Store it and try to interpret */
static int testdev_write(CharDriverState *chr, const uint8_t *buf, int len) static int testdev_write(CharDriverState *chr, const uint8_t *buf, int len)
{ {
TestdevCharState *testdev = chr->opaque; TestdevCharState *testdev = (TestdevCharState *)chr;
int tocopy, eaten, orig_len = len; int tocopy, eaten, orig_len = len;
while (len) { while (len) {
@ -102,13 +103,6 @@ static int testdev_write(CharDriverState *chr, const uint8_t *buf, int len)
return orig_len; return orig_len;
} }
static void testdev_free(struct CharDriverState *chr)
{
TestdevCharState *testdev = chr->opaque;
g_free(testdev);
}
static CharDriverState *chr_testdev_init(const CharDriver *driver, static CharDriverState *chr_testdev_init(const CharDriver *driver,
const char *id, const char *id,
ChardevBackend *backend, ChardevBackend *backend,
@ -116,14 +110,10 @@ static CharDriverState *chr_testdev_init(const CharDriver *driver,
bool *be_opened, bool *be_opened,
Error **errp) Error **errp)
{ {
TestdevCharState *testdev; TestdevCharState *testdev = g_new0(TestdevCharState, 1);;
CharDriverState *chr; CharDriverState *chr = (CharDriverState *)testdev;
testdev = g_new0(TestdevCharState, 1);
testdev->chr = chr = g_new0(CharDriverState, 1);
chr->driver = driver; chr->driver = driver;
chr->opaque = testdev;
return chr; return chr;
} }
@ -131,10 +121,10 @@ static CharDriverState *chr_testdev_init(const CharDriver *driver,
static void register_types(void) static void register_types(void)
{ {
static const CharDriver driver = { static const CharDriver driver = {
.instance_size = sizeof(TestdevCharState),
.kind = CHARDEV_BACKEND_KIND_TESTDEV, .kind = CHARDEV_BACKEND_KIND_TESTDEV,
.create = chr_testdev_init, .create = chr_testdev_init,
.chr_write = testdev_write, .chr_write = testdev_write,
.chr_free = testdev_free,
}; };
register_char_driver(&driver); register_char_driver(&driver);
} }

View File

@ -1733,6 +1733,7 @@ int gdbserver_start(const char *device)
CharDriverState *mon_chr; CharDriverState *mon_chr;
ChardevCommon common = { 0 }; ChardevCommon common = { 0 };
static const CharDriver driver = { static const CharDriver driver = {
.instance_size = sizeof(CharDriverState),
.kind = -1, .kind = -1,
.chr_write = gdb_monitor_write, .chr_write = gdb_monitor_write,
}; };

View File

@ -28,11 +28,11 @@
#include "hw/bt.h" #include "hw/bt.h"
struct csrhci_s { struct csrhci_s {
CharDriverState chr;
int enable; int enable;
qemu_irq *pins; qemu_irq *pins;
int pin_state; int pin_state;
int modem_state; int modem_state;
CharDriverState chr;
#define FIFO_LEN 4096 #define FIFO_LEN 4096
int out_start; int out_start;
int out_len; int out_len;
@ -314,7 +314,7 @@ static void csrhci_ready_for_next_inpkt(struct csrhci_s *s)
static int csrhci_write(struct CharDriverState *chr, static int csrhci_write(struct CharDriverState *chr,
const uint8_t *buf, int len) const uint8_t *buf, int len)
{ {
struct csrhci_s *s = (struct csrhci_s *) chr->opaque; struct csrhci_s *s = (struct csrhci_s *)chr;
int total = 0; int total = 0;
if (!s->enable) if (!s->enable)
@ -387,7 +387,7 @@ static void csrhci_out_hci_packet_acl(void *opaque,
static int csrhci_ioctl(struct CharDriverState *chr, int cmd, void *arg) static int csrhci_ioctl(struct CharDriverState *chr, int cmd, void *arg)
{ {
QEMUSerialSetParams *ssp; QEMUSerialSetParams *ssp;
struct csrhci_s *s = (struct csrhci_s *) chr->opaque; struct csrhci_s *s = (struct csrhci_s *) chr;
int prev_state = s->modem_state; int prev_state = s->modem_state;
switch (cmd) { switch (cmd) {
@ -455,7 +455,7 @@ static void csrhci_pins(void *opaque, int line, int level)
qemu_irq *csrhci_pins_get(CharDriverState *chr) qemu_irq *csrhci_pins_get(CharDriverState *chr)
{ {
struct csrhci_s *s = (struct csrhci_s *) chr->opaque; struct csrhci_s *s = (struct csrhci_s *) chr;
return s->pins; return s->pins;
} }
@ -463,6 +463,7 @@ qemu_irq *csrhci_pins_get(CharDriverState *chr)
CharDriverState *uart_hci_init(void) CharDriverState *uart_hci_init(void)
{ {
static const CharDriver hci_driver = { static const CharDriver hci_driver = {
.instance_size = sizeof(struct csrhci_s),
.kind = -1, .kind = -1,
.chr_write = csrhci_write, .chr_write = csrhci_write,
.chr_ioctl = csrhci_ioctl, .chr_ioctl = csrhci_ioctl,
@ -470,7 +471,6 @@ CharDriverState *uart_hci_init(void)
struct csrhci_s *s = (struct csrhci_s *) struct csrhci_s *s = (struct csrhci_s *)
g_malloc0(sizeof(struct csrhci_s)); g_malloc0(sizeof(struct csrhci_s));
s->chr.opaque = s;
s->chr.driver = &hci_driver; s->chr.driver = &hci_driver;
s->hci = qemu_next_hci(); s->hci = qemu_next_hci();

View File

@ -93,7 +93,6 @@ struct CharDriverState {
const CharDriver *driver; const CharDriver *driver;
QemuMutex chr_write_lock; QemuMutex chr_write_lock;
CharBackend *be; CharBackend *be;
void *opaque;
char *label; char *label;
char *filename; char *filename;
int logfd; int logfd;
@ -484,6 +483,7 @@ struct CharDriver {
ChardevBackend *backend, ChardevBackend *backend,
ChardevReturn *ret, bool *be_opened, ChardevReturn *ret, bool *be_opened,
Error **errp); Error **errp);
size_t instance_size;
int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len); int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
int (*chr_sync_read)(struct CharDriverState *s, int (*chr_sync_read)(struct CharDriverState *s,

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,8 @@
typedef struct SpiceCharDriver { typedef struct SpiceCharDriver {
CharDriverState* chr; CharDriverState parent;
SpiceCharDeviceInstance sin; SpiceCharDeviceInstance sin;
bool active; bool active;
bool blocked; bool blocked;
@ -27,17 +28,18 @@ static QLIST_HEAD(, SpiceCharDriver) spice_chars =
static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len) static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
{ {
SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
CharDriverState *chr = (CharDriverState *)scd;
ssize_t out = 0; ssize_t out = 0;
ssize_t last_out; ssize_t last_out;
uint8_t* p = (uint8_t*)buf; uint8_t* p = (uint8_t*)buf;
while (len > 0) { while (len > 0) {
int can_write = qemu_chr_be_can_write(scd->chr); int can_write = qemu_chr_be_can_write(chr);
last_out = MIN(len, can_write); last_out = MIN(len, can_write);
if (last_out <= 0) { if (last_out <= 0) {
break; break;
} }
qemu_chr_be_write(scd->chr, p, last_out); qemu_chr_be_write(chr, p, last_out);
out += last_out; out += last_out;
len -= last_out; len -= last_out;
p += last_out; p += last_out;
@ -70,6 +72,7 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
static void vmc_event(SpiceCharDeviceInstance *sin, uint8_t event) static void vmc_event(SpiceCharDeviceInstance *sin, uint8_t event)
{ {
SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
CharDriverState *chr = (CharDriverState *)scd;
int chr_event; int chr_event;
switch (event) { switch (event) {
@ -81,20 +84,21 @@ static void vmc_event(SpiceCharDeviceInstance *sin, uint8_t event)
} }
trace_spice_vmc_event(chr_event); trace_spice_vmc_event(chr_event);
qemu_chr_be_event(scd->chr, chr_event); qemu_chr_be_event(chr, chr_event);
} }
#endif #endif
static void vmc_state(SpiceCharDeviceInstance *sin, int connected) static void vmc_state(SpiceCharDeviceInstance *sin, int connected)
{ {
SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
CharDriverState *chr = (CharDriverState *)scd;
if ((scd->chr->be_open && connected) || if ((chr->be_open && connected) ||
(!scd->chr->be_open && !connected)) { (!chr->be_open && !connected)) {
return; return;
} }
qemu_chr_be_event(scd->chr, qemu_chr_be_event(chr,
connected ? CHR_EVENT_OPENED : CHR_EVENT_CLOSED); connected ? CHR_EVENT_OPENED : CHR_EVENT_CLOSED);
} }
@ -168,7 +172,7 @@ static GSourceFuncs SpiceCharSourceFuncs = {
static GSource *spice_chr_add_watch(CharDriverState *chr, GIOCondition cond) static GSource *spice_chr_add_watch(CharDriverState *chr, GIOCondition cond)
{ {
SpiceCharDriver *scd = chr->opaque; SpiceCharDriver *scd = (SpiceCharDriver *)chr;
SpiceCharSource *src; SpiceCharSource *src;
assert(cond & G_IO_OUT); assert(cond & G_IO_OUT);
@ -182,7 +186,7 @@ static GSource *spice_chr_add_watch(CharDriverState *chr, GIOCondition cond)
static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len) static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{ {
SpiceCharDriver *s = chr->opaque; SpiceCharDriver *s = (SpiceCharDriver *)chr;
int read_bytes; int read_bytes;
assert(s->datalen == 0); assert(s->datalen == 0);
@ -201,7 +205,7 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
static void spice_chr_free(struct CharDriverState *chr) static void spice_chr_free(struct CharDriverState *chr)
{ {
SpiceCharDriver *s = chr->opaque; SpiceCharDriver *s = (SpiceCharDriver *)chr;
vmc_unregister_interface(s); vmc_unregister_interface(s);
QLIST_REMOVE(s, next); QLIST_REMOVE(s, next);
@ -210,12 +214,11 @@ static void spice_chr_free(struct CharDriverState *chr)
#if SPICE_SERVER_VERSION >= 0x000c02 #if SPICE_SERVER_VERSION >= 0x000c02
g_free((char *)s->sin.portname); g_free((char *)s->sin.portname);
#endif #endif
g_free(s);
} }
static void spice_vmc_set_fe_open(struct CharDriverState *chr, int fe_open) static void spice_vmc_set_fe_open(struct CharDriverState *chr, int fe_open)
{ {
SpiceCharDriver *s = chr->opaque; SpiceCharDriver *s = (SpiceCharDriver *)chr;
if (fe_open) { if (fe_open) {
vmc_register_interface(s); vmc_register_interface(s);
} else { } else {
@ -226,7 +229,7 @@ static void spice_vmc_set_fe_open(struct CharDriverState *chr, int fe_open)
static void spice_port_set_fe_open(struct CharDriverState *chr, int fe_open) static void spice_port_set_fe_open(struct CharDriverState *chr, int fe_open)
{ {
#if SPICE_SERVER_VERSION >= 0x000c02 #if SPICE_SERVER_VERSION >= 0x000c02
SpiceCharDriver *s = chr->opaque; SpiceCharDriver *s = (SpiceCharDriver *)chr;
if (fe_open) { if (fe_open) {
spice_server_port_event(&s->sin, SPICE_PORT_EVENT_OPENED); spice_server_port_event(&s->sin, SPICE_PORT_EVENT_OPENED);
@ -255,7 +258,7 @@ static void print_allowed_subtypes(void)
static void spice_chr_accept_input(struct CharDriverState *chr) static void spice_chr_accept_input(struct CharDriverState *chr)
{ {
SpiceCharDriver *s = chr->opaque; SpiceCharDriver *s = (SpiceCharDriver *)chr;
spice_server_char_device_wakeup(&s->sin); spice_server_char_device_wakeup(&s->sin);
} }
@ -272,11 +275,9 @@ static CharDriverState *chr_open(const CharDriver *driver,
if (!chr) { if (!chr) {
return NULL; return NULL;
} }
s = g_malloc0(sizeof(SpiceCharDriver)); s = (SpiceCharDriver *)chr;
s->chr = chr;
s->active = false; s->active = false;
s->sin.subtype = g_strdup(subtype); s->sin.subtype = g_strdup(subtype);
chr->opaque = s;
QLIST_INSERT_HEAD(&spice_chars, s, next); QLIST_INSERT_HEAD(&spice_chars, s, next);
@ -334,7 +335,7 @@ static CharDriverState *qemu_chr_open_spice_port(const CharDriver *driver,
return NULL; return NULL;
} }
*be_opened = false; *be_opened = false;
s = chr->opaque; s = (SpiceCharDriver *)chr;
s->sin.portname = g_strdup(name); s->sin.portname = g_strdup(name);
return chr; return chr;
@ -386,6 +387,7 @@ static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend,
static void register_types(void) static void register_types(void)
{ {
static const CharDriver vmc_driver = { static const CharDriver vmc_driver = {
.instance_size = sizeof(SpiceCharDriver),
.kind = CHARDEV_BACKEND_KIND_SPICEVMC, .kind = CHARDEV_BACKEND_KIND_SPICEVMC,
.parse = qemu_chr_parse_spice_vmc, .parse = qemu_chr_parse_spice_vmc,
.create = qemu_chr_open_spice_vmc, .create = qemu_chr_open_spice_vmc,
@ -396,6 +398,7 @@ static void register_types(void)
.chr_free = spice_chr_free, .chr_free = spice_chr_free,
}; };
static const CharDriver port_driver = { static const CharDriver port_driver = {
.instance_size = sizeof(SpiceCharDriver),
.kind = CHARDEV_BACKEND_KIND_SPICEPORT, .kind = CHARDEV_BACKEND_KIND_SPICEPORT,
.parse = qemu_chr_parse_spice_port, .parse = qemu_chr_parse_spice_port,
.create = qemu_chr_open_spice_port, .create = qemu_chr_open_spice_port,

View File

@ -1046,9 +1046,15 @@ void console_select(unsigned int index)
} }
} }
typedef struct VCDriverState {
CharDriverState parent;
QemuConsole *console;
} VCDriverState;
static int console_puts(CharDriverState *chr, const uint8_t *buf, int len) static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
{ {
QemuConsole *s = chr->opaque; VCDriverState *drv = (VCDriverState *)chr;
QemuConsole *s = drv->console;
int i; int i;
if (!s->ds) { if (!s->ds) {
@ -1958,7 +1964,8 @@ int qemu_console_get_height(QemuConsole *con, int fallback)
static void text_console_set_echo(CharDriverState *chr, bool echo) static void text_console_set_echo(CharDriverState *chr, bool echo)
{ {
QemuConsole *s = chr->opaque; VCDriverState *drv = (VCDriverState *)chr;
QemuConsole *s = drv->console;
s->echo = echo; s->echo = echo;
} }
@ -1998,12 +2005,11 @@ static const GraphicHwOps text_console_ops = {
static void text_console_do_init(CharDriverState *chr, DisplayState *ds) static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
{ {
QemuConsole *s; VCDriverState *drv = (VCDriverState *)chr;
QemuConsole *s = drv->console;
int g_width = 80 * FONT_WIDTH; int g_width = 80 * FONT_WIDTH;
int g_height = 24 * FONT_HEIGHT; int g_height = 24 * FONT_HEIGHT;
s = chr->opaque;
s->out_fifo.buf = s->out_fifo_buf; s->out_fifo.buf = s->out_fifo_buf;
s->out_fifo.buf_size = sizeof(s->out_fifo_buf); s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
s->kbd_timer = timer_new_ms(QEMU_CLOCK_REALTIME, kbd_send_chars, s); s->kbd_timer = timer_new_ms(QEMU_CLOCK_REALTIME, kbd_send_chars, s);
@ -2056,6 +2062,7 @@ static CharDriverState *text_console_init(ChardevVC *vc, Error **errp)
{ {
ChardevCommon *common = qapi_ChardevVC_base(vc); ChardevCommon *common = qapi_ChardevVC_base(vc);
CharDriverState *chr; CharDriverState *chr;
VCDriverState *drv;
QemuConsole *s; QemuConsole *s;
unsigned width = 0; unsigned width = 0;
unsigned height = 0; unsigned height = 0;
@ -2092,7 +2099,8 @@ static CharDriverState *text_console_init(ChardevVC *vc, Error **errp)
} }
s->chr = chr; s->chr = chr;
chr->opaque = s; drv = (VCDriverState *)chr;
drv->console = s;
if (display_state) { if (display_state) {
text_console_do_init(chr, display_state); text_console_do_init(chr, display_state);
@ -2196,6 +2204,7 @@ static const TypeInfo qemu_console_info = {
}; };
static const CharDriver vc_driver = { static const CharDriver vc_driver = {
.instance_size = sizeof(VCDriverState),
.kind = CHARDEV_BACKEND_KIND_VC, .kind = CHARDEV_BACKEND_KIND_VC,
.parse = qemu_chr_parse_vc, .parse = qemu_chr_parse_vc,
.create = vc_init, .create = vc_init,

View File

@ -181,6 +181,12 @@ struct GtkDisplayState {
bool ignore_keys; bool ignore_keys;
}; };
typedef struct VCDriverState {
CharDriverState parent;
VirtualConsole *console;
bool echo;
} VCDriverState;
static void gd_grab_pointer(VirtualConsole *vc, const char *reason); static void gd_grab_pointer(VirtualConsole *vc, const char *reason);
static void gd_ungrab_pointer(GtkDisplayState *s); static void gd_ungrab_pointer(GtkDisplayState *s);
static void gd_grab_keyboard(VirtualConsole *vc, const char *reason); static void gd_grab_keyboard(VirtualConsole *vc, const char *reason);
@ -1685,7 +1691,8 @@ static void gd_vc_adjustment_changed(GtkAdjustment *adjustment, void *opaque)
static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len) static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{ {
VirtualConsole *vc = chr->opaque; VCDriverState *vcd = (VCDriverState *)chr;
VirtualConsole *vc = vcd->console;
vte_terminal_feed(VTE_TERMINAL(vc->vte.terminal), (const char *)buf, len); vte_terminal_feed(VTE_TERMINAL(vc->vte.terminal), (const char *)buf, len);
return len; return len;
@ -1693,9 +1700,14 @@ static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
static void gd_vc_chr_set_echo(CharDriverState *chr, bool echo) static void gd_vc_chr_set_echo(CharDriverState *chr, bool echo)
{ {
VirtualConsole *vc = chr->opaque; VCDriverState *vcd = (VCDriverState *)chr;
VirtualConsole *vc = vcd->console;
vc->vte.echo = echo; if (vc) {
vc->vte.echo = echo;
} else {
vcd->echo = echo;
}
} }
static int nb_vcs; static int nb_vcs;
@ -1704,6 +1716,7 @@ static CharDriverState *vcs[MAX_VCS];
static CharDriverState *gd_vc_handler(ChardevVC *vc, Error **errp) static CharDriverState *gd_vc_handler(ChardevVC *vc, Error **errp)
{ {
static const CharDriver gd_vc_driver = { static const CharDriver gd_vc_driver = {
.instance_size = sizeof(VCDriverState),
.kind = CHARDEV_BACKEND_KIND_VC, .kind = CHARDEV_BACKEND_KIND_VC,
.chr_write = gd_vc_chr_write, .chr_write = gd_vc_chr_write,
.chr_set_echo = gd_vc_chr_set_echo, .chr_set_echo = gd_vc_chr_set_echo,
@ -1722,9 +1735,6 @@ static CharDriverState *gd_vc_handler(ChardevVC *vc, Error **errp)
return NULL; return NULL;
} }
/* Temporary, until gd_vc_vte_init runs. */
chr->opaque = g_new0(VirtualConsole, 1);
vcs[nb_vcs++] = chr; vcs[nb_vcs++] = chr;
return chr; return chr;
@ -1765,14 +1775,12 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc,
GtkWidget *box; GtkWidget *box;
GtkWidget *scrollbar; GtkWidget *scrollbar;
GtkAdjustment *vadjustment; GtkAdjustment *vadjustment;
VirtualConsole *tmp_vc = chr->opaque; VCDriverState *vcd = (VCDriverState *)chr;
vc->s = s; vc->s = s;
vc->vte.echo = tmp_vc->vte.echo; vc->vte.echo = vcd->echo;
vc->vte.chr = chr; vc->vte.chr = chr;
chr->opaque = vc; vcd->console = vc;
g_free(tmp_vc);
snprintf(buffer, sizeof(buffer), "vc%d", idx); snprintf(buffer, sizeof(buffer), "vc%d", idx);
vc->label = g_strdup_printf("%s", vc->vte.chr->label vc->label = g_strdup_printf("%s", vc->vte.chr->label