📄 ir_inf_combo.c
字号:
static void raw_ir_event(UINT32 timediff){ UINT32 uCode; if(ir_osi_detect_hitachi_code(timediff, &uCode) > 0) { ir_osi_process_hitachi_code(uCode, handle_raw_ir_code); }}static int rawir_open(struct inode *inode, struct file *file){ RAWIR_DEVICE_SLOTS *pSlot; PDEBUG("rawir_open(%p)\n", file); /* We don't want to talk to two processes at the * same time */ if (rawir_open_count >= RAWIR_MAX_OPENS) { return -EBUSY; } if(file->f_mode & FMODE_WRITE) { return -EPERM; } pSlot = (RAWIR_DEVICE_SLOTS *)MALLOC(sizeof(RAWIR_DEVICE_SLOTS)); if(!pSlot) { PFATAL("Out of memeory!\n"); return -EIO; } memset(pSlot, 0, sizeof(RAWIR_DEVICE_SLOTS)); if(os_create_queue(&pSlot->dataq, pSlot->queuebuf, RAWIR_QUEUE_SIZE, sizeof(UINT32)) < 0) { PDEBUG("this os_create_queue should never fail!\n"); FREE(pSlot); return -EIO; } init_waitqueue_head(&pSlot->wait); spin_lock_init(&pSlot->lock); file->private_data = pSlot; // ok, assign the slot pSlot->pNext = _gpRawIRSlots; // always add before to avoid locks _gpRawIRSlots = pSlot; // unless there can be another open (never for linux) rawir_open_count++; MOD_INC_USE_COUNT; // MODULE return 0;}/* This function is called when a process closes the* device file. It doesn't have a return value because * it cannot fail. Regardless of what else happens, you * should always be able to close a device (in 2.0, a 2.2* device file could be impossible to close). */static int rawir_release(struct inode *inode, struct file *file){ RAWIR_DEVICE_SLOTS *pSlot; PDEBUG("rawir_release(%p,%p)\n", inode, file); if (!rawir_open_count) { PDEBUG("try to close before open!\n"); return -EBADF; } if (!file->private_data) { PFATAL("Release: Where is my private data ?\n"); return -EBADF; } pSlot = (RAWIR_DEVICE_SLOTS *)file->private_data; if(_gpRawIRSlots == pSlot) // oh, it's the head { spin_lock_bh(&_g_irlock); _gpRawIRSlots = _gpRawIRSlots->pNext; spin_unlock_bh(&_g_irlock); } else { RAWIR_DEVICE_SLOTS *pMySlot; pMySlot = _gpRawIRSlots; while(pMySlot->pNext && pMySlot->pNext != pSlot) pMySlot = pMySlot->pNext; if(pMySlot->pNext != pSlot) { PFATAL("Release: who messed up my private data ?\n"); return -EBADF; } spin_lock_bh(&_g_irlock); pMySlot->pNext = pMySlot->pNext->pNext; spin_unlock_bh(&_g_irlock); } rawir_fasync(-1, file, 0); spin_lock(&pSlot->lock); os_delete_queue(&pSlot->dataq); spin_unlock(&pSlot->lock); FREE(pSlot); rawir_open_count--; MOD_DEC_USE_COUNT; return 0;}static int rawir_fasync(int fd, struct file *filp, int mode){ RAWIR_DEVICE_SLOTS *pSlot = (RAWIR_DEVICE_SLOTS *)filp->private_data; return fasync_helper(fd, filp, mode, &pSlot->async_queue);}/* This function is called whenever a process which * has already opened the device file attempts to * read from it. */static ssize_t rawir_read(struct file *filp, char *buffer, /* The buffer to fill with the data */ size_t length, /* The length of the buffer */ loff_t * offset) /* offset to the file */{ /* Number of bytes actually written to the buffer */ RAWIR_DEVICE_SLOTS *pSlot; USHORT key; INT rtn; ssize_t char_read=0; /* #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) int i, is_sig=0; #endif */ PDEBUG("rawir_read(%p,%p,%d)\n", filp, buffer, (int) length); if (length < sizeof(USHORT)) return 0; pSlot = (RAWIR_DEVICE_SLOTS *)filp->private_data; rtn = os_dequeue(&pSlot->dataq, &key); // FixMe: shall we use locks ? if(rtn < 0) // queue empty { if (filp->f_flags & O_NONBLOCK) return -EAGAIN; interruptible_sleep_on(&pSlot->wait); // FixMe: can this die when race happens? if(signal_pending(current)) return -EINTR; rtn = os_dequeue(&pSlot->dataq, &key); // FixMe: shall we use locks ? if(rtn < 0) return 0; } do { if(copy_to_user(buffer, &key, sizeof(USHORT))) return -EFAULT; char_read += 2; if(char_read > length-2) break; rtn = os_dequeue(&pSlot->dataq, &key); // FixMe: shall we use locks ? } while(!rtn); return char_read;}static unsigned int rawir_poll(struct file *filp, struct poll_table_struct *wait){ RAWIR_DEVICE_SLOTS *pSlot = (RAWIR_DEVICE_SLOTS *)filp->private_data; poll_wait(filp, &pSlot->wait, wait); if (os_get_queue_status(&pSlot->dataq)>0) return POLLIN | POLLRDNORM; return 0;}///////////////////////////////////////////////////////////////////////////////// Acer Keyboard Mouse driver section///////////////////////////////////////////////////////////////////////////////static int acer_kbms_init(void){#ifdef _IR_MOUSE_SUPPORT if( acer_mouse_init() < 0) return -1;#endif ir_osi_reset_acer_detector(); return 0;}static void acer_kbms_cleanup(void){#ifdef _IR_MOUSE_SUPPORT acer_mouse_cleanup();#endif}static void handle_acer_keyboard_scan_code(USHORT wCode, USHORT wDone){ handle_scancode((unsigned char)wCode, (int)wDone);}static void acer_kbms_event(UINT32 timediff){ UINT32 uCode; if (ir_osi_detect_acer_keycode(timediff, &uCode)>0) { ir_osi_process_acer_keycode(uCode, handle_acer_keyboard_scan_code, pMouseHandle ); }}#ifdef _IR_MOUSE_SUPPORT /*----------------------------------------------------| Linux Mouse driver for Redwood 4 and Acer IR KB || by Yudong Yang IBM CRL, May/10/2001 |------------------------------------------------------| It requires the busmouse common driver in kernel | |----------------------------------------------------*/static int msedev;static void acer_mouse_event_handle(INT dx, INT dy, USHORT button){ if (dx || dy) { busmouse_add_movement(msedev, -dx, -dy); } if (button & __IR_MOUSE_LBUTTON_DOWN) { busmouse_add_buttons(msedev, 0x04, 0); } else if (button & __IR_MOUSE_LBUTTON_UP) { busmouse_add_buttons(msedev, 0x04, 4); } if (button & __IR_MOUSE_RBUTTON_DOWN) { busmouse_add_buttons(msedev, 0x01, 0); } else if (button & __IR_MOUSE_RBUTTON_UP) { busmouse_add_buttons(msedev, 0x01, 1); }}static int release_mouse(struct inode *inode, struct file *file){ pMouseHandle = NULL; MOD_DEC_USE_COUNT; return 0;}static int open_mouse(struct inode *inode, struct file *file){ pMouseHandle = acer_mouse_event_handle; MOD_INC_USE_COUNT; return 0;}static struct busmouse acermouse = { ACER_MOUSE_MINOR, "acerirmouse", THIS_MODULE, open_mouse, release_mouse, 7};static int acer_mouse_init(void){ msedev = register_busmouse(&acermouse); if (msedev < 0) printk(KERN_WARNING "Unable to register Acer IR mouse driver.\n"); else printk(KERN_INFO "Acer IR mouse installed.\n"); pMouseHandle = NULL; return msedev < 0 ? msedev : 0;}static void acer_mouse_cleanup(void){ pMouseHandle = NULL; unregister_busmouse(msedev); msedev = 0;}#endif // _IR_MOUSE_SUPPORT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -