aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortissoire2009-09-25 09:33:54 +0000
committertissoire2009-09-25 09:33:54 +0000
commitcb3f991754d20ee1e433687c494c969335bdbee8 (patch)
tree621dec329d548e4ed2e6d74afcff627161010095
parente397e828cc041ad1e3e0ae218940acc47acf9223 (diff)
downloadivypointer-cb3f991754d20ee1e433687c494c969335bdbee8.zip
ivypointer-cb3f991754d20ee1e433687c494c969335bdbee8.tar.gz
ivypointer-cb3f991754d20ee1e433687c494c969335bdbee8.tar.bz2
ivypointer-cb3f991754d20ee1e433687c494c969335bdbee8.tar.xz
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
-rw-r--r--src/ivypointer.c376
1 files changed, 197 insertions, 179 deletions
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 (x<coords_input[0]) {
-// printf("x < x0\n");
- return 0;
- }
- if (x>coords_input[2]) {
-// printf("x > x1\n");
- return 0;
- }
- if (y<coords_input[1]){
-// printf("y < y0\n");
- return 0;
- }
- if (y>coords_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);