/* * GRacer * * Copyright (C) 1999 Takashi Matsuda * * 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 #include #include #include #include #include #include "joystick.h" #include #include #define JOYSTICK_INTERVAL 10 static int js_fd = -1; static Tcl_Interp *js_interp; static Tcl_Obj *js_obj; static Tcl_Obj *obj_time; static Tcl_Obj *obj_value; static Tcl_Obj *obj_type; static Tcl_Obj *obj_number; #ifdef ENABLE_LINUX_JOYSTICK #include static void joystick_timer_func (int value) { struct js_event event[256]; int res, num, i; Tcl_Obj *obj; Tcl_Interp *interp; double lf; double sign; const double margin = 0.1; if (!js_obj) return; while ((res = read (js_fd, event, sizeof (event))) > 0) { num = res / sizeof (struct js_event); for (i=0; i margin) { lf = sign * (lf - margin) / (1.0 - margin); } else { lf = 0.0; } Tcl_ObjSetVar2 (interp, obj_value, NULL, Tcl_NewDoubleObj (lf), 0); } Tcl_ObjSetVar2 (interp, obj_type, NULL, Tcl_NewIntObj (event[i].type & ~JS_EVENT_INIT), 0); Tcl_ObjSetVar2 (interp, obj_number, NULL, Tcl_NewIntObj (event[i].number), 0); Tcl_IncrRefCount (obj); if ((res = Tcl_EvalObj (interp, obj)) == TCL_ERROR) fputs (Tcl_GetVar (interp, "errorInfo", TCL_GLOBAL_ONLY), stderr); Tcl_DecrRefCount (obj); if (!js_obj) return; } } if (errno != EAGAIN) { perror (NULL); } glutTimerFunc (JOYSTICK_INTERVAL, joystick_timer_func, -1); } #endif /* ENABLE_LINUX_JOYSTICK */ static int joystick_cmd (ClientData data, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { #ifdef ENABLE_LINUX_JOYSTICK int length; char *str; char *filename; if (objc < 2) { return TCL_ERROR; } str = Tcl_GetStringFromObj (objv[1], NULL); if (!strcmp (str, "open")) { if (objc < 3) { return TCL_ERROR; } filename = Tcl_GetStringFromObj (objv[2], NULL); js_fd = open (filename, O_RDONLY | O_NONBLOCK); if (js_fd == -1) { Tcl_SetObjResult (interp, objv[0]); Tcl_AppendResult (interp, ": can not open joystick device (", sys_errlist[errno], ")", NULL); return TCL_ERROR; } return TCL_OK; } else if (!strcmp (str, "close")) { if (js_fd != 0) close (js_fd); if (js_obj) { Tcl_DecrRefCount (js_obj); js_obj = NULL; } return TCL_OK; } else if (!strcmp (str, "command")) { if (js_fd == -1) { return TCL_ERROR; } if (objc < 3) { return TCL_ERROR; } if (js_obj) { Tcl_DecrRefCount (js_obj); js_obj = NULL; } Tcl_ListObjLength (interp, objv[2], &length); if (length == 0) { return TCL_OK; } js_interp = interp; js_obj = objv[2]; Tcl_IncrRefCount (js_obj); glutTimerFunc (JOYSTICK_INTERVAL, joystick_timer_func, -1); return TCL_OK; } #endif /* ENABLE_LINUX_JOYSTICK */ return TCL_ERROR; } int Joystick_Init (Tcl_Interp *interp) { obj_time = Tcl_NewStringObj ("TIME", 4); obj_value = Tcl_NewStringObj ("VALUE", 5); obj_type = Tcl_NewStringObj ("TYPE", 4); obj_number = Tcl_NewStringObj ("NUMBER", 6); Tcl_CreateObjCommand (interp, "joystick", joystick_cmd, NULL, NULL); return TCL_OK; }