diff --git a/doc/example-spnavrc b/doc/example-spnavrc index 0e4ea53..765c7b2 100644 --- a/doc/example-spnavrc +++ b/doc/example-spnavrc @@ -85,6 +85,7 @@ # sensitivity-up, sensitivity-down, sensitivity-reset # disable-rotation # disable-translation +# dominant-axis # #bnact16 = sensitivity-up #bnact17 = sensitivity-down diff --git a/src/cfgfile.c b/src/cfgfile.c index 1a587da..ef3413d 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -690,6 +690,7 @@ static struct { {"sensitivity-reset", BNACT_SENS_RESET}, {"disable-rotation", BNACT_DISABLE_ROTATION}, {"disable-translation", BNACT_DISABLE_TRANSLATION}, + {"dominant-axis", BNACT_DOMINANT_AXIS}, {0, 0} }; diff --git a/src/cfgfile.h b/src/cfgfile.h index e833432..9605afb 100644 --- a/src/cfgfile.h +++ b/src/cfgfile.h @@ -39,6 +39,7 @@ enum { BNACT_SENS_DEC, BNACT_DISABLE_ROTATION, BNACT_DISABLE_TRANSLATION, + BNACT_DOMINANT_AXIS, MAX_BNACT }; diff --git a/src/event.c b/src/event.c index c404de5..7638077 100644 --- a/src/event.c +++ b/src/event.c @@ -47,6 +47,10 @@ struct dev_event { struct dev_event *next; }; +struct dev_input inp_dominant = { -1, {0}, -1, 0 }; +struct timeval dominant_offset = { 0, 100000 }; // 0.1s +int dominant_axis_treshold = 2; + static struct dev_event *add_dev_event(struct device *dev); static struct dev_event *device_event_in_use(struct device *dev); static void handle_button_action(int act, int val); @@ -56,7 +60,7 @@ static unsigned int msec_dif(struct timeval tv1, struct timeval tv2); static struct dev_event *dev_ev_list = NULL; -static int disable_translation, disable_rotation; +static int disable_translation, disable_rotation, dominant_axis; static struct dev_event *add_dev_event(struct device *dev) @@ -140,6 +144,10 @@ static inline int map_axis(int devaxis) return axis; } +int dominant_threshold(int val, int threshold) { + return val <= -threshold || val >= threshold; +} + /* process_input processes an device input event, and dispatches * spacenav events to the clients by calling dispatch_event. * relative inputs (INP_MOTION) are accumulated, and dispatched when @@ -150,7 +158,7 @@ void process_input(struct device *dev, struct dev_input *inp) { int sign, axis; struct dev_event *dev_ev; - float sens_rot, sens_trans; + float sens_rot, sens_trans, axis_sensitivity; spnav_event ev; switch(inp->type) { @@ -170,8 +178,30 @@ void process_input(struct device *dev, struct dev_input *inp) sens_rot = disable_rotation ? 0 : cfg.sens_rot[axis - 3]; sens_trans = disable_translation ? 0 : cfg.sens_trans[axis]; + axis_sensitivity = axis < 3 ? sens_trans : sens_rot; - inp->val = (int)((float)inp->val * cfg.sensitivity * (axis < 3 ? sens_trans : sens_rot)); + if(dominant_axis) { + if(inp_dominant.idx != -1) { + struct timeval diff; + timersub(&(inp->tm), &(inp_dominant.tm), &diff); + if (timercmp(&diff, &dominant_offset, >=)) { + inp_dominant.idx = -1; + inp_dominant.tm = (struct timeval){0}; + inp_dominant.type = INP_FLUSH; + inp_dominant.val = 0; + } + } + if((inp_dominant.idx == -1 && dominant_threshold(inp->val, dominant_axis_treshold)) + || inp_dominant.idx == axis) { + inp_dominant.idx = axis; + inp_dominant.tm = inp->tm; + inp_dominant.type = inp->type; + inp_dominant.val = inp->val; + } else { + axis_sensitivity = 0; + } + } + inp->val = (int)((float)inp->val * cfg.sensitivity * axis_sensitivity); dev_ev = device_event_in_use(dev); if(verbose && dev_ev == NULL) @@ -281,6 +311,9 @@ static void handle_button_action(int act, int pressed) disable_rotation = 0; } break; + case BNACT_DOMINANT_AXIS: + dominant_axis = !dominant_axis; + break; } }