int more_multies(int button, int clicks) { switch(clicks) { case 0: if(mouse_events & (1<<CIOLIB_BUTTON_CLICK(button))) return(1); case 1: if(mouse_events & (1<<CIOLIB_BUTTON_DBL_CLICK(button))) return(1); case 2: if(mouse_events & (1<<CIOLIB_BUTTON_TRPL_CLICK(button))) return(1); case 3: if(mouse_events & (1<<CIOLIB_BUTTON_QUAD_CLICK(button))) return(1); } return(0); }
int CIOLIBCALL more_multies(int button, int clicks) { switch(clicks) { case 0: if(mouse_events & (1<<CIOLIB_BUTTON_CLICK(button))) return(1); /* Fall-through */ case 1: if(mouse_events & (1<<CIOLIB_BUTTON_DBL_CLICK(button))) return(1); /* Fall-through */ case 2: if(mouse_events & (1<<CIOLIB_BUTTON_TRPL_CLICK(button))) return(1); /* Fall-through */ case 3: if(mouse_events & (1<<CIOLIB_BUTTON_QUAD_CLICK(button))) return(1); /* Fall-through */ } return(0); }
void CIOLIBCALL ciolib_mouse_thread(void *data) { int timedout; int timeout_button=0; int but; int delay; clock_t ttime=0; SetThreadName("Mouse"); init_mouse(); while(1) { timedout=0; if(timeout_button) { delay=state.timeout[timeout_button-1]-MSEC_CLOCK(); if(delay<=0) { timedout=1; } else { timedout=!listSemTryWaitBlock(&state.input,delay); } } else { listSemWait(&state.input); } if(timedout) { state.timeout[timeout_button-1]=0; switch(state.button_state[timeout_button-1]) { case MOUSE_SINGLEPRESSED: /* Press event */ add_outevent(CIOLIB_BUTTON_PRESS(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]); break; case MOUSE_CLICKED: /* Click Event */ add_outevent(CIOLIB_BUTTON_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]); break; case MOUSE_DOUBLEPRESSED: /* Click event, then press event */ add_outevent(CIOLIB_BUTTON_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]); add_outevent(CIOLIB_BUTTON_PRESS(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]); break; case MOUSE_DOUBLECLICKED: /* Double-click event */ add_outevent(CIOLIB_BUTTON_DBL_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]); break; case MOUSE_TRIPLEPRESSED: /* Double-click event, then press event */ add_outevent(CIOLIB_BUTTON_DBL_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]); add_outevent(CIOLIB_BUTTON_PRESS(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]); break; case MOUSE_TRIPLECLICKED: /* Triple-click event */ add_outevent(CIOLIB_BUTTON_TRPL_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]); break; case MOUSE_QUADPRESSED: /* Triple-click evetn then press event */ add_outevent(CIOLIB_BUTTON_TRPL_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]); add_outevent(CIOLIB_BUTTON_PRESS(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]); break; case MOUSE_QUADCLICKED: add_outevent(CIOLIB_BUTTON_QUAD_CLICK(timeout_button),state.button_x[timeout_button-1],state.button_y[timeout_button-1]); /* Quad click event (This doesn't need a timeout does it? */ break; } state.button_state[timeout_button-1]=MOUSE_NOSTATE; } else { struct in_mouse_event *in; in=listShiftNode(&state.input); if(in==NULL) { YIELD(); continue; } but=CIOLIB_BUTTON_NUMBER(in->event); switch(CIOLIB_BUTTON_BASE(in->event)) { case CIOLIB_MOUSE_MOVE: if(in->x==state.curx && in->y==state.cury) break; add_outevent(CIOLIB_MOUSE_MOVE,in->x,in->y); for(but=1;but<=3;but++) { switch(state.button_state[but-1]) { case MOUSE_NOSTATE: if(state.buttonstate & CIOLIB_BUTTON(but)) { add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]); add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y); state.button_state[but-1]=MOUSE_DRAGSTARTED; } break; case MOUSE_SINGLEPRESSED: add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]); add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y); state.button_state[but-1]=MOUSE_DRAGSTARTED; break; case MOUSE_CLICKED: add_outevent(CIOLIB_BUTTON_CLICK(but),state.button_x[but-1],state.button_y[but-1]); state.button_state[but-1]=MOUSE_NOSTATE; break; case MOUSE_DOUBLEPRESSED: add_outevent(CIOLIB_BUTTON_CLICK(but),state.button_x[but-1],state.button_y[but-1]); add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]); add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y); state.button_state[but-1]=MOUSE_DRAGSTARTED; break; case MOUSE_DOUBLECLICKED: add_outevent(CIOLIB_BUTTON_DBL_CLICK(but),state.button_x[but-1],state.button_y[but-1]); state.button_state[but-1]=MOUSE_NOSTATE; break; case MOUSE_TRIPLEPRESSED: add_outevent(CIOLIB_BUTTON_DBL_CLICK(but),state.button_x[but-1],state.button_y[but-1]); add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]); add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y); state.button_state[but-1]=MOUSE_DRAGSTARTED; break; case MOUSE_TRIPLECLICKED: add_outevent(CIOLIB_BUTTON_TRPL_CLICK(but),state.button_x[but-1],state.button_y[but-1]); state.button_state[but-1]=MOUSE_NOSTATE; break; case MOUSE_QUADPRESSED: add_outevent(CIOLIB_BUTTON_TRPL_CLICK(but),state.button_x[but-1],state.button_y[but-1]); add_outevent(CIOLIB_BUTTON_DRAG_START(but),state.button_x[but-1],state.button_y[but-1]); add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y); state.button_state[but-1]=MOUSE_DRAGSTARTED; break; case MOUSE_DRAGSTARTED: add_outevent(CIOLIB_BUTTON_DRAG_MOVE(but),in->x,in->y); break; } } break; case CIOLIB_BUTTON_1_PRESS: state.buttonstate|=1<<(but-1); state.knownbuttonstatemask|=1<<(but-1); switch(state.button_state[but-1]) { case MOUSE_NOSTATE: state.button_state[but-1]=MOUSE_SINGLEPRESSED; state.button_x[but-1]=in->x; state.button_y[but-1]=in->y; state.timeout[but-1]=MSEC_CLOCK()+state.click_timeout; if(state.timeout[but-1]==0) state.timeout[but-1]=1; if(state.click_timeout==0) state.timeout[but-1]=0; if(!more_multies(but,0)) { add_outevent(CIOLIB_BUTTON_PRESS(but),state.button_x[but-1],state.button_y[but-1]); state.button_state[but-1]=MOUSE_NOSTATE; state.timeout[but-1]=0; } break; case MOUSE_CLICKED: state.button_state[but-1]=MOUSE_DOUBLEPRESSED; state.timeout[but-1]=MSEC_CLOCK()+state.click_timeout; if(state.timeout[but-1]==0) state.timeout[but-1]=1; if(state.click_timeout==0) state.timeout[but-1]=0; break; case MOUSE_DOUBLECLICKED: state.button_state[but-1]=MOUSE_TRIPLEPRESSED; state.timeout[but-1]=MSEC_CLOCK()+state.click_timeout; if(state.timeout[but-1]==0) state.timeout[but-1]=1; if(state.click_timeout==0) state.timeout[but-1]=0; break; case MOUSE_TRIPLECLICKED: state.button_state[but-1]=MOUSE_QUADPRESSED; state.timeout[but-1]=MSEC_CLOCK()+state.click_timeout; if(state.timeout[but-1]==0) state.timeout[but-1]=1; if(state.click_timeout==0) state.timeout[but-1]=0; break; } break; case CIOLIB_BUTTON_1_RELEASE: state.buttonstate&= ~(1<<(but-1)); state.knownbuttonstatemask|=1<<(but-1); switch(state.button_state[but-1]) { case MOUSE_NOSTATE: state.button_x[but-1]=in->x; state.button_y[but-1]=in->y; add_outevent(CIOLIB_BUTTON_RELEASE(but),state.button_x[but-1],state.button_y[but-1]); break; case MOUSE_SINGLEPRESSED: state.button_state[but-1]=MOUSE_CLICKED; state.timeout[but-1]=more_multies(but,1)?MSEC_CLOCK()+state.multi_timeout:MSEC_CLOCK(); if(state.timeout[but-1]==0) state.timeout[but-1]=1; break; case MOUSE_DOUBLEPRESSED: state.button_state[but-1]=MOUSE_DOUBLECLICKED; state.timeout[but-1]=more_multies(but,2)?MSEC_CLOCK()+state.multi_timeout:MSEC_CLOCK(); if(state.timeout[but-1]==0) state.timeout[but-1]=1; break; case MOUSE_TRIPLEPRESSED: state.button_state[but-1]=MOUSE_TRIPLECLICKED; state.timeout[but-1]=more_multies(but,3)?MSEC_CLOCK()+state.multi_timeout:MSEC_CLOCK(); if(state.timeout[but-1]==0) state.timeout[but-1]=1; break; case MOUSE_QUADPRESSED: state.button_state[but-1]=MOUSE_NOSTATE; add_outevent(CIOLIB_BUTTON_QUAD_CLICK(but),state.button_x[but-1],state.button_y[but-1]); state.timeout[but-1]=0; if(state.timeout[but-1]==0) state.timeout[but-1]=1; break; case MOUSE_DRAGSTARTED: add_outevent(CIOLIB_BUTTON_DRAG_END(but),in->x,in->y); state.button_state[but-1]=0; } } state.curx=in->x; state.cury=in->y; free(in); } timeout_button=0; for(but=1;but<=3;but++) { if(state.button_state[but-1]!=MOUSE_NOSTATE && state.button_state[but-1]!=MOUSE_DRAGSTARTED && state.timeout[but-1]!=0 && (timeout_button==0 || state.timeout[but-1]<ttime)) { ttime=state.timeout[but-1]; timeout_button=but; } } } }