1 event device
in /dev/input/event?
cat data from /dev/input/event? the data format is :
struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
e.g :
xx xx xx xx yy yy yy yy tt tt cc cc vv vv vv vv
xx is usec
yy is sec
tt is type
cc is key code
vv is value, might be it means keyup or keydown
for mouse event, you can get the same message format
xx, yy is the same as keyboard
tt is EV_REL, it means the value feild is relativedistance;
cc is REL_X or REL_Y
vv is the value of relative distance
经过与实际的对比,似乎上面与上面的内容有一定的出入!!!
2 register input_dev
static int vkm_vmouse_register(void)
{
struct input_dev *vmouse_dev;
vmouse_dev = input_allocate_device();
if (!vmouse_dev)
return -ENOMEM;
vmouse_dev->name = "VMouse ";
vmouse_dev->phys = "xxmouse/input1";
vmouse_dev->id.bustype = BUS_HOST;
vmouse_dev->id.vendor = 0x0001;
vmouse_dev->id.product = 0x0002;
vmouse_dev->id.version = 0x0100;
vmouse_dev->evbit[0] = BIT_MASK(EV_KEY) |BIT_MASK(EV_REL);
vmouse_dev->keybit[BIT_WORD(BTN_MOUSE)] =
BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
vmouse_dev->relbit[0] = BIT_MASK(REL_X) |BIT_MASK(REL_Y);
error = input_register_device(vmouse_dev);
if (error) {
input_free_device(vmouse_dev);
return error;
}
}
static int vkm_vkbd_register(void)
{
int i, error;
struct input_dev *vkbd_dev;
vkbd_dev = input_allocate_device();
if (!vkbd_dev)
return -ENOMEM;
vkbd_dev->name = "VKBD Keyboard";
vkbd_dev->phys = "atakbd/input0";
vkbd_dev->id.bustype = BUS_HOST;
vkbd_dev->id.vendor = 0x0001;
vkbd_dev->id.product = 0x0001;
vkbd_dev->id.version = 0x0100;
vkbd_dev->evbit[0] = BIT_MASK(EV_KEY) |BIT_MASK(EV_REP);
vkbd_dev->keycode = atakbd_keycode;
vkbd_dev->keycodesize = sizeof(unsignedchar);
vkbd_dev->keycodemax =ARRAY_SIZE(atakbd_keycode);
for (i = 1; i < 0x72; i++) {
set_bit(atakbd_keycode[i],vkbd_dev->keybit);
}
error = input_register_device(vkbd_dev);
if (error) {
input_free_device(vkbd_dev);
return error;
}
return 0;
}
send keyboard event to input handler like this:
input_report_key(vkbd_dev,KEY_A,0);
input_sync(vkbd_dev);
and send mouse event to input handler like this:
input_report_rel(vmouse_dev, REL_X, 10);
input_report_rel(vmouse_dev, REL_Y, 10);
input_sync(vmouse_dev);
以下是我自己的代码:(验证通过的代码)
// vmouse.c(爱的就是米)
#include <linux/input.h>
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
static struct input_dev *vmouse_dev;
static int __init vmouse_init(void)
{
int error;
memset(&vmouse_dev, 0,sizeof(struct input_dev));
//init_input_dev(&vmouse_dev);
vmouse_dev = kzalloc(sizeof(struct input_dev),GFP_KERNEL);
vmouse_dev= input_allocate_device();
if (!vmouse_dev)
{
printk("Badinput_alloc_device()\n");
return -ENOMEM;
}
vmouse_dev->name = "virtual mouse driver";
vmouse_dev->phys = "/dev/input/eventX";
vmouse_dev->id.bustype = BUS_HOST;
vmouse_dev->id.vendor = 0x0001;
vmouse_dev->id.product = 0x0001;
vmouse_dev->id.version = 0x0100;
set_bit(EV_REL, vmouse_dev->evbit);
set_bit(REL_X, vmouse_dev->relbit);
set_bit(REL_Y, vmouse_dev->relbit);
set_bit(EV_KEY, vmouse_dev->evbit);
set_bit(BTN_LEFT, vmouse_dev->keybit);
set_bit(BTN_RIGHT,vmouse_dev->keybit);
set_bit(BTN_MIDDLE,vmouse_dev->keybit);
error = input_register_device(vmouse_dev);
if(error)
{
input_free_device(vmouse_dev);
}
// ... do initialization...
returnerror;
}
static void __exit vmouse_exit(void)
{
input_unregister_device(vmouse_dev);
kfree(vmouse_dev);
}
module_init(vmouse_init);
module_exit(vmouse_exit);
//vkbd.c(爱的就是米)
#include <linux/input.h>
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
static struct input_dev *vkbd_dev;
static unsigned short usb_kbd_keycode[256] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,76, 77, 78, 79,
80, 81, 82, 83, 84,118, 86, 87,88,115,120,119,121,112,123, 92,
284,285,309, 0,312,91,327,328,329,331,333,335,336,337,338,339,
367,288,302,304,350,89,334,326,267,126,268,269,125,347,348,349,
360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355,
103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361,
291,108,381,281,290,272,292,305,280,99,112,257,306,359,113,114,
264,117,271,374,379,265,266, 93, 94, 95,85,259,375,260, 90,116,
377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307,
308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372};
static unsigned char atakbd_keycode[0x72] ={
[0] = KEY_GRAVE,
[1] = KEY_ESC,
[2] = KEY_1,
[3] = KEY_2,
[4] = KEY_3,
[5] = KEY_4,
[6] = KEY_5,
[7] = KEY_6,
[8] = KEY_7,
[9] = KEY_8,
[10] = KEY_9,
[11] = KEY_0,
[12] = KEY_MINUS,
[13] = KEY_EQUAL,
[14] = KEY_BACKSPACE,
[15] = KEY_TAB,
[16] = KEY_Q,
[17] = KEY_W,
[18] = KEY_E,
[19] = KEY_R,
[20] = KEY_T,
[21] = KEY_Y,
[22] = KEY_U,
[23] = KEY_I,
[24] = KEY_O,
[25] = KEY_P,
[26] = KEY_LEFTBRACE,
[27] = KEY_RIGHTBRACE,
[28] = KEY_ENTER,
[29] = KEY_LEFTCTRL,
[30] = KEY_A,
[31] = KEY_S,
[32] = KEY_D,
[33] = KEY_F,
[34] = KEY_G,
[35] = KEY_H,
[36] = KEY_J,
[37] = KEY_K,
[38] = KEY_L,
[39] = KEY_SEMICOLON,
[40] = KEY_APOSTROPHE,
[41] =KEY_BACKSLASH,
[42] = KEY_LEFTSHIFT,
[43] =KEY_GRAVE,
[44] = KEY_Z,
[45] = KEY_X,
[46] = KEY_C,
[47] = KEY_V,
[48] = KEY_B,
[49] = KEY_N,
[50] = KEY_M,
[51] = KEY_COMMA,
[52] = KEY_DOT,
[53] = KEY_SLASH,
[54] = KEY_RIGHTSHIFT,
[55] = KEY_KPASTERISK,
[56] = KEY_LEFTALT,
[57] = KEY_SPACE,
[58] = KEY_CAPSLOCK,
[59] = KEY_F1,
[60] = KEY_F2,
[61] = KEY_F3,
[62] = KEY_F4,
[63] = KEY_F5,
[64] = KEY_F6,
[65] = KEY_F7,
[66] = KEY_F8,
[67] = KEY_F9,
[68] = KEY_F10,
[69] = KEY_ESC,
[70] = KEY_DELETE,
[71] = KEY_KP7,
[72] = KEY_KP8,
[73] = KEY_KP9,
[74] = KEY_KPMINUS,
[75] = KEY_KP4,
[76] = KEY_KP5,
[77] = KEY_KP6,
[78] = KEY_KPPLUS,
[79] = KEY_KP1,
[80] = KEY_KP2,
[81] = KEY_KP3,
[82] = KEY_KP0,
[83] = KEY_KPDOT,
[90] = KEY_KPLEFTPAREN,
[91] = KEY_KPRIGHTPAREN,
[92] =KEY_KPASTERISK,
[93] = KEY_KPASTERISK,
[94] = KEY_KPPLUS,
[95] = KEY_HELP,
[96] =KEY_BACKSLASH,
[97] =KEY_KPASTERISK,
[98] = KEY_KPSLASH,
[99] = KEY_KPLEFTPAREN,
[100] = KEY_KPRIGHTPAREN,
[101] = KEY_KPSLASH,
[102] = KEY_KPASTERISK,
[103] = KEY_UP,
[104] =KEY_KPASTERISK,
[105] = KEY_LEFT,
[106] = KEY_RIGHT,
[107] =KEY_KPASTERISK,
[108] = KEY_DOWN,
[109] =KEY_KPASTERISK,
[110] =KEY_KPASTERISK,
[111] =KEY_KPASTERISK,
[112] =KEY_KPASTERISK,
[113] =KEY_KPASTERISK
};
static int __init vkbd_init(void)
{
int i, error;
memset(&vkbd_dev, 0,sizeof(struct input_dev));
//init_input_dev(&vkbd_dev);
vkbd_dev = kzalloc(sizeof(struct input_dev),GFP_KERNEL);
vkbd_dev= input_allocate_device();
if (!vkbd_dev)
{
printk("Badinput_alloc_device()\n");
return -ENOMEM;
}
vkbd_dev->name = "virtual keyboard driver";
vkbd_dev->phys = "/dev/input/eventX";
vkbd_dev->id.bustype = BUS_HOST;
vkbd_dev->id.vendor = 0x0001;
vkbd_dev->id.product = 0x0001;
vkbd_dev->id.version = 0x0100;
set_bit(EV_KEY,vkbd_dev->evbit);
for(i = 0; i < 0x72; i++)
{
set_bit(atakbd_keycode[i],vkbd_dev->keybit);
}
error = input_register_device(vkbd_dev);
if(error)
{
input_free_device(vkbd_dev);
return error;
}
return0;
}
static void __exit vkbd_exit(void)
{
input_unregister_device(vkbd_dev);
kfree(vkbd_dev);
return ;
}
module_init(vkbd_init);
module_exit(vkbd_exit);
Makefile:
ifeq ($(KERNELRELEASE),)$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD)modules_install
clean:
rm -rf *.o *~core .depend .*.cmd *.ko *.mod.cmodules.* Module.* tmp_versions
.PHONY: modules modules_insall clean
else
obj-m :=vmouse.o //这里要根据需要进行更改
endif