root / ui / spice-input.c @ 78dd9ac1
History | View | Annotate | Download (3.9 kB)
1 |
/*
|
---|---|
2 |
* Copyright (C) 2010 Red Hat, Inc.
|
3 |
*
|
4 |
* This program is free software; you can redistribute it and/or
|
5 |
* modify it under the terms of the GNU General Public License as
|
6 |
* published by the Free Software Foundation; either version 2 or
|
7 |
* (at your option) version 3 of the License.
|
8 |
*
|
9 |
* This program is distributed in the hope that it will be useful,
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12 |
* GNU General Public License for more details.
|
13 |
*
|
14 |
* You should have received a copy of the GNU General Public License
|
15 |
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
16 |
*/
|
17 |
|
18 |
#include <stdlib.h> |
19 |
#include <stdio.h> |
20 |
#include <string.h> |
21 |
|
22 |
#include <spice.h> |
23 |
#include <spice/enums.h> |
24 |
|
25 |
#include "qemu-common.h" |
26 |
#include "qemu-spice.h" |
27 |
#include "console.h" |
28 |
|
29 |
/* keyboard bits */
|
30 |
|
31 |
typedef struct QemuSpiceKbd { |
32 |
SpiceKbdInstance sin; |
33 |
int ledstate;
|
34 |
} QemuSpiceKbd; |
35 |
|
36 |
static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag); |
37 |
static uint8_t kbd_get_leds(SpiceKbdInstance *sin);
|
38 |
static void kbd_leds(void *opaque, int l); |
39 |
|
40 |
static const SpiceKbdInterface kbd_interface = { |
41 |
.base.type = SPICE_INTERFACE_KEYBOARD, |
42 |
.base.description = "qemu keyboard",
|
43 |
.base.major_version = SPICE_INTERFACE_KEYBOARD_MAJOR, |
44 |
.base.minor_version = SPICE_INTERFACE_KEYBOARD_MINOR, |
45 |
.push_scan_freg = kbd_push_key, |
46 |
.get_leds = kbd_get_leds, |
47 |
}; |
48 |
|
49 |
static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag) |
50 |
{ |
51 |
kbd_put_keycode(frag); |
52 |
} |
53 |
|
54 |
static uint8_t kbd_get_leds(SpiceKbdInstance *sin)
|
55 |
{ |
56 |
QemuSpiceKbd *kbd = container_of(sin, QemuSpiceKbd, sin); |
57 |
return kbd->ledstate;
|
58 |
} |
59 |
|
60 |
static void kbd_leds(void *opaque, int ledstate) |
61 |
{ |
62 |
QemuSpiceKbd *kbd = opaque; |
63 |
|
64 |
kbd->ledstate = 0;
|
65 |
if (ledstate & QEMU_SCROLL_LOCK_LED) {
|
66 |
kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_SCROLL_LOCK; |
67 |
} |
68 |
if (ledstate & QEMU_NUM_LOCK_LED) {
|
69 |
kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_NUM_LOCK; |
70 |
} |
71 |
if (ledstate & QEMU_CAPS_LOCK_LED) {
|
72 |
kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_CAPS_LOCK; |
73 |
} |
74 |
spice_server_kbd_leds(&kbd->sin, ledstate); |
75 |
} |
76 |
|
77 |
/* mouse bits */
|
78 |
|
79 |
typedef struct QemuSpiceMouse { |
80 |
SpiceMouseInstance sin; |
81 |
} QemuSpiceMouse; |
82 |
|
83 |
static int map_buttons(int spice_buttons) |
84 |
{ |
85 |
int qemu_buttons = 0; |
86 |
|
87 |
/*
|
88 |
* Note: SPICE_MOUSE_BUTTON_* specifies the wire protocol but this
|
89 |
* isn't what we get passed in via interface callbacks for the
|
90 |
* middle and right button ...
|
91 |
*/
|
92 |
if (spice_buttons & SPICE_MOUSE_BUTTON_MASK_LEFT) {
|
93 |
qemu_buttons |= MOUSE_EVENT_LBUTTON; |
94 |
} |
95 |
if (spice_buttons & 0x04 /* SPICE_MOUSE_BUTTON_MASK_MIDDLE */) { |
96 |
qemu_buttons |= MOUSE_EVENT_MBUTTON; |
97 |
} |
98 |
if (spice_buttons & 0x02 /* SPICE_MOUSE_BUTTON_MASK_RIGHT */) { |
99 |
qemu_buttons |= MOUSE_EVENT_RBUTTON; |
100 |
} |
101 |
return qemu_buttons;
|
102 |
} |
103 |
|
104 |
static void mouse_motion(SpiceMouseInstance *sin, int dx, int dy, int dz, |
105 |
uint32_t buttons_state) |
106 |
{ |
107 |
kbd_mouse_event(dx, dy, dz, map_buttons(buttons_state)); |
108 |
} |
109 |
|
110 |
static void mouse_buttons(SpiceMouseInstance *sin, uint32_t buttons_state) |
111 |
{ |
112 |
kbd_mouse_event(0, 0, 0, map_buttons(buttons_state)); |
113 |
} |
114 |
|
115 |
static const SpiceMouseInterface mouse_interface = { |
116 |
.base.type = SPICE_INTERFACE_MOUSE, |
117 |
.base.description = "mouse",
|
118 |
.base.major_version = SPICE_INTERFACE_MOUSE_MAJOR, |
119 |
.base.minor_version = SPICE_INTERFACE_MOUSE_MINOR, |
120 |
.motion = mouse_motion, |
121 |
.buttons = mouse_buttons, |
122 |
}; |
123 |
|
124 |
void qemu_spice_input_init(void) |
125 |
{ |
126 |
QemuSpiceKbd *kbd; |
127 |
QemuSpiceMouse *mouse; |
128 |
|
129 |
kbd = qemu_mallocz(sizeof(*kbd));
|
130 |
kbd->sin.base.sif = &kbd_interface.base; |
131 |
qemu_spice_add_interface(&kbd->sin.base); |
132 |
qemu_add_led_event_handler(kbd_leds, kbd); |
133 |
|
134 |
mouse = qemu_mallocz(sizeof(*mouse));
|
135 |
mouse->sin.base.sif = &mouse_interface.base; |
136 |
qemu_spice_add_interface(&mouse->sin.base); |
137 |
} |