8 #include "qemu-common.h"
9 #include "qemu-spice.h"
14 typedef struct QemuSpiceKbd
{
19 static void kbd_push_key(SpiceKbdInstance
*sin
, uint8_t frag
);
20 static uint8_t kbd_get_leds(SpiceKbdInstance
*sin
);
21 static void kbd_leds(void *opaque
, int l
);
23 static const SpiceKbdInterface kbd_interface
= {
24 .base
.type
= SPICE_INTERFACE_KEYBOARD
,
25 .base
.description
= "qemu keyboard",
26 .base
.major_version
= SPICE_INTERFACE_KEYBOARD_MAJOR
,
27 .base
.minor_version
= SPICE_INTERFACE_KEYBOARD_MINOR
,
28 .push_scan_freg
= kbd_push_key
,
29 .get_leds
= kbd_get_leds
,
32 static void kbd_push_key(SpiceKbdInstance
*sin
, uint8_t frag
)
34 kbd_put_keycode(frag
);
37 static uint8_t kbd_get_leds(SpiceKbdInstance
*sin
)
39 QemuSpiceKbd
*kbd
= container_of(sin
, QemuSpiceKbd
, sin
);
43 static void kbd_leds(void *opaque
, int ledstate
)
45 QemuSpiceKbd
*kbd
= opaque
;
46 kbd
->ledstate
= ledstate
;
47 spice_server_kbd_leds(&kbd
->sin
, ledstate
);
52 typedef struct QemuSpicePointer
{
53 SpiceMouseInstance mouse
;
54 SpiceTabletInstance tablet
;
55 int width
, height
, x
, y
;
60 static void mouse_motion(SpiceMouseInstance
*sin
, int dx
, int dy
, int dz
,
61 uint32_t buttons_state
)
63 kbd_mouse_event(dx
, dy
, dz
, buttons_state
);
66 static void mouse_buttons(SpiceMouseInstance
*sin
, uint32_t buttons_state
)
68 kbd_mouse_event(0, 0, 0, buttons_state
);
71 static const SpiceMouseInterface mouse_interface
= {
72 .base
.type
= SPICE_INTERFACE_MOUSE
,
73 .base
.description
= "mouse",
74 .base
.major_version
= SPICE_INTERFACE_MOUSE_MAJOR
,
75 .base
.minor_version
= SPICE_INTERFACE_MOUSE_MINOR
,
76 .motion
= mouse_motion
,
77 .buttons
= mouse_buttons
,
80 static void tablet_set_logical_size(SpiceTabletInstance
* sin
, int width
, int height
)
82 QemuSpicePointer
*pointer
= container_of(sin
, QemuSpicePointer
, tablet
);
84 fprintf(stderr
, "%s: %dx%d\n", __FUNCTION__
, width
, height
);
89 pointer
->width
= width
;
90 pointer
->height
= height
;
93 static void tablet_position(SpiceTabletInstance
* sin
, int x
, int y
,
94 uint32_t buttons_state
)
96 QemuSpicePointer
*pointer
= container_of(sin
, QemuSpicePointer
, tablet
);
98 pointer
->x
= x
* 0x7FFF / (pointer
->width
- 1);
99 pointer
->y
= y
* 0x7FFF / (pointer
->height
- 1);
100 kbd_mouse_event(pointer
->x
, pointer
->y
, 0, buttons_state
);
104 static void tablet_wheel(SpiceTabletInstance
* sin
, int wheel
,
105 uint32_t buttons_state
)
107 QemuSpicePointer
*pointer
= container_of(sin
, QemuSpicePointer
, tablet
);
109 kbd_mouse_event(pointer
->x
, pointer
->y
, wheel
, buttons_state
);
112 static void tablet_buttons(SpiceTabletInstance
*sin
,
113 uint32_t buttons_state
)
115 QemuSpicePointer
*pointer
= container_of(sin
, QemuSpicePointer
, tablet
);
117 kbd_mouse_event(pointer
->x
, pointer
->y
, 0, buttons_state
);
120 static const SpiceTabletInterface tablet_interface
= {
121 .base
.type
= SPICE_INTERFACE_TABLET
,
122 .base
.description
= "tablet",
123 .base
.major_version
= SPICE_INTERFACE_TABLET_MAJOR
,
124 .base
.minor_version
= SPICE_INTERFACE_TABLET_MINOR
,
125 .set_logical_size
= tablet_set_logical_size
,
126 .position
= tablet_position
,
127 .wheel
= tablet_wheel
,
128 .buttons
= tablet_buttons
,
131 static void mouse_mode_notifier(Notifier
*notifier
)
133 QemuSpicePointer
*pointer
= container_of(notifier
, QemuSpicePointer
, mouse_mode
);
134 bool is_absolute
= kbd_mouse_is_absolute();
135 bool has_absolute
= kbd_mouse_has_absolute();
137 fprintf(stderr
, "%s: absolute pointer: %s%s\n", __FUNCTION__
,
138 has_absolute
? "present" : "not available",
139 is_absolute
? "+active" : "");
141 if (pointer
->absolute
== is_absolute
)
145 fprintf(stderr
, "%s: using absolute pointer (client mode)\n", __FUNCTION__
);
146 spice_server_add_interface(spice_server
, &pointer
->tablet
.base
);
148 fprintf(stderr
, "%s: using relative pointer (server mode)\n", __FUNCTION__
);
149 spice_server_remove_interface(&pointer
->tablet
.base
);
151 pointer
->absolute
= is_absolute
;
154 void qemu_spice_input_init(void)
157 QemuSpicePointer
*pointer
;
159 kbd
= qemu_mallocz(sizeof(*kbd
));
160 kbd
->sin
.base
.sif
= &kbd_interface
.base
;
161 spice_server_add_interface(spice_server
, &kbd
->sin
.base
);
162 qemu_add_led_event_handler(kbd_leds
, kbd
);
164 pointer
= qemu_mallocz(sizeof(*pointer
));
165 pointer
->mouse
.base
.sif
= &mouse_interface
.base
;
166 pointer
->tablet
.base
.sif
= &tablet_interface
.base
;
167 spice_server_add_interface(spice_server
, &pointer
->mouse
.base
);
169 pointer
->absolute
= false;
170 pointer
->mouse_mode
.notify
= mouse_mode_notifier
;
171 qemu_add_mouse_mode_change_notifier(&pointer
->mouse_mode
);
172 mouse_mode_notifier(&pointer
->mouse_mode
);