int CIOLIBCALL ciolib_getmouse(struct mouse_event *mevent) { int retval=0; while(!ciolib_mouse_initialized) SLEEP(1); if(listCountNodes(&state.output)) { struct out_mouse_event *out; out=listShiftNode(&state.output); if(out==NULL) return(-1); if(mevent != NULL) { mevent->event=out->event; mevent->bstate=out->bstate; mevent->kbsm=out->kbsm; mevent->startx=out->startx; mevent->starty=out->starty; mevent->endx=out->endx; mevent->endy=out->endy; } free(out); } else { fprintf(stderr,"WARNING: attempt to get a mouse key when none pending!\n"); if(mevent != NULL) memset(mevent,0,sizeof(struct mouse_event)); retval=-1; } return(retval); }
void* DLLCALL msgQueueRead(msg_queue_t* q, long timeout) { link_list_t* list = msgQueueReadList(q); list_wait(list,timeout); return listShiftNode(list); }
int main(int arg, char** argv) { int i; char* p; char str[32]; link_list_t list; listInit(&list,0); for(i=0; i<100; i++) { sprintf(str,"%u",i); listPushNodeString(&list,str); } while((p=listShiftNode(&list))!=NULL) printf("%d %s\n",listCountNodes(&list),p), free(p); /* Yes, this test code leaks heap memory. :-) */ gets(str); 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; } } } }