@@ -437,6 +437,11 @@ static void mux_chr_event(void *opaque, int event)
MuxDriver *d = chr->opaque;
int i;
+ if (event == CHR_EVENT_RESIZE) {
+ chr->rows = d->drv->rows;
+ chr->cols = d->drv->cols;
+ }
+
/* Send the event to all registered listeners */
for (i = 0; i < d->mux_cnt; i++)
mux_chr_send_event(d, i, event);
@@ -465,6 +470,10 @@ static void mux_chr_update_read_handler(CharDriverState *chr)
d->focus = d->mux_cnt;
d->mux_cnt++;
mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
+
+ if (chr->rows > 0 && chr->cols > 0) {
+ mux_chr_send_event(d, d->focus, CHR_EVENT_RESIZE);
+ }
}
static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
@@ -545,6 +554,7 @@ int send_all(int fd, const void *buf, int len1)
typedef struct {
int fd_in, fd_out;
int max_size;
+ QEMUTimer *timer;
} FDCharDriver;
#define STDIO_MAX_CLIENTS 1
@@ -600,6 +610,8 @@ static void fd_chr_update_read_handler(CharDriverState *chr)
fd_chr_read, NULL, chr);
}
}
+
+ qemu_mod_timer(s->timer, qemu_get_clock(vm_clock));
}
static void fd_chr_close(struct CharDriverState *chr)
@@ -613,10 +625,31 @@ static void fd_chr_close(struct CharDriverState *chr)
}
}
+ qemu_del_timer(s->timer);
+ qemu_free_timer(s->timer);
qemu_free(s);
qemu_chr_event(chr, CHR_EVENT_CLOSED);
}
+static void fd_chr_timer(void *opaque)
+{
+ struct CharDriverState *chr = opaque;
+ FDCharDriver *s = chr->opaque;
+ struct winsize size;
+
+ if (ioctl(s->fd_out, TIOCGWINSZ, &size) == -1) {
+ return;
+ }
+
+ if (size.ws_row != chr->rows || size.ws_col != chr->cols) {
+ chr->rows = size.ws_row;
+ chr->cols = size.ws_col;
+ qemu_chr_event(chr, CHR_EVENT_RESIZE);
+ }
+
+ qemu_mod_timer(s->timer, qemu_get_clock(vm_clock) + get_ticks_per_sec());
+}
+
/* open a character device to a unix fd */
static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
{
@@ -627,6 +660,7 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
s = qemu_mallocz(sizeof(FDCharDriver));
s->fd_in = fd_in;
s->fd_out = fd_out;
+ s->timer = qemu_new_timer(vm_clock, fd_chr_timer, chr);
chr->opaque = s;
chr->chr_write = fd_chr_write;
chr->chr_update_read_handler = fd_chr_update_read_handler;
@@ -15,6 +15,7 @@
#define CHR_EVENT_MUX_IN 3 /* mux-focus was set to this terminal */
#define CHR_EVENT_MUX_OUT 4 /* mux-focus will move on */
#define CHR_EVENT_CLOSED 5 /* connection closed */
+#define CHR_EVENT_RESIZE 6 /* terminal resize */
#define CHR_IOCTL_SERIAL_SET_PARAMS 1
@@ -68,6 +69,8 @@ struct CharDriverState {
char *label;
char *filename;
int opened;
+ int rows;
+ int cols;
QTAILQ_ENTRY(CharDriverState) next;
};