From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1HNi5L-0001IF-Cz for qemu-devel@nongnu.org; Sat, 03 Mar 2007 23:12:35 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1HNi5K-0001I3-I3 for qemu-devel@nongnu.org; Sat, 03 Mar 2007 23:12:35 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HNi5K-0001I0-Bs for qemu-devel@nongnu.org; Sat, 03 Mar 2007 23:12:34 -0500 Received: from wx-out-0506.google.com ([66.249.82.226]) by monty-python.gnu.org with esmtp (Exim 4.52) id 1HNi5J-0001n3-RV for qemu-devel@nongnu.org; Sat, 03 Mar 2007 23:12:34 -0500 Received: by wx-out-0506.google.com with SMTP id i30so1908881wxd for ; Sat, 03 Mar 2007 20:12:33 -0800 (PST) Message-ID: <45EA472D.1040508@codemonkey.ws> Date: Sat, 03 Mar 2007 22:12:29 -0600 From: Anthony Liguori MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------020204070403060601070200" Subject: [Qemu-devel] [PATCH] Enhance monitor change command Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------020204070403060601070200 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Howdy, The following patch allows the change monitor command to be used with vnc, serial, and parallel devices. It depends on my previously posted patches. The patch implements: 1) A vnc "null" display 2) The ability to reopen character devices 3) Appropriate tab expansions for devices This patch is quite useful for management tools as it allows much more flexibility in allowing the user to configure running instances. Regards, Anthony Liguori --------------020204070403060601070200 Content-Type: text/x-patch; name="enhance-change.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="enhance-change.diff" diff -r 6b23d9afec55 console.c --- a/console.c Sat Mar 03 21:35:55 2007 -0600 +++ b/console.c Sat Mar 03 21:42:27 2007 -0600 @@ -1155,16 +1155,12 @@ int is_graphic_console(void) return !active_console->text_console; } -CharDriverState *text_console_init(DisplayState *ds) -{ - CharDriverState *chr; +CharDriverState *text_console_init(CharDriverState *chr, DisplayState *ds) +{ TextConsole *s; int i,j; static int color_inited; - chr = qemu_mallocz(sizeof(CharDriverState)); - if (!chr) - return NULL; s = new_console(ds, 1); if (!s) { free(chr); diff -r 6b23d9afec55 monitor.c --- a/monitor.c Sat Mar 03 21:35:55 2007 -0600 +++ b/monitor.c Sat Mar 03 21:58:55 2007 -0600 @@ -372,7 +372,7 @@ static void do_eject(int force, const ch eject_device(bs, force); } -static void do_change(const char *device, const char *filename) +static void do_change_block(const char *device, const char *filename) { BlockDriverState *bs; int i; @@ -395,6 +395,33 @@ static void do_change(const char *device term_printf("invalid password\n"); } } +} + +static void do_change(const char *device, const char *target) +{ + const char *p; + + if (strcmp(device, "vnc") == 0) { + if (vnc_display_open(NULL, target) == -1) + term_printf("could not start VNC server on %s\n", target); + } else if (strstart(device, "serial", &p)) { + int index = atoi(p); + if (index < 0 || index >= MAX_SERIAL_PORTS) { + term_printf("Invalid serial device %d\n", index); + return; + } + if (qemu_chr_open2(serial_hds[index], target) == NULL) + term_printf("Could not reopen serial device\n"); + } else if (strstart(device, "parallel", &p)) { + int index = atoi(p); + if (index < 0 || index >= MAX_PARALLEL_PORTS) { + term_printf("Invalid parallel device %d\n", index); + return; + } + if (qemu_chr_open2(parallel_hds[index], target) == NULL) + term_printf("Could not reopen serial device\n"); + } else + do_change_block(device, target); } static void do_screen_dump(const char *filename) @@ -1205,8 +1232,8 @@ static term_cmd_t term_cmds[] = { "", "quit the emulator" }, { "eject", "-fB", do_eject, "[-f] device", "eject a removable media (use -f to force it)" }, - { "change", "BF", do_change, - "device filename", "change a removable media" }, + { "change", "DF", do_change, + "device filename", "change a device target" }, { "screendump", "F", do_screen_dump, "filename", "save screen into PPM image 'filename'" }, { "log", "s", do_log, @@ -1988,6 +2015,7 @@ static void monitor_handle_command(const switch(c) { case 'F': case 'B': + case 'D': case 's': { int ret; @@ -2012,6 +2040,9 @@ static void monitor_handle_command(const case 'B': term_printf("%s: block device name expected\n", cmdname); break; + case 'D': + term_printf("%s: device name expected\n", cmdname); + break; default: term_printf("%s: string expected\n", cmdname); break; @@ -2312,7 +2343,7 @@ static void file_completion(const char * closedir(ffs); } -static void block_completion_it(void *opaque, const char *name) +static void device_completion_it(void *opaque, const char *name) { const char *input = opaque; @@ -2320,6 +2351,26 @@ static void block_completion_it(void *op !strncmp(name, (char *)input, strlen(input))) { add_completion(name); } +} + +static void device_iterate(void (*it)(void *opaque, const char *name), void *opaque) +{ + char buf[128]; + int i; + + bdrv_iterate(it, opaque); + + for (i = 0; i < MAX_SERIAL_PORTS; i++) { + snprintf(buf, sizeof(buf), "serial%d", i); + it(opaque, buf); + } + + for (i = 0; i < MAX_SERIAL_PORTS; i++) { + snprintf(buf, sizeof(buf), "parallel%d", i); + it(opaque, buf); + } + + it(opaque, "vnc"); } /* NOTE: this parser is an approximate form of the real command parser */ @@ -2408,8 +2459,13 @@ void readline_find_completion(const char case 'B': /* block device name completion */ completion_index = strlen(str); - bdrv_iterate(block_completion_it, (void *)str); - break; + bdrv_iterate(device_completion_it, (void *)str); + break; + case 'D': + /* device name completion */ + completion_index = strlen(str); + device_iterate(device_completion_it, (void *)str); + break; case 's': /* XXX: more generic ? */ if (!strcmp(cmd->name, "info")) { diff -r 6b23d9afec55 vl.c --- a/vl.c Sat Mar 03 21:35:55 2007 -0600 +++ b/vl.c Sat Mar 03 22:01:35 2007 -0600 @@ -1219,13 +1219,8 @@ static int null_chr_write(CharDriverStat return len; } -static CharDriverState *qemu_chr_open_null(void) -{ - CharDriverState *chr; - - chr = qemu_mallocz(sizeof(CharDriverState)); - if (!chr) - return NULL; +static CharDriverState *qemu_chr_open_null(CharDriverState *chr) +{ chr->chr_write = null_chr_write; return chr; } @@ -1587,15 +1582,16 @@ static void fd_chr_update_read_handler(C } } +static void fd_chr_close(CharDriverState *chr) +{ + free(chr->opaque); +} + /* open a character device to a unix fd */ -static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out) -{ - CharDriverState *chr; +static CharDriverState *qemu_chr_open_fd(CharDriverState *chr, int fd_in, int fd_out) +{ FDCharDriver *s; - chr = qemu_mallocz(sizeof(CharDriverState)); - if (!chr) - return NULL; s = qemu_mallocz(sizeof(FDCharDriver)); if (!s) { free(chr); @@ -1606,23 +1602,24 @@ static CharDriverState *qemu_chr_open_fd chr->opaque = s; chr->chr_write = fd_chr_write; chr->chr_update_read_handler = fd_chr_update_read_handler; + chr->chr_close = fd_chr_close; qemu_chr_reset(chr); return chr; } -static CharDriverState *qemu_chr_open_file_out(const char *file_out) +static CharDriverState *qemu_chr_open_file_out(CharDriverState *chr, const char *file_out) { int fd_out; fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666); if (fd_out < 0) return NULL; - return qemu_chr_open_fd(-1, fd_out); -} - -static CharDriverState *qemu_chr_open_pipe(const char *filename) + return qemu_chr_open_fd(chr, -1, fd_out); +} + +static CharDriverState *qemu_chr_open_pipe(CharDriverState *chr, const char *filename) { int fd_in, fd_out; char filename_in[256], filename_out[256]; @@ -1640,7 +1637,7 @@ static CharDriverState *qemu_chr_open_pi if (fd_in < 0) return NULL; } - return qemu_chr_open_fd(fd_in, fd_out); + return qemu_chr_open_fd(chr, fd_in, fd_out); } @@ -1726,13 +1723,11 @@ static void term_init(void) fcntl(0, F_SETFL, O_NONBLOCK); } -static CharDriverState *qemu_chr_open_stdio(void) -{ - CharDriverState *chr; - +static CharDriverState *qemu_chr_open_stdio(CharDriverState *chr) +{ if (stdio_nb_clients >= STDIO_MAX_CLIENTS) return NULL; - chr = qemu_chr_open_fd(0, 1); + chr = qemu_chr_open_fd(chr, 0, 1); qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr); stdio_nb_clients++; term_init(); @@ -1741,7 +1736,7 @@ static CharDriverState *qemu_chr_open_st } #if defined(__linux__) -static CharDriverState *qemu_chr_open_pty(void) +static CharDriverState *qemu_chr_open_pty(CharDriverState *chr) { struct termios tty; char slave_name[1024]; @@ -1760,7 +1755,7 @@ static CharDriverState *qemu_chr_open_pt tcsetattr (master_fd, TCSAFLUSH, &tty); fprintf(stderr, "char device redirected to %s\n", slave_name); - return qemu_chr_open_fd(master_fd, master_fd); + return qemu_chr_open_fd(chr, master_fd, master_fd); } static void tty_serial_init(int fd, int speed, @@ -1880,9 +1875,8 @@ static int tty_serial_ioctl(CharDriverSt return 0; } -static CharDriverState *qemu_chr_open_tty(const char *filename) -{ - CharDriverState *chr; +static CharDriverState *qemu_chr_open_tty(CharDriverState *chr, const char *filename) +{ int fd; fd = open(filename, O_RDWR | O_NONBLOCK); @@ -1890,7 +1884,7 @@ static CharDriverState *qemu_chr_open_tt return NULL; fcntl(fd, F_SETFL, O_NONBLOCK); tty_serial_init(fd, 115200, 'N', 8, 1); - chr = qemu_chr_open_fd(fd, fd); + chr = qemu_chr_open_fd(chr, fd, fd); if (!chr) return NULL; chr->chr_ioctl = tty_serial_ioctl; @@ -2002,9 +1996,8 @@ static void pp_close(CharDriverState *ch qemu_free(drv); } -static CharDriverState *qemu_chr_open_pp(const char *filename) -{ - CharDriverState *chr; +static CharDriverState *qemu_chr_open_pp(CharDriverState *chr, const char *filename) +{ ParallelCharDriver *drv; int fd; @@ -2025,12 +2018,6 @@ static CharDriverState *qemu_chr_open_pp drv->fd = fd; drv->mode = IEEE1284_MODE_COMPAT; - chr = qemu_mallocz(sizeof(CharDriverState)); - if (!chr) { - qemu_free(drv); - close(fd); - return NULL; - } chr->chr_write = null_chr_write; chr->chr_ioctl = pp_ioctl; chr->chr_close = pp_close; @@ -2249,14 +2236,10 @@ static int win_chr_poll(void *opaque) return 0; } -static CharDriverState *qemu_chr_open_win(const char *filename) -{ - CharDriverState *chr; +static CharDriverState *qemu_chr_open_win(CharDriverState *chr, const char *filename) +{ WinCharState *s; - chr = qemu_mallocz(sizeof(CharDriverState)); - if (!chr) - return NULL; s = qemu_mallocz(sizeof(WinCharState)); if (!s) { free(chr); @@ -2354,14 +2337,10 @@ static int win_chr_pipe_init(CharDriverS } -static CharDriverState *qemu_chr_open_win_pipe(const char *filename) -{ - CharDriverState *chr; +static CharDriverState *qemu_chr_open_win_pipe(CharDriverState *chr, const char *filename) +{ WinCharState *s; - chr = qemu_mallocz(sizeof(CharDriverState)); - if (!chr) - return NULL; s = qemu_mallocz(sizeof(WinCharState)); if (!s) { free(chr); @@ -2380,14 +2359,10 @@ static CharDriverState *qemu_chr_open_wi return chr; } -static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out) -{ - CharDriverState *chr; +static CharDriverState *qemu_chr_open_win_file(CharDriverState *chr, HANDLE fd_out) +{ WinCharState *s; - chr = qemu_mallocz(sizeof(CharDriverState)); - if (!chr) - return NULL; s = qemu_mallocz(sizeof(WinCharState)); if (!s) { free(chr); @@ -2400,7 +2375,7 @@ static CharDriverState *qemu_chr_open_wi return chr; } -static CharDriverState *qemu_chr_open_win_file_out(const char *file_out) +static CharDriverState *qemu_chr_open_win_file_out(CharDriverState *chr, const char *file_out) { HANDLE fd_out; @@ -2409,7 +2384,7 @@ static CharDriverState *qemu_chr_open_wi if (fd_out == INVALID_HANDLE_VALUE) return NULL; - return qemu_chr_open_win_file(fd_out); + return qemu_chr_open_win_file(chr, fd_out); } #endif @@ -2489,16 +2464,12 @@ int parse_host_src_port(struct sockaddr_ struct sockaddr_in *saddr, const char *str); -static CharDriverState *qemu_chr_open_udp(const char *def) -{ - CharDriverState *chr = NULL; +static CharDriverState *qemu_chr_open_udp(CharDriverState *chr, const char *def) +{ NetCharDriver *s = NULL; int fd = -1; struct sockaddr_in saddr; - chr = qemu_mallocz(sizeof(CharDriverState)); - if (!chr) - goto return_err; s = qemu_mallocz(sizeof(NetCharDriver)); if (!s) goto return_err; @@ -2735,11 +2706,11 @@ static void tcp_chr_close(CharDriverStat qemu_free(s); } -static CharDriverState *qemu_chr_open_tcp(const char *host_str, +static CharDriverState *qemu_chr_open_tcp(CharDriverState *chr, + const char *host_str, int is_telnet, int is_unix) { - CharDriverState *chr = NULL; TCPCharDriver *s = NULL; int fd = -1, ret, err, val; int is_listen = 0; @@ -2785,9 +2756,6 @@ static CharDriverState *qemu_chr_open_tc if (!is_listen) is_waitconnect = 0; - chr = qemu_mallocz(sizeof(CharDriverState)); - if (!chr) - goto fail; s = qemu_mallocz(sizeof(TCPCharDriver)); if (!s) goto fail; @@ -2881,31 +2849,36 @@ static CharDriverState *qemu_chr_open_tc return NULL; } -CharDriverState *qemu_chr_open(const char *filename) +CharDriverState *qemu_chr_open2(CharDriverState *chr, const char *filename) { const char *p; - CharDriverState *chr; + CharDriverState *saved_chr; + + saved_chr = chr; + + if (chr->filename) + free(chr->filename); + chr->filename = strdup(filename); if (!strcmp(filename, "vc")) { - chr = text_console_init(&display_state); + chr = text_console_init(chr, &display_state); } else if (!strcmp(filename, "null")) { - chr = qemu_chr_open_null(); + chr = qemu_chr_open_null(chr); } else if (strstart(filename, "tcp:", &p)) { - chr = qemu_chr_open_tcp(p, 0, 0); + chr = qemu_chr_open_tcp(chr, p, 0, 0); } else if (strstart(filename, "telnet:", &p)) { - chr = qemu_chr_open_tcp(p, 1, 0); + chr = qemu_chr_open_tcp(chr, p, 1, 0); } else if (strstart(filename, "udp:", &p)) { - chr = qemu_chr_open_udp(p); + chr = qemu_chr_open_udp(chr, p); } else if (strstart(filename, "mon:", &p)) { - CharDriverState *drv = qemu_chr_open(p); - if (drv) { - drv = qemu_chr_open_mux(drv); - monitor_init(drv, !nographic); - chr = drv; + chr = qemu_chr_open(p); + if (chr) { + chr = qemu_chr_open_mux(chr); + monitor_init(chr, !nographic); } else { printf("Unable to open driver: %s\n", p); return 0; @@ -2913,44 +2886,61 @@ CharDriverState *qemu_chr_open(const cha } else #ifndef _WIN32 if (strstart(filename, "unix:", &p)) { - chr = qemu_chr_open_tcp(p, 0, 1); + chr = qemu_chr_open_tcp(chr, p, 0, 1); } else if (strstart(filename, "file:", &p)) { - chr = qemu_chr_open_file_out(p); + chr = qemu_chr_open_file_out(chr, p); } else if (strstart(filename, "pipe:", &p)) { - chr = qemu_chr_open_pipe(p); + chr = qemu_chr_open_pipe(chr, p); } else if (!strcmp(filename, "pty")) { - chr = qemu_chr_open_pty(); + chr = qemu_chr_open_pty(chr); } else if (!strcmp(filename, "stdio")) { - chr = qemu_chr_open_stdio(); + chr = qemu_chr_open_stdio(chr); } else #endif #if defined(__linux__) if (strstart(filename, "/dev/parport", NULL)) { - chr = qemu_chr_open_pp(filename); + chr = qemu_chr_open_pp(chr, filename); } else if (strstart(filename, "/dev/", NULL)) { - chr = qemu_chr_open_tty(filename); + chr = qemu_chr_open_tty(chr, filename); } else #endif #ifdef _WIN32 if (strstart(filename, "COM", NULL)) { - chr = qemu_chr_open_win(filename); + chr = qemu_chr_open_win(chr, filename); } else if (strstart(filename, "pipe:", &p)) { - chr = qemu_chr_open_win_pipe(p); + chr = qemu_chr_open_win_pipe(chr, p); } else if (strstart(filename, "file:", &p)) { - chr = qemu_chr_open_win_file_out(p); + chr = qemu_chr_open_win_file_out(chr, p); } else #endif { - return NULL; - } - - if (chr) - chr->filename = strdup(filename); + chr = NULL; + } + + if (chr == NULL) { + free(saved_chr->filename); + saved_chr->filename = NULL; + } return chr; +} + +CharDriverState *qemu_chr_open(const char *filename) +{ + CharDriverState *chr, *drv; + + chr = qemu_mallocz(sizeof(CharDriverState)); + if (!chr) + return NULL; + + drv = qemu_chr_open2(chr, filename); + if (!drv) + qemu_free(chr); + + return drv; } void qemu_chr_close(CharDriverState *chr) @@ -7562,7 +7552,7 @@ int main(int argc, char **argv) for(i = 0; i < MAX_PARALLEL_PORTS; i++) { const char *devname = parallel_devices[i]; - if (devname[0] != '\0' && strcmp(devname, "none")) { + if (devname[0] != '\0' && strcmp(devname, "none")) { parallel_hds[i] = qemu_chr_open(devname); if (!parallel_hds[i]) { fprintf(stderr, "qemu: could not open parallel device '%s'\n", @@ -7571,7 +7561,7 @@ int main(int argc, char **argv) } if (!strcmp(devname, "vc")) qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i); - } + } } machine->init(ram_size, vga_ram_size, boot_device, diff -r 6b23d9afec55 vl.h --- a/vl.h Sat Mar 03 21:35:55 2007 -0600 +++ b/vl.h Sat Mar 03 21:55:54 2007 -0600 @@ -311,6 +311,7 @@ typedef struct CharDriverState { } CharDriverState; CharDriverState *qemu_chr_open(const char *filename); +CharDriverState *qemu_chr_open2(CharDriverState *chr, const char *filename); void qemu_chr_printf(CharDriverState *s, const char *fmt, ...); int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len); void qemu_chr_send_event(CharDriverState *s, int event); @@ -342,7 +343,7 @@ void vga_hw_screen_dump(const char *file void vga_hw_screen_dump(const char *filename); int is_graphic_console(void); -CharDriverState *text_console_init(DisplayState *ds); +CharDriverState *text_console_init(CharDriverState *chr, DisplayState *ds); void console_select(unsigned int index); /* serial ports */ @@ -921,6 +922,7 @@ void cocoa_display_init(DisplayState *ds /* vnc.c */ void vnc_display_init(DisplayState *ds, const char *display); +int vnc_display_open(DisplayState *ds, const char *display); void do_info_vnc(void); /* x_keymap.c */ diff -r 6b23d9afec55 vnc.c --- a/vnc.c Sat Mar 03 21:35:55 2007 -0600 +++ b/vnc.c Sat Mar 03 21:55:54 2007 -0600 @@ -73,7 +73,7 @@ struct VncState int last_x; int last_y; - const char *display; + char *display; Buffer output; Buffer input; @@ -1160,7 +1160,7 @@ static void vnc_listen_read(void *opaque extern int parse_host_port(struct sockaddr_in *saddr, const char *str); -void vnc_display_init(DisplayState *ds, const char *arg) +int vnc_display_open(DisplayState *ds, const char *arg) { struct sockaddr *addr; struct sockaddr_in iaddr; @@ -1172,38 +1172,31 @@ void vnc_display_init(DisplayState *ds, const char *p; VncState *vs; - vs = qemu_mallocz(sizeof(VncState)); - if (!vs) - exit(1); - - ds->opaque = vs; - vnc_state = vs; - vs->display = arg; - - vs->lsock = -1; - vs->csock = -1; - vs->depth = 4; - vs->last_x = -1; - vs->last_y = -1; - - vs->ds = ds; - - if (!keyboard_layout) - keyboard_layout = "en-us"; - - vs->kbd_layout = init_keyboard_layout(keyboard_layout); - if (!vs->kbd_layout) - exit(1); - - vs->ds->data = NULL; - vs->ds->dpy_update = vnc_dpy_update; - vs->ds->dpy_resize = vnc_dpy_resize; - vs->ds->dpy_refresh = vnc_dpy_refresh; - - memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row)); - - vnc_dpy_resize(vs->ds, 640, 400); - + if (ds == NULL) + ds = vnc_state->ds; + + vs = ds->opaque; + + free(vs->display); + vs->display = strdup(arg); + if (vs->csock != -1) { + qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL); + closesocket(vs->csock); + vs->csock = -1; + buffer_reset(&vs->input); + buffer_reset(&vs->output); + vs->need_update = 0; + } + + if (vs->lsock != -1) { + qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL); + close(vs->lsock); + vs->lsock = -1; + } + + if (strcmp(arg, "null") == 0) + return 0; + else #ifndef _WIN32 if (strstart(arg, "unix:", &p)) { addr = (struct sockaddr *)&uaddr; @@ -1212,7 +1205,7 @@ void vnc_display_init(DisplayState *ds, vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0); if (vs->lsock == -1) { fprintf(stderr, "Could not create socket\n"); - exit(1); + return -1; } uaddr.sun_family = AF_UNIX; @@ -1229,12 +1222,12 @@ void vnc_display_init(DisplayState *ds, vs->lsock = socket(PF_INET, SOCK_STREAM, 0); if (vs->lsock == -1) { fprintf(stderr, "Could not create socket\n"); - exit(1); + return -1; } if (parse_host_port(&iaddr, arg) < 0) { fprintf(stderr, "Could not parse VNC address\n"); - exit(1); + return -1; } iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900); @@ -1244,22 +1237,63 @@ void vnc_display_init(DisplayState *ds, (const char *)&reuse_addr, sizeof(reuse_addr)); if (ret == -1) { fprintf(stderr, "setsockopt() failed\n"); - exit(1); + return -1; } } if (bind(vs->lsock, addr, addrlen) == -1) { fprintf(stderr, "bind() failed\n"); - exit(1); + return -1; } if (listen(vs->lsock, 1) == -1) { fprintf(stderr, "listen() failed\n"); + return -1; + } + + ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs); + if (ret == -1) + return -1; + + return 0; +} + +void vnc_display_init(DisplayState *ds, const char *arg) +{ + VncState *vs; + + vs = qemu_mallocz(sizeof(VncState)); + if (!vs) exit(1); - } - - ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs); - if (ret == -1) { + + ds->opaque = vs; + vnc_state = vs; + + vs->lsock = -1; + vs->csock = -1; + vs->depth = 4; + vs->last_x = -1; + vs->last_y = -1; + + vs->ds = ds; + vs->display = NULL; + + if (!keyboard_layout) + keyboard_layout = "en-us"; + + vs->kbd_layout = init_keyboard_layout(keyboard_layout); + if (!vs->kbd_layout) exit(1); - } -} + + vs->ds->data = NULL; + vs->ds->dpy_update = vnc_dpy_update; + vs->ds->dpy_resize = vnc_dpy_resize; + vs->ds->dpy_refresh = vnc_dpy_refresh; + + memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row)); + + vnc_dpy_resize(vs->ds, 640, 400); + + if (vnc_display_open(vs->ds, arg) == -1) + exit(1); +} diff -r 6b23d9afec55 qemu-doc.texi --- a/qemu-doc.texi Sat Mar 03 21:35:55 2007 -0600 +++ b/qemu-doc.texi Sat Mar 03 22:09:34 2007 -0600 @@ -267,7 +267,8 @@ will only be allowed from @var{interface will only be allowed from @var{interface} on display @var{d}. Optionally, @var{interface} can be omitted. @var{display} can also be in the form @var{unix:path} where @var{path} is the location of a unix socket to listen for -connections on. +connections on. @var{display} can also be @var{null} which create a VNC server +that does not listen on any interfaces. @item -k language --------------020204070403060601070200--