/* * Ivy probe * * Copyright (C) 2007 * DGAC / DSNA / DTI / R&D * * Main and only file * * Authors: Benjamin Tissoires * * Please refer to file version.h for the * copyright notice regarding this software */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #if X_DISPLAY_MISSING # error X11 is required to build xtest #else # include # include # include # define XK_MISCELLANY # define XK_XKB_KEYS # include # if HAVE_X11_EXTENSIONS_XTEST_H # include //# 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 } # endif # if HAVE_XKB_EXTENSION # include # endif #endif #include #include #include #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; }