summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bluetooth/bthidd/hid.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bluetooth/bthidd/hid.c')
-rw-r--r--usr.sbin/bluetooth/bthidd/hid.c134
1 files changed, 121 insertions, 13 deletions
diff --git a/usr.sbin/bluetooth/bthidd/hid.c b/usr.sbin/bluetooth/bthidd/hid.c
index 5a7ab66..4495dbc 100644
--- a/usr.sbin/bluetooth/bthidd/hid.c
+++ b/usr.sbin/bluetooth/bthidd/hid.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: hid.c,v 1.3 2004/02/26 21:47:35 max Exp $
+ * $Id: hid.c,v 1.4 2004/11/17 21:59:42 max Exp $
* $FreeBSD$
*/
@@ -40,13 +40,18 @@
#include <stdio.h>
#include <string.h>
#include <syslog.h>
+#include <unistd.h>
#include <usbhid.h>
#include "bthidd.h"
#include "bthid_config.h"
+#include "kbd.h"
#undef min
#define min(x, y) (((x) < (y))? (x) : (y))
+#undef ASIZE
+#define ASIZE(a) (sizeof(a)/sizeof(a[0]))
+
/*
* Process data from control channel
*/
@@ -123,9 +128,10 @@ hid_interrupt(bthid_session_p s, char *data, int len)
hid_item_t h;
int report_id, usage, page, val,
mouse_x, mouse_y, mouse_z, mouse_butt,
- nkeys, keys[32]; /* XXX how big keys[] should be? */
+ mevents, kevents;
assert(s != NULL);
+ assert(s->srv != NULL);
assert(data != NULL);
if (len < 3) {
@@ -148,7 +154,7 @@ hid_interrupt(bthid_session_p s, char *data, int len)
hid_device = get_hid_device(&s->bdaddr);
assert(hid_device != NULL);
- mouse_x = mouse_y = mouse_z = mouse_butt = nkeys = 0;
+ mouse_x = mouse_y = mouse_z = mouse_butt = mevents = kevents = 0;
for (d = hid_start_parse(hid_device->desc, 1 << hid_input, -1);
hid_get_item(d, &h) > 0; ) {
@@ -164,14 +170,17 @@ hid_interrupt(bthid_session_p s, char *data, int len)
switch (usage) {
case HUG_X:
mouse_x = val;
+ mevents ++;
break;
case HUG_Y:
mouse_y = val;
+ mevents ++;
break;
case HUG_WHEEL:
mouse_z = -val;
+ mevents ++;
break;
case HUG_SYSTEM_SLEEP:
@@ -182,20 +191,24 @@ hid_interrupt(bthid_session_p s, char *data, int len)
break;
case HUP_KEYBOARD:
+ kevents ++;
+
if (h.flags & HIO_VARIABLE) {
- if (val && nkeys < sizeof(keys))
- keys[nkeys ++] = usage;
+ if (val && usage < kbd_maxkey())
+ bit_set(s->srv->keys, usage);
} else {
- if (val && nkeys < sizeof(keys))
- keys[nkeys ++] = val;
+ if (val && val < kbd_maxkey())
+ bit_set(s->srv->keys, val);
+
data ++;
len --;
len = min(len, h.report_size);
while (len > 0) {
val = hid_get_data(data, &h);
- if (val && nkeys < sizeof(keys))
- keys[nkeys ++] = val;
+ if (val && val < kbd_maxkey())
+ bit_set(s->srv->keys, val);
+
data ++;
len --;
}
@@ -204,6 +217,97 @@ hid_interrupt(bthid_session_p s, char *data, int len)
case HUP_BUTTON:
mouse_butt |= (val << (usage - 1));
+ mevents ++;
+ break;
+
+ case HUP_CONSUMER:
+ if (!val)
+ break;
+
+ switch (usage) {
+ case 0xb5: /* Scan Next Track */
+ val = 0x19;
+ break;
+
+ case 0xb6: /* Scan Previous Track */
+ val = 0x10;
+ break;
+
+ case 0xb7: /* Stop */
+ val = 0x24;
+ break;
+
+ case 0xcd: /* Play/Pause */
+ val = 0x22;
+ break;
+
+ case 0xe2: /* Mute */
+ val = 0x20;
+ break;
+
+ case 0xe9: /* Volume Up */
+ val = 0x30;
+ break;
+
+ case 0xea: /* Volume Down */
+ val = 0x2E;
+ break;
+
+ case 0x183: /* Media Select */
+ val = 0x6D;
+ break;
+
+ case 0x018a: /* Mail */
+ val = 0x6C;
+ break;
+
+ case 0x192: /* Calculator */
+ val = 0x21;
+ break;
+
+ case 0x194: /* My Computer */
+ val = 0x6B;
+ break;
+
+ case 0x221: /* WWW Search */
+ val = 0x65;
+ break;
+
+ case 0x223: /* WWW Home */
+ val = 0x32;
+ break;
+
+ case 0x224: /* WWW Back */
+ val = 0x6A;
+ break;
+
+ case 0x225: /* WWW Forward */
+ val = 0x69;
+ break;
+
+ case 0x226: /* WWW Stop */
+ val = 0x68;
+ break;
+
+ case 0227: /* WWW Refresh */
+ val = 0x67;
+ break;
+
+ case 0x22a: /* WWW Favorites */
+ val = 0x66;
+ break;
+
+ default:
+ val = 0;
+ break;
+ }
+
+ /* XXX FIXME - UGLY HACK */
+ if (val != 0) {
+ int buf[4] = { 0xe0, val, 0xe0, val|0x80 };
+
+ write(s->srv->vkbd, buf, sizeof(buf));
+ }
break;
case HUP_MICROSOFT:
@@ -236,13 +340,17 @@ hid_interrupt(bthid_session_p s, char *data, int len)
}
hid_end_parse(d);
+ /* Feed keyboard events into kernel */
+ if (kevents > 0)
+ kbd_process_keys(s);
+
/*
- * XXX FIXME Feed mouse and keyboard events into kernel
- * The code block below works, but it is not
- * good enough
+ * XXX FIXME Feed mouse events into kernel.
+ * The code block below works, but it is not good enough.
+ * Need to track double-clicks etc.
*/
- if (mouse_x != 0 || mouse_y != 0 || mouse_z != 0 || mouse_butt != 0) {
+ if (mevents > 0) {
struct mouse_info mi;
mi.operation = MOUSE_ACTION;
OpenPOWER on IntegriCloud