aboutsummaryrefslogtreecommitdiff
path: root/src/ivypointer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ivypointer.c')
-rw-r--r--src/ivypointer.c242
1 files changed, 242 insertions, 0 deletions
diff --git a/src/ivypointer.c b/src/ivypointer.c
new file mode 100644
index 0000000..fe6e5a8
--- /dev/null
+++ b/src/ivypointer.c
@@ -0,0 +1,242 @@
+/*
+ * Ivy probe
+ *
+ * Copyright (C) 2007
+ * DGAC / DSNA / DTI / R&D
+ *
+ * Main and only file
+ *
+ * Authors: Benjamin Tissoires <tissoire@cena.fr>
+ *
+ * Please refer to file version.h for the
+ * copyright notice regarding this software
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if X_DISPLAY_MISSING
+# error X11 is required to build xtest
+#else
+# include <X11/Xlib.h>
+# include <X11/X.h>
+# include <X11/Xutil.h>
+# define XK_MISCELLANY
+# define XK_XKB_KEYS
+# include <X11/keysymdef.h>
+# if HAVE_X11_EXTENSIONS_XTEST_H
+# include <X11/extensions/XTest.h>
+//# else
+//# error The XTest extension is required to build xtest
+# endif
+# if HAVE_X11_EXTENSIONS_XINERAMA_H
+ // Xinerama.h may lack extern "C" for inclusion by C++
+ extern "C" {
+# include <X11/extensions/Xinerama.h>
+ }
+# endif
+# if HAVE_XKB_EXTENSION
+# include <X11/XKBlib.h>
+# endif
+#endif
+
+#include <Ivy/ivyloop.h>
+#include <Ivy/ivy.h>
+#include <Ivy/version.h>
+
+
+#include "getopt.h"
+
+#define REGEXP_MOVE "^TelepointerMotion Id=(.*) X=(.*) Y=(.*)"
+#define REGEXP_DRAG "^TelepointerDrag Id=(.*) X=(.*) Y=(.*)"
+//#define REGEXP_MOVE "^IvyPointer Move=(.*),(.*)"
+#define REGEXP_REL_MOVE "^TelepointerRelativeMotion Id=(.*) X=(.*) Y=(.*)"
+#define REGEXP_BUTTON "^TelepointerButton Id=(.*) Button=(.*) status=(.*)"
+
+
+Display* display = NULL;
+int width,height;
+
+int dragged = 0;
+
+Display*
+openDisplay(const char* displayName)
+{
+ // get the DISPLAY
+ if (displayName == NULL) {
+ displayName = getenv("DISPLAY");
+ if (displayName == NULL) {
+ displayName = ":0.0";
+ }
+ }
+
+ // open the display
+ printf("XOpenDisplay(\"%s\")\n", displayName);
+ display = XOpenDisplay(displayName);
+ if (display == NULL) {
+ printf("EE : can't open display \"%s\"\n", displayName);
+ return NULL;
+// throw XScreenUnavailable(60.0);
+ }
+
+ // verify the availability of the XTest extension
+ int majorOpcode, firstEvent, firstError;
+#if HAVE_X11_EXTENSIONS_XTEST_H
+ if (!XQueryExtension(display, XTestExtensionName,
+ &majorOpcode, &firstEvent, &firstError)) {
+ printf("XTEST extension not available");
+ XCloseDisplay(display);
+ return NULL;
+ }
+#endif
+#if HAVE_XKB_EXTENSION
+ {
+ m_xkb = false;
+ int major = XkbMajorVersion, minor = XkbMinorVersion;
+ if (XkbLibraryVersion(&major, &minor)) {
+ int opcode, firstError;
+ if (XkbQueryExtension(display, &opcode, &m_xkbEventBase,
+ &firstError, &major, &minor)) {
+ m_xkb = true;
+ XkbSelectEvents(display, XkbUseCoreKbd,
+ XkbMapNotifyMask, XkbMapNotifyMask);
+ XkbSelectEventDetails(display, XkbUseCoreKbd,
+ XkbStateNotifyMask,
+ XkbGroupStateMask, XkbGroupStateMask);
+ }
+ }
+ }
+#endif
+
+ return display;
+}
+
+void
+fakeMouseButton(const unsigned int xButton, Bool press)
+{
+#if HAVE_X11_EXTENSIONS_XTEST_H
+ if (xButton != 0) {
+ XTestFakeButtonEvent(display, xButton, press ? True : False, 0);
+ XFlush(display);
+ }
+#endif
+}
+
+void
+fakeMouseMove(int x, int y)
+{
+ XWarpPointer(display, None, RootWindow(display, 0), 0, 0, 0, 0, x, y);
+ XFlush(display);
+}
+
+void
+fakeMouseRelativeMove(int dx, int dy)
+{
+ XWarpPointer(display, None, None, 0, 0, 0, 0, dx, dy);
+ XFlush(display);
+}
+
+
+void CallbackMove (IvyClientPtr app, void *user_data, int argc, char *argv[]) {
+// printf ("%s sent (size : %d)",IvyGetApplicationName(app),argc);
+// for (i = 0; i < argc; i++)
+// printf(" '%s'",argv[i]);
+ if (dragged){
+ fakeMouseButton(1,0);
+ dragged = 0;
+ }
+ char *id = argv[0];
+ float x = atof(argv[1]);
+ float y = atof(argv[2]);
+// printf("x = %f,y = %f; ",x,y);
+ x = x*width/100.0;
+ y = y*height/100.0;
+// printf("x = %f,y = %f\n",x,y);
+ fakeMouseMove((int)x,(int)y);
+// IvyUnbindMsg(*ptr);
+}
+
+void CallbackDrag (IvyClientPtr app, void *user_data, int argc, char *argv[]) {
+ if (!dragged){
+ fakeMouseButton(1,1);
+ dragged = 1;
+ }
+ char *id = argv[0];
+ float x = atof(argv[1]);
+ float y = atof(argv[2]);
+ x *= width/100.0;
+ y *= height/100.0;
+// printf("x = %f,y = %f\n",x,y);
+ fakeMouseMove((int)x,(int)y);
+}
+
+void CallbackRelMove (IvyClientPtr app, void *user_data, int argc, char *argv[]) {
+ char *id = argv[0];
+ float x = atof(argv[1]);
+ float y = atof(argv[2]);
+ x *= width/100.0;
+ y *= height/100.0;
+ fakeMouseRelativeMove((int)x,(int)y);
+}
+
+void CallbackButton (IvyClientPtr app, void *user_data, int argc, char *argv[]) {
+ char *id = argv[0];
+ int b = atoi(argv[1]);
+ int press = atoi(argv[2]);
+// if (!b)
+// return
+ fakeMouseButton(b,press);
+}
+
+int main(int argc, char *argv[]) {
+ const char* bus = 0;
+ char busbuf [1024] = "";
+ const char* helpmsg =
+ "[options] [regexps]\n\t-b bus\tdefines the Ivy bus to which to connect to, defaults to 127:2010\n"
+ "\t-v\tprints the ivy relase number\n\n"
+ ;
+ int c;
+ while ((c = getopt(argc, argv, "vb:")) != EOF)
+ switch (c) {
+ case 'b':
+ strcpy (busbuf, optarg);
+ bus = busbuf;
+ break;
+ case 'v':
+ printf("ivy c library version %d.%d\n",IVYMAJOR_VERSION,IVYMINOR_VERSION);
+ break;
+ default:
+ printf("usage: %s %s",argv[0],helpmsg);
+ exit(1);
+ }
+ Display* d = openDisplay(NULL);
+ if (!d){
+ return 1;
+ }
+
+ width = DisplayWidth(d, DefaultScreen(d));
+ height = DisplayHeight(d, DefaultScreen(d));
+ printf("screen : %dx%d\n",width,height);
+ MsgRcvPtr ptrMove,ptrRelMove,ptrButton;
+ IvyInit("IvyPointer","IvyPointer Ready",NULL,NULL,NULL,NULL);
+ ptrMove=IvyBindMsg(CallbackMove,&ptrMove,REGEXP_MOVE);
+ printf("bound to %s\n",REGEXP_MOVE);
+ ptrMove=IvyBindMsg(CallbackDrag,&ptrMove,REGEXP_DRAG);
+ printf("bound to %s\n",REGEXP_DRAG);
+ ptrMove=IvyBindMsg(CallbackRelMove,&ptrRelMove,REGEXP_REL_MOVE);
+ printf("bound to %s\n",REGEXP_REL_MOVE);
+ ptrMove=IvyBindMsg(CallbackButton,&ptrButton,REGEXP_BUTTON);
+ printf("bound to %s\n",REGEXP_BUTTON);
+ IvyStart(bus);
+#if (IVYMAJOR_VERSION == 3) && (IVYMINOR_VERSION < 9)
+ IvyMainLoop(NULL, NULL);
+#else
+ IvyMainLoop();
+#endif
+ return 0;
+}