vdagentd: Add per agent data to vdagentd
[vd_agent/hramrach.git] / vdagentd-uinput.c
bloba9cfa526ac7822899f6deb8b4f179dec506b4d25
1 /* vdagentd-uinput.c vdagentd uinput handling code
3 Copyright 2010 Red Hat, Inc.
5 Red Hat Authors:
6 Hans de Goede <hdegoede@redhat.com>
7 Gerd Hoffmann <kraxel@redhat.com>
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <errno.h>
29 #include <linux/input.h>
30 #include <linux/uinput.h>
31 #include <spice/vd_agent.h>
33 static int tablet = -1;
35 void uinput_setup(const char *uinput_devname, int width, int height)
37 struct uinput_user_dev device = {
38 .name = "spice vdagent tablet",
39 .absmax [ ABS_X ] = width,
40 .absmax [ ABS_Y ] = height,
42 int rc;
44 if (tablet != -1)
45 close(tablet);
47 tablet = open(uinput_devname, O_RDWR);
48 if (tablet == -1) {
49 fprintf(stderr, "open %s: %s\n", uinput_devname, strerror(errno));
50 exit(1);
53 rc = write(tablet, &device, sizeof(device));
54 if (rc != sizeof(device)) {
55 fprintf(stderr, "%s: write error\n", __FUNCTION__);
56 exit(1);
59 /* buttons */
60 ioctl(tablet, UI_SET_EVBIT, EV_KEY);
61 ioctl(tablet, UI_SET_KEYBIT, BTN_LEFT);
62 ioctl(tablet, UI_SET_KEYBIT, BTN_MIDDLE);
63 ioctl(tablet, UI_SET_KEYBIT, BTN_RIGHT);
65 /* wheel */
66 ioctl(tablet, UI_SET_EVBIT, EV_REL);
67 ioctl(tablet, UI_SET_RELBIT, REL_WHEEL);
69 /* abs ptr */
70 ioctl(tablet, UI_SET_EVBIT, EV_ABS);
71 ioctl(tablet, UI_SET_ABSBIT, ABS_X);
72 ioctl(tablet, UI_SET_ABSBIT, ABS_Y);
74 rc = ioctl(tablet, UI_DEV_CREATE);
75 if (rc < 0) {
76 fprintf(stderr, "%s: create error\n", __FUNCTION__);
77 exit(1);
81 void uinput_close(void)
83 close(tablet);
84 tablet = -1;
87 static void uinput_send_event(__u16 type, __u16 code, __s32 value)
89 struct input_event event = {
90 .type = type,
91 .code = code,
92 .value = value,
94 int rc;
96 rc = write(tablet, &event, sizeof(event));
97 if (rc != sizeof(event)) {
98 fprintf(stderr, "%s: write error\n", __FUNCTION__);
99 exit(1);
103 void uinput_do_mouse(VDAgentMouseState *mouse, int verbose)
105 struct button_s {
106 const char *name;
107 int mask;
108 int btn;
110 static const struct button_s btns[] = {
111 { .name = "left", .mask = VD_AGENT_LBUTTON_MASK, .btn = BTN_LEFT },
112 { .name = "middle", .mask = VD_AGENT_MBUTTON_MASK, .btn = BTN_MIDDLE },
113 { .name = "right", .mask = VD_AGENT_RBUTTON_MASK, .btn = BTN_RIGHT },
115 static const struct button_s wheel[] = {
116 { .name = "up", .mask = VD_AGENT_UBUTTON_MASK, .btn = 1 },
117 { .name = "down", .mask = VD_AGENT_DBUTTON_MASK, .btn = -1 },
119 static VDAgentMouseState last;
120 int i, down;
122 if (last.x != mouse->x) {
123 if (verbose)
124 fprintf(stderr, "mouse: abs-x %d\n", mouse->x);
125 uinput_send_event(EV_ABS, ABS_X, mouse->x);
127 if (last.y != mouse->y) {
128 if (verbose)
129 fprintf(stderr, "mouse: abs-y %d\n", mouse->y);
130 uinput_send_event(EV_ABS, ABS_Y, mouse->y);
132 for (i = 0; i < sizeof(btns)/sizeof(btns[0]); i++) {
133 if ((last.buttons & btns[i].mask) == (mouse->buttons & btns[i].mask))
134 continue;
135 down = !!(mouse->buttons & btns[i].mask);
136 if (verbose)
137 fprintf(stderr, "mouse: btn-%s %s\n",
138 btns[i].name, down ? "down" : "up");
139 uinput_send_event(EV_KEY, btns[i].btn, down);
141 for (i = 0; i < sizeof(wheel)/sizeof(wheel[0]); i++) {
142 if ((last.buttons & wheel[i].mask) == (mouse->buttons & wheel[i].mask))
143 continue;
144 if (mouse->buttons & wheel[i].mask) {
145 if (verbose)
146 fprintf(stderr, "mouse: wheel-%s\n", wheel[i].name);
147 uinput_send_event(EV_REL, REL_WHEEL, wheel[i].btn);
150 if (verbose)
151 fprintf(stderr, "mouse: syn\n");
152 uinput_send_event(EV_SYN, SYN_REPORT, 0);
154 last = *mouse;