2006年12月18日

    鼠标早就坏了,左键不能用,懒的跑出去买。再说就这么坏了就换就有点被鼠标打败了的感觉。最主要的原因还是懒人啥都能凑合。

    windows下还好说,我用鼠标键+左右键调换还能凑合着用。这两天突然想学学linux,x下没左键是寸步难行,只好改改了。我鼠标还有滚轮,可以
当左键往下按。
    linux下负责鼠标,键盘,及其它usb输入设备的被称做input subsystem。linux journAl上有两篇介绍的文章www.linuxjournal.com/article/6396
http://www.linuxjournal.com/article/6429
    在\drivers\input\mouse\psmouse-base.c里是ps/2鼠标的驱动,psmouse_process_byte()
 

/* * psmouse_process_byte() analyzes the PS/2 data stream and reports * relevant events to the input module once full packet has arrived. */  static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs){ 	struct input_dev *dev = psmouse->dev; 	unsigned char *packet = psmouse->packet;  	if (psmouse->pktcnt < psmouse->pktsize) 		return PSMOUSE_GOOD_DATA;  /*  * Full packet accumulated, process it  */  	input_regs(dev, regs);  /*  * Scroll wheel on IntelliMice, scroll buttons on NetMice  */  	if (psmouse->type == PSMOUSE_IMPS || psmouse->type == PSMOUSE_GENPS) 		input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]);  /*  * Scroll wheel and buttons on IntelliMouse Explorer  */  	if (psmouse->type == PSMOUSE_IMEX) { 		input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); 		input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); 		input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1);	}  /*  * Extra buttons on Genius NewNet 3D  */  	if (psmouse->type == PSMOUSE_GENPS) { 		input_report_key(dev, BTN_SIDE, (packet[0] >> 6) & 1); 		input_report_key(dev, BTN_EXTRA, (packet[0] >> 7) & 1);	}  /*  * Extra button on ThinkingMouse  */ 	if (psmouse->type == PSMOUSE_THINKPS) { 		input_report_key(dev, BTN_EXTRA, (packet[0] >> 3) & 1); 		/* Without this bit of weirdness moving up gives wildly high Y changes. */ 		packet[1] |= (packet[0] & 0x40) << 1;	}  /*  * Generic PS/2 Mouse  */  	input_report_key(dev, BTN_LEFT,    packet[0]       & 1); 	input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1); 	input_report_key(dev, BTN_RIGHT,  (packet[0] >> 1) & 1);  	input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0); 	input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);  	input_sync(dev);  	return PSMOUSE_FULL_PACKET;} 
这个函数就是向input subsystem提交鼠标按键数据的地方。就改一个地方就可以了

/* * Generic PS/2 Mouse */  	input_report_key(dev, BTN_LEFT,    packet[0]       & 1); 	input_report_key(dev, BTN_LEFT, (packet[0] >> 2) & 1);  <----- 把BTN_MIDDLE改为BTN_LEFT 	input_report_key(dev, BTN_RIGHT,  (packet[0] >> 1) & 1);  	input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0); 	input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);  	input_sync(dev); 

input subsystem里的程序都还没有仔细看,就急着改了,到还真的工作了!以后慢慢看input subsystem。
 
 
该是windows了,windows的更是没仔细看,同学招呼我打魔兽,所以比较着急。ddk里有moufiltr,鼠标的过滤驱动。
里面说
        // Hook into the report chain.  Everytime a mouse packet is reported to
        // the system, MouFilter_ServiceCallback will be called
        //
那这样在MouFilter_ServiceCallback 里改就行了。

VOIDMouFilter_ServiceCallback(     IN PDEVICE_OBJECT DeviceObject,     IN PMOUSE_INPUT_DATA InputDataStart,     IN PMOUSE_INPUT_DATA InputDataEnd,     IN OUT PULONG InputDataConsumed     ) /*++  Routine Description:      Called when there are mouse packets to report to the RIT.  You can do      anything you like to the packets.  For instance:          o Drop a packet altogether     o Mutate the contents of a packet      o Insert packets into the stream                       Arguments:      DeviceObject - Context passed during the connect IOCTL          InputDataStart - First packet to be reported          InputDataEnd - One past the last packet to be reported.  Total number of                    packets is equal to InputDataEnd - InputDataStart          InputDataConsumed - Set to the total number of packets consumed by the RIT                         (via the function pointer we replaced in the connect                         IOCTL)  Return Value:      Status is returned.  --*/ {     PDEVICE_EXTENSION   devExt;      devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;      //     // UpperConnectData must be called at DISPATCH     //     (*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(         devExt->UpperConnectData.ClassDeviceObject,         InputDataStart,         InputDataEnd,         InputDataConsumed         ); }

改成

{     PDEVICE_EXTENSION   devExt; 	int	i;      devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; 	for(i = 0;i < (InputDataEnd - InputDataStart);i++) { 		if (InputDataStart[i].ButtonFlags == MOUSE_MIDDLE_BUTTON_DOWN){ 			InputDataStart[i].ButtonFlags = MOUSE_LEFT_BUTTON_DOWN;		} 		if (InputDataStart[i].ButtonFlags == MOUSE_MIDDLE_BUTTON_UP){ 			InputDataStart[i].ButtonFlags = MOUSE_LEFT_BUTTON_UP;		}	}      //     // UpperConnectData must be called at DISPATCH     //     (*(PSERVICE_CALLBACK_ROUTINE) devExt->UpperConnectData.ClassService)(         devExt->UpperConnectData.ClassDeviceObject,         InputDataStart,         InputDataEnd,         InputDataConsumed         ); } 

然后按它说的,通过.inf文件把这个驱动一装,重起后就行了。
 
 
又是一大堆东西等着看了。
2006年12月10日

http://writeblog.donews.com/login.aspx?ReturnUrl=/editposts.aspx
在教育网里点登陆就不是这个地址,奇怪