Unix domain socket support for VNC, by Anthony Liguori.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2260 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
ffd843bcdc
commit
73fc97427b
@ -247,14 +247,21 @@ command line application. The emulated serial port is redirected on
|
||||
the console. Therefore, you can still use QEMU to debug a Linux kernel
|
||||
with a serial console.
|
||||
|
||||
@item -vnc d
|
||||
@item -vnc display
|
||||
|
||||
Normally, QEMU uses SDL to display the VGA output. With this option,
|
||||
you can have QEMU listen on VNC display @var{d} and redirect the VGA
|
||||
you can have QEMU listen on VNC display @var{display} and redirect the VGA
|
||||
display over the VNC session. It is very useful to enable the usb
|
||||
tablet device when using this option (option @option{-usbdevice
|
||||
tablet}). When using the VNC display, you must use the @option{-k}
|
||||
option to set the keyboard layout.
|
||||
option to set the keyboard layout if you are not using en-us.
|
||||
|
||||
@var{display} may be in the form @var{interface:d}, in which case connections
|
||||
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.
|
||||
|
||||
|
||||
@item -k language
|
||||
|
||||
|
10
vl.c
10
vl.c
@ -152,7 +152,7 @@ int win2k_install_hack = 0;
|
||||
int usb_enabled = 0;
|
||||
static VLANState *first_vlan;
|
||||
int smp_cpus = 1;
|
||||
int vnc_display = -1;
|
||||
const char *vnc_display;
|
||||
#if defined(TARGET_SPARC)
|
||||
#define MAX_CPUS 16
|
||||
#elif defined(TARGET_I386)
|
||||
@ -6818,11 +6818,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case QEMU_OPTION_vnc:
|
||||
vnc_display = atoi(optarg);
|
||||
if (vnc_display < 0) {
|
||||
fprintf(stderr, "Invalid VNC display\n");
|
||||
exit(1);
|
||||
}
|
||||
vnc_display = optarg;
|
||||
break;
|
||||
case QEMU_OPTION_no_acpi:
|
||||
acpi_enabled = 0;
|
||||
@ -6946,7 +6942,7 @@ int main(int argc, char **argv)
|
||||
/* terminal init */
|
||||
if (nographic) {
|
||||
dumb_display_init(ds);
|
||||
} else if (vnc_display != -1) {
|
||||
} else if (vnc_display != NULL) {
|
||||
vnc_display_init(ds, vnc_display);
|
||||
} else {
|
||||
#if defined(CONFIG_SDL)
|
||||
|
2
vl.h
2
vl.h
@ -867,7 +867,7 @@ void sdl_display_init(DisplayState *ds, int full_screen);
|
||||
void cocoa_display_init(DisplayState *ds, int full_screen);
|
||||
|
||||
/* vnc.c */
|
||||
void vnc_display_init(DisplayState *ds, int display);
|
||||
void vnc_display_init(DisplayState *ds, const char *display);
|
||||
|
||||
/* ide.c */
|
||||
#define MAX_DISKS 4
|
||||
|
90
vnc.c
90
vnc.c
@ -1101,10 +1101,18 @@ static void vnc_listen_read(void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
void vnc_display_init(DisplayState *ds, int display)
|
||||
extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
|
||||
|
||||
void vnc_display_init(DisplayState *ds, const char *arg)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
struct sockaddr *addr;
|
||||
struct sockaddr_in iaddr;
|
||||
#ifndef _WIN32
|
||||
struct sockaddr_un uaddr;
|
||||
#endif
|
||||
int reuse_addr, ret;
|
||||
socklen_t addrlen;
|
||||
const char *p;
|
||||
VncState *vs;
|
||||
|
||||
vs = qemu_mallocz(sizeof(VncState));
|
||||
@ -1126,25 +1134,60 @@ void vnc_display_init(DisplayState *ds, int display)
|
||||
if (!vs->kbd_layout)
|
||||
exit(1);
|
||||
|
||||
vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (vs->lsock == -1) {
|
||||
fprintf(stderr, "Could not create socket\n");
|
||||
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);
|
||||
|
||||
#ifndef _WIN32
|
||||
if (strstart(arg, "unix:", &p)) {
|
||||
addr = (struct sockaddr *)&uaddr;
|
||||
addrlen = sizeof(uaddr);
|
||||
|
||||
vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
if (vs->lsock == -1) {
|
||||
fprintf(stderr, "Could not create socket\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uaddr.sun_family = AF_UNIX;
|
||||
memset(uaddr.sun_path, 0, 108);
|
||||
snprintf(uaddr.sun_path, 108, "%s", p);
|
||||
|
||||
unlink(uaddr.sun_path);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
addr = (struct sockaddr *)&iaddr;
|
||||
addrlen = sizeof(iaddr);
|
||||
|
||||
vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (vs->lsock == -1) {
|
||||
fprintf(stderr, "Could not create socket\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (parse_host_port(&iaddr, arg) < 0) {
|
||||
fprintf(stderr, "Could not parse VNC address\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
|
||||
|
||||
reuse_addr = 1;
|
||||
ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char *)&reuse_addr, sizeof(reuse_addr));
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "setsockopt() failed\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(5900 + display);
|
||||
memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));
|
||||
|
||||
reuse_addr = 1;
|
||||
ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
|
||||
(const char *)&reuse_addr, sizeof(reuse_addr));
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "setsockopt() failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (bind(vs->lsock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
||||
if (bind(vs->lsock, addr, addrlen) == -1) {
|
||||
fprintf(stderr, "bind() failed\n");
|
||||
exit(1);
|
||||
}
|
||||
@ -1158,13 +1201,4 @@ void vnc_display_init(DisplayState *ds, int display)
|
||||
if (ret == -1) {
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user