mirror of https://github.com/xemu-project/xemu.git
console: use linked list for QemuConsoles
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Message-id: 20180507095424.16220-1-kraxel@redhat.com
This commit is contained in:
parent
7a61f43859
commit
cd6cd8fa0d
105
ui/console.c
105
ui/console.c
|
@ -165,6 +165,8 @@ struct QemuConsole {
|
||||||
QEMUFIFO out_fifo;
|
QEMUFIFO out_fifo;
|
||||||
uint8_t out_fifo_buf[16];
|
uint8_t out_fifo_buf[16];
|
||||||
QEMUTimer *kbd_timer;
|
QEMUTimer *kbd_timer;
|
||||||
|
|
||||||
|
QTAILQ_ENTRY(QemuConsole) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DisplayState {
|
struct DisplayState {
|
||||||
|
@ -180,8 +182,8 @@ struct DisplayState {
|
||||||
|
|
||||||
static DisplayState *display_state;
|
static DisplayState *display_state;
|
||||||
static QemuConsole *active_console;
|
static QemuConsole *active_console;
|
||||||
static QemuConsole **consoles;
|
static QTAILQ_HEAD(consoles_head, QemuConsole) consoles =
|
||||||
static int nb_consoles = 0;
|
QTAILQ_HEAD_INITIALIZER(consoles);
|
||||||
static bool cursor_visible_phase;
|
static bool cursor_visible_phase;
|
||||||
static QEMUTimer *cursor_timer;
|
static QEMUTimer *cursor_timer;
|
||||||
|
|
||||||
|
@ -197,7 +199,7 @@ static void gui_update(void *opaque)
|
||||||
uint64_t dcl_interval;
|
uint64_t dcl_interval;
|
||||||
DisplayState *ds = opaque;
|
DisplayState *ds = opaque;
|
||||||
DisplayChangeListener *dcl;
|
DisplayChangeListener *dcl;
|
||||||
int i;
|
QemuConsole *con;
|
||||||
|
|
||||||
ds->refreshing = true;
|
ds->refreshing = true;
|
||||||
dpy_refresh(ds);
|
dpy_refresh(ds);
|
||||||
|
@ -212,9 +214,9 @@ static void gui_update(void *opaque)
|
||||||
}
|
}
|
||||||
if (ds->update_interval != interval) {
|
if (ds->update_interval != interval) {
|
||||||
ds->update_interval = interval;
|
ds->update_interval = interval;
|
||||||
for (i = 0; i < nb_consoles; i++) {
|
QTAILQ_FOREACH(con, &consoles, next) {
|
||||||
if (consoles[i]->hw_ops->update_interval) {
|
if (con->hw_ops->update_interval) {
|
||||||
consoles[i]->hw_ops->update_interval(consoles[i]->hw, interval);
|
con->hw_ops->update_interval(con->hw, interval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trace_console_refresh(interval);
|
trace_console_refresh(interval);
|
||||||
|
@ -1292,10 +1294,13 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type,
|
||||||
s->ds = ds;
|
s->ds = ds;
|
||||||
s->console_type = console_type;
|
s->console_type = console_type;
|
||||||
|
|
||||||
consoles = g_realloc(consoles, sizeof(*consoles) * (nb_consoles+1));
|
if (QTAILQ_EMPTY(&consoles)) {
|
||||||
if (console_type != GRAPHIC_CONSOLE || qdev_hotplug) {
|
s->index = 0;
|
||||||
s->index = nb_consoles;
|
QTAILQ_INSERT_TAIL(&consoles, s, next);
|
||||||
consoles[nb_consoles++] = s;
|
} else if (console_type != GRAPHIC_CONSOLE || qdev_hotplug) {
|
||||||
|
QemuConsole *last = QTAILQ_LAST(&consoles, consoles_head);
|
||||||
|
s->index = last->index + 1;
|
||||||
|
QTAILQ_INSERT_TAIL(&consoles, s, next);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* HACK: Put graphical consoles before text consoles.
|
* HACK: Put graphical consoles before text consoles.
|
||||||
|
@ -1303,15 +1308,24 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type,
|
||||||
* Only do that for coldplugged devices. After initial device
|
* Only do that for coldplugged devices. After initial device
|
||||||
* initialization we will not renumber the consoles any more.
|
* initialization we will not renumber the consoles any more.
|
||||||
*/
|
*/
|
||||||
for (i = nb_consoles; i > 0; i--) {
|
QemuConsole *c = QTAILQ_FIRST(&consoles);
|
||||||
if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE)
|
|
||||||
break;
|
while (QTAILQ_NEXT(c, next) != NULL &&
|
||||||
consoles[i] = consoles[i - 1];
|
c->console_type == GRAPHIC_CONSOLE) {
|
||||||
consoles[i]->index = i;
|
c = QTAILQ_NEXT(c, next);
|
||||||
|
}
|
||||||
|
if (c->console_type == GRAPHIC_CONSOLE) {
|
||||||
|
/* have no text consoles */
|
||||||
|
s->index = c->index + 1;
|
||||||
|
QTAILQ_INSERT_AFTER(&consoles, c, s, next);
|
||||||
|
} else {
|
||||||
|
s->index = c->index;
|
||||||
|
QTAILQ_INSERT_BEFORE(c, s, next);
|
||||||
|
/* renumber text consoles */
|
||||||
|
for (i = s->index + 1; c != NULL; c = QTAILQ_NEXT(c, next), i++) {
|
||||||
|
c->index = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
s->index = i;
|
|
||||||
consoles[i] = s;
|
|
||||||
nb_consoles++;
|
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -1861,21 +1875,21 @@ static DisplayState *get_alloc_displaystate(void)
|
||||||
DisplayState *init_displaystate(void)
|
DisplayState *init_displaystate(void)
|
||||||
{
|
{
|
||||||
gchar *name;
|
gchar *name;
|
||||||
int i;
|
QemuConsole *con;
|
||||||
|
|
||||||
get_alloc_displaystate();
|
get_alloc_displaystate();
|
||||||
for (i = 0; i < nb_consoles; i++) {
|
QTAILQ_FOREACH(con, &consoles, next) {
|
||||||
if (consoles[i]->console_type != GRAPHIC_CONSOLE &&
|
if (con->console_type != GRAPHIC_CONSOLE &&
|
||||||
consoles[i]->ds == NULL) {
|
con->ds == NULL) {
|
||||||
text_console_do_init(consoles[i]->chr, display_state);
|
text_console_do_init(con->chr, display_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hook up into the qom tree here (not in new_console()), once
|
/* Hook up into the qom tree here (not in new_console()), once
|
||||||
* all QemuConsoles are created and the order / numbering
|
* all QemuConsoles are created and the order / numbering
|
||||||
* doesn't change any more */
|
* doesn't change any more */
|
||||||
name = g_strdup_printf("console[%d]", i);
|
name = g_strdup_printf("console[%d]", con->index);
|
||||||
object_property_add_child(container_get(object_get_root(), "/backend"),
|
object_property_add_child(container_get(object_get_root(), "/backend"),
|
||||||
name, OBJECT(consoles[i]), &error_abort);
|
name, OBJECT(con), &error_abort);
|
||||||
g_free(name);
|
g_free(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1957,33 +1971,34 @@ void graphic_console_close(QemuConsole *con)
|
||||||
|
|
||||||
QemuConsole *qemu_console_lookup_by_index(unsigned int index)
|
QemuConsole *qemu_console_lookup_by_index(unsigned int index)
|
||||||
{
|
{
|
||||||
if (index >= nb_consoles) {
|
QemuConsole *con;
|
||||||
return NULL;
|
|
||||||
|
QTAILQ_FOREACH(con, &consoles, next) {
|
||||||
|
if (con->index == index) {
|
||||||
|
return con;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return consoles[index];
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head)
|
QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head)
|
||||||
{
|
{
|
||||||
|
QemuConsole *con;
|
||||||
Object *obj;
|
Object *obj;
|
||||||
uint32_t h;
|
uint32_t h;
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < nb_consoles; i++) {
|
QTAILQ_FOREACH(con, &consoles, next) {
|
||||||
if (!consoles[i]) {
|
obj = object_property_get_link(OBJECT(con),
|
||||||
continue;
|
|
||||||
}
|
|
||||||
obj = object_property_get_link(OBJECT(consoles[i]),
|
|
||||||
"device", &error_abort);
|
"device", &error_abort);
|
||||||
if (DEVICE(obj) != dev) {
|
if (DEVICE(obj) != dev) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
h = object_property_get_uint(OBJECT(consoles[i]),
|
h = object_property_get_uint(OBJECT(con),
|
||||||
"head", &error_abort);
|
"head", &error_abort);
|
||||||
if (h != head) {
|
if (h != head) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return consoles[i];
|
return con;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2013,22 +2028,19 @@ QemuConsole *qemu_console_lookup_by_device_name(const char *device_id,
|
||||||
|
|
||||||
QemuConsole *qemu_console_lookup_unused(void)
|
QemuConsole *qemu_console_lookup_unused(void)
|
||||||
{
|
{
|
||||||
|
QemuConsole *con;
|
||||||
Object *obj;
|
Object *obj;
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < nb_consoles; i++) {
|
QTAILQ_FOREACH(con, &consoles, next) {
|
||||||
if (!consoles[i]) {
|
if (con->hw_ops != &unused_ops) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (consoles[i]->hw_ops != &unused_ops) {
|
obj = object_property_get_link(OBJECT(con),
|
||||||
continue;
|
|
||||||
}
|
|
||||||
obj = object_property_get_link(OBJECT(consoles[i]),
|
|
||||||
"device", &error_abort);
|
"device", &error_abort);
|
||||||
if (obj != NULL) {
|
if (obj != NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return consoles[i];
|
return con;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2130,12 +2142,11 @@ static void text_console_update_cursor_timer(void)
|
||||||
static void text_console_update_cursor(void *opaque)
|
static void text_console_update_cursor(void *opaque)
|
||||||
{
|
{
|
||||||
QemuConsole *s;
|
QemuConsole *s;
|
||||||
int i, count = 0;
|
int count = 0;
|
||||||
|
|
||||||
cursor_visible_phase = !cursor_visible_phase;
|
cursor_visible_phase = !cursor_visible_phase;
|
||||||
|
|
||||||
for (i = 0; i < nb_consoles; i++) {
|
QTAILQ_FOREACH(s, &consoles, next) {
|
||||||
s = consoles[i];
|
|
||||||
if (qemu_console_is_graphic(s) ||
|
if (qemu_console_is_graphic(s) ||
|
||||||
!qemu_console_is_visible(s)) {
|
!qemu_console_is_visible(s)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in New Issue