From cb3f991754d20ee1e433687c494c969335bdbee8 Mon Sep 17 00:00:00 2001 From: tissoire Date: Fri, 25 Sep 2009 09:33:54 +0000 Subject: Modifications ivypointer : * suppression callback input geometry * suppression switch relative/absolute par defaut * suppression gestion bouton 1 par pression si absolute * menage * filtrage evenements si en dehors de la zone active * ajout callback lock/unlock --- src/ivypointer.c | 376 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 197 insertions(+), 179 deletions(-) (limited to 'src/ivypointer.c') diff --git a/src/ivypointer.c b/src/ivypointer.c index e536888..85fb017 100644 --- a/src/ivypointer.c +++ b/src/ivypointer.c @@ -62,48 +62,71 @@ #include "getopt.h" -#define REGEXP_CHANGE_GEOMETRY_INPUT "^geometry_event device_id=%s x0=(.*) y0=(.*) x1=(.*) y1=(.*)" #define REGEXP_CHANGE_GEOMETRY_SCREEN "^screen_geometry_event device_id=%s x0=(.*) y0=(.*) x1=(.*) y1=(.*)" +#define REGEXP_LOCK_UNLOCK "^lock_event device_id=%s status=(lock|unlock)" #define REGEXP_MOVE "^TelepointerMotion Id=%s X=(.*) Y=(.*)" #define REGEXP_DRAG "^TelepointerDrag Id=%s X=(.*) Y=(.*)" #define REGEXP_REL_MOVE "^TelepointerRelativeMotion Id=%s X=(.*) Y=(.*)" #define REGEXP_BUTTON "^TelepointerButton Id=%s Button=(.*) status=(.*)" +#define CHAMP_X_TELEPOINTEUR 1 +#define CHAMP_Y_TELEPOINTEUR 2 + #define REGEXP_POINTER "^pointer_event device_id=%s x=(.*) y=(.*) presure=(.*) tilt_x=(.*) tilt_y=(.*) wheel=(.*) predicted_x=(.*) predicted_y=(.*) type=(.*) serial_number=(.*) time=(.*) hires_x=(.*) hires_y=(.*) proximity=(.*)" #define REGEXP_PAD "^pad_event device_id=%s button=(.*) status=(.*) time=(.*)" #define REGEXP_SLIDER "^slider_event device_id=%s value=(.*) side=(.*) time=(.*)" #define REGEXP_BUTTON_WACOM "^button_event device_id=%s button=(.*) status=(.*) x=(.*) y=(.*) presure=(.*) tilt_x=(.*) tilt_y=(.*) wheel=(.*) predicted_x=(.*) predicted_y=(.*) type=(.*) serial_number=(.*) time=(.*) hires_x=(.*) hires_y=(.*) proximity=(.*)" - -#define WIDTH_WACOM 1600.0 -#define HEIGHT_WACOM 1200.0 -//#define WIDTH_WACOM 1.0 -//#define HEIGHT_WACOM 1.0 +#define CHAMP_X_WACOM 12 +#define CHAMP_Y_WACOM 13 + +#define CHAMP_X_WACOM_BUTTON 14 +#define CHAMP_Y_WACOM_BUTTON 15 + +#define CHAMP_X_WACOM_PREDICTIVE 7 +#define CHAMP_Y_WACOM_PREDICTIVE 8 + +#define CHAMP_X_WACOM_PREDICTIVE_BUTTON 9 +#define CHAMP_Y_WACOM_PREDICTIVE_BUTTON 10 + #define TIME_CLICK 200 #define TIME_BETWEEN_CLICK 200 -Display* display = NULL; + +static void printHelpMsg(const char *name); + +static Display* display = NULL; #ifdef _MPX_ -XDevice* dev = NULL; +static XDevice* dev = NULL; //#else //# error plop #endif -float width,height; -float coords_input[4] = {0.0,0.0,100.0,100.0}; -float width_input,height_input, offsetx, offsety; +static float width,height; +static float coords_input[4] = {0.0,0.0,100.0,100.0}; +static float width_input,height_input, offsetx, offsety; +static float horiz_ratio; // width / width_input +static float vert_ratio; // height / height_input + +static int dragged = 0; +static int relative = 0; +static int switch_mode = 0; -int dragged = 0; -int relative = 0; +static int locked = 0; -//int champX = 1; -//int champY = 2; -int champX = 12; -int champY = 13; +static int predictive_mode = 0; -int device_input_id_given = 0; +static int champX; +static int champY; +static int champXButton; +static int champYButton; -Display* +static float old_x = 0; +static float old_y = 0; + +static int device_input_id_given = 0; + +static Display* openDisplay(const char* displayName) { // get the DISPLAY @@ -154,43 +177,25 @@ openDisplay(const char* displayName) return display; } -XDevice *openDevice(Display * dpy, int id){ +#ifdef _MPX_ +static XDevice *openDevice(Display * dpy, int id){ return XOpenDevice(dpy, id); } +#endif // -------------------------------------------------------------------------- // tools // -------------------------------------------------------------------------- -void print_coords_input(void){ - printf("coords of input : %.2f,%.2f %.2f,%.2f\n", coords_input[0], coords_input[1], coords_input[2], coords_input[3]); -} - -int valid(float x, float y) { - if (xcoords_input[2]) { -// printf("x > x1\n"); - return 0; - } - if (ycoords_input[3]){ -// printf("y < y1\n"); - return 0; - } - return 1; +static int valid(float x, float y) { + return !locked && x>=coords_input[0] && x<=coords_input[2] && y>=coords_input[1] && y<=coords_input[3]; } // -------------------------------------------------------------------------- // X11 functions // -------------------------------------------------------------------------- -void +static void fakeMouseButton(const unsigned int xButton, Bool press, int x, int y) { if (xButton != 0) { @@ -204,7 +209,7 @@ fakeMouseButton(const unsigned int xButton, Bool press, int x, int y) } } -void +static void fakeMouseMove(int x, int y) { // printf("x = %d,y = %d;\n ",x,y); @@ -218,7 +223,7 @@ fakeMouseMove(int x, int y) XFlush(display); } -void +static void fakeMouseRelativeMove(int dx, int dy) { #ifndef _MPX_ @@ -234,26 +239,8 @@ fakeMouseRelativeMove(int dx, int dy) // -------------------------------------------------------------------------- // Geometry callback // -------------------------------------------------------------------------- -void CallbackGeometry(IvyClientPtr app, void *user_data, int argc, char *argv[]) { -// char *id = argv[0]; - float x0 = atof(argv[1-device_input_id_given]); - float y0 = atof(argv[2-device_input_id_given]); - float x1 = atof(argv[3-device_input_id_given]); - float y1 = atof(argv[4-device_input_id_given]); - if (x1 > x0 && y1 > y0 ){ - coords_input[0] = x0; - coords_input[1] = y0; - coords_input[2] = x1; - coords_input[3] = y1; - width_input = coords_input[2]-coords_input[0]; - height_input = coords_input[3]-coords_input[1]; - print_coords_input(); - } else { - printf("bad coords received : %.0f,%.0f %.0f,%.0f\n",x0,y0,x1,y1); - } -} -void CallbackScreen(IvyClientPtr app, void *user_data, int argc, char *argv[]) { +static void CallbackScreen(IvyClientPtr app, void *user_data, int argc, char *argv[]) { // char *id = argv[0]; float x0 = atof(argv[1-device_input_id_given]); float y0 = atof(argv[2-device_input_id_given]); @@ -264,6 +251,8 @@ void CallbackScreen(IvyClientPtr app, void *user_data, int argc, char *argv[]) { offsety = y0; width = x1-x0; height = y1-y0; + horiz_ratio = width / width_input; + vert_ratio = height / height_input; printf("screen : %f+%f x %f+%f\n",offsetx,width,offsety,height); } else { printf("bad coords received : %.2f,%.2f %.2f,%.2f\n",x0,y0,x1,y1); @@ -271,61 +260,75 @@ void CallbackScreen(IvyClientPtr app, void *user_data, int argc, char *argv[]) { } // -------------------------------------------------------------------------- +// Lock/Unlock callback +// -------------------------------------------------------------------------- + +static void CallbackLockUnlock(IvyClientPtr app, void *user_data, int argc, char *argv[]) { + locked = strcmp(argv[1-device_input_id_given],"lock"); +} + +// -------------------------------------------------------------------------- // Telepointer callbacks // -------------------------------------------------------------------------- -void CallbackMove (IvyClientPtr app, void *user_data, int argc, char *argv[]) { +static 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]); - float x = atof(argv[1-device_input_id_given]); - float y = atof(argv[2-device_input_id_given]); - x = x*width/100.0; - y = y*height/100.0; -// char *id = argv[0]; -// printf("x = %f,y = %f; ",x,y); + float x = atof(argv[champX]); + float y = atof(argv[champY]); + if (!valid(x,y)){ + // ignore outside events + return; + } + x = offsetx + x * horiz_ratio; + y = offsety + y * vert_ratio; // printf("x = %f,y = %f\n",x,y); - if (valid(x,y)){ - fakeMouseMove((int)x,(int)y); - if (dragged){ - fakeMouseButton(1,0,x,y); - dragged = 0; - } - } + old_x = x; + old_y = y; + fakeMouseMove((int)x,(int)y); + if (dragged){ + fakeMouseButton(1,0,x,y); + dragged = 0; + } } -void CallbackDrag (IvyClientPtr app, void *user_data, int argc, char *argv[]) { +static void CallbackDrag (IvyClientPtr app, void *user_data, int argc, char *argv[]) { // char *id = argv[0]; - float x = atof(argv[1-device_input_id_given]); - float y = atof(argv[2-device_input_id_given]); - x *= width/100.0; - y *= height/100.0; + float x = atof(argv[champX]); + float y = atof(argv[champY]); + if (!valid(x,y)){ + // ignore outside events + return; + } + x = offsetx + x * horiz_ratio; + y = offsety + y * vert_ratio; // printf("x = %f,y = %f\n",x,y); - if (valid(x,y)){ - fakeMouseMove((int)x,(int)y); - if (!dragged){ - fakeMouseButton(1,1,x,y); - dragged = 1; - } - } + old_x = x; + old_y = y; + fakeMouseMove((int)x,(int)y); + if (!dragged){ + fakeMouseButton(1,1,x,y); + dragged = 1; + } } -void CallbackRelMove (IvyClientPtr app, void *user_data, int argc, char *argv[]) { +static void CallbackRelMove (IvyClientPtr app, void *user_data, int argc, char *argv[]) { // char *id = argv[0]; - float x = atof(argv[1-device_input_id_given]); - float y = atof(argv[2-device_input_id_given]); - x *= width/100.0; - y *= height/100.0; - fakeMouseRelativeMove((int)x,(int)y); + float dx = atof(argv[1-device_input_id_given]); + float dy = atof(argv[2-device_input_id_given]); + fakeMouseRelativeMove((int)dx,(int)dy); } -void CallbackButton (IvyClientPtr app, void *user_data, int argc, char *argv[]) { +static void CallbackButton (IvyClientPtr app, void *user_data, int argc, char *argv[]) { // char *id = argv[0]; int b = atoi(argv[1-device_input_id_given]); int press = atoi(argv[2-device_input_id_given]); -// if (!b) -// return + if (!valid(old_x,old_y)){ + // ignore outside events + return; + } fakeMouseButton(b,press,0,0); } @@ -333,14 +336,12 @@ void CallbackButton (IvyClientPtr app, void *user_data, int argc, char *argv[]) // Wacom callbacks // -------------------------------------------------------------------------- -void CallbackPointer (IvyClientPtr app, void *user_data, int argc, char *argv[]) { +static void CallbackPointer (IvyClientPtr app, void *user_data, int argc, char *argv[]) { // char *id = argv[0]; float x = atof(argv[champX]); // predicted position float y = atof(argv[champY]); // predicted position int time = atoi(argv[11-device_input_id_given]); int presure = atoi(argv[3-device_input_id_given]); - static float old_x = 0; - static float old_y = 0; static int old_time = 0; static int should_click = 0; static int clicked = 0; @@ -348,18 +349,16 @@ void CallbackPointer (IvyClientPtr app, void *user_data, int argc, char *argv[]) // ignore outside events return; } -// printf("x = %f,y = %f;\n ",x,y); - x = offsetx + (x-coords_input[0])*width/width_input; - y = offsety + (y-coords_input[1])*height/height_input; - + + if (!predictive_mode) { + // in predictive mode, we don't allow the geometry to be changed + x = offsetx + x * horiz_ratio; + y = offsety + y * vert_ratio; + } if (!relative) { //absolute mode fakeMouseMove((int)x,(int)y); - if (!dragged && presure>0){ - fakeMouseButton(1,1,x,y); - dragged = 1; - } } else { //relative mode int dx = (int)(x-old_x); @@ -416,8 +415,11 @@ void CallbackPointer (IvyClientPtr app, void *user_data, int argc, char *argv[]) old_y = y; } -void CallbackPad (IvyClientPtr app, void *user_data, int argc, char *argv[]) { -// char *id = argv[0]; +static void CallbackPad (IvyClientPtr app, void *user_data, int argc, char *argv[]) { + if (!valid(old_x,old_y)){ + // ignore outside events + return; + } int b = atoi(argv[1-device_input_id_given]); int press = 0; // if (!b) @@ -426,7 +428,7 @@ void CallbackPad (IvyClientPtr app, void *user_data, int argc, char *argv[]) { press = 1; } // printf("Pad button=%d pressed%d event received\n",b, press); - if (b==11 || b==15 || (press && (b==12 || b==16))){ + if (switch_mode && (b==11 || b==15 || (press && (b==12 || b==16)))){ //inversion du mode relative = !relative; } else { @@ -434,7 +436,7 @@ void CallbackPad (IvyClientPtr app, void *user_data, int argc, char *argv[]) { } } -void CallbackSlider (IvyClientPtr app, void *user_data, int argc, char *argv[]) { +static void CallbackSlider (IvyClientPtr app, void *user_data, int argc, char *argv[]) { //TODO // char *id = argv[0]; // int b = atoi(argv[1]); @@ -444,31 +446,23 @@ void CallbackSlider (IvyClientPtr app, void *user_data, int argc, char *argv[]) // fakeMouseButton(b,press); } -void CallbackButtonWacom (IvyClientPtr app, void *user_data, int argc, char *argv[]) { +static void CallbackButtonWacom (IvyClientPtr app, void *user_data, int argc, char *argv[]) { // char *id = argv[0]; int b = atoi(argv[1-device_input_id_given]); - if (b == 1) // gestion propre du bouton 1 + if (b == 1 && relative) // gestion propre du bouton 1 return; int press = strcmp(argv[2-device_input_id_given],"up"); + float x = atof(argv[champXButton]); + float y = atof(argv[champYButton]); + if (!valid(x,y)){ + // ignore outside events + return; + } + fakeMouseButton(b,press,0,0); } - -void printHelpMsg(const char *name){ - const char* helpmsg = - "[options] [regexps]\n\t-b bus\t\tdefines the Ivy bus to which to connect to, defaults to 127:2010\n" - "\t-t\t\tuse data from ModeManager instead of xinput_wacom\n" - "\t-c x0,y0,x1,y1\tspecify the coords of the input used (only used with wacom)\n" - "\t-C x0,y0,x1,y1\tspecify the coords of the screen used\n" - "\t-d device\tuse \"device\" as the source of the events\n" - "\t-r\tuse relative mode by default\n" - "\t-p\tuse predictive mode\n" - "\t-v\t\tprints the ivy relase number\n\n" - ; - printf("usage: %s %s",name,helpmsg); -} - -int extractValues(char optarg[], float* output, const char name[]){ +static int extractValues(char optarg[], float* output, const char name[]){ int i = 0; int j = 0; int last = 0; @@ -501,6 +495,20 @@ int extractValues(char optarg[], float* output, const char name[]){ return 1; } +static void printHelpMsg(const char *name){ + const char* helpmsg = + "[options] [regexps]\n\t-b bus\t\tdefines the Ivy bus to which to connect to, defaults to 127:2010\n" + "\t-t\t\tuse data from ModeManager instead of xinput_wacom\n" + "\t-C x0,y0,x1,y1\tspecify the coords of the screen used\n" + "\t-d device\tuse \"device\" as the source of the events\n" + "\t-r\tuse relative mode by default\n" + "\t-s\tenable the ability to dynamically switch between relative and absolute\n" + "\t-p\tuse predictive mode (disable geometry)\n" + "\t-v\t\tprints the ivy relase number\n\n" + ; + printf("usage: %s %s",name,helpmsg); +} + // -------------------------------------------------------------------------- // Main // -------------------------------------------------------------------------- @@ -510,14 +518,11 @@ int main(int argc, char *argv[]) { char busbuf [1024] = ""; char device_input_id [1024] = "(.*)"; int wacom = 1; - int predictive_mode = 0; - float user_coordsI = 0; float user_coordsO = 0; - float coordsI[4] = {0,0,0,0}; float coordsO[4] = {0,0,0,0}; int c; int id = -1; - while ((c = getopt(argc, argv, "vb:td:c:C:rpi:")) != EOF) + while ((c = getopt(argc, argv, "vb:td:C:rpi:s")) != EOF) switch (c) { case 'b': strcpy (busbuf, optarg); @@ -537,19 +542,17 @@ int main(int argc, char *argv[]) { wacom = 0; break; case 'p': - champX = 7; - champY = 8; predictive_mode = 1; break; - case 'c': - user_coordsI = extractValues(optarg, coordsI, argv[0]); - break; case 'C': user_coordsO = extractValues(optarg, coordsO, argv[0]); break; case 'i': id = atoi(optarg); break; + case 's': + switch_mode = 1; + break; default: printf("bad option : %s\n",(char*)&c); printHelpMsg(argv[0]); @@ -563,35 +566,13 @@ int main(int argc, char *argv[]) { if (id >=0){ printf("opening device id=%d\n",id); dev = openDevice(d,id); - if (!dev) { - printf("unable to open device id=%d\n",id); - } + if (!dev) { + printf("unable to open device id=%d\n",id); + } } #endif - if (wacom) { - if (user_coordsI){ - int i; - for (i=0;i<4;i++) { - coords_input[i] = coordsI[i]; - } - } else { - if (predictive_mode){ - coords_input[2] = WIDTH_WACOM; - coords_input[3] = HEIGHT_WACOM; - } else { - coords_input[2] = 1.0; - coords_input[3] = 1.0; - } - } - print_coords_input(); - width_input = coords_input[2]-coords_input[0]; - height_input = coords_input[3]-coords_input[1]; - champX -= device_input_id_given; - champY -= device_input_id_given; - } - - if (user_coordsO){ + if (!predictive_mode && user_coordsO){ offsetx = coordsO[0]; offsety = coordsO[1]; width = coordsO[2]-coordsO[0]; @@ -602,18 +583,53 @@ int main(int argc, char *argv[]) { width = DisplayWidth(d, DefaultScreen(d)); height = DisplayHeight(d, DefaultScreen(d)); } - + printf("screen : %.2f+%.2f x %.2f+%.2f\n",offsetx,width,offsety,height); // verifications - if (width < 2 || height < 2 ){//|| (wacom && (width_input < || height_input < 2))){ - print_coords_input(); - printf("%.2f %.2f %.2f %.2f\n",width,height,width_input,height_input); + if (width < 2 || height < 2 ){ + printf("screen geometry : %.2f %.2f\n",width,height); printHelpMsg(argv[0]); exit(1); } - MsgRcvPtr ptrMove,ptrRelMove,ptrButton; + if (wacom) { + if (predictive_mode){ + coords_input[2] = width; + coords_input[3] = height; + } else { + coords_input[2] = 1.0; + coords_input[3] = 1.0; + } + //~ print_coords_input(); + if (!predictive_mode) { + champX = CHAMP_X_WACOM; + champY = CHAMP_Y_WACOM; + champXButton = CHAMP_X_WACOM_BUTTON; + champYButton = CHAMP_Y_WACOM_BUTTON; + } else { + champX = CHAMP_X_WACOM_PREDICTIVE; + champY = CHAMP_Y_WACOM_PREDICTIVE; + champXButton = CHAMP_X_WACOM_PREDICTIVE_BUTTON; + champYButton = CHAMP_Y_WACOM_PREDICTIVE_BUTTON; + } + } else { + champX = CHAMP_X_TELEPOINTEUR; + champY = CHAMP_Y_TELEPOINTEUR; + } + + champX -= device_input_id_given; + champY -= device_input_id_given; + champXButton -= device_input_id_given; + champYButton -= device_input_id_given; + + width_input = coords_input[2]-coords_input[0]; + height_input = coords_input[3]-coords_input[1]; + + horiz_ratio = width / width_input; + vert_ratio = height / height_input; + + MsgRcvPtr ptrMove,ptrRelMove,ptrButton,ptrGeometry,ptrLockUnlock; IvyInit("IvyPointer","IvyPointer Ready",NULL,NULL,NULL,NULL); char regexp[2048] = ""; @@ -637,10 +653,6 @@ int main(int argc, char *argv[]) { printf("bound to %s\n",regexp); } else { //wacom callbacks - sprintf(regexp, REGEXP_CHANGE_GEOMETRY_INPUT, device_input_id); - ptrMove=IvyBindMsg(CallbackGeometry,&ptrMove,REGEXP_CHANGE_GEOMETRY_INPUT, device_input_id); - printf("bound to %s\n",regexp); - sprintf(regexp, REGEXP_POINTER, device_input_id); ptrMove=IvyBindMsg(CallbackPointer,&ptrMove, REGEXP_POINTER, device_input_id); printf("bound to %s\n",regexp); @@ -657,10 +669,16 @@ int main(int argc, char *argv[]) { printf("bound to %s\n",regexp); } - sprintf(regexp, REGEXP_CHANGE_GEOMETRY_SCREEN, device_input_id); - ptrMove=IvyBindMsg(CallbackScreen,&ptrMove, REGEXP_CHANGE_GEOMETRY_SCREEN, device_input_id); - printf("bound to %s\n",regexp); + if (!predictive_mode) { + sprintf(regexp, REGEXP_CHANGE_GEOMETRY_SCREEN, device_input_id); + ptrGeometry=IvyBindMsg(CallbackScreen,&ptrGeometry, REGEXP_CHANGE_GEOMETRY_SCREEN, device_input_id); + printf("bound to %s\n",regexp); + } + sprintf(regexp, REGEXP_LOCK_UNLOCK, device_input_id); + ptrLockUnlock=IvyBindMsg(CallbackLockUnlock,&ptrLockUnlock, REGEXP_LOCK_UNLOCK, device_input_id); + printf("bound to %s\n",regexp); + IvyStart(bus); #if (IVYMAJOR_VERSION == 3) && (IVYMINOR_VERSION < 9) IvyMainLoop(NULL, NULL); -- cgit v1.1