]> Joshua Wise's Git repositories - xvmouse.git/commitdiff
initial import of xvmouse
authorJoshua Wise <joshua@laminarflow.(none)>
Fri, 20 Jun 2008 19:13:58 +0000 (15:13 -0400)
committerJoshua Wise <joshua@laminarflow.(none)>
Fri, 20 Jun 2008 19:13:58 +0000 (15:13 -0400)
Makefile [new file with mode: 0644]
xvmouse.c [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..965ee6a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,2 @@
+xvmouse: xvmouse.c
+       gcc -o xvmouse xvmouse.c -lm -lX11 /usr/lib/libXtst.so.6
diff --git a/xvmouse.c b/xvmouse.c
new file mode 100644 (file)
index 0000000..44e94d9
--- /dev/null
+++ b/xvmouse.c
@@ -0,0 +1,158 @@
+#include <X11/Xlib.h>
+#include <math.h>
+#include <X11/extensions/XTest.h>
+#include <stdio.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <time.h>
+
+#define STATUS_LEFT 0x01
+#define STATUS_RIGHT 0x02
+#define STATUS_UP 0x04
+#define STATUS_DOWN 0x08
+#define STATUS_MOVING 0xF
+#define STATUS_TAPJUMP 0x100
+#define STATUS_RUNNING 0x80000000
+
+#define MIN(a,b) ({int __a = (a), __b = (b); (__a < __b) ? __a : __b; })
+#define MAX(a,b) ({int __a = (a), __b = (b); (__a > __b) ? __a : __b; })
+
+unsigned long long now()
+{
+       struct timeval tv;
+       gettimeofday(&tv, NULL);
+       return tv.tv_sec*1000000 + tv.tv_usec;
+}
+
+void main()
+{
+       int e;
+       XEvent ev;
+       Display *dpy;
+       int status = 0, dmy;
+       char key = 0, lastkey = 0;
+       unsigned long long lasttime = 0;
+       int repeats = 1;
+       int starttime = 0;
+       
+       dpy = XOpenDisplay(NULL);
+       if (!dpy)
+       {
+               printf("Display open failed; bailing out\n");
+               exit(1);
+       }
+       
+       if (!XTestQueryExtension(dpy, &dmy, &dmy, &dmy, &dmy))
+       {
+               printf("XTest NOT supported\n");
+               exit(1);
+       }
+       
+       printf("Grabbing keyboard...\n");
+       XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("grave")), Mod1Mask, RootWindow(dpy, DefaultScreen(dpy)), True, GrabModeAsync, GrabModeAsync);
+       
+       while (1)
+       {
+               while (XCheckMaskEvent(dpy, 0xFFFFFFFF, &ev))
+               {
+                       switch (ev.type)
+                       {
+                       case KeyPress:
+                       case KeyRelease:
+                       {
+                               XKeyEvent *ke = (XKeyEvent*)&ev;
+                               char *keystr = XKeysymToString(XKeycodeToKeysym(dpy, ke->keycode, 0));
+                               //printf("Key %s: %s\n", ev.type == KeyPress ? "PRESS  " : "RELEASE", keystr);
+                               
+                               if (!strcmp(keystr, "grave")) {
+                                       if (ev.type == KeyPress)
+                                       {
+                                               XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("grave")), AnyModifier, RootWindow(dpy, DefaultScreen(dpy)), True, GrabModeAsync, GrabModeAsync);
+                                               XAutoRepeatOff(dpy);
+                                               status |= STATUS_RUNNING;
+                                       } else {
+                                               XUngrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("grave")), AnyModifier, RootWindow(dpy, DefaultScreen(dpy)));
+                                               XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("grave")), Mod1Mask, RootWindow(dpy, DefaultScreen(dpy)), True, GrabModeAsync, GrabModeAsync);
+                                               XAutoRepeatOn(dpy);
+                                               status &= ~STATUS_RUNNING;
+                                       }
+                               } else if (!strcmp(keystr, "u")) 
+                                       XTestFakeButtonEvent(dpy, 1, ev.type == KeyPress, 0);
+                               else if (!strcmp(keystr, "o"))
+                                       XTestFakeButtonEvent(dpy, 3, ev.type == KeyPress, 0);
+                               else if (!strcmp(keystr, "apostrophe") || !strcmp(keystr, "semicolon")) {
+                                       if (ev.type == KeyPress)
+                                               status |= STATUS_TAPJUMP;
+                                       else
+                                               status &= ~STATUS_TAPJUMP;
+                                       repeats = 1;
+                               } else if (!strcmp(keystr, "j")) {
+                                       if (ev.type == KeyPress)
+                                       {
+                                               status |= STATUS_LEFT;
+                                               if ((lastkey == 'j') && ((now() - lasttime) < 250000) && (status & STATUS_TAPJUMP))
+                                                       XTestFakeRelativeMotionEvent(dpy, -100.0 * pow(repeats++, 0.8), 0, 0);
+                                       } else
+                                               status &= ~STATUS_LEFT;
+                               } else if (!strcmp(keystr, "l")) {
+                                       if (ev.type == KeyPress)
+                                       {
+                                               status |= STATUS_RIGHT;
+                                               if ((lastkey == 'l') && ((now() - lasttime) < 250000) && (status & STATUS_TAPJUMP))
+                                                       XTestFakeRelativeMotionEvent(dpy, 100.0 * pow(repeats++, 0.8), 0, 0);
+                                       } else
+                                               status &= ~STATUS_RIGHT;
+                               } else if (!strcmp(keystr, "i")) {
+                                       if (ev.type == KeyPress)
+                                       {
+                                               status |= STATUS_UP;
+                                               if ((lastkey == 'i') && ((now() - lasttime) < 250000) && (status & STATUS_TAPJUMP))
+                                                       XTestFakeRelativeMotionEvent(dpy, 0, -100.0 * pow(repeats++, 0.8), 0);
+                                       } else
+                                               status &= ~STATUS_UP;
+                               } else if (!strcmp(keystr, "k")) {
+                                       if (ev.type == KeyPress)
+                                       {
+                                               status |= STATUS_DOWN;
+                                               if (lastkey == 'k' && (now() - lasttime) < 250000 && (status & STATUS_TAPJUMP))
+                                                       XTestFakeRelativeMotionEvent(dpy, 0, 100.0 * pow(repeats++, 0.8), 0);
+                                       } else
+                                               status &= ~STATUS_DOWN;
+                               }
+                               if (strlen(keystr) == 1 && ev.type == KeyPress)
+                               {
+                                       lastkey = keystr[0];
+                                       lasttime = now();
+                               } else if (ev.type == KeyPress) {
+                                       lastkey = 0;
+                                       repeats = 0;
+                               }
+                               break;
+                       }
+                       default:
+                               printf("NFI what %d is\n", ev.type);
+                       }
+               }
+               if (!(status & STATUS_RUNNING))
+                       status = 0;
+               if (!(status & STATUS_MOVING))  // if we haven't anything to do, don't sit and suck up cycles
+               {
+                       XPeekEvent(dpy, &ev);
+                       starttime = now();
+               }
+               usleep(20000 - MIN(MAX(pow(13 * (now() - starttime), 0.6), 0), 18000));
+               if (now() - lasttime > 250000)
+                       repeats = 1;
+               if (status & STATUS_LEFT)
+                       XTestFakeRelativeMotionEvent(dpy, -2, 0, 0);
+               if (status & STATUS_RIGHT)
+                       XTestFakeRelativeMotionEvent(dpy, 2, 0, 0);
+               if (status & STATUS_UP)
+                       XTestFakeRelativeMotionEvent(dpy, 0, -2, 0);
+               if (status & STATUS_DOWN)
+                       XTestFakeRelativeMotionEvent(dpy, 0, 2, 0);
+       }
+       
+       
+       exit(0);
+}
\ No newline at end of file
This page took 0.031705 seconds and 4 git commands to generate.