# On branch master # Changes to be committed: # (use "git reset HEAD ..." to unstage) # # modified: man/xinput.man # modified: src/feedback.c # modified: src/xinput.c # modified: src/xinput.h # diff --git a/man/xinput.man b/man/xinput.man index 410ecd0..7d81bf8 100644 --- a/man/xinput.man +++ b/man/xinput.man @@ -10,6 +10,9 @@ xinput - utility to configure and test XInput devices [get-feedbacks \fIdevice_name\fP] [set-mode \fIdevice_name\fP \fIABSOLUTE|RELATIVE\fP] [set-ptr-feedback \fIdevice_name\fP \fIthreshold\fP \fInum\fP \fIdenom\fP] +[set-ptr-accel \fIdevice_name\fP \fI[reset]\fP \fI\fP +\fI[int]\fP [\fI[numerator]\fP \fI[denumerator]\fP] ] +[get-ptr-accel \fIdevice_name\fP] [set-integer-feedback \fIdevice_name\fP \fIindex\fP \fIvalue\fP] [set-button-map \fIdevice_name\fP \fImap button 1\fP [\fImap button 2\fP [\fI...\fP]]] [query-state \fIdevice_name\fP] @@ -40,7 +43,14 @@ Switch \fIdevice_name\fP in core pointer. Uses XChangePointerDevice(3). Change the mode of \fIdevice_name\fP. Uses XSetDeviceMode(3). .PP .TP 8 -.B xinput set-ptr-feedback \fIdevice_name\fP \fIthreshold\fP \fInum\fP \fIdenom\fP +.B xinput set-ptr-accel \fIdevice_name\fP \fI[reset]\fP \fI\fP +\fI[int]\fP [\fI[numerator]\fP \fI[denumerator]\fP] +Change the acceleration paramters of \fIdevice_name\fP if it uses the predictable +scheme. +.PP +.B xinput get-ptr-feedback \fIdevice_name\fP +Query the acceleration parameters of \fIdevice_name\fP. Uses XChangeFeedbackControl(3). +.PP.B xinput set-ptr-feedback \fIdevice_name\fP \fIthreshold\fP \fInum\fP \fIdenom\fP Change the acceleration of \fIdevice_name\fP. Uses XChangeFeedbackControl(3). .PP .TP 8 diff --git a/src/feedback.c b/src/feedback.c index 7f4da57..e193360 100644 --- a/src/feedback.c +++ b/src/feedback.c @@ -23,6 +23,8 @@ #include "xinput.h" +#include + int set_ptr_feedback(Display *display, int argc, @@ -183,4 +185,207 @@ get_feedbacks(Display *display, return EXIT_SUCCESS; } +/* + * This relates to bug#8583 + * to conveniently switch more than 2 profiles (with their respective + * settings) this is to be redone, i.e. query scheme first and + * then allow for matching controls. + */ +int +set_ptr_feedback_advanced(Display *display, + int argc, + char *argv[], + char *name, + char *desc) +{ + XDeviceInfo *info; + XDevice *device; + XDeviceAccelPredictableControl *pctrl; + int ppos = 1; + int pmask = 0; + int nargc = 2; + int *intp = NULL, *ratp = NULL; + short *shortp = NULL; + Bool set_default = 0; + + pctrl = malloc(sizeof(XDeviceAccelPredictableControl)); + if (!pctrl) { + fprintf(stderr, "unable to allocate memory\n"); + return 1; + } + memset(pctrl, 0 , sizeof(XDeviceAccelPredictableControl)); + + pctrl->length = sizeof(XDeviceAccelPredictableControl); + + pctrl->control = DEVICE_PTRACCEL; + + pctrl->scheme = PtrAccelPredictable; + + if (argc < nargc) { + fprintf(stderr, "usage: xinput %s %s\n", name, desc); + return 1; + } + + info = find_device_info(display, argv[0], True); + + if (!info) { + fprintf(stderr, "unable to find extension device %s\n", argv[0]); + return 1; + } + + device = XOpenDevice(display, info->id); + + if (!device) { + fprintf(stderr, "unable to open device %s\n", argv[0]); + return 1; + } + + if (strcmp(argv[ppos], "reset") == 0) { + nargc++; + ppos++; + set_default = 1; + + if (argc < nargc) { + fprintf(stderr, "you need to specify a parameter or 'all'.\n"); + return 1; + } + } + + if (strcmp(argv[ppos], "scheme") == 0) { + if(set_default) { + fprintf(stderr, "use scheme 1 instead.\n"); + return 1; + } + pctrl->length = sizeof(XDeviceAccelControl); + shortp = &pctrl->scheme; + } + + if (strcmp(argv[ppos], "profile") == 0) { + pmask = PredictableAccelProfile; + intp = &pctrl->profile; + } + + if (strcmp(argv[ppos], "scale") == 0) { + pmask = PredictableAccelScale; + ratp = &pctrl->scale_num; + } + + if (strcmp(argv[ppos], "halflife") == 0) { + pmask = PredictableAccelHalflife; + intp = &pctrl->halflife_ms; + } + + if (strcmp(argv[ppos], "const-dec") == 0) { + pmask = PredictableAccelConstDec; + intp = &pctrl->const_deceleration; + } + + if (strcmp(argv[ppos], "adapt-dec") == 0) { + pmask = PredictableAccelAdaptiveDec; + ratp = &pctrl->adaptive_deceleration_num; + } + + if (strcmp(argv[ppos], "all") == 0) { + if (!set_default) { + fprintf(stderr, " can only be used with reset.\n"); + return 1; + } + pmask = 255; /* no big term or'ing together all PredictableAccels */ + } + + if (!shortp && pmask == 0) { + fprintf(stderr, "parameters '%s' unknown.\n", argv[ppos]); + return 1; + } + + if (set_default) { + pctrl->default_set = pmask; + intp = NULL; + shortp = NULL; + ratp = NULL; + } else { + pctrl->valid_set = pmask; + + if(intp || shortp) + nargc++; + /* a rational may need only one parameter; + den = 1 is assumed then */ + if(ratp) + nargc++; + } + + if (argc < nargc) { + fprintf(stderr, "not enough parameters for '%s'\n", argv[ppos]); + return 1; + } + + if (intp) { + *intp = atoi(argv[++ppos]); + }else if (shortp) { + *shortp = atoi(argv[++ppos]); + } + if (ratp) { + *ratp = atoi(argv[++ppos]); + if(ppos < (argc - 1)) + *(ratp+1) = atoi(argv[++ppos]); + else + *(ratp+1) = 1; + } + + XChangeDeviceControl(display, device, DEVICE_PTRACCEL, + (XDeviceControl*)pctrl); + free (pctrl); + return EXIT_SUCCESS; +} + +int +get_ptr_feedback_advanced(Display *display, + int argc, + char *argv[], + char *name, + char *desc) +{ + XDeviceInfo *info; + XDevice *device; + XDeviceAccelPredictableState* state; + + if (argc < 1) { + fprintf(stderr, "usage: xinput %s %s\n", name, desc); + return 1; + } + + info = find_device_info(display, argv[0], True); + + if (!info) { + fprintf(stderr, "unable to find extension device %s\n", argv[0]); + return 1; + } + + device = XOpenDevice(display, info->id); + + if (!device) { + fprintf(stderr, "unable to open device %s\n", argv[0]); + return 1; + } + + state = (XDeviceAccelPredictableState*)XGetDeviceControl( + display, device, DEVICE_PTRACCEL); + + printf("Acceleration scheme : %i\n", state->scheme); + switch(state->scheme){ + case PtrAccelPredictable : + /* in princliple we should check valid_set bits */ + printf("profile : %i\n", state->profile); + printf("const-dec : %i\n", state->const_deceleration); + printf("scale : %i/%i\n", + state->scale_num, + state->scale_den); + printf("adapt-dec : %i/%i\n", + state->adaptive_deceleration_num, + state->adaptive_deceleration_den); + printf("halflife : %i\n", state->halflife_ms); + } + return EXIT_SUCCESS; +} + /* end of ptrfdbk.c */ diff --git a/src/xinput.c b/src/xinput.c index f74dee5..b43115b 100644 --- a/src/xinput.c +++ b/src/xinput.c @@ -49,6 +49,14 @@ static entry drivers[] = " ", set_ptr_feedback }, + {"set-ptr-accel", + " [reset] [] [ [denum] ]", + set_ptr_feedback_advanced + }, + {"get-ptr-accel", + "", + get_ptr_feedback_advanced + }, {"set-integer-feedback", " ", set_integer_feedback diff --git a/src/xinput.h b/src/xinput.h index a43ab73..3a4ad5d 100644 --- a/src/xinput.h +++ b/src/xinput.h @@ -65,6 +65,28 @@ set_ptr_feedback( ); int +set_ptr_feedback_advanced( +#if NeedFunctionPrototypes + Display* display, + int argc, + char *argv[], + char *prog_name, + char *prog_desc +#endif +); + +int +get_ptr_feedback_advanced( +#if NeedFunctionPrototypes + Display* display, + int argc, + char *argv[], + char *prog_name, + char *prog_desc +#endif +); + +int set_button_map( #if NeedFunctionPrototypes Display* display,