Exemplo n.º 1
0
/**
 * Intercept a KeyRelease-KeyPress sequence and ignore
 */
static bool Sys_XRepeatPress( XEvent *event ) {
	XEvent	peekevent;
	bool	repeated = false;
	int		lookupRet;
	char	buf[5];
	KeySym	keysym;

	if ( Sys_XPendingInput() ) {
		XPeekEvent( dpy, &peekevent );

		if ((peekevent.type == KeyPress) &&
			(peekevent.xkey.keycode == event->xkey.keycode) &&
			(peekevent.xkey.time == event->xkey.time)) {
			repeated = true;
			XNextEvent( dpy, &peekevent );
			// emit an SE_CHAR for the repeat
			lookupRet = XLookupString( (XKeyEvent*)&peekevent, buf, sizeof(buf), &keysym, NULL );
			if (lookupRet > 0) {
				Posix_QueEvent( SE_CHAR, buf[ 0 ], 0, 0, NULL);
			} else {
				// shouldn't we be doing a release/press in this order rather?
				// ( doesn't work .. but that's what I would have expected to do though )
				Posix_QueEvent( SE_KEY, s_scantokey[peekevent.xkey.keycode], true, 0, NULL);
				Posix_QueEvent( SE_KEY, s_scantokey[peekevent.xkey.keycode], false, 0, NULL);
			}
		}
	}

	return repeated;
}
/*
called during frame loops, pacifier updates etc.
this is only for console input polling and misc mouse grab tasks
the actual mouse and keyboard input is in the Sys_Poll logic
*/
void Sys_GenerateEvents( void ) {
	char *s;
	if ( ( s = Posix_ConsoleInput() ) ) {
		char *b;
		int len;

		len = strlen( s ) + 1;
		b = (char *)Mem_Alloc( len );
		strcpy( b, s );
		Posix_QueEvent( SE_CONSOLE, 0, 0, len, b );
	}
}
Exemplo n.º 3
0
/*
==========================
Posix_PollInput
==========================
*/
void Posix_PollInput() {
	static char buf[16];
	static XEvent event;
	static XKeyEvent *key_event = (XKeyEvent*)&event;
	int lookupRet;
	int b, dx, dy;
	KeySym keysym;

	if ( !dpy ) {
		return;
	}

	// NOTE: Sys_GetEvent only calls when there are no events left
	// but here we pump all X events that have accumulated
	// pump one by one? or use threaded input?
	while ( XPending( dpy ) ) {
		XNextEvent( dpy, &event );
		switch (event.type) {
			case KeyPress:
				#ifdef XEVT_DBG
				if (key_event->keycode > 0x7F)
					common->DPrintf("WARNING: KeyPress keycode > 0x7F");
				#endif
				key_event->keycode &= 0x7F;
				#ifdef XEVT_DBG2
					printf("SE_KEY press %d\n", key_event->keycode);
				#endif
				Posix_QueEvent( SE_KEY, s_scantokey[key_event->keycode], true, 0, NULL);
				lookupRet = XLookupString(key_event, buf, sizeof(buf), &keysym, NULL);
				if (lookupRet > 0) {
					char s = buf[0];
					#ifdef XEVT_DBG
						if (buf[1]!=0)
							common->DPrintf("WARNING: got XLookupString buffer '%s' (%d)\n", buf, strlen(buf));
					#endif
					#ifdef XEVT_DBG2
						printf("SE_CHAR %s\n", buf);
					#endif
					Posix_QueEvent( SE_CHAR, s, 0, 0, NULL);
				}
				if (!Posix_AddKeyboardPollEvent( s_scantokey[key_event->keycode], true ))
					return;
			break;

			case KeyRelease:
				if (Sys_XRepeatPress(&event)) {
					#ifdef XEVT_DBG2
						printf("RepeatPress\n");
					#endif
					continue;
				}
				#ifdef XEVT_DBG
				if (key_event->keycode > 0x7F)
					common->DPrintf("WARNING: KeyRelease keycode > 0x7F");
				#endif
				key_event->keycode &= 0x7F;
				#ifdef XEVT_DBG2
					printf("SE_KEY release %d\n", key_event->keycode);
				#endif
				Posix_QueEvent( SE_KEY, s_scantokey[key_event->keycode], false, 0, NULL);
				if (!Posix_AddKeyboardPollEvent( s_scantokey[key_event->keycode], false ))
					return;
			break;

			case ButtonPress:
				if (event.xbutton.button == 4) {
					Posix_QueEvent( SE_KEY, K_MWHEELUP, true, 0, NULL);
					if (!Posix_AddMousePollEvent( M_DELTAZ, 1 ))
						return;
				} else if (event.xbutton.button == 5) {
					Posix_QueEvent( SE_KEY, K_MWHEELDOWN, true, 0, NULL);
					if (!Posix_AddMousePollEvent( M_DELTAZ, -1 ))
						return;
				} else {
					b = -1;
					if (event.xbutton.button == 1) {
						b = 0;		// K_MOUSE1
					} else if (event.xbutton.button == 2) {
						b = 2;		// K_MOUSE3
					} else if (event.xbutton.button == 3) {
						b = 1;		// K_MOUSE2
					} else if (event.xbutton.button == 6) {
						b = 3;		// K_MOUSE4
					} else if (event.xbutton.button == 7) {
						b = 4;		// K_MOUSE5
					}
					if (b == -1 || b > 4) {
						common->DPrintf("X ButtonPress %d not supported\n", event.xbutton.button);
					} else {
						Posix_QueEvent( SE_KEY, K_MOUSE1 + b, true, 0, NULL);
						if (!Posix_AddMousePollEvent( M_ACTION1 + b, true ))
							return;
					}
				}
			break;

			case ButtonRelease:
				if (event.xbutton.button == 4) {
					Posix_QueEvent( SE_KEY, K_MWHEELUP, false, 0, NULL);
				} else if (event.xbutton.button == 5) {
					Posix_QueEvent( SE_KEY, K_MWHEELDOWN, false, 0, NULL);
				} else {
					b = -1;
					if (event.xbutton.button == 1) {
						b = 0;
					} else if (event.xbutton.button == 2) {
						b = 2;
					} else if (event.xbutton.button == 3) {
						b = 1;
					} else if (event.xbutton.button == 6) {
						b = 3;		// K_MOUSE4
					} else if (event.xbutton.button == 7) {
						b = 4;		// K_MOUSE5
					}
					if (b == -1 || b > 4) {
						common->DPrintf("X ButtonRelease %d not supported\n", event.xbutton.button);
					} else {
						Posix_QueEvent( SE_KEY, K_MOUSE1 + b, false, 0, NULL);
						if (!Posix_AddMousePollEvent( M_ACTION1 + b, false ))
							return;
					}
				}
			break;

			case MotionNotify:
				if (!mouse_active)
					break;
				if (in_dgamouse.GetBool()) {
					dx = event.xmotion.x_root;
					dy = event.xmotion.y_root;

					Posix_QueEvent( SE_MOUSE, dx, dy, 0, NULL);

					// if we overflow here, we'll get a warning, but the delta will be completely processed anyway
					Posix_AddMousePollEvent( M_DELTAX, dx );
					if (!Posix_AddMousePollEvent( M_DELTAY, dy ))
						return;
				} else {
					// if it's a center motion, we've just returned from our warp
					// FIXME: we generate mouse delta on wrap return, but that lags us quite a bit from the initial event..
					if (event.xmotion.x == glConfig.vidWidth / 2 &&
						event.xmotion.y == glConfig.vidHeight / 2) {
						mwx = glConfig.vidWidth / 2;
						mwy = glConfig.vidHeight / 2;

						Posix_QueEvent( SE_MOUSE, mx, my, 0, NULL);

						Posix_AddMousePollEvent( M_DELTAX, mx );
						if (!Posix_AddMousePollEvent( M_DELTAY, my ))
							return;
						mx = my = 0;
						break;
					}

					dx = ((int) event.xmotion.x - mwx);
					dy = ((int) event.xmotion.y - mwy);
					mx += dx;
					my += dy;

					mwx = event.xmotion.x;
					mwy = event.xmotion.y;
					XWarpPointer(dpy,None,win,0,0,0,0, (glConfig.vidWidth/2),(glConfig.vidHeight/2));
				}
			break;
		}
	}
}