/* usbhotkey: Turn USB keyboard events into X11 keyboard events. */ /* Copyright (C) 2007 Lars Krueger */ /* */ /* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Portions of this code (overlay image) are ported from xteddy-2.0.1. * * The ruby specific code is taken from various tutorials and forum entries * from all over the net. */ #include #include #include #include /* Undef the symbols that may collide with ruby. */ #undef PACKAGE_NAME #undef PACKAGE_VERSION #undef PACKAGE_STRING #undef PACKAGE_TARNAME #include #include #include #include #include "constants.h" /* Uncomment this to enable packet debugging. */ /* #define DEBUG_PACKET */ /*################################# variables ################################*/ /*=========================== HID device interface ===========================*/ /** @name HID device interface * */ /*@{*/ /** Handle for opened Human Interface Device */ static HIDInterface * theHid; /** Set non-zero if ruby script called the "open device" function */ static unsigned theHidIsOpen=0; /** Set by signal handler to quit the program. */ static unsigned thePrgShouldQuit=0; /** Number of the device endpoint. */ static unsigned theEndPoint; /*@}*/ /*=========================== USB keyboard packets ===========================*/ /** @name USB keyboard packets * We hardcode the packet length here, although it is theoretically possible * that a USB keyboard sends other packets. * * Each USB packet consists of a byte indicating the state of the shift, ctrl, * alt, and windows key. The next byte is reserved. * Then 6 bytes follow that hold the the ids of the currently pressed keys. * Such a packet is sent every time a key is pressed or released. */ /*@{*/ /** Number of usable bytes for keycode */ #define thePacketLen 6 /** Storage space for 2 packets: the last one seen and that of the current * event */ static char thePktBuf[2][2+thePacketLen]; /** Points to current packet */ static char * thePacket=thePktBuf[0]; /** Points to packet of last event. */ static char * theLastPacket=thePktBuf[1]; /** The time of the last event. */ static struct timeval theLastTime; /*@}*/ /*====================== ruby variables and callback ids =====================*/ /** @name ruby access * * In order to access ruby from C, we need to store function ids and pointer * to variables. */ /*@{*/ /** Id of the ruby function "UHK_keyup" */ static ID theKeyUpFcn; /** Id of the ruby function "UHK_keydn" */ static ID theKeyDnFcn; /** Id of the ruby function "UHK_mark" */ static ID theMarkFcn=0; /*@}*/ /*==================================== X11 ===================================*/ /** @name X11 * */ /*@{*/ /** X11 server connection */ static Display * the_display=NULL; /** Number of milliseconds to wait after a keypress was sent. */ #define INTERKEY_DELAY 0 /*@}*/ /*############################## infrastructure ##############################*/ /** @name Infrastructure * */ /*@{*/ /** Displays error message and help. */ static void errorHelp( const char * msg) { fprintf( stderr, "usbhotkey: %s\n", msg); fputs( "usbhotkey: Intercept USB keyboard events and send them to X.\n" "USAGE: usbhotkey [OPTIONS]