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 | ... | ... |