@@ 1,164 @@
+#if 0
+# Copyright (c) 2011, Thomas Spurden <thomas@spurden.name>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# Generate key press/release events from joystick button press/release events.
+
+# This file can be read by either GNU Make or a C99 compiler.
+# Easy way to compile is: make -f thisfile output
+# Which will produce a binary called output.
+
+# Dependencies: X11 with XTest extension and SDL.
+
+! := $(lastword $(MAKEFILE_LIST))
+%: $!
+ $(CC) -pedantic -Wall -O2 -std=c99 -lX11 -lXtst -lSDL -o $@ -xc $!
+
+define program
+#endif
+
+// If set, print each joystick button event to stdout.
+#define VERBOSE (1)
+
+// Choose your joystick index.
+#define JoyIndex 0
+
+// List the buttons in order (see jstest output) and the X11 keysym you want to
+// be generated by it (or zero for no keysym). To work out your buttons just
+// compile with verbose on; each button press will be printed to stdout.
+#define KEYS \
+ KEY(Select, XK_a), \
+ KEY(LClick, 0), \
+ KEY(RClick, 0), \
+ KEY(Start, XK_Escape), \
+ KEY(Up, XK_Up), \
+ KEY(Right, XK_Right), \
+ KEY(Down, XK_Down), \
+ KEY(Left, XK_Left), \
+ KEY(L2, 0), \
+ KEY(R2, 0), \
+ KEY(L1, 0), \
+ KEY(R1, 0), \
+ KEY(Triangle, 0), \
+ KEY(Circle, 0), \
+ KEY(Cross, XK_space), \
+ KEY(Square, XK_Shift_L), \
+ KEY(PS, 0)
+
+// Actual program now
+#include <SDL/SDL.h>
+#include <SDL/SDL_joystick.h>
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include <X11/XF86keysym.h>
+#include <X11/extensions/XTest.h>
+
+#define KEY(k,x) Key_ ## k
+enum Key {
+ KEYS,
+ Keys_Num
+};
+#undef KEY
+
+#define KEY(k,x) [Key_ ## k] = x
+static int const buttonMap[Keys_Num] = {
+ KEYS
+};
+#undef KEY
+
+#if VERBOSE
+#define KEY(k,x) { .button = #k, .key = #x }
+struct {
+ char const* button;
+ char const* key;
+} mapNames[Keys_Num] = {
+ KEYS
+};
+#undef KEY
+#endif
+
+Display* dpy = NULL;
+SDL_Joystick* input = NULL;
+
+void die(char const* str) {
+ fprintf(stderr, "Exited: %s: %s\n", str, SDL_GetError());
+ exit(1);
+}
+
+void cleanup() {
+ if(dpy) XCloseDisplay(dpy);
+ if(input) SDL_JoystickClose(input);
+ SDL_Quit();
+}
+
+int main()
+{
+ SDL_Event ev;
+
+ if(SDL_Init(SDL_INIT_JOYSTICK|SDL_INIT_VIDEO) < 0) die("SDL_Init failed");
+ atexit(cleanup);
+
+ if(SDL_JoystickEventState(SDL_ENABLE) == -1)
+ die("Could not set joystick events to be queued");
+
+ if((dpy = XOpenDisplay(0)) == NULL)
+ die("Could not open X display");
+
+ if((input = SDL_JoystickOpen(JoyIndex)) == NULL)
+ die("Could not open joystick");
+#if VERBOSE
+ printf(
+ "Joystick %i: %s; %i axes, %i buttons, %i hats, %i balls\n",
+ JoyIndex,
+ SDL_JoystickName(JoyIndex),
+ SDL_JoystickNumAxes(input),
+ SDL_JoystickNumButtons(input),
+ SDL_JoystickNumHats(input),
+ SDL_JoystickNumBalls(input)
+ );
+#endif
+
+ while(SDL_WaitEvent(&ev)) {
+ if(ev.type == SDL_QUIT) die("Quit");
+
+ if(ev.type == SDL_JOYBUTTONDOWN || ev.type == SDL_JOYBUTTONUP) {
+ int const n = ev.jbutton.button;
+ if(n < Keys_Num && buttonMap[n]) {
+#if VERBOSE
+ printf(
+ "%s %s => %s\n",
+ mapNames[n].button,
+ ev.type == SDL_JOYBUTTONDOWN? "down" : "up",
+ mapNames[n].key
+ );
+#endif
+ XTestFakeKeyEvent(
+ dpy,
+ XKeysymToKeycode(dpy, buttonMap[n]),
+ ev.type == SDL_JOYBUTTONDOWN,
+ CurrentTime
+ );
+ XFlush(dpy);
+ XSync(dpy, False);
+ }
+#if VERBOSE
+ printf("Unmapped button %i pressed\n", n);
+#endif
+ }
+ }
+}
+
+#if 0
+endef
+#endif