示例#1
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;
			}
		}
	}
}
示例#2
0
static int x11_event(XEvent *ev)
{
	switch (ev->type) {
		/* Graphics related events */
		case ConfigureNotify:
			x11_window_xpos=ev->xconfigure.x;
			x11_window_ypos=ev->xconfigure.y;
			x11_window_width=ev->xconfigure.width;
			x11_window_height=ev->xconfigure.height;
			handle_resize_event(ev->xconfigure.width, ev->xconfigure.height);
			break;
        case NoExpose:
                break;
        case GraphicsExpose:
			expose_rect(ev->xgraphicsexpose.x, ev->xgraphicsexpose.y, ev->xgraphicsexpose.width, ev->xgraphicsexpose.height);
			break;
        case Expose:
			expose_rect(ev->xexpose.x, ev->xexpose.y, ev->xexpose.width, ev->xexpose.height);
			break;

		/* Copy/Paste events */
		case SelectionClear:
			{
				XSelectionClearEvent *req;

				req=&(ev->xselectionclear);
				pthread_mutex_lock(&copybuf_mutex);
				if(req->selection==CONSOLE_CLIPBOARD)
					FREE_AND_NULL(copybuf);
				pthread_mutex_unlock(&copybuf_mutex);
			}
			break;
		case SelectionNotify:
			{
				int format;
				unsigned long len, bytes_left, dummy;
				Atom type;

				if(ev->xselection.selection != CONSOLE_CLIPBOARD)
					break;
				if(ev->xselection.requestor!=win)
					break;
				if(ev->xselection.property) {
					x11.XGetWindowProperty(dpy, win, ev->xselection.property, 0, 0, 0, AnyPropertyType, &type, &format, &len, &bytes_left, (unsigned char **)(&pastebuf));
					if(bytes_left > 0 && format==8)
						x11.XGetWindowProperty(dpy, win, ev->xselection.property,0,bytes_left,0,AnyPropertyType,&type,&format,&len,&dummy,(unsigned char **)&pastebuf);
					else
						pastebuf=NULL;
				}
				else
					pastebuf=NULL;

				/* Set paste buffer */
				sem_post(&pastebuf_set);
				sem_wait(&pastebuf_used);
				x11.XFree(pastebuf);
				pastebuf=NULL;
			}
			break;
		case SelectionRequest:
			{
				XSelectionRequestEvent *req;
				XEvent respond;

				req=&(ev->xselectionrequest);
				pthread_mutex_lock(&copybuf_mutex);
				if(copybuf==NULL) {
					respond.xselection.property=None;
				}
				else {
					if(req->target==XA_STRING) {
						x11.XChangeProperty(dpy, req->requestor, req->property, XA_STRING, 8, PropModeReplace, (unsigned char *)copybuf, strlen(copybuf));
						respond.xselection.property=req->property;
					}
					else
						respond.xselection.property=None;
				}
				respond.xselection.type=SelectionNotify;
				respond.xselection.display=req->display;
				respond.xselection.requestor=req->requestor;
				respond.xselection.selection=req->selection;
				respond.xselection.target=req->target;
				respond.xselection.time=req->time;
				x11.XSendEvent(dpy,req->requestor,0,0,&respond);
				pthread_mutex_unlock(&copybuf_mutex);
			}
			break;

		/* Mouse Events */
		case MotionNotify:
			{
				XMotionEvent *me = (XMotionEvent *)ev;

				me->x/=vstat.scaling;
				me->x/=vstat.charwidth;
				me->y/=vstat.scaling;
				me->y/=vstat.charheight;
				me->x++;
				me->y++;
				if(me->x<1)
					me->x=1;
				if(me->y<1)
					me->y=1;
				if(me->x>vstat.cols)
					me->x=vstat.cols;
				if(me->y>vstat.rows+1)
					me->y=vstat.rows+1;
				ciomouse_gotevent(CIOLIB_MOUSE_MOVE,me->x,me->y);
	    	}
			break;
		case ButtonRelease:
			{
				XButtonEvent *be = (XButtonEvent *)ev;

				be->x/=vstat.scaling;
				be->x/=vstat.charwidth;
				be->y/=vstat.scaling;
				be->y/=vstat.charheight;
				be->x++;
				be->y++;
				if(be->x<1)
					be->x=1;
				if(be->y<1)
					be->y=1;
				if(be->x>vstat.cols)
					be->x=vstat.cols;
				if(be->y>vstat.rows+1)
					be->y=vstat.rows+1;
				if (be->button <= 3) {
					ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(be->button),be->x,be->y);
				}
	    	}
			break;
		case ButtonPress:
			{
				XButtonEvent *be = (XButtonEvent *)ev;

				be->x/=vstat.scaling;
				be->x/=vstat.charwidth;
				be->y/=vstat.scaling;
				be->y/=vstat.charheight;
				be->x++;
				be->y++;
				if(be->x<1)
					be->x=1;
				if(be->y<1)
					be->y=1;
				if(be->x>vstat.cols)
					be->x=vstat.cols;
				if(be->y>vstat.rows+1)
					be->y=vstat.rows+1;
				if (be->button <= 3) {
					ciomouse_gotevent(CIOLIB_BUTTON_PRESS(be->button),be->x,be->y);
				}
	    	}
			break;

		/* Keyboard Events */
		case KeyPress:
			{
				static char buf[128];
				KeySym ks;
				int n;
				int nlock = 0;
				WORD scan = 0xffff;

				n = x11.XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &ks, 0);

				switch (ks) {
				
					case XK_Escape:
						scan = 1;
						goto docode;

					case XK_Tab:
					case XK_ISO_Left_Tab:
						scan = 15;
						goto docode;
			
					case XK_Return:
					case XK_KP_Enter:
						scan = 28;
						goto docode;

					case XK_Print:
						scan = 55;
						goto docode;

					case XK_F1:
					case XK_F2:
					case XK_F3:
					case XK_F4:
					case XK_F5:
					case XK_F6:
					case XK_F7:
					case XK_F8:
					case XK_F9:
					case XK_F10:
						scan = ks - XK_F1 + 59;
						goto docode;

					case XK_KP_7:
						nlock = 1;
					case XK_Home:
					case XK_KP_Home:
						scan = 71;
						goto docode;

					case XK_KP_8:
						nlock = 1;
					case XK_Up:
					case XK_KP_Up:
						scan = 72;
						goto docode;

					case XK_KP_9:
						nlock = 1;
					case XK_Prior:
					case XK_KP_Prior:
						scan = 73;
						goto docode;

					case XK_KP_Subtract:
						scan = 74;
						goto docode;

					case XK_KP_4:
						nlock = 1;
					case XK_Left:
					case XK_KP_Left:
						scan = 75;
						goto docode;

					case XK_KP_5:
						nlock = 1;
					case XK_Begin:
					case XK_KP_Begin:
						scan = 76;
						goto docode;

					case XK_KP_6:
						nlock = 1;
					case XK_Right:
					case XK_KP_Right:
						scan = 77;
						goto docode;

					case XK_KP_Add:
						scan = 78;
						goto docode;

					case XK_KP_1:
						nlock = 1;
					case XK_End:
					case XK_KP_End:
						scan = 79;
						goto docode;

					case XK_KP_2:
						nlock = 1;
					case XK_Down:
					case XK_KP_Down:
						scan = 80;
						goto docode;

					case XK_KP_3:
						nlock = 1;
					case XK_Next:
					case XK_KP_Next:
						scan = 81;
						goto docode;

					case XK_KP_0:
						nlock = 1;
					case XK_Insert:
					case XK_KP_Insert:
						scan = 82;
						goto docode;

					case XK_KP_Decimal:
						nlock = 1;
						scan = 83;
						goto docode;

					case XK_Delete:
					case XK_KP_Delete:
						/* scan = flipdelete ? 14 : 83; */
						scan = 83;
						goto docode;

					case XK_BackSpace:
						/* scan = flipdelete ? 83 : 14; */
						scan = 14;
						goto docode;

					case XK_F11:
						scan = 87;
						goto docode;
					case XK_F12:
						scan = 88;
						goto docode;


					case XK_KP_Divide:
						scan = Ascii2Scan['/'];
						goto docode;

					case XK_KP_Multiply:
						scan = Ascii2Scan['*'];
						goto docode;

					default:
						if (ks < ' ' || ks > '~')
							break;
						scan = Ascii2Scan[ks]; 
						docode:
						if (nlock)
							scan |= 0x100;

						if ((scan & ~0x100) > 88) {
							scan = 0xffff;
							break;
						}

						if (ev->xkey.state & Mod1Mask) {
							scan = ScanCodes[scan & 0xff].alt;
						} else if ((ev->xkey.state & ShiftMask) || (scan & 0x100)) {
							scan = ScanCodes[scan & 0xff].shift;
						} else if (ev->xkey.state & ControlMask) {
							scan = ScanCodes[scan & 0xff].ctrl;
						}  else
							scan = ScanCodes[scan & 0xff].base;

						break;
				}
				if (scan != 0xffff) {
					uint16_t key=scan;
					write(key_pipe[1], &key, (scan&0xff)?1:2);
				}
				return(1);
			}
		default:
			break;
	}
	return(0);
}