summaryrefslogtreecommitdiffstats
path: root/vdagentd.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2010-09-22 09:20:24 +0200
committerHans de Goede <hdegoede@redhat.com>2010-09-22 09:20:24 +0200
commit958197f7227ae7eeeb02f714806880ce073c5942 (patch)
treedcf9d23389226fe3b6b34bff8662469c0bc18d4e /vdagentd.c
parent2a46a63ac22416c481bd71f321535f1d6b0f7eb8 (diff)
downloadvd_agent-958197f7227ae7eeeb02f714806880ce073c5942.tar.gz
vd_agent-958197f7227ae7eeeb02f714806880ce073c5942.tar.xz
vd_agent-958197f7227ae7eeeb02f714806880ce073c5942.zip
Put uinput code into its own file
Diffstat (limited to 'vdagentd.c')
-rw-r--r--vdagentd.c165
1 files changed, 16 insertions, 149 deletions
diff --git a/vdagentd.c b/vdagentd.c
index a52b586..cc7b40d 100644
--- a/vdagentd.c
+++ b/vdagentd.c
@@ -1,169 +1,28 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <inttypes.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/select.h>
-
-#include <linux/input.h>
-#include <linux/uinput.h>
-
-/* spice structs */
-
#include <spice/vd_agent.h>
#include "udscs.h"
#include "vdagentd-proto.h"
+#include "vdagentd-uinput.h"
#include "vdagent-virtio-port.h"
/* variables */
static const char *portdev = "/dev/virtio-ports/com.redhat.spice.0";
static const char *uinput = "/dev/uinput";
-static int tablet = -1;
static int connection_count = 0;
static int debug = 0;
-static int width, height;
static struct udscs_server *server = NULL;
static struct vdagent_virtio_port *virtio_port = NULL;
static VDAgentMonitorsConfig *mon_config = NULL;
-int virtio_port_read_complete(
- struct vdagent_virtio_port *port,
- VDIChunkHeader *chunk_header,
- VDAgentMessage *message_header,
- uint8_t *data);
-
-/* uinput */
-static void uinput_setup(void)
-{
- struct uinput_user_dev device = {
- .name = "spice vdagent tablet",
- .absmax [ ABS_X ] = width,
- .absmax [ ABS_Y ] = height,
- };
- int rc;
-
- if (tablet != -1)
- close(tablet);
-
- tablet = open(uinput, O_RDWR);
- if (tablet == -1) {
- fprintf(stderr, "open %s: %s\n", uinput, strerror(errno));
- exit(1);
- }
-
- rc = write(tablet, &device, sizeof(device));
- if (rc != sizeof(device)) {
- fprintf(stderr, "%s: write error\n", __FUNCTION__);
- exit(1);
- }
-
- /* buttons */
- ioctl(tablet, UI_SET_EVBIT, EV_KEY);
- ioctl(tablet, UI_SET_KEYBIT, BTN_LEFT);
- ioctl(tablet, UI_SET_KEYBIT, BTN_MIDDLE);
- ioctl(tablet, UI_SET_KEYBIT, BTN_RIGHT);
-
- /* wheel */
- ioctl(tablet, UI_SET_EVBIT, EV_REL);
- ioctl(tablet, UI_SET_RELBIT, REL_WHEEL);
-
- /* abs ptr */
- ioctl(tablet, UI_SET_EVBIT, EV_ABS);
- ioctl(tablet, UI_SET_ABSBIT, ABS_X);
- ioctl(tablet, UI_SET_ABSBIT, ABS_Y);
-
- rc = ioctl(tablet, UI_DEV_CREATE);
- if (rc < 0) {
- fprintf(stderr, "%s: create error\n", __FUNCTION__);
- exit(1);
- }
-
- /* Now that we have a tablet and thus can forward mouse events,
- we can open the vdagent virtio port. */
- if (!virtio_port) {
- virtio_port = vdagent_virtio_port_create(portdev,
- virtio_port_read_complete,
- NULL);
- if (!virtio_port)
- exit(1);
- }
-}
-
-static void uinput_send_event(__u16 type, __u16 code, __s32 value)
-{
- struct input_event event = {
- .type = type,
- .code = code,
- .value = value,
- };
- int rc;
-
- rc = write(tablet, &event, sizeof(event));
- if (rc != sizeof(event)) {
- fprintf(stderr, "%s: write error\n", __FUNCTION__);
- exit(1);
- }
-}
-
-/* spice port */
-
-static void do_mouse(VDAgentMouseState *mouse)
-{
- struct button_s {
- const char *name;
- int mask;
- int btn;
- };
- static const struct button_s btns[] = {
- { .name = "left", .mask = VD_AGENT_LBUTTON_MASK, .btn = BTN_LEFT },
- { .name = "middle", .mask = VD_AGENT_MBUTTON_MASK, .btn = BTN_MIDDLE },
- { .name = "right", .mask = VD_AGENT_RBUTTON_MASK, .btn = BTN_RIGHT },
- };
- static const struct button_s wheel[] = {
- { .name = "up", .mask = VD_AGENT_UBUTTON_MASK, .btn = 1 },
- { .name = "down", .mask = VD_AGENT_DBUTTON_MASK, .btn = -1 },
- };
- static VDAgentMouseState last;
- int i, down;
-
- if (last.x != mouse->x) {
- if (debug > 1)
- fprintf(stderr, "mouse: abs-x %d\n", mouse->x);
- uinput_send_event(EV_ABS, ABS_X, mouse->x);
- }
- if (last.y != mouse->y) {
- if (debug > 1)
- fprintf(stderr, "mouse: abs-y %d\n", mouse->y);
- uinput_send_event(EV_ABS, ABS_Y, mouse->y);
- }
- for (i = 0; i < sizeof(btns)/sizeof(btns[0]); i++) {
- if ((last.buttons & btns[i].mask) == (mouse->buttons & btns[i].mask))
- continue;
- down = !!(mouse->buttons & btns[i].mask);
- if (debug > 1)
- fprintf(stderr, "mouse: btn-%s %s\n",
- btns[i].name, down ? "down" : "up");
- uinput_send_event(EV_KEY, btns[i].btn, down);
- }
- for (i = 0; i < sizeof(wheel)/sizeof(wheel[0]); i++) {
- if ((last.buttons & wheel[i].mask) == (mouse->buttons & wheel[i].mask))
- continue;
- if (mouse->buttons & wheel[i].mask) {
- if (debug > 1)
- fprintf(stderr, "mouse: wheel-%s\n", wheel[i].name);
- uinput_send_event(EV_REL, REL_WHEEL, wheel[i].btn);
- }
- }
- if (debug > 1)
- fprintf(stderr, "mouse: syn\n");
- uinput_send_event(EV_SYN, SYN_REPORT, 0);
-
- last = *mouse;
-}
+/* vdagent virtio port handling */
static void do_monitors(
struct vdagent_virtio_port *port,
@@ -220,7 +79,7 @@ int virtio_port_read_complete(
}
switch (message_header->type) {
case VD_AGENT_MOUSE_STATE:
- do_mouse((VDAgentMouseState *)data);
+ uinput_do_mouse((VDAgentMouseState *)data, debug > 1);
break;
case VD_AGENT_MONITORS_CONFIG:
do_monitors(port, (VDAgentMonitorsConfig *)data, chunk_header->port);
@@ -265,6 +124,8 @@ void daemonize(void)
}
}
+/* vdagent client handling */
+
void client_connect(struct udscs_connection *conn)
{
struct udscs_message_header udscs_header;
@@ -286,8 +147,7 @@ void client_disconnect(struct udscs_connection *conn)
{
connection_count--;
if (connection_count == 0) {
- close(tablet);
- tablet = -1;
+ uinput_close();
vdagent_virtio_port_destroy(&virtio_port);
}
}
@@ -306,10 +166,17 @@ int client_read_complete(struct udscs_connection *conn,
return -1;
}
- width = res->width;
- height = res->height;
/* Now that we know the xorg resolution setup the uinput device */
- uinput_setup();
+ uinput_setup(uinput, res->width, res->height);
+ /* Now that we have a tablet and thus can forward mouse events,
+ we can open the vdagent virtio port. */
+ if (!virtio_port) {
+ virtio_port = vdagent_virtio_port_create(portdev,
+ virtio_port_read_complete,
+ NULL);
+ if (!virtio_port)
+ exit(1);
+ }
break;
}
default: