diff options
Diffstat (limited to 'src/ivypointer.c')
-rw-r--r-- | src/ivypointer.c | 242 |
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; +} |