예제 #1
0
/*
===============
IN_ProcessEvents
===============
*/
static void IN_ProcessEvents( bool dropInput )
{
	SDL_Event  e;
	keyNum_t   key = (keyNum_t) 0;
	static keyNum_t lastKeyDown = (keyNum_t) 0;

	if ( !SDL_WasInit( SDL_INIT_VIDEO ) )
	{
		return;
	}

	while ( SDL_PollEvent( &e ) )
	{
		switch ( e.type )
		{
			case SDL_KEYDOWN:
				if ( !dropInput && ( !e.key.repeat || cls.keyCatchers ) )
				{
					key = IN_TranslateSDLToQ3Key( &e.key.keysym, true );

					if ( key )
					{
						Com_QueueEvent( 0, sysEventType_t::SE_KEY, key, true, 0, nullptr );
					}

					lastKeyDown = key;
				}

				break;

			case SDL_KEYUP:
				if ( !dropInput )
				{
					key = IN_TranslateSDLToQ3Key( &e.key.keysym, false );

					if ( key )
					{
						Com_QueueEvent( 0, sysEventType_t::SE_KEY, key, false, 0, nullptr );
					}

					lastKeyDown = (keyNum_t) 0;
				}

				break;
			case SDL_TEXTINPUT:
				if ( lastKeyDown != K_CONSOLE )
				{
					char *c = e.text.text;

					while ( *c )
					{
						int width = Q_UTF8_Width( c );
						int sc = Q_UTF8_Store( c );
						Com_QueueEvent( 0, sysEventType_t::SE_CHAR, sc, 0, 0, nullptr );
						c += width;
					}
				}
				break;
			case SDL_MOUSEMOTION:
				if ( !dropInput )
				{
					if ( mouse_mode != MouseMode::Deltas )
					{
						Com_QueueEvent( 0, sysEventType_t::SE_MOUSE_POS, e.motion.x, e.motion.y, 0, nullptr );
					}
					else
					{
						Com_QueueEvent( 0, sysEventType_t::SE_MOUSE, e.motion.xrel, e.motion.yrel, 0, nullptr );
#if defined( __linux__ ) || defined( __BSD__ )
						if ( !in_nograb->integer )
						{
							// work around X window managers and edge-based workspace flipping
							// - without this, we get LeaveNotify, no mouse button events, EnterNotify;
							//   we would likely miss some button presses and releases.
							IN_CenterMouse();
						}
#endif
					}
				}
				break;

			case SDL_MOUSEBUTTONDOWN:
			case SDL_MOUSEBUTTONUP:
				if ( !dropInput )
				{
					unsigned char b;

					switch ( e.button.button )
					{
						case SDL_BUTTON_LEFT:
							b = K_MOUSE1;
							break;

						case SDL_BUTTON_MIDDLE:
							b = K_MOUSE3;
							break;

						case SDL_BUTTON_RIGHT:
							b = K_MOUSE2;
							break;
						case SDL_BUTTON_X1:
							b = K_MOUSE4;
							break;

						case SDL_BUTTON_X2:
							b = K_MOUSE5;
							break;

						default:
							b = K_AUX1 + ( e.button.button - ( SDL_BUTTON_X2 + 1 ) ) % 16;
							break;
					}

					Com_QueueEvent( 0, sysEventType_t::SE_KEY, b,
					                ( e.type == SDL_MOUSEBUTTONDOWN ? true : false ), 0, nullptr );
				}
				break;
			case SDL_MOUSEWHEEL:
				// FIXME: mouse wheel support shouldn't use keys!
				if ( e.wheel.y > 0 )
				{
					Com_QueueEvent( 0, sysEventType_t::SE_KEY, K_MWHEELUP, true, 0, nullptr );
					Com_QueueEvent( 0, sysEventType_t::SE_KEY, K_MWHEELUP, false, 0, nullptr );
				}
				else
				{
					Com_QueueEvent( 0, sysEventType_t::SE_KEY, K_MWHEELDOWN, true, 0, nullptr );
					Com_QueueEvent( 0, sysEventType_t::SE_KEY, K_MWHEELDOWN, false, 0, nullptr );
				}
				break;

			case SDL_WINDOWEVENT:
				switch( e.window.event )
				{
					case SDL_WINDOWEVENT_RESIZED:
						{
							char width[32], height[32];
							Com_sprintf( width, sizeof( width ), "%d", e.window.data1 );
							Com_sprintf( height, sizeof( height ), "%d", e.window.data2 );
							Cvar_Set( "r_customwidth", width );
							Cvar_Set( "r_customheight", height );
							Cvar_Set( "r_mode", "-1" );
						}
						break;

					case SDL_WINDOWEVENT_MINIMIZED:    Cvar_SetValue( "com_minimized", 1 ); break;
					case SDL_WINDOWEVENT_RESTORED:
					case SDL_WINDOWEVENT_MAXIMIZED:    Cvar_SetValue( "com_minimized", 0 ); break;
					case SDL_WINDOWEVENT_FOCUS_LOST:   Cvar_SetValue( "com_unfocused", 1 ); break;
					case SDL_WINDOWEVENT_FOCUS_GAINED: Cvar_SetValue( "com_unfocused", 0 ); break;
				}
				break;
			case SDL_QUIT:
				Cmd::ExecuteCommand("quit Closed window");
				break;
			default:
				break;
		}
	}
}
예제 #2
0
/*
===============
IN_ProcessEvents
===============
*/
static void IN_ProcessEvents( qboolean dropInput )
{
	SDL_Event  e;
	keyNum_t   key = (keyNum_t) 0;
	static keyNum_t lastKeyDown = (keyNum_t) 0;

	if ( !SDL_WasInit( SDL_INIT_VIDEO ) )
	{
		return;
	}

#if !SDL_VERSION_ATLEAST( 2, 0, 0 )
	if ( cls.keyCatchers == 0 && keyRepeatEnabled )
	{
		SDL_EnableKeyRepeat( 0, 0 );
		keyRepeatEnabled = qfalse;
	}
	else if ( !keyRepeatEnabled )
	{
		SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY,
		                     SDL_DEFAULT_REPEAT_INTERVAL );
		keyRepeatEnabled = qtrue;
	}
#endif
	while ( SDL_PollEvent( &e ) )
	{
		switch ( e.type )
		{
			case SDL_KEYDOWN:
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
				if ( !dropInput && ( !e.key.repeat || cls.keyCatchers ) )
#else
				if ( !dropInput )
#endif
				{
					key = IN_TranslateSDLToQ3Key( &e.key.keysym, qtrue );

					if ( key )
					{
						Com_QueueEvent( 0, SE_KEY, key, qtrue, 0, NULL );
#if !SDL_VERSION_ATLEAST( 2, 0, 0 )
						if ( key != K_CONSOLE )
						{
							Com_QueueEvent( 0, SE_CHAR, Q_UTF8_Store( Q_UTF8_Encode( e.key.keysym.unicode ) ), 0, 0, NULL );
						}
#endif
					}

					lastKeyDown = key;
				}

				break;

			case SDL_KEYUP:
				if ( !dropInput )
				{
					key = IN_TranslateSDLToQ3Key( &e.key.keysym, qfalse );

					if ( key )
					{
						Com_QueueEvent( 0, SE_KEY, key, qfalse, 0, NULL );
					}

					lastKeyDown = (keyNum_t) 0;
				}

				break;
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
			case SDL_TEXTINPUT:
				if ( lastKeyDown != K_CONSOLE )
				{
					char *c = e.text.text;

					while ( *c )
					{
						int width = Q_UTF8_Width( c );
						int sc = Q_UTF8_Store( c );
						Com_QueueEvent( 0, SE_CHAR, sc, 0, 0, NULL );
						c += width;
					}
				}
				break;
#endif
			case SDL_MOUSEMOTION:
				if ( !dropInput )
				{
					if ( mouseActive )
					{
						Com_QueueEvent( 0, SE_MOUSE, e.motion.xrel, e.motion.yrel, 0, NULL );
#if ( defined( __linux__ ) || defined( __BSD__ ) ) && SDL_VERSION_ATLEAST( 2, 0, 0 )
						{
							// work around X window managers and edge-based workspace flipping
							// - without this, we get LeaveNotify, no mouse button events, EnterNotify;
							//   we would likely miss some button presses and releases.
							int w, h;
							SDL_GetWindowSize( window, &w, &h );
							SDL_WarpMouseInWindow( window, w / 2, h / 2 );
						}
#endif
					}
					else if ( uivm )
					{
						// TODO (after no compatibility needed with alpha 8): remove argument
						int mousepos = VM_Call( uivm, UI_MOUSE_POSITION, 0 );
						int cursorx = mousepos & 0xFFFF;
						int cursory = mousepos >> 16;
						VM_Call( uivm, UI_MOUSE_EVENT, e.motion.x - cursorx, e.motion.y - cursory );
					}
				}
				break;

			case SDL_MOUSEBUTTONDOWN:
			case SDL_MOUSEBUTTONUP:
				if ( !dropInput )
				{
					unsigned char b;

					switch ( e.button.button )
					{
						case SDL_BUTTON_LEFT:
							b = K_MOUSE1;
							break;

						case SDL_BUTTON_MIDDLE:
							b = K_MOUSE3;
							break;

						case SDL_BUTTON_RIGHT:
							b = K_MOUSE2;
							break;
#if !SDL_VERSION_ATLEAST( 2, 0, 0 )
						case SDL_BUTTON_WHEELUP:
							b = K_MWHEELUP;
							break;

						case SDL_BUTTON_WHEELDOWN:
							b = K_MWHEELDOWN;
							break;
#endif
						case SDL_BUTTON_X1:
							b = K_MOUSE4;
							break;

						case SDL_BUTTON_X2:
							b = K_MOUSE5;
							break;

						default:
							b = K_AUX1 + ( e.button.button - ( SDL_BUTTON_X2 + 1 ) ) % 16;
							break;
					}

					Com_QueueEvent( 0, SE_KEY, b,
					                ( e.type == SDL_MOUSEBUTTONDOWN ? qtrue : qfalse ), 0, NULL );
				}
				break;
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
			case SDL_MOUSEWHEEL:
				// FIXME: mouse wheel support shouldn't use keys!
				if ( e.wheel.y > 0 )
				{
					Com_QueueEvent( 0, SE_KEY, K_MWHEELUP, qtrue, 0, NULL );
					Com_QueueEvent( 0, SE_KEY, K_MWHEELUP, qfalse, 0, NULL );
				}
				else
				{
					Com_QueueEvent( 0, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL );
					Com_QueueEvent( 0, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL );
				}
				break;

			case SDL_WINDOWEVENT:
				switch( e.window.event )
				{
					case SDL_WINDOWEVENT_RESIZED:
						{
							char width[32], height[32];
							Com_sprintf( width, sizeof( width ), "%d", e.window.data1 );
							Com_sprintf( height, sizeof( height ), "%d", e.window.data2 );
							Cvar_Set( "r_customwidth", width );
							Cvar_Set( "r_customheight", height );
							Cvar_Set( "r_mode", "-1" );
						}
						break;

					case SDL_WINDOWEVENT_MINIMIZED:    Cvar_SetValue( "com_minimized", 1 ); break;
					case SDL_WINDOWEVENT_RESTORED:
					case SDL_WINDOWEVENT_MAXIMIZED:    Cvar_SetValue( "com_minimized", 0 ); break;
					case SDL_WINDOWEVENT_FOCUS_LOST:   Cvar_SetValue( "com_unfocused", 1 ); break;
					case SDL_WINDOWEVENT_FOCUS_GAINED: Cvar_SetValue( "com_unfocused", 0 ); break;
				}
				break;
#else
			case SDL_VIDEORESIZE:
				{
					char width[32], height[32];
					Com_sprintf( width, sizeof( width ), "%d", e.resize.w );
					Com_sprintf( height, sizeof( height ), "%d", e.resize.h );
					Cvar_Set( "r_customwidth", width );
					Cvar_Set( "r_customheight", height );
					Cvar_Set( "r_mode", "-1" );
				}
				break;
			case SDL_ACTIVEEVENT:
				if ( e.active.state & SDL_APPINPUTFOCUS )
				{
					Cvar_SetValue( "com_unfocused", !e.active.gain );
				}

				if ( e.active.state & SDL_APPACTIVE )
				{
					Cvar_SetValue( "com_minimized", !e.active.gain );
				}
				break;
#endif
			case SDL_QUIT:
				Cmd::ExecuteCommand("quit Closed window");
				break;
			default:
				break;
		}
	}
}