mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-09 18:44:58 -06:00
Refactor VNC server setup API, by Daniel P. Berrange.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3133 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
6ab43fdc31
commit
71cab5ca0d
3 changed files with 82 additions and 29 deletions
4
vl.c
4
vl.c
|
@ -8319,7 +8319,9 @@ int main(int argc, char **argv)
|
||||||
/* nearly nothing to do */
|
/* nearly nothing to do */
|
||||||
dumb_display_init(ds);
|
dumb_display_init(ds);
|
||||||
} else if (vnc_display != NULL) {
|
} else if (vnc_display != NULL) {
|
||||||
vnc_display_init(ds, vnc_display);
|
vnc_display_init(ds);
|
||||||
|
if (vnc_display_open(ds, vnc_display) < 0)
|
||||||
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
#if defined(CONFIG_SDL)
|
#if defined(CONFIG_SDL)
|
||||||
sdl_display_init(ds, full_screen, no_frame);
|
sdl_display_init(ds, full_screen, no_frame);
|
||||||
|
|
4
vl.h
4
vl.h
|
@ -967,7 +967,9 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame);
|
||||||
void cocoa_display_init(DisplayState *ds, int full_screen);
|
void cocoa_display_init(DisplayState *ds, int full_screen);
|
||||||
|
|
||||||
/* vnc.c */
|
/* vnc.c */
|
||||||
void vnc_display_init(DisplayState *ds, const char *display);
|
void vnc_display_init(DisplayState *ds);
|
||||||
|
void vnc_display_close(DisplayState *ds);
|
||||||
|
int vnc_display_open(DisplayState *ds, const char *display);
|
||||||
void do_info_vnc(void);
|
void do_info_vnc(void);
|
||||||
|
|
||||||
/* x_keymap.c */
|
/* x_keymap.c */
|
||||||
|
|
103
vnc.c
103
vnc.c
|
@ -73,7 +73,7 @@ struct VncState
|
||||||
int last_x;
|
int last_x;
|
||||||
int last_y;
|
int last_y;
|
||||||
|
|
||||||
const char *display;
|
char *display;
|
||||||
|
|
||||||
Buffer output;
|
Buffer output;
|
||||||
Buffer input;
|
Buffer input;
|
||||||
|
@ -1169,16 +1169,8 @@ static void vnc_listen_read(void *opaque)
|
||||||
|
|
||||||
extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
|
extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
|
||||||
|
|
||||||
void vnc_display_init(DisplayState *ds, const char *arg)
|
void vnc_display_init(DisplayState *ds)
|
||||||
{
|
{
|
||||||
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;
|
VncState *vs;
|
||||||
|
|
||||||
vs = qemu_mallocz(sizeof(VncState));
|
vs = qemu_mallocz(sizeof(VncState));
|
||||||
|
@ -1187,7 +1179,7 @@ void vnc_display_init(DisplayState *ds, const char *arg)
|
||||||
|
|
||||||
ds->opaque = vs;
|
ds->opaque = vs;
|
||||||
vnc_state = vs;
|
vnc_state = vs;
|
||||||
vs->display = arg;
|
vs->display = NULL;
|
||||||
|
|
||||||
vs->lsock = -1;
|
vs->lsock = -1;
|
||||||
vs->csock = -1;
|
vs->csock = -1;
|
||||||
|
@ -1212,7 +1204,49 @@ void vnc_display_init(DisplayState *ds, const char *arg)
|
||||||
memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
|
memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
|
||||||
|
|
||||||
vnc_dpy_resize(vs->ds, 640, 400);
|
vnc_dpy_resize(vs->ds, 640, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vnc_display_close(DisplayState *ds)
|
||||||
|
{
|
||||||
|
VncState *vs = (VncState *)ds->opaque;
|
||||||
|
|
||||||
|
if (vs->display) {
|
||||||
|
qemu_free(vs->display);
|
||||||
|
vs->display = NULL;
|
||||||
|
}
|
||||||
|
if (vs->lsock != -1) {
|
||||||
|
qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL);
|
||||||
|
close(vs->lsock);
|
||||||
|
vs->lsock = -1;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int vnc_display_open(DisplayState *ds, const char *arg)
|
||||||
|
{
|
||||||
|
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 = (VncState *)ds->opaque;
|
||||||
|
|
||||||
|
vnc_display_close(ds);
|
||||||
|
if (strcmp(arg, "none") == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(vs->display = strdup(arg)))
|
||||||
|
return -1;
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (strstart(arg, "unix:", &p)) {
|
if (strstart(arg, "unix:", &p)) {
|
||||||
addr = (struct sockaddr *)&uaddr;
|
addr = (struct sockaddr *)&uaddr;
|
||||||
|
@ -1221,7 +1255,9 @@ void vnc_display_init(DisplayState *ds, const char *arg)
|
||||||
vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
|
vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||||
if (vs->lsock == -1) {
|
if (vs->lsock == -1) {
|
||||||
fprintf(stderr, "Could not create socket\n");
|
fprintf(stderr, "Could not create socket\n");
|
||||||
exit(1);
|
free(vs->display);
|
||||||
|
vs->display = NULL;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uaddr.sun_family = AF_UNIX;
|
uaddr.sun_family = AF_UNIX;
|
||||||
|
@ -1235,40 +1271,53 @@ void vnc_display_init(DisplayState *ds, const char *arg)
|
||||||
addr = (struct sockaddr *)&iaddr;
|
addr = (struct sockaddr *)&iaddr;
|
||||||
addrlen = sizeof(iaddr);
|
addrlen = sizeof(iaddr);
|
||||||
|
|
||||||
|
if (parse_host_port(&iaddr, arg) < 0) {
|
||||||
|
fprintf(stderr, "Could not parse VNC address\n");
|
||||||
|
free(vs->display);
|
||||||
|
vs->display = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
|
||||||
|
|
||||||
vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
|
vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
|
||||||
if (vs->lsock == -1) {
|
if (vs->lsock == -1) {
|
||||||
fprintf(stderr, "Could not create socket\n");
|
fprintf(stderr, "Could not create socket\n");
|
||||||
exit(1);
|
free(vs->display);
|
||||||
|
vs->display = NULL;
|
||||||
|
return -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;
|
reuse_addr = 1;
|
||||||
ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
|
ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
|
||||||
(const char *)&reuse_addr, sizeof(reuse_addr));
|
(const char *)&reuse_addr, sizeof(reuse_addr));
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
fprintf(stderr, "setsockopt() failed\n");
|
fprintf(stderr, "setsockopt() failed\n");
|
||||||
exit(1);
|
close(vs->lsock);
|
||||||
|
vs->lsock = -1;
|
||||||
|
free(vs->display);
|
||||||
|
vs->display = NULL;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bind(vs->lsock, addr, addrlen) == -1) {
|
if (bind(vs->lsock, addr, addrlen) == -1) {
|
||||||
fprintf(stderr, "bind() failed\n");
|
fprintf(stderr, "bind() failed\n");
|
||||||
exit(1);
|
close(vs->lsock);
|
||||||
|
vs->lsock = -1;
|
||||||
|
free(vs->display);
|
||||||
|
vs->display = NULL;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen(vs->lsock, 1) == -1) {
|
if (listen(vs->lsock, 1) == -1) {
|
||||||
fprintf(stderr, "listen() failed\n");
|
fprintf(stderr, "listen() failed\n");
|
||||||
exit(1);
|
close(vs->lsock);
|
||||||
|
vs->lsock = -1;
|
||||||
|
free(vs->display);
|
||||||
|
vs->display = NULL;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);
|
return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);
|
||||||
if (ret == -1) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue