예제 #1
0
static void handle_button(XGenericEventCookie *cookie)
{
	XIDeviceEvent *ev = (XIDeviceEvent *)cookie->data;
	qboolean down = cookie->evtype == XI_ButtonPress;
	int button = ev->detail;
	unsigned time = Sys_XTimeToSysTime(ev->time);
	int k_button;

	if(!mouse_active)
		return;

	switch(button) {
		case 1: k_button = K_MOUSE1; break;
		case 2: k_button = K_MOUSE3; break;
		case 3: k_button = K_MOUSE2; break;
		case 4: k_button = K_MWHEELUP; break;
		case 5: k_button = K_MWHEELDOWN; break;
			/* Switch place of MOUSE4-5 with MOUSE6-7 */
		case 6: k_button = K_MOUSE6; break;
		case 7: k_button = K_MOUSE7; break;
		case 8: k_button = K_MOUSE4; break;
		case 9: k_button = K_MOUSE5; break;
			/* End switch */
		case 10: k_button = K_MOUSE8; break;
		default: return;
	}

	Key_Event(k_button, down, time);
}
예제 #2
0
static void handle_key(XGenericEventCookie *cookie)
{
	XIDeviceEvent *ev = (XIDeviceEvent *)cookie->data;
	qboolean down = cookie->evtype == XI_KeyPress;
	int keycode = ev->detail;
	unsigned time = Sys_XTimeToSysTime(ev->time);

	// Ignore shift_level for game key press
	KeySym keysym = XkbKeycodeToKeysym(x11display.dpy, keycode, 0, 0);
	int key = XLateKey( keysym );

	// Set or clear 1 in the shift_level bitmask
	if ( keysym == XK_Shift_L || keysym == XK_Shift_R )
		shift_level ^=  (-down ^ shift_level) & 1;

	// Set or clear 2 in the shift_level bitmask
	else if( keysym == XK_ISO_Level3_Shift )
		shift_level ^=  (-down ^ shift_level) & 2;

	Key_Event(key, down, time);

	if( down )
	{
		// Use shift_level for chat and console input
		qwchar wc = keysym2ucs(XkbKeycodeToKeysym(x11display.dpy, keycode, 0, shift_level));
		if( wc == -1 && key > K_NUMLOCK && key <= KP_EQUAL )
			wc = ( qwchar )key;

		// Convert ctrl-c / ctrl-v combinations to the expected events
		if( Key_IsDown(K_LCTRL) || Key_IsDown(K_RCTRL) )
		{
			if( key == 'v' )
			{
				key = CTRLV;
				wc = CTRLV;
			}
			else if( key == 'c' )
			{
				key = CTRLC;
				wc = CTRLC;
			}
		}
		Key_CharEvent( key, wc );
	}
}
예제 #3
0
static void HandleEvents( void ) {
	int b;
	int key;
	XEvent event;
	qboolean dowarp = qfalse;
	char *p;
	int dx, dy;
	int t = 0; // default to 0 in case we don't set

	if ( !dpy ) {
		return;
	}

	while ( XPending( dpy ) )
	{
		XNextEvent( dpy, &event );
		switch ( event.type )
		{
		case KeyPress:
			t = Sys_XTimeToSysTime( event.xkey.time );
			p = XLateKey( &event.xkey, &key );
			if ( key ) {
				Sys_QueEvent( t, SE_KEY, key, qtrue, 0, NULL );
			}
			if ( p ) {
				while ( *p )
				{
					Sys_QueEvent( t, SE_CHAR, *p++, 0, 0, NULL );
				}
			}
			break;

		case KeyRelease:
			t = Sys_XTimeToSysTime( event.xkey.time );
			// bk001206 - handle key repeat w/o XAutRepatOn/Off
			//            also: not done if console/menu is active.
			// From Ryan's Fakk2.
			// see game/q_shared.h, KEYCATCH_* . 0 == in 3d game.
			if ( cls.keyCatchers == 0 ) { // FIXME: KEYCATCH_NONE
				if ( repeated_press( &event ) == qtrue ) {
					continue;
				}
			} // if
			XLateKey( &event.xkey, &key );

			Sys_QueEvent( t, SE_KEY, key, qfalse, 0, NULL );
			break;

		case MotionNotify:
			t = Sys_XTimeToSysTime( event.xkey.time );
			if ( mouse_active ) {
				if ( in_dgamouse->value ) {
					if ( abs( event.xmotion.x_root ) > 1 ) {
						mx += event.xmotion.x_root * 2;
					} else {
						mx += event.xmotion.x_root;
					}
					if ( abs( event.xmotion.y_root ) > 1 ) {
						my += event.xmotion.y_root * 2;
					} else {
						my += event.xmotion.y_root;
					}
					if ( t - mouseResetTime > MOUSE_RESET_DELAY ) {
						Sys_QueEvent( t, SE_MOUSE, mx, my, 0, NULL );
					}
					mx = my = 0;
				} else
				{
					// If it's a center motion, we've just returned from our warp
					if ( event.xmotion.x == glConfig.vidWidth / 2 &&
						 event.xmotion.y == glConfig.vidHeight / 2 ) {
						mwx = glConfig.vidWidth / 2;
						mwy = glConfig.vidHeight / 2;
						if ( t - mouseResetTime > MOUSE_RESET_DELAY ) {
							Sys_QueEvent( t, SE_MOUSE, mx, my, 0, NULL );
						}
						mx = my = 0;
						break;
					}

					dx = ( (int)event.xmotion.x - mwx );
					dy = ( (int)event.xmotion.y - mwy );
					if ( abs( dx ) > 1 ) {
						mx += dx * 2;
					} else {
						mx += dx;
					}
					if ( abs( dy ) > 1 ) {
						my += dy * 2;
					} else {
						my += dy;
					}

					mwx = event.xmotion.x;
					mwy = event.xmotion.y;
					dowarp = qtrue;
				}
			}
			break;

		case ButtonPress:
			t = Sys_XTimeToSysTime( event.xkey.time );
			if ( event.xbutton.button == 4 ) {
				Sys_QueEvent( t, SE_KEY, K_MWHEELUP, qtrue, 0, NULL );
			} else if ( event.xbutton.button == 5 ) {
				Sys_QueEvent( t, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL );
			} else
			{
				// NOTE TTimo there seems to be a weird mapping for K_MOUSE1 K_MOUSE2 K_MOUSE3 ..
				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
				}
				;

				Sys_QueEvent( t, SE_KEY, K_MOUSE1 + b, qtrue, 0, NULL );
			}
			break;

		case ButtonRelease:
			t = Sys_XTimeToSysTime( event.xkey.time );
			if ( event.xbutton.button == 4 ) {
				Sys_QueEvent( t, SE_KEY, K_MWHEELUP, qfalse, 0, NULL );
			} else if ( event.xbutton.button == 5 ) {
				Sys_QueEvent( t, SE_KEY, K_MWHEELDOWN, qfalse, 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
				}
				;
				Sys_QueEvent( t, SE_KEY, K_MOUSE1 + b, qfalse, 0, NULL );
			}
			break;

		case CreateNotify:
			win_x = event.xcreatewindow.x;
			win_y = event.xcreatewindow.y;
			break;

		case ConfigureNotify:
			win_x = event.xconfigure.x;
			win_y = event.xconfigure.y;
			break;
		}
	}

	if ( dowarp ) {
		XWarpPointer( dpy,None,win,0,0,0,0,
					  ( glConfig.vidWidth / 2 ),( glConfig.vidHeight / 2 ) );
	}
}
예제 #4
0
static void HandleEvents(void)
{
	int key;
	XEvent event;
	char *p;
	static int dx = 0, dy = 0;
	int t = 0;		// default to 0 in case we don't set

	if (!dpy)
		return;

	while (XPending(dpy)) {
		XNextEvent(dpy, &event);
		switch (event.type) {
		case KeyPress:
			t = Sys_XTimeToSysTime(event.xkey.time);
			p = XLateKey(&event.xkey, &key);
			if (key) {
				Com_QueueEvent(t, SE_KEY, key, qtrue, 0, NULL);
			}
			if (p) {
				while (*p) {
					Com_QueueEvent(t, SE_CHAR, *p++, 0, 0,
						       NULL);
				}
			}
			break;

		case KeyRelease:
			t = Sys_XTimeToSysTime(event.xkey.time);
#if 0
			// bk001206 - handle key repeat w/o XAutRepatOn/Off
			//            also: not done if console/menu is active.
			// From Ryan's Fakk2.
			// see game/q_shared.h, KEYCATCH_* . 0 == in 3d game.  
			if (cls.keyCatchers == 0) {	// FIXME: KEYCATCH_NONE
				if (repeated_press(&event) == qtrue)
					continue;
			}	// if
#endif
			XLateKey(&event.xkey, &key);

			Com_QueueEvent(t, SE_KEY, key, qfalse, 0, NULL);
			break;

		case MotionNotify:
			t = Sys_XTimeToSysTime(event.xkey.time);
			dx = event.xmotion.x;
			dy = event.xmotion.y;
			break;

		case ButtonPress:
		case ButtonRelease:
			t = Sys_XTimeToSysTime(event.xkey.time);
			motionPressed = (qboolean) (event.type == ButtonPress);
			if (Key_GetCatcher() & (KEYCATCH_CGAME | KEYCATCH_UI)) {
				Com_QueueEvent(t, SE_KEY, K_MOUSE1,
					       motionPressed, 0, NULL);
			}
			break;

		case CreateNotify:
			win_x = event.xcreatewindow.x;
			win_y = event.xcreatewindow.y;
			break;

		case ConfigureNotify:
			win_x = event.xconfigure.x;
			win_y = event.xconfigure.y;
			break;
		}
	}

	if (motionPressed) {
		Com_QueueEvent(t, SE_MOUSE, dx, dy, 0, NULL);
	}

	Proximity_HandleEvents();

	Accelerometer_HandleEvents();
}
예제 #5
0
static void HandleEvents( void )
{
	XEvent event;
	qboolean dowarp = qfalse, was_focused = focus;
	int mwx = x11display.win_width / 2;
	int mwy = x11display.win_height / 2;
	char *p;
	int key = 0;
	int time = 0;

	assert( x11display.dpy && x11display.win );

#ifdef WSW_EVDEV
	if( mouse_active && m_evdev_num )
	{
		evdev_read();
	}
	else
#endif
		if( mouse_active && !dgamouse )
		{
			int root_x, root_y, win_x, win_y;
			unsigned int mask;
			Window root, child;

			if( XQueryPointer( x11display.dpy, x11display.win, &root, &child,
				&root_x, &root_y, &win_x, &win_y, &mask ) )
			{
				mx += ( (int)win_x - mwx );
				my += ( (int)win_y - mwy );
				mwx = win_x;
				mwy = win_y;

				if( mx || my )
					dowarp = qtrue;

				if( ignore_one )
				{
					mx = my = 0;
					ignore_one = qfalse;
				}
			}
		}


		while( XPending( x11display.dpy ) )
		{
			XNextEvent( x11display.dpy, &event );

			switch( event.type )
			{
			case KeyPress:
				time = Sys_XTimeToSysTime(event.xkey.time);
				p = XLateKey( &event.xkey, &key );
				if( key )
					Key_Event( key, qtrue, time );
				while ( p && *p )
				{
					qwchar wc = Q_GrabWCharFromUtf8String( (const char **)&p );
					Key_CharEvent( key, wc );
				}
				break;

			case KeyRelease:
				if( repeated_press( &event ) )
					break; // don't send release events when repeating

				time = Sys_XTimeToSysTime(event.xkey.time);
				XLateKey( &event.xkey, &key );
				Key_Event( key, event.type == KeyPress, time );
				break;

			case MotionNotify:
#ifdef WSW_EVDEV
				if( mouse_active && dgamouse && !m_evdev_num )
#else
				if( mouse_active && dgamouse )
#endif
				{
					mx += event.xmotion.x_root;
					my += event.xmotion.y_root;
					if( ignore_one )
					{
						mx = my = 0;
						ignore_one = qfalse;
					}
				}
				break;

			case ButtonPress:
				if( ( cls.key_dest == key_console ) && !in_grabinconsole->integer )
					break;
#ifdef WSW_EVDEV
				if( m_evdev_num )
					break;
#endif
				time = Sys_XTimeToSysTime(event.xkey.time);
				if( event.xbutton.button == 1 ) Key_MouseEvent( K_MOUSE1, 1, time );
				else if( event.xbutton.button == 2 ) Key_MouseEvent( K_MOUSE3, 1, time );
				else if( event.xbutton.button == 3 ) Key_MouseEvent( K_MOUSE2, 1, time );
				else if( event.xbutton.button == 4 ) Key_Event( K_MWHEELUP, 1, time );
				else if( event.xbutton.button == 5 ) Key_Event( K_MWHEELDOWN, 1, time );
				else if( event.xbutton.button >= 6 && event.xbutton.button <= 10 ) Key_MouseEvent( K_MOUSE4+event.xbutton.button-6, 1, time );
				break;

			case ButtonRelease:
				if( ( cls.key_dest == key_console ) && !in_grabinconsole->integer )
					break;
#ifdef WSW_EVDEV
				if( m_evdev_num )
					break;
#endif
				time = Sys_XTimeToSysTime(event.xkey.time);
				if( event.xbutton.button == 1 ) Key_MouseEvent( K_MOUSE1, 0, time );
				else if( event.xbutton.button == 2 ) Key_MouseEvent( K_MOUSE3, 0, time );
				else if( event.xbutton.button == 3 ) Key_MouseEvent( K_MOUSE2, 0, time );
				else if( event.xbutton.button == 4 ) Key_Event( K_MWHEELUP, 0, time );
				else if( event.xbutton.button == 5 ) Key_Event( K_MWHEELDOWN, 0, time );
				else if( event.xbutton.button >= 6 && event.xbutton.button <= 10 ) Key_MouseEvent( K_MOUSE4+event.xbutton.button-6, 0, time );
				break;

			case FocusIn:
				if( x11display.ic )
					XSetICFocus(x11display.ic);
				if( !focus )
				{
					focus = qtrue;
				}
				break;

			case FocusOut:
				if( x11display.ic )
					XUnsetICFocus(x11display.ic);
				if( focus )
				{
					Key_ClearStates();
					focus = qfalse;
				}
				break;

			case ClientMessage:
				if( event.xclient.data.l[0] == x11display.wmDeleteWindow )
					Cbuf_ExecuteText( EXEC_NOW, "quit" );
				break;

			case MapNotify:
				mapped = qtrue;
				if( x11display.modeset )
				{
					if ( x11display.dpy && x11display.win )
					{
						XSetInputFocus( x11display.dpy, x11display.win, RevertToPointerRoot, CurrentTime );
						x11display.modeset = qfalse;
					}
				}
				if( input_active )
				{
					uninstall_grabs();
					install_grabs();
				}
				break;

			case ConfigureNotify:
				VID_AppActivate( qtrue, qfalse );
				break;

			case PropertyNotify:
				if( event.xproperty.window == x11display.win )
				{
					if ( event.xproperty.atom == x11display.wmState )
					{
						qboolean was_minimized = minimized;

						_X11_CheckWMSTATE();

						if( minimized != was_minimized )
						{
							// FIXME: find a better place for this?..
							CL_SoundModule_Activate( !minimized );
						}
					}
				}
				break;
			}
		}

		if( dowarp )
		{
			XWarpPointer( x11display.dpy, None, x11display.win, 0, 0, 0, 0,
				x11display.win_width/2, x11display.win_height/2 );
		}

		// set fullscreen or windowed mode upon focus in/out events if:
		//  a) lost focus in fullscreen -> windowed
		//  b) received focus -> fullscreen if a)
		if( ( focus != was_focused ) )
		{
			if( x11display.features.wmStateFullscreen )
			{
				if( !focus && Cvar_Value( "vid_fullscreen" ) )
				{
					go_fullscreen_on_focus = qtrue;
					Cbuf_ExecuteText( EXEC_APPEND, "vid_fullscreen 0\n" );
				}
				else if( focus && go_fullscreen_on_focus )
				{
					go_fullscreen_on_focus = qfalse;
					Cbuf_ExecuteText( EXEC_APPEND, "vid_fullscreen 1\n" );
				}
			}
		}
}