⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vnc.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    ret = recv(vs->csock, buffer_end(&vs->input), 4096, 0);    ret = vnc_client_io_error(vs, ret, socket_error());    if (!ret)	return;    vs->input.offset += ret;    while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {	size_t len = vs->read_handler_expect;	int ret;	ret = vs->read_handler(vs, vs->input.buffer, len);	if (vs->csock == -1)	    return;	if (!ret) {	    memmove(vs->input.buffer, vs->input.buffer + len, (vs->input.offset - len));	    vs->input.offset -= len;	} else {	    vs->read_handler_expect = ret;	}    }}static void vnc_write(VncState *vs, const void *data, size_t len){    buffer_reserve(&vs->output, len);    if (buffer_empty(&vs->output)) {	qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);    }    buffer_append(&vs->output, data, len);}static void vnc_write_s32(VncState *vs, int32_t value){    vnc_write_u32(vs, *(uint32_t *)&value);}static void vnc_write_u32(VncState *vs, uint32_t value){    uint8_t buf[4];    buf[0] = (value >> 24) & 0xFF;    buf[1] = (value >> 16) & 0xFF;    buf[2] = (value >>  8) & 0xFF;    buf[3] = value & 0xFF;    vnc_write(vs, buf, 4);}static void vnc_write_u16(VncState *vs, uint16_t value){    char buf[2];    buf[0] = (value >> 8) & 0xFF;    buf[1] = value & 0xFF;    vnc_write(vs, buf, 2);}static void vnc_write_u8(VncState *vs, uint8_t value){    vnc_write(vs, (char *)&value, 1);}static void vnc_flush(VncState *vs){    if (vs->output.offset)	vnc_client_write(vs);}static uint8_t read_u8(char *data, size_t offset){    return data[offset];}static uint16_t read_u16(char *data, size_t offset){    return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);}static int32_t read_s32(char *data, size_t offset){    return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |		     (data[offset + 2] << 8) | data[offset + 3]);}static uint32_t read_u32(char *data, size_t offset){    return ((data[offset] << 24) | (data[offset + 1] << 16) |	    (data[offset + 2] << 8) | data[offset + 3]);}static void client_cut_text(VncState *vs, size_t len, char *text){}static void pointer_event(VncState *vs, int button_mask, int x, int y){    int buttons = 0;    int dz = 0;    if (button_mask & 0x01)	buttons |= MOUSE_EVENT_LBUTTON;    if (button_mask & 0x02)	buttons |= MOUSE_EVENT_MBUTTON;    if (button_mask & 0x04)	buttons |= MOUSE_EVENT_RBUTTON;    if (button_mask & 0x08)	dz = -1;    if (button_mask & 0x10)	dz = 1;	        if (kbd_mouse_is_absolute()) {	kbd_mouse_event(x * 0x7FFF / vs->ds->width,			y * 0x7FFF / vs->ds->height,			dz, buttons);    } else {	static int last_x = -1;	static int last_y = -1;	if (last_x != -1)	    kbd_mouse_event(x - last_x, y - last_y, dz, buttons);	last_x = x;	last_y = y;    }}static void do_key_event(VncState *vs, int down, uint32_t sym){    int keycode;    keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);    if (keycode & 0x80)	kbd_put_keycode(0xe0);    if (down)	kbd_put_keycode(keycode & 0x7f);    else	kbd_put_keycode(keycode | 0x80);}static void key_event(VncState *vs, int down, uint32_t sym){    if (sym >= 'A' && sym <= 'Z')	sym = sym - 'A' + 'a';    do_key_event(vs, down, sym);}static void framebuffer_update_request(VncState *vs, int incremental,				       int x_position, int y_position,				       int w, int h){    int i;    vs->need_update = 1;    if (!incremental) {	char *old_row = vs->old_data + y_position * vs->ds->linesize;	for (i = 0; i < h; i++) {	    vs->dirty_row[y_position + i] = (1ULL << (vs->ds->width / 16)) - 1;	    if (vs->ds->width == 1024) {	      vs->dirty_row[y_position + i] = ~(0ULL);	    }	    memset(old_row, 42, vs->ds->width * vs->depth);	    old_row += vs->ds->linesize;	}    }}static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings){    int i;    vs->has_hextile = 0;    vs->has_resize = 0;    vs->ds->dpy_copy = NULL;    for (i = n_encodings - 1; i >= 0; i--) {	switch (encodings[i]) {	case 0: /* Raw */	    vs->has_hextile = 0;	    break;	case 1: /* CopyRect */	    vs->ds->dpy_copy = vnc_copy;	    break;	case 5: /* Hextile */	    vs->has_hextile = 1;	    break;	case -223: /* DesktopResize */	    vs->has_resize = 1;	    break;	default:	    break;	}    }}static void set_pixel_format(VncState *vs,			     int bits_per_pixel, int depth,			     int big_endian_flag, int true_color_flag,			     int red_max, int green_max, int blue_max,			     int red_shift, int green_shift, int blue_shift){    switch (bits_per_pixel) {    case 32:    case 24:	vs->depth = 4;	break;    case 16:	vs->depth = 2;	break;    case 8:	vs->depth = 1;	break;    default:	vnc_client_error(vs);	break;    }    if (!true_color_flag)	vnc_client_error(vs);    vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);    memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));    memset(vs->old_data, 42, vs->ds->linesize * vs->ds->height);    vga_hw_invalidate();    vga_hw_update();}static int protocol_client_msg(VncState *vs, char *data, size_t len){    int i;    uint16_t limit;    switch (data[0]) {    case 0:	if (len == 1)	    return 20;	set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),			 read_u8(data, 6), read_u8(data, 7),			 read_u16(data, 8), read_u16(data, 10),			 read_u16(data, 12), read_u8(data, 14),			 read_u8(data, 15), read_u8(data, 16));	break;    case 2:	if (len == 1)	    return 4;	if (len == 4)	    return 4 + (read_u16(data, 2) * 4);	limit = read_u16(data, 2);	for (i = 0; i < limit; i++) {	    int32_t val = read_s32(data, 4 + (i * 4));	    memcpy(data + 4 + (i * 4), &val, sizeof(val));	}	set_encodings(vs, (int32_t *)(data + 4), limit);	break;    case 3:	if (len == 1)	    return 10;	framebuffer_update_request(vs,				   read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),				   read_u16(data, 6), read_u16(data, 8));	break;    case 4:	if (len == 1)	    return 8;	key_event(vs, read_u8(data, 1), read_u32(data, 4));	break;    case 5:	if (len == 1)	    return 6;	pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));	break;    case 6:	if (len == 1)	    return 8;	if (len == 8)	    return 8 + read_u32(data, 4);	client_cut_text(vs, read_u32(data, 4), data + 8);	break;    default:	printf("Msg: %d\n", data[0]);	vnc_client_error(vs);	break;    }	    vnc_read_when(vs, protocol_client_msg, 1);    return 0;}static int protocol_client_init(VncState *vs, char *data, size_t len){    char pad[3] = { 0, 0, 0 };    vs->width = vs->ds->width;    vs->height = vs->ds->height;    vnc_write_u16(vs, vs->ds->width);    vnc_write_u16(vs, vs->ds->height);    vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */    vnc_write_u8(vs, vs->depth * 8); /* depth */    vnc_write_u8(vs, 0);             /* big-endian-flag */    vnc_write_u8(vs, 1);             /* true-color-flag */    if (vs->depth == 4) {	vnc_write_u16(vs, 0xFF);     /* red-max */	vnc_write_u16(vs, 0xFF);     /* green-max */	vnc_write_u16(vs, 0xFF);     /* blue-max */	vnc_write_u8(vs, 16);        /* red-shift */	vnc_write_u8(vs, 8);         /* green-shift */	vnc_write_u8(vs, 0);         /* blue-shift */    } else if (vs->depth == 2) {	vnc_write_u16(vs, 31);       /* red-max */	vnc_write_u16(vs, 63);       /* green-max */	vnc_write_u16(vs, 31);       /* blue-max */	vnc_write_u8(vs, 11);        /* red-shift */	vnc_write_u8(vs, 5);         /* green-shift */	vnc_write_u8(vs, 0);         /* blue-shift */    } else if (vs->depth == 1) {	vnc_write_u16(vs, 3);        /* red-max */	vnc_write_u16(vs, 7);        /* green-max */	vnc_write_u16(vs, 3);        /* blue-max */	vnc_write_u8(vs, 5);         /* red-shift */	vnc_write_u8(vs, 2);         /* green-shift */	vnc_write_u8(vs, 0);         /* blue-shift */    }	    vnc_write(vs, pad, 3);           /* padding */    vnc_write_u32(vs, 4);            vnc_write(vs, "QEMU", 4);    vnc_flush(vs);    vnc_read_when(vs, protocol_client_msg, 1);    return 0;}static int protocol_version(VncState *vs, char *version, size_t len){    char local[13];    int maj, min;    memcpy(local, version, 12);    local[12] = 0;    if (sscanf(local, "RFB %03d.%03d\n", &maj, &min) != 2) {	vnc_client_error(vs);	return 0;    }    vnc_write_u32(vs, 1); /* None */    vnc_flush(vs);    vnc_read_when(vs, protocol_client_init, 1);    return 0;}static void vnc_listen_read(void *opaque){    VncState *vs = opaque;    struct sockaddr_in addr;    socklen_t addrlen = sizeof(addr);    vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);    if (vs->csock != -1) {        socket_set_nonblock(vs->csock);	qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque);	vnc_write(vs, "RFB 003.003\n", 12);	vnc_flush(vs);	vnc_read_when(vs, protocol_version, 12);	memset(vs->old_data, 0, vs->ds->linesize * vs->ds->height);	memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));	vs->has_resize = 0;	vs->has_hextile = 0;	vs->ds->dpy_copy = NULL;    }}void vnc_display_init(DisplayState *ds, int display){    struct sockaddr_in addr;    int reuse_addr, ret;    VncState *vs;    vs = qemu_mallocz(sizeof(VncState));    if (!vs)	exit(1);    ds->opaque = vs;    vs->lsock = -1;    vs->csock = -1;    vs->depth = 4;    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->lsock = socket(PF_INET, SOCK_STREAM, 0);    if (vs->lsock == -1) {	fprintf(stderr, "Could not create socket\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) {	fprintf(stderr, "bind() failed\n");	exit(1);    }    if (listen(vs->lsock, 1) == -1) {	fprintf(stderr, "listen() failed\n");	exit(1);    }    ret = qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);    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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -