#include #include #include #include #include #include #include #include "WheelMouse.h" char *WindowModeNames[]={"Window under pointer", "Active window",NULL }; char *ClickModeNames[]={"Ignore", "Shift", "Shift + Left Button", "Toggle Left Button", "Movement -> Scroll", "Move/Scroll Toggle", "Cycle screens",NULL}; char *ClickRollModeNames[]={"Ignore", "Depth Arrange Windows", "Horizontal Scroll",NULL}; char *DoubleClickModeNames[]={"Ignore", "Cycle Screens", "Swap Axis",NULL}; void *InputBase; BOOL WheelMouse_Handle(struct WheelMouseContext *wmc,unsigned long signals); void WheelMouse_Dispose(struct WheelMouseContext *wmc); void WheelMouse_Dispose(struct WheelMouseContext *wmc) { if(wmc) { if(wmc->IOReq) { CloseDevice((struct IORequest *)wmc->IOReq); DeleteIORequest((struct IORequest *)wmc->IOReq); wmc->IOReq=NULL; } if(wmc->IOPort) DeleteMsgPort(wmc->IOPort); wmc->IOPort=NULL; if(wmc->ReplyPort) DeleteMsgPort(wmc->ReplyPort); if(wmc->SigBit>-1) FreeSignal(wmc->SigBit); free(wmc); } } struct WheelMouseContext *WheelMouse_Create() { struct WheelMouseContext *wmc; if(!(wmc=malloc(sizeof(struct WheelMouseContext)))) return(NULL); memset(wmc,0,sizeof(struct WheelMouseContext)); wmc->Dispose=WheelMouse_Dispose; wmc->Handle=WheelMouse_Handle; wmc->WindowModeNames=WindowModeNames; wmc->MidButton.ClickModeNames=ClickModeNames; wmc->MidButton.ClickRollModeNames=ClickRollModeNames; wmc->MidButton.DoubleClickModeNames=DoubleClickModeNames; wmc->FourthButton.ClickModeNames=ClickModeNames; wmc->FourthButton.ClickRollModeNames=ClickRollModeNames; wmc->FourthButton.DoubleClickModeNames=DoubleClickModeNames; wmc->MouseSpeedX=wmc->MouseSpeedY=100; wmc->ClickToFront=FALSE; wmc->MainTask=FindTask(NULL); if((wmc->SigBit=AllocSignal(-1))==-1) { wmc->Dispose(wmc); return(NULL); } wmc->Signals=1<SigBit; if(!(wmc->ReplyPort=CreateMsgPort())) { wmc->Dispose(wmc); return(NULL); } if(!(wmc->IOPort=CreateMsgPort())) { wmc->Dispose(wmc); return(NULL); } if(!(wmc->IOReq=(struct IOStdReq *)CreateIORequest(wmc->IOPort,sizeof(struct IOStdReq)))) { wmc->Dispose(wmc); return(NULL); } if(OpenDevice("input.device",0,(struct IORequest *)wmc->IOReq,0)) { DeleteIORequest((struct IORequest *)wmc->IOReq); wmc->IOReq=NULL; wmc->Dispose(wmc); } InputBase=wmc->IOReq->io_Device; wmc->IOReq->io_Command=IND_WRITEEVENT; wmc->IOReq->io_Length=sizeof(struct InputEvent); wmc->IOReq->io_Data=&wmc->Event; return(wmc); } void AddIntAtomic(int *a,int v) { *a+=v; /* Make sure your compiler generates a single instruction for this operation, i.e. add.l d0,(a0), and not move.l (a0),d1 add.l d0,d1 move.l d1,(a0) */ } BOOL WheelMouse_Handle(struct WheelMouseContext *wmc,unsigned long signals) { int distance; if(!(signals&wmc->Signals)) return(TRUE); while(wmc->ScrollX||wmc->ScrollY||wmc->FakeX||wmc->FakeY) { if(distance=wmc->ScrollX) { distance=DoScroll(wmc,FREEHORIZ,distance); AddIntAtomic(&wmc->ScrollX,-distance); } if(distance=wmc->ScrollY) { distance=DoScroll(wmc,FREEHORIZ|FREEVERT,distance); AddIntAtomic(&wmc->ScrollY,-distance); } if(wmc->FakeX<0) { AddIntAtomic(&wmc->FakeX,1); wmc->Event.ie_Class=IECLASS_RAWKEY; wmc->Event.ie_Code=NM_WHEEL_LEFT; wmc->Event.ie_Qualifier=PeekQualifier(); DoIO((struct IORequest *)wmc->IOReq); wmc->Event.ie_Class=IECLASS_NEWMOUSE; wmc->Event.ie_Code=NM_WHEEL_LEFT; wmc->Event.ie_Qualifier=PeekQualifier(); DoIO((struct IORequest *)wmc->IOReq); } if(wmc->FakeX>0) { AddIntAtomic(&wmc->FakeX,-1); wmc->Event.ie_Class=IECLASS_RAWKEY; wmc->Event.ie_Code=NM_WHEEL_RIGHT; wmc->Event.ie_Qualifier=PeekQualifier(); DoIO((struct IORequest *)wmc->IOReq); wmc->Event.ie_Class=IECLASS_NEWMOUSE; wmc->Event.ie_Code=NM_WHEEL_RIGHT; wmc->Event.ie_Qualifier=PeekQualifier(); DoIO((struct IORequest *)wmc->IOReq); } if(wmc->FakeY<0) { AddIntAtomic(&wmc->FakeY,1); wmc->Event.ie_Class=IECLASS_RAWKEY; wmc->Event.ie_Code=NM_WHEEL_UP; wmc->Event.ie_Qualifier=PeekQualifier(); DoIO((struct IORequest *)wmc->IOReq); wmc->Event.ie_Class=IECLASS_NEWMOUSE; wmc->Event.ie_Code=NM_WHEEL_UP; wmc->Event.ie_Qualifier=PeekQualifier(); DoIO((struct IORequest *)wmc->IOReq); } if(wmc->FakeY>0) { AddIntAtomic(&wmc->FakeY,-1); wmc->Event.ie_Class=IECLASS_RAWKEY; wmc->Event.ie_Code=NM_WHEEL_DOWN; wmc->Event.ie_Qualifier=PeekQualifier(); DoIO((struct IORequest *)wmc->IOReq); wmc->Event.ie_Class=IECLASS_NEWMOUSE; wmc->Event.ie_Code=NM_WHEEL_DOWN; wmc->Event.ie_Qualifier=PeekQualifier(); DoIO((struct IORequest *)wmc->IOReq); } } return(TRUE); }