summaryrefslogtreecommitdiff
path: root/source/in_evdev.c
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2007-08-14 20:18:08 +0000
committerAndrey Nazarov <skuller@skuller.net>2007-08-14 20:18:08 +0000
commitf294db4ccf45f6274e65260dd6f9a2c5faa94313 (patch)
treee8cf1ba2bfe9c8417eec17faf912442f52fc4ef2 /source/in_evdev.c
Initial import of the new Q2PRO tree.
Diffstat (limited to 'source/in_evdev.c')
-rw-r--r--source/in_evdev.c227
1 files changed, 227 insertions, 0 deletions
diff --git a/source/in_evdev.c b/source/in_evdev.c
new file mode 100644
index 0000000..a34eabf
--- /dev/null
+++ b/source/in_evdev.c
@@ -0,0 +1,227 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "com_local.h"
+#include "key_public.h"
+#include "in_public.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <linux/input.h>
+#include <errno.h>
+
+#include <SDL.h>
+
+static cvar_t *in_device;
+
+static qboolean mouseinitialized;
+static qboolean mouseactive;
+static int evdev_fd;
+
+#define MAX_EVENTS 64
+#define EVENT_SIZE sizeof( struct input_event )
+
+/*
+===========
+Evdev_SendMouseMoveEvents
+===========
+*/
+static void Evdev_SendMouseMoveEvents( void ) {
+ struct input_event ev[MAX_EVENTS];
+ fd_set fdset;
+ struct timeval timeout;
+ int bytes, count;
+ int dx, dy;
+ int i, button;
+ uint32 time;
+
+ if( !mouseinitialized ) {
+ return;
+ }
+
+ if( !mouseactive ) {
+ return;
+ }
+
+ FD_ZERO( &fdset );
+ FD_SET( evdev_fd, &fdset );
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ if( select( FD_SETSIZE, &fdset, NULL, NULL, &timeout ) == -1 ) {
+ return;
+ }
+
+ if( !FD_ISSET( evdev_fd, &fdset ) ) {
+ return;
+ }
+
+ bytes = read( evdev_fd, ev, EVENT_SIZE * MAX_EVENTS );
+ if( bytes < EVENT_SIZE ) {
+ return;
+ }
+
+ dx = dy = 0;
+ count = bytes / EVENT_SIZE;
+ for( i = 0 ; i < count; i++ ) {
+ time = ev[i].time.tv_sec * 1000 + ev[i].time.tv_usec / 1000;
+ switch( ev[i].type ) {
+ case EV_KEY:
+ if( ev[i].code >= BTN_MOUSE && ev[i].code < BTN_MOUSE + 8 ) {
+ button = K_MOUSE1 + ev[i].code - BTN_MOUSE;
+ if( ev[i].value ) {
+ Key_Event( button, qtrue, time );
+ } else {
+ Key_Event( button, qfalse, time );
+ }
+ }
+ break;
+ case EV_REL:
+ switch( ev[i].code ) {
+ case REL_X:
+ dx += ( int )ev[i].value;
+ break;
+ case REL_Y:
+ dy += ( int )ev[i].value;
+ break;
+ case REL_WHEEL:
+ if( ( int )ev[i].value == 1 ) {
+ Key_Event( K_MWHEELUP, qtrue, time );
+ Key_Event( K_MWHEELUP, qfalse, time );
+ } else if( ( int )ev[i].value == -1 ) {
+ Key_Event( K_MWHEELDOWN, qtrue, time );
+ Key_Event( K_MWHEELDOWN, qfalse, time );
+ }
+ break;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+
+ if( dx || dy ) {
+ CL_MouseEvent( dx, dy );
+ }
+
+}
+
+/*
+===========
+Evdev_ShutdownMouse
+===========
+*/
+static void Evdev_ShutdownMouse( void ) {
+ if( !mouseinitialized ) {
+ return;
+ }
+ close( evdev_fd );
+ mouseinitialized = qfalse;
+ mouseactive = qfalse;
+}
+
+/*
+===========
+Evdev_StartupMouse
+===========
+*/
+static qboolean Evdev_InitMouse( void ) {
+ in_device = Cvar_Get( "in_device", "/dev/input/event2", CVAR_LATCH );
+
+ evdev_fd = open( in_device->string, O_RDONLY );
+
+ if( evdev_fd == -1 ) {
+ Com_EPrintf( "Couldn't open %s: %s\n", in_device->string,
+ strerror( errno ) );
+ return qfalse;
+ }
+
+ fcntl( evdev_fd, F_SETFL, fcntl( evdev_fd, F_GETFL, 0 ) | FNDELAY );
+
+ Com_Printf( "Event interface initialized.\n" );
+ mouseinitialized = qtrue;
+
+ return qtrue;
+}
+
+/*
+===========
+Evdev_ActivateMouse
+
+Called when the main window gains or loses focus.
+The window may have been destroyed and recreated
+between a deactivate and an activate.
+===========
+*/
+static void Evdev_ActivateMouse( qboolean active ) {
+ if( !mouseinitialized ) {
+ return;
+ }
+
+ if( mouseactive == active ) {
+ return;
+ }
+
+#ifdef EVIOCGRAB
+ if( ioctl( evdev_fd, EVIOCGRAB, active ) == -1 ) {
+ Com_EPrintf( "Grab/Release failed: %s\n", strerror( errno ) );
+ }
+#endif // EVIOCGRAB
+
+ if( active ) {
+ struct input_event ev;
+
+ SDL_ShowCursor( SDL_DISABLE );
+
+ while( read( evdev_fd, &ev, EVENT_SIZE ) == EVENT_SIZE )
+ ;
+ } else {
+ SDL_ShowCursor( SDL_ENABLE );
+ }
+
+ mouseactive = active;
+}
+
+/*
+===================
+Evdev_ClearMouseStates
+===================
+*/
+static void Evdev_ClearMouseStates( void ) {
+}
+
+/*
+@@@@@@@@@@@@@@@@@@@
+Evdev_FillAPI
+@@@@@@@@@@@@@@@@@@@
+*/
+void Evdev_FillAPI( inputAPI_t *api ) {
+ api->Init = Evdev_InitMouse;
+ api->Shutdown = Evdev_ShutdownMouse;
+ api->Activate = Evdev_ActivateMouse;
+ api->Frame = Evdev_SendMouseMoveEvents;
+ api->ClearStates = Evdev_ClearMouseStates;
+}
+
+