--- lirc_imon.c.old 2005-04-16 20:10:02.000000000 +0200 +++ lirc_imon.c 2005-07-25 01:04:04.406805182 +0200 @@ -53,6 +53,7 @@ #include #include +#include #include #include #include @@ -68,7 +69,7 @@ #define MOD_AUTHOR "Venky Raju " #define MOD_DESC "Driver for Soundgraph iMON MultiMedian IR/VFD" #define MOD_NAME "lirc_imon" -#define MOD_VERSION "0.3" +#define MOD_VERSION "0.3M" #define VFD_MINOR_BASE 144 /* Same as LCD */ #define DEVFS_MODE S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH @@ -83,6 +84,7 @@ #define TRUE 1 #define FALSE 0 +#define CURSOR_LIMIT 2 /* ------------------------------------------------------------ * P R O T O T Y P E S @@ -160,7 +162,11 @@ struct completion finished; /* wait for write to finish */ atomic_t busy; /* write in progress */ int status; /* status of tx completion */ + } tx; + + int mode_kbd; /* keyboard/mouse mode */ + struct input_dev mouse; /* mouse interface */ }; #define LOCK_CONTEXT down (&context ->sem) @@ -573,6 +579,8 @@ context ->rx.initial_space = 1; context ->rx.prev_bit = 0; + context ->mode_kbd = 1; /* init keyboard mode */ + usb_fill_int_urb (context ->rx_urb, context ->dev, usb_rcvintpipe (context ->dev, context ->rx_endpoint-> bEndpointAddress), @@ -616,7 +624,7 @@ LOCK_CONTEXT; - usb_unlink_urb (context ->rx_urb); + usb_kill_urb (context ->rx_urb); context ->ir_isopen = FALSE; MOD_DEC_USE_COUNT; info ("IR port closed"); @@ -701,11 +709,72 @@ if (context ->ir_onboard_decode) { - /* The signals have been decoded onboard the iMON controller */ + /* The signals have been decoded onboard the iMON controller */ - lirc_buffer_write_1 (context ->plugin ->rbuf, buf); - wake_up (&context ->plugin ->rbuf ->wait_poll); - return; + if(buf[0] & 0x40) { + int rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 | (buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6; + int rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 | (buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6; + if(buf[0] & 0x02) rel_x |= ~0x10+1; + if(buf[0] & 0x01) rel_y |= ~0x10+1; + + /* keyboard direction key emulation */ + if(context->mode_kbd) { + + if(buf[1] & 0x01 || buf[1] >> 2 & 0x01) { + // warn("press\n"); + /* mouse pressed */ + } + + if(abs(rel_y) > abs(rel_x)) { + if(rel_y > CURSOR_LIMIT) { /* mouse s */ + buf[0] = 0x68; + buf[1] = 0x82; + buf[2] = 0x91; + } else if(rel_y < -CURSOR_LIMIT) { /* mouse n */ + buf[0] = 0x69; + buf[1] = 0x02; + buf[2] = 0x81; + } else { + return; /* discard those key codes */ + } + + } else { + if(rel_x > CURSOR_LIMIT) { /* mouse e */ + buf[0] = 0x68; + buf[1] = 0x8A; + buf[2] = 0x81; + } else if(rel_x < -CURSOR_LIMIT) { /* mouse w */ + buf[0] = 0x6A; + buf[1] = 0x82; + buf[2] = 0x81; + } else { + return; /* discard those key codes */ + } + } + + } else { + + /* mouse emulation */ + struct input_dev *mouse = &context->mouse; + input_report_key(mouse, BTN_LEFT, buf[1] & 0x01); + input_report_key(mouse, BTN_RIGHT, buf[1] >> 2 & 0x01); + input_report_rel(mouse, REL_X, rel_x); + input_report_rel(mouse, REL_Y, rel_y); + input_sync(mouse); + return; + } + } + + /* mouse/kbd button 29 91 15 b7 */ + if((buf[0] == 0x29) && (buf[1] == 0x91) && (buf[2] == 0x15) && (buf[3] == 0xb7)) { + // warn("toggle kbd %d -> %d\n", context->mode_kbd, !context->mode_kbd); + context->mode_kbd = !context->mode_kbd; + return; + } + + lirc_buffer_write_1 (context ->plugin ->rbuf, buf); + wake_up (&context ->plugin ->rbuf ->wait_poll); + return; } /* @@ -1082,6 +1151,22 @@ #endif } + /* register with kernel input system for PAD mouse */ + context->mouse.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + context->mouse.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); + context->mouse.relbit[0] = BIT(REL_X) | BIT(REL_Y); + context->mouse.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA); + context->mouse.relbit[0] |= BIT(REL_WHEEL); + context->mouse.private = context; + + context->mouse.id.bustype = BUS_USB; + context->mouse.id.vendor = le16_to_cpu(dev->descriptor.idVendor); + context->mouse.id.product = le16_to_cpu(dev->descriptor.idProduct); + context->mouse.id.version = le16_to_cpu(dev->descriptor.bcdDevice); + context->mouse.dev = &dev->dev; + + input_register_device(&context->mouse); + info ("%s: iMON device on usb<%d:%d> initialized", __FUNCTION__, dev ->bus ->busnum, dev ->devnum); @@ -1125,12 +1210,12 @@ context ->dev_present = FALSE; /* Stop reception */ - usb_unlink_urb (context ->rx_urb); + usb_kill_urb (context ->rx_urb); /* Abort ongoing write */ if (atomic_read (&context ->tx.busy)) { - usb_unlink_urb (context ->tx_urb); + usb_kill_urb (context ->tx_urb); wait_for_completion (&context ->tx.finished); } @@ -1147,6 +1232,8 @@ #endif } + input_unregister_device (&context ->mouse); + UNLOCK_CONTEXT; if (!context ->ir_isopen && !context ->vfd_isopen)