Commit 564c337efd415df3ab58c5bd080139e9f997d265
1 parent
2a252826
Mouse relative offset VNC extension (Anthony Liguori)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2390 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
42 additions
and
10 deletions
vnc.c
| ... | ... | @@ -68,6 +68,11 @@ struct VncState |
| 68 | 68 | int depth; /* internal VNC frame buffer byte per pixel */ |
| 69 | 69 | int has_resize; |
| 70 | 70 | int has_hextile; |
| 71 | + int has_pointer_type_change; | |
| 72 | + int absolute; | |
| 73 | + int last_x; | |
| 74 | + int last_y; | |
| 75 | + | |
| 71 | 76 | Buffer output; |
| 72 | 77 | Buffer input; |
| 73 | 78 | kbd_layout_t *kbd_layout; |
| ... | ... | @@ -671,6 +676,19 @@ static void client_cut_text(VncState *vs, size_t len, char *text) |
| 671 | 676 | { |
| 672 | 677 | } |
| 673 | 678 | |
| 679 | +static void check_pointer_type_change(VncState *vs, int absolute) | |
| 680 | +{ | |
| 681 | + if (vs->has_pointer_type_change && vs->absolute != absolute) { | |
| 682 | + vnc_write_u8(vs, 0); | |
| 683 | + vnc_write_u8(vs, 0); | |
| 684 | + vnc_write_u16(vs, 1); | |
| 685 | + vnc_framebuffer_update(vs, absolute, 0, | |
| 686 | + vs->ds->width, vs->ds->height, -257); | |
| 687 | + vnc_flush(vs); | |
| 688 | + } | |
| 689 | + vs->absolute = absolute; | |
| 690 | +} | |
| 691 | + | |
| 674 | 692 | static void pointer_event(VncState *vs, int button_mask, int x, int y) |
| 675 | 693 | { |
| 676 | 694 | int buttons = 0; |
| ... | ... | @@ -686,21 +704,26 @@ static void pointer_event(VncState *vs, int button_mask, int x, int y) |
| 686 | 704 | dz = -1; |
| 687 | 705 | if (button_mask & 0x10) |
| 688 | 706 | dz = 1; |
| 689 | - | |
| 690 | - if (kbd_mouse_is_absolute()) { | |
| 707 | + | |
| 708 | + if (vs->absolute) { | |
| 691 | 709 | kbd_mouse_event(x * 0x7FFF / vs->ds->width, |
| 692 | 710 | y * 0x7FFF / vs->ds->height, |
| 693 | 711 | dz, buttons); |
| 694 | - } else { | |
| 695 | - static int last_x = -1; | |
| 696 | - static int last_y = -1; | |
| 697 | - | |
| 698 | - if (last_x != -1) | |
| 699 | - kbd_mouse_event(x - last_x, y - last_y, dz, buttons); | |
| 712 | + } else if (vs->has_pointer_type_change) { | |
| 713 | + x -= 0x7FFF; | |
| 714 | + y -= 0x7FFF; | |
| 700 | 715 | |
| 701 | - last_x = x; | |
| 702 | - last_y = y; | |
| 716 | + kbd_mouse_event(x, y, dz, buttons); | |
| 717 | + } else { | |
| 718 | + if (vs->last_x != -1) | |
| 719 | + kbd_mouse_event(x - vs->last_x, | |
| 720 | + y - vs->last_y, | |
| 721 | + dz, buttons); | |
| 722 | + vs->last_x = x; | |
| 723 | + vs->last_y = y; | |
| 703 | 724 | } |
| 725 | + | |
| 726 | + check_pointer_type_change(vs, kbd_mouse_is_absolute()); | |
| 704 | 727 | } |
| 705 | 728 | |
| 706 | 729 | static void reset_keys(VncState *vs) |
| ... | ... | @@ -829,6 +852,8 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) |
| 829 | 852 | |
| 830 | 853 | vs->has_hextile = 0; |
| 831 | 854 | vs->has_resize = 0; |
| 855 | + vs->has_pointer_type_change = 0; | |
| 856 | + vs->absolute = -1; | |
| 832 | 857 | vs->ds->dpy_copy = NULL; |
| 833 | 858 | |
| 834 | 859 | for (i = n_encodings - 1; i >= 0; i--) { |
| ... | ... | @@ -845,10 +870,15 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) |
| 845 | 870 | case -223: /* DesktopResize */ |
| 846 | 871 | vs->has_resize = 1; |
| 847 | 872 | break; |
| 873 | + case -257: | |
| 874 | + vs->has_pointer_type_change = 1; | |
| 875 | + break; | |
| 848 | 876 | default: |
| 849 | 877 | break; |
| 850 | 878 | } |
| 851 | 879 | } |
| 880 | + | |
| 881 | + check_pointer_type_change(vs, kbd_mouse_is_absolute()); | |
| 852 | 882 | } |
| 853 | 883 | |
| 854 | 884 | static int compute_nbits(unsigned int val) |
| ... | ... | @@ -1124,6 +1154,8 @@ void vnc_display_init(DisplayState *ds, const char *arg) |
| 1124 | 1154 | vs->lsock = -1; |
| 1125 | 1155 | vs->csock = -1; |
| 1126 | 1156 | vs->depth = 4; |
| 1157 | + vs->last_x = -1; | |
| 1158 | + vs->last_y = -1; | |
| 1127 | 1159 | |
| 1128 | 1160 | vs->ds = ds; |
| 1129 | 1161 | ... | ... |