diff options
author | Hans de Goede <hdegoede@redhat.com> | 2010-09-22 09:20:24 +0200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2010-09-22 09:20:24 +0200 |
commit | 958197f7227ae7eeeb02f714806880ce073c5942 (patch) | |
tree | dcf9d23389226fe3b6b34bff8662469c0bc18d4e /vdagentd.c | |
parent | 2a46a63ac22416c481bd71f321535f1d6b0f7eb8 (diff) | |
download | vd_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.c | 165 |
1 files changed, 16 insertions, 149 deletions
@@ -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: |