Commit 7dd1556e authored by Jeremy White's avatar Jeremy White

Added a tablet interface to give us mouse control.

We are now at a (very) basic level of function.
parent aaba877f
......@@ -37,6 +37,9 @@ typedef struct
SpiceKbdInstance keyboard_sin;
uint8_t escape;
SpiceTabletInstance tablet_sin;
uint32_t buttons_state;
QXLWorker *worker;
int compression_level;
......
......@@ -232,6 +232,59 @@ void session_handle_key(void *session_ptr, uint8_t keycode, int is_press)
XFlush(s->display.xdisplay);
}
void session_handle_mouse_position(void *session_ptr, int x, int y, uint32_t buttons_state)
{
session_t *s = (session_t *) session_ptr;
int scr = DefaultScreen(s->display.xdisplay);
XFlush(s->display.xdisplay);
g_debug("mouse position: x %d, y %d, buttons 0x%x", x, y, buttons_state);
XTestFakeMotionEvent(s->display.xdisplay, scr, x, y, CurrentTime);
XFlush(s->display.xdisplay);
}
#define BUTTONS 5
static void session_handle_button_change(session_t *s, uint32_t buttons_state)
{
int i;
for (i = 0; i < BUTTONS; i++) {
if ((buttons_state ^ s->spice.buttons_state) & (1 << i)) {
int action = (buttons_state & (1 << i));
XTestFakeButtonEvent(s->display.xdisplay, i + 1, action, CurrentTime);
}
}
s->spice.buttons_state = buttons_state;
XFlush(s->display.xdisplay);
}
static uint32_t convert_spice_buttons(int wheel, uint32_t buttons_state)
{
// For some reason spice switches the second and third button, undo that.
// basically undo RED_MOUSE_STATE_TO_LOCAL
buttons_state = (buttons_state & SPICE_MOUSE_BUTTON_MASK_LEFT) |
((buttons_state & SPICE_MOUSE_BUTTON_MASK_MIDDLE) << 1) |
((buttons_state & SPICE_MOUSE_BUTTON_MASK_RIGHT) >> 1) |
(buttons_state & ~(SPICE_MOUSE_BUTTON_MASK_LEFT | SPICE_MOUSE_BUTTON_MASK_MIDDLE
|SPICE_MOUSE_BUTTON_MASK_RIGHT));
return buttons_state | (wheel > 0 ? (1<<4) : 0)
| (wheel < 0 ? (1<<3) : 0);
}
void session_handle_mouse_wheel(void *session_ptr, int wheel_motion, uint32_t buttons_state)
{
session_t *s = (session_t *) session_ptr;
g_debug("mouse wheel: motion %d, buttons 0x%x", wheel_motion, buttons_state);
session_handle_button_change(s, convert_spice_buttons(wheel_motion, buttons_state));
}
void session_handle_mouse_buttons(void *session_ptr, uint32_t buttons_state)
{
session_t *s = (session_t *) session_ptr;
g_debug("mouse button: buttons 0x%x", buttons_state);
session_handle_button_change(s, convert_spice_buttons(0, buttons_state));
}
int session_start(session_t *s)
{
int rc = 0;
......
......@@ -50,4 +50,7 @@ void session_end(session_t *s);
void *session_pop_draw(void *session_ptr);
int session_draw_waiting(void *session_ptr);
void session_handle_key(void *session_ptr, uint8_t keycode, int is_press);
void session_handle_mouse_position(void *session_ptr, int x, int y, uint32_t buttons_state);
void session_handle_mouse_buttons(void *session_ptr, uint32_t buttons_state);
void session_handle_mouse_wheel(void *session_ptr, int wheel_motion, uint32_t buttons_state);
#endif
......@@ -363,6 +363,29 @@ static uint8_t kbd_get_leds(SpiceKbdInstance *sin)
return 0;
}
void tablet_set_logical_size(SpiceTabletInstance* tablet, int width, int height)
{
g_debug("FIXME! UNIMPLEMENTED! %s (width %dx%d)", __func__, width, height);
}
void tablet_position(SpiceTabletInstance* tablet, int x, int y, uint32_t buttons_state)
{
spice_t *s = SPICE_CONTAINEROF(tablet, spice_t, tablet_sin);
session_handle_mouse_position(s->session_ptr, x, y, buttons_state);
}
void tablet_wheel(SpiceTabletInstance* tablet, int wheel_motion, uint32_t buttons_state)
{
spice_t *s = SPICE_CONTAINEROF(tablet, spice_t, tablet_sin);
session_handle_mouse_wheel(s->session_ptr, wheel_motion, buttons_state);
}
void tablet_buttons(SpiceTabletInstance* tablet, uint32_t buttons_state)
{
spice_t *s = SPICE_CONTAINEROF(tablet, spice_t, tablet_sin);
session_handle_mouse_buttons(s->session_ptr, buttons_state);
}
void initialize_spice_instance(spice_t *s)
{
static int id = 0;
......@@ -417,16 +440,23 @@ void initialize_spice_instance(spice_t *s)
.get_leds = kbd_get_leds,
};
static const SpiceTabletInterface tablet_sif = {
.base.type = SPICE_INTERFACE_TABLET,
.base.description = "x11spice tablet",
.base.major_version = SPICE_INTERFACE_TABLET_MAJOR,
.base.minor_version = SPICE_INTERFACE_TABLET_MINOR,
.set_logical_size = tablet_set_logical_size,
.position = tablet_position,
.wheel = tablet_wheel,
.buttons = tablet_buttons,
};
s->core = &core;
s->display_sin.base.sif = &display_sif.base;
s->display_sin.id = id++;
// FIXME - this cast seems dubious to me
s->display_sin.st = (struct QXLState*) s;
s->keyboard_sin.base.sif = &keyboard_sif.base;
// FIXME - this cast seems dubious to me
s->keyboard_sin.st = (SpiceKbdState*) s;
s->tablet_sin.base.sif = &tablet_sif.base;
}
......@@ -446,6 +476,8 @@ static void set_options(spice_t *s, options_t *options)
int spice_start(spice_t *s, options_t *options)
{
memset(s, 0, sizeof(*s));
s->server = spice_server_new();
if (! s->server)
return X11SPICE_ERR_SPICE_INIT_FAILED;
......@@ -472,6 +504,12 @@ int spice_start(spice_t *s, options_t *options)
return X11SPICE_ERR_SPICE_INIT_FAILED;
}
if (spice_server_add_interface(s->server, &s->tablet_sin.base))
{
spice_server_destroy(s->server);
return X11SPICE_ERR_SPICE_INIT_FAILED;
}
spice_server_vm_start(s->server);
return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment