Index: code/sdl/sdl_input.c =================================================================== --- code/sdl/sdl_input.c (révision 1788) +++ code/sdl/sdl_input.c (copie de travail) @@ -50,6 +50,19 @@ #include #endif +#define EVDEV_MOUSE 1 +#ifdef EVDEV_MOUSE +#include + +#include +#include + +// needed for open () +#include +#include +#include +#endif + static cvar_t *in_keyboardDebug = NULL; static SDL_Joystick *stick = NULL; @@ -65,6 +78,12 @@ #endif static cvar_t *in_nograb; +#ifdef EVDEV_MOUSE +static cvar_t *in_mousedevice; +static int evdev_fd = -1; +static pthread_t evdev_thread; +#endif + static cvar_t *in_joystick = NULL; static cvar_t *in_joystickDebug = NULL; static cvar_t *in_joystickThreshold = NULL; @@ -875,13 +894,23 @@ break; case SDL_MOUSEMOTION: - if( mouseActive ) + // evdev input not active when fd = -1 +#ifdef EVDEV_MOUSE + if( mouseActive && evdev_fd == -1) +#else + if( mouseActive) +#endif Com_QueueEvent( 0, SE_MOUSE, e.motion.xrel, e.motion.yrel, 0, NULL ); break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: { +#ifdef EVDEV_MOUSE + // evdev input managing clics too + if (evdev_fd != -1) + break; +#endif unsigned char b; switch( e.button.button ) { @@ -932,6 +961,170 @@ } } +#ifdef EVDEV_MOUSE +void +IN_ListEvdev_f (void) +{ + int fd, i; + char device[64], name[128]; + + Com_Printf( "------- Evdev Input Listing -------\n" ); + + for (i = 0; i < 16; i++) + { + snprintf (device, sizeof(device), "/dev/input/event%i", i); + fd = open (device, O_RDONLY); + + // error = we can't use it so don't bother know the kind of error it is + // the most common error will be that the device doesn't exist + if (fd == -1) + continue; + + name[0] = 0; + ioctl (fd, EVIOCGNAME (sizeof(name)), name); + close (fd); + + Com_Printf ("event%i : %s\n", i, name); + } + Com_Printf( "------- Listing Ended -------\n" ); +} + +void +EvDev_UpdateMouse (void * args) +{ + struct input_event event; + int ret; + + // we want to be stoped immediatly when asked + ret = pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + if (ret) + { + Com_Printf ("pthread_setcanceltype failed with error : %i\n", ret); + } + + Com_Printf ("Starting mouse thread\n"); + + // lets do the work and infinite loop + while (1) + { + ret = read (evdev_fd, &event, sizeof (struct input_event)); + + if (ret == -1) + { + Com_Printf ("read () error : %m\n"); + } + + if (ret < sizeof (struct input_event)) + { + Com_Printf ("read (), couldn't grab all the infos : %m\n"); + } + + // mouse mouvement + if (event.type == EV_REL) + { + switch (event.code) + { + case REL_X: + Com_QueueEvent (0, SE_MOUSE, event.value, 0, 0, NULL); + break; + + case REL_Y: + Com_QueueEvent (0, SE_MOUSE, 0, event.value, 0, NULL); + break; + + // no key release for mouse wheel ? (can't bind +action) + case REL_WHEEL: + switch (event.value) + { + case 1: + Com_QueueEvent (0, SE_KEY, K_MWHEELUP, 1, 0, NULL); + break; + case -1: + Com_QueueEvent (0, SE_KEY, K_MWHEELDOWN, 1, 0, NULL); + break; + } + break; + } + } + else if (event.type == EV_KEY) + { + switch (event.code) + { + case BTN_LEFT: + Com_QueueEvent (0, SE_KEY, K_MOUSE1, event.value, 0, NULL); + break; + case BTN_RIGHT: + Com_QueueEvent (0, SE_KEY, K_MOUSE2, event.value, 0, NULL); + break; + case BTN_MIDDLE: + Com_QueueEvent (0, SE_KEY, K_MOUSE3, event.value, 0, NULL); + break; + case BTN_SIDE: + Com_QueueEvent (0, SE_KEY, K_MOUSE4, event.value, 0, NULL); + break; + case BTN_EXTRA: + Com_QueueEvent (0, SE_KEY, K_MOUSE5, event.value, 0, NULL); + break; + case BTN_FORWARD: + Com_QueueEvent (0, SE_KEY, K_AUX1, event.value, 0, NULL); + break; + case BTN_BACK: + Com_QueueEvent (0, SE_KEY, K_AUX2, event.value, 0, NULL); + break; + case BTN_TASK: + Com_QueueEvent (0, SE_KEY, K_AUX3, event.value, 0, NULL); + break; + } + } + } +} + +int +IN_InitializeEvdevMouse (void) +{ + int everror; + + Com_Printf ("Initializing evdev input : %s\n", in_mousedevice->string); + + evdev_fd = open (in_mousedevice->string, O_RDONLY); + + if (evdev_fd == -1) + { + Com_Printf ("error opening input device : %s - error : %m\n", in_mousedevice->string); + return 0; + } + + everror = pthread_create (&evdev_thread, NULL, (void *)EvDev_UpdateMouse, NULL); + + if (everror) + { + Com_Printf ("thread creation failed with error : %i\n", everror); + return 0; + } + + mouseActive = qtrue; + + return 1; +} +void +IN_EvdevMouseShutdown (void) +{ + if (evdev_fd != -1) + { + int everror; + + Com_Printf ("Stopping Evdev mouse thread\n"); + everror = pthread_cancel (evdev_thread); + if (everror) + { + Com_Printf ("thread_cancel failed with error : %i\n", everror); + } + evdev_fd = -1; + mouseAvailable = qfalse; + } +} +#endif + /* =============== IN_Frame @@ -981,6 +1174,8 @@ void IN_Init( void ) { int appState; + int ret; + int style; if( !SDL_WasInit( SDL_INIT_VIDEO ) ) { @@ -1004,15 +1199,36 @@ in_disablemacosxmouseaccel = Cvar_Get( "in_disablemacosxmouseaccel", "1", CVAR_ARCHIVE ); #endif +#ifdef EVDEV_MOUSE + Cmd_AddCommand ("in_listevdev", IN_ListEvdev_f); + in_mousedevice = Cvar_Get ("in_mousedevice", "", CVAR_ARCHIVE); +#endif + SDL_EnableUNICODE( 1 ); SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); keyRepeatEnabled = qtrue; - if( in_mouse->value ) - { - mouseAvailable = qtrue; - IN_ActivateMouse( ); - } + style = in_mouse->integer; + if (style) + { + mouseAvailable = qtrue; +#ifdef EVDEV_MOUSE + if (style == 2) + { + ret = IN_InitializeEvdevMouse (); + + if (!ret) + { + Com_Printf ("Couldn't initialize Evdev mouse, switching back to SDL mouse\n"); + style == 1; + } + } +#endif + if (style == 1) + { + IN_ActivateMouse (); + } + } else { IN_DeactivateMouse( ); @@ -1037,6 +1253,9 @@ IN_DeactivateMouse( ); mouseAvailable = qfalse; +#ifdef EVDEV_MOUSE + IN_EvdevMouseShutdown (); +#endif IN_ShutdownJoystick( ); } @@ -1048,5 +1267,9 @@ void IN_Restart( void ) { IN_ShutdownJoystick( ); + +#ifdef EVDEV_MOUSE + IN_EvdevMouseShutdown (); +#endif IN_Init( ); }