Deleted Added
full compact
hid.c (128080) hid.c (137868)
1/*
2 * hid.c
3 *
4 * Copyright (c) 2004 Maksim Yevmenkin <m_evmenkin@yahoo.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 11 unchanged lines hidden (view full) ---

20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
1/*
2 * hid.c
3 *
4 * Copyright (c) 2004 Maksim Yevmenkin <m_evmenkin@yahoo.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 11 unchanged lines hidden (view full) ---

20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $Id: hid.c,v 1.3 2004/02/26 21:47:35 max Exp $
29 * $FreeBSD: head/usr.sbin/bluetooth/bthidd/hid.c 128080 2004-04-10 00:18:00Z emax $
28 * $Id: hid.c,v 1.4 2004/11/17 21:59:42 max Exp $
29 * $FreeBSD: head/usr.sbin/bluetooth/bthidd/hid.c 137868 2004-11-18 18:05:15Z emax $
30 */
31
32#include <sys/consio.h>
33#include <sys/mouse.h>
34#include <sys/queue.h>
35#include <assert.h>
36#include <bluetooth.h>
37#include <errno.h>
38#include <dev/usb/usb.h>
39#include <dev/usb/usbhid.h>
40#include <stdio.h>
41#include <string.h>
42#include <syslog.h>
30 */
31
32#include <sys/consio.h>
33#include <sys/mouse.h>
34#include <sys/queue.h>
35#include <assert.h>
36#include <bluetooth.h>
37#include <errno.h>
38#include <dev/usb/usb.h>
39#include <dev/usb/usbhid.h>
40#include <stdio.h>
41#include <string.h>
42#include <syslog.h>
43#include <unistd.h>
43#include <usbhid.h>
44#include "bthidd.h"
45#include "bthid_config.h"
44#include <usbhid.h>
45#include "bthidd.h"
46#include "bthid_config.h"
47#include "kbd.h"
46
47#undef min
48#define min(x, y) (((x) < (y))? (x) : (y))
49
48
49#undef min
50#define min(x, y) (((x) < (y))? (x) : (y))
51
52#undef ASIZE
53#define ASIZE(a) (sizeof(a)/sizeof(a[0]))
54
50/*
51 * Process data from control channel
52 */
53
54int
55hid_control(bthid_session_p s, char *data, int len)
56{
57 assert(s != NULL);

--- 60 unchanged lines hidden (view full) ---

118int
119hid_interrupt(bthid_session_p s, char *data, int len)
120{
121 hid_device_p hid_device = NULL;
122 hid_data_t d;
123 hid_item_t h;
124 int report_id, usage, page, val,
125 mouse_x, mouse_y, mouse_z, mouse_butt,
55/*
56 * Process data from control channel
57 */
58
59int
60hid_control(bthid_session_p s, char *data, int len)
61{
62 assert(s != NULL);

--- 60 unchanged lines hidden (view full) ---

123int
124hid_interrupt(bthid_session_p s, char *data, int len)
125{
126 hid_device_p hid_device = NULL;
127 hid_data_t d;
128 hid_item_t h;
129 int report_id, usage, page, val,
130 mouse_x, mouse_y, mouse_z, mouse_butt,
126 nkeys, keys[32]; /* XXX how big keys[] should be? */
131 mevents, kevents;
127
128 assert(s != NULL);
132
133 assert(s != NULL);
134 assert(s->srv != NULL);
129 assert(data != NULL);
130
131 if (len < 3) {
132 syslog(LOG_ERR, "Got short message (%d bytes) on Interrupt " \
133 "channel from %s", len, bt_ntoa(&s->bdaddr, NULL));
134 return (-1);
135 }
136

--- 6 unchanged lines hidden (view full) ---

143
144 report_id = data[1];
145 data += 2;
146 len -= 2;
147
148 hid_device = get_hid_device(&s->bdaddr);
149 assert(hid_device != NULL);
150
135 assert(data != NULL);
136
137 if (len < 3) {
138 syslog(LOG_ERR, "Got short message (%d bytes) on Interrupt " \
139 "channel from %s", len, bt_ntoa(&s->bdaddr, NULL));
140 return (-1);
141 }
142

--- 6 unchanged lines hidden (view full) ---

149
150 report_id = data[1];
151 data += 2;
152 len -= 2;
153
154 hid_device = get_hid_device(&s->bdaddr);
155 assert(hid_device != NULL);
156
151 mouse_x = mouse_y = mouse_z = mouse_butt = nkeys = 0;
157 mouse_x = mouse_y = mouse_z = mouse_butt = mevents = kevents = 0;
152
153 for (d = hid_start_parse(hid_device->desc, 1 << hid_input, -1);
154 hid_get_item(d, &h) > 0; ) {
155 if ((h.flags & HIO_CONST) || (h.report_ID != report_id))
156 continue;
157
158 page = HID_PAGE(h.usage);
159 usage = HID_USAGE(h.usage);
160 val = hid_get_data(data, &h);
161
162 switch (page) {
163 case HUP_GENERIC_DESKTOP:
164 switch (usage) {
165 case HUG_X:
166 mouse_x = val;
158
159 for (d = hid_start_parse(hid_device->desc, 1 << hid_input, -1);
160 hid_get_item(d, &h) > 0; ) {
161 if ((h.flags & HIO_CONST) || (h.report_ID != report_id))
162 continue;
163
164 page = HID_PAGE(h.usage);
165 usage = HID_USAGE(h.usage);
166 val = hid_get_data(data, &h);
167
168 switch (page) {
169 case HUP_GENERIC_DESKTOP:
170 switch (usage) {
171 case HUG_X:
172 mouse_x = val;
173 mevents ++;
167 break;
168
169 case HUG_Y:
170 mouse_y = val;
174 break;
175
176 case HUG_Y:
177 mouse_y = val;
178 mevents ++;
171 break;
172
173 case HUG_WHEEL:
174 mouse_z = -val;
179 break;
180
181 case HUG_WHEEL:
182 mouse_z = -val;
183 mevents ++;
175 break;
176
177 case HUG_SYSTEM_SLEEP:
178 if (val)
179 syslog(LOG_NOTICE, "Sleep button pressed");
180 break;
181 }
182 break;
183
184 case HUP_KEYBOARD:
184 break;
185
186 case HUG_SYSTEM_SLEEP:
187 if (val)
188 syslog(LOG_NOTICE, "Sleep button pressed");
189 break;
190 }
191 break;
192
193 case HUP_KEYBOARD:
194 kevents ++;
195
185 if (h.flags & HIO_VARIABLE) {
196 if (h.flags & HIO_VARIABLE) {
186 if (val && nkeys < sizeof(keys))
187 keys[nkeys ++] = usage;
197 if (val && usage < kbd_maxkey())
198 bit_set(s->srv->keys, usage);
188 } else {
199 } else {
189 if (val && nkeys < sizeof(keys))
190 keys[nkeys ++] = val;
200 if (val && val < kbd_maxkey())
201 bit_set(s->srv->keys, val);
202
191 data ++;
192 len --;
193
194 len = min(len, h.report_size);
195 while (len > 0) {
196 val = hid_get_data(data, &h);
203 data ++;
204 len --;
205
206 len = min(len, h.report_size);
207 while (len > 0) {
208 val = hid_get_data(data, &h);
197 if (val && nkeys < sizeof(keys))
198 keys[nkeys ++] = val;
209 if (val && val < kbd_maxkey())
210 bit_set(s->srv->keys, val);
211
199 data ++;
200 len --;
201 }
202 }
203 break;
204
205 case HUP_BUTTON:
206 mouse_butt |= (val << (usage - 1));
212 data ++;
213 len --;
214 }
215 }
216 break;
217
218 case HUP_BUTTON:
219 mouse_butt |= (val << (usage - 1));
220 mevents ++;
207 break;
208
221 break;
222
223 case HUP_CONSUMER:
224 if (!val)
225 break;
226
227 switch (usage) {
228 case 0xb5: /* Scan Next Track */
229 val = 0x19;
230 break;
231
232 case 0xb6: /* Scan Previous Track */
233 val = 0x10;
234 break;
235
236 case 0xb7: /* Stop */
237 val = 0x24;
238 break;
239
240 case 0xcd: /* Play/Pause */
241 val = 0x22;
242 break;
243
244 case 0xe2: /* Mute */
245 val = 0x20;
246 break;
247
248 case 0xe9: /* Volume Up */
249 val = 0x30;
250 break;
251
252 case 0xea: /* Volume Down */
253 val = 0x2E;
254 break;
255
256 case 0x183: /* Media Select */
257 val = 0x6D;
258 break;
259
260 case 0x018a: /* Mail */
261 val = 0x6C;
262 break;
263
264 case 0x192: /* Calculator */
265 val = 0x21;
266 break;
267
268 case 0x194: /* My Computer */
269 val = 0x6B;
270 break;
271
272 case 0x221: /* WWW Search */
273 val = 0x65;
274 break;
275
276 case 0x223: /* WWW Home */
277 val = 0x32;
278 break;
279
280 case 0x224: /* WWW Back */
281 val = 0x6A;
282 break;
283
284 case 0x225: /* WWW Forward */
285 val = 0x69;
286 break;
287
288 case 0x226: /* WWW Stop */
289 val = 0x68;
290 break;
291
292 case 0227: /* WWW Refresh */
293 val = 0x67;
294 break;
295
296 case 0x22a: /* WWW Favorites */
297 val = 0x66;
298 break;
299
300 default:
301 val = 0;
302 break;
303 }
304
305 /* XXX FIXME - UGLY HACK */
306 if (val != 0) {
307 int buf[4] = { 0xe0, val, 0xe0, val|0x80 };
308
309 write(s->srv->vkbd, buf, sizeof(buf));
310 }
311 break;
312
209 case HUP_MICROSOFT:
210 switch (usage) {
211 case 0xfe01:
212 if (!hid_device->battery_power)
213 break;
214
215 switch (val) {
216 case 1:

--- 14 unchanged lines hidden (view full) ---

231 }
232 break;
233 }
234 break;
235 }
236 }
237 hid_end_parse(d);
238
313 case HUP_MICROSOFT:
314 switch (usage) {
315 case 0xfe01:
316 if (!hid_device->battery_power)
317 break;
318
319 switch (val) {
320 case 1:

--- 14 unchanged lines hidden (view full) ---

335 }
336 break;
337 }
338 break;
339 }
340 }
341 hid_end_parse(d);
342
343 /* Feed keyboard events into kernel */
344 if (kevents > 0)
345 kbd_process_keys(s);
346
239 /*
347 /*
240 * XXX FIXME Feed mouse and keyboard events into kernel
241 * The code block below works, but it is not
242 * good enough
348 * XXX FIXME Feed mouse events into kernel.
349 * The code block below works, but it is not good enough.
350 * Need to track double-clicks etc.
243 */
244
351 */
352
245 if (mouse_x != 0 || mouse_y != 0 || mouse_z != 0 || mouse_butt != 0) {
353 if (mevents > 0) {
246 struct mouse_info mi;
247
248 mi.operation = MOUSE_ACTION;
249 mi.u.data.x = mouse_x;
250 mi.u.data.y = mouse_y;
251 mi.u.data.z = mouse_z;
252 mi.u.data.buttons = mouse_butt;
253
254 if (ioctl(s->srv->cons, CONS_MOUSECTL, &mi) < 0)
255 syslog(LOG_ERR, "Could not process mouse events from " \
256 "%s. %s (%d)", bt_ntoa(&s->bdaddr, NULL),
257 strerror(errno), errno);
258 }
259
260 return (0);
261}
262
354 struct mouse_info mi;
355
356 mi.operation = MOUSE_ACTION;
357 mi.u.data.x = mouse_x;
358 mi.u.data.y = mouse_y;
359 mi.u.data.z = mouse_z;
360 mi.u.data.buttons = mouse_butt;
361
362 if (ioctl(s->srv->cons, CONS_MOUSECTL, &mi) < 0)
363 syslog(LOG_ERR, "Could not process mouse events from " \
364 "%s. %s (%d)", bt_ntoa(&s->bdaddr, NULL),
365 strerror(errno), errno);
366 }
367
368 return (0);
369}
370