On 22/03/2019 21.33, Bill Allombert wrote: >> I'm not sure what the best course of action is. Some possibilities are: >> * If it isn't too much of a problem, we could just leave it how it is. >> * We could disable selections while mouse tracking is active > > If this can be done on a per tty basis, this might be the best course of > action.
Ok, I've now created patch for this. This time, I've based the patch on the current master branch (commit c12a8c2d0cf72a340b13b00e6d4b98bfed57ce01) of the salsa.debian.org git repo. Regards, Daniel Abrecht
diff --git a/src/action.c b/src/action.c index 5c47fda..58d8af0 100644 --- a/src/action.c +++ b/src/action.c @@ -19,6 +19,7 @@ static double xx=1, yy=1, x0=-1, y0=-1, x1=-1, y1=-1; static int mode = 0; +static enum current_button button = BUTTON_RELEASED; void set_pointer(double x, double y) @@ -26,6 +27,11 @@ set_pointer(double x, double y) xx = x+1; yy = y+1; if (xx < 1) xx = 1; else if (xx > screen_width) xx = screen_width; if (yy < 1) yy = 1; else if (yy > screen_height) yy = screen_height; + if (mouse_reporting != MOUSE_REPORTING_OFF) + { + x0 = -1; y0 = -1; + mode = 0; + } if (x0 >= 0 && y0 >= 0) select_region((int)xx,(int)yy,(int)x0,(int)y0); else @@ -55,6 +61,11 @@ move_pointer(double x, double y) xx += x/20; yy += y/20; if (xx < 1) xx = 1; else if (xx > screen_width) xx = screen_width; if (yy < 1) yy = 1; else if (yy > screen_height) yy = screen_height; + if (mouse_reporting != MOUSE_REPORTING_OFF) + { + x0 = -1; y0 = -1; + mode = 0; + } if (x0 >= 0 && y0 >= 0) select_mode(mode,(int)xx,(int)yy,(int)x0,(int)y0); else @@ -64,36 +75,85 @@ move_pointer(double x, double y) void press_left_button(void) { - if ((int)x1==(int)xx && (int)y1==(int)yy) + if (mouse_reporting != MOUSE_REPORTING_OFF) { - mode = (mode+1)%3; - select_mode(mode,(int)xx,(int)yy,(int)xx,(int)yy); + button = BUTTON_LEFT; + report_pointer((int)xx,(int)yy,button); } else { - mode = 0; - select_region((int)xx,(int)yy,(int)xx,(int)yy); + if ((int)x1==(int)xx && (int)y1==(int)yy) + { + mode = (mode+1)%3; + select_mode(mode,(int)xx,(int)yy,(int)xx,(int)yy); + } + else + { + mode = 0; + select_region((int)xx,(int)yy,(int)xx,(int)yy); + } + x0=xx; y0=yy; x1=x0; y1=y0; } - x0=xx; y0=yy; x1=x0; y1=y0; } void release_left_button(void) { + if (mouse_reporting == MOUSE_REPORTING_X11) + { + button = BUTTON_RELEASED; + report_pointer((int)xx,(int)yy,button); + } x0=-1; y0=-1; } void press_middle_button(void) { - paste(); + if (mouse_reporting != MOUSE_REPORTING_OFF) + { + button = BUTTON_MIDDLE; + report_pointer((int)xx,(int)yy,button); + } + else + { + paste(); + } +} + +void +release_middle_button(void) +{ + if (mouse_reporting == MOUSE_REPORTING_X11) + { + button = BUTTON_RELEASED; + report_pointer((int)xx,(int)yy,button); + } } void press_right_button(void) { - if (x1>=0 && y1>=0) - select_region((int)xx,(int)yy,(int)x1,(int)y1); + if (mouse_reporting != MOUSE_REPORTING_OFF) + { + button = BUTTON_RIGHT; + report_pointer((int)xx,(int)yy,button); + } + else + { + if (x1>=0 && y1>=0) + select_region((int)xx,(int)yy,(int)x1,(int)y1); + } +} + +void +release_right_button(void) +{ + if (mouse_reporting == MOUSE_REPORTING_X11) + { + button = BUTTON_RELEASED; + report_pointer((int)xx,(int)yy,button); + } } void diff --git a/src/consolation.h b/src/consolation.h index f907906..5290d65 100644 --- a/src/consolation.h +++ b/src/consolation.h @@ -19,14 +19,30 @@ extern int nodaemon; +enum current_button { + BUTTON_LEFT, + BUTTON_MIDDLE, + BUTTON_RIGHT, + BUTTON_RELEASED +}; + +enum mouse_reporting_mode { + MOUSE_REPORTING_OFF, + MOUSE_REPORTING_X10, + MOUSE_REPORTING_X11, + MOUSE_REPORTING_MODE_COUNT +}; + /* global state */ extern unsigned int screen_width; extern unsigned int screen_height; +extern enum mouse_reporting_mode mouse_reporting; /* selection.c */ -void set_screen_size(void); +void set_screen_size_and_mouse_reporting(void); +void report_pointer(int x, int y, enum current_button button); void draw_pointer(int x, int y); void select_region(int x, int y, int x2, int y2); void select_words(int x, int y, int x2, int y2); @@ -42,7 +58,9 @@ void move_pointer(double x, double y); void press_left_button(void); void release_left_button(void); void press_middle_button(void); +void release_middle_button(void); void press_right_button(void); +void release_right_button(void); void vertical_axis(double v); /* input.c */ diff --git a/src/input.c b/src/input.c index 74ec072..4a6f99a 100644 --- a/src/input.c +++ b/src/input.c @@ -46,6 +46,7 @@ int nodaemon = false; unsigned int screen_width; unsigned int screen_height; +enum mouse_reporting_mode mouse_reporting = MOUSE_REPORTING_OFF; static struct tools_options options; static unsigned int stop = 0; @@ -92,10 +93,14 @@ handle_pointer_button_event(struct libinput_event *ev) case BTN_MIDDLE: if (state==LIBINPUT_BUTTON_STATE_PRESSED) press_middle_button(); + else + release_middle_button(); break; case BTN_RIGHT: if (state==LIBINPUT_BUTTON_STATE_PRESSED) press_right_button(); + else + release_right_button(); break; } } @@ -146,7 +151,7 @@ handle_events(struct libinput *li) struct libinput_event *ev; libinput_dispatch(li); - set_screen_size(); + set_screen_size_and_mouse_reporting(); while ((ev = libinput_get_event(li))) { switch (libinput_event_get_type(ev)) { diff --git a/src/selection.c b/src/selection.c index 6fbfee8..6563c01 100644 --- a/src/selection.c +++ b/src/selection.c @@ -22,6 +22,7 @@ #include <linux/tiocl.h> #include <stdint.h> #include <linux/kd.h> +#include <errno.h> #include "consolation.h" @@ -34,14 +35,38 @@ check_mode(int fd) } void -set_screen_size(void) +set_screen_size_and_mouse_reporting(void) { struct winsize s; int fd = open("/dev/tty0",O_RDONLY); - if (ioctl(fd, TIOCGWINSZ, &s)) perror("TIOCGWINSZ"); + if (fd == -1) + { + perror("open /dev/tty0"); + return; + } + if (ioctl(fd, TIOCGWINSZ, &s)) + { + perror("TIOCGWINSZ"); + } + else + { + screen_width = s.ws_col; + screen_height = s.ws_row; + } + unsigned char request = TIOCL_GETMOUSEREPORTING; + if (ioctl(fd, TIOCLINUX, &request)) + { + perror("TIOCLINUX, TIOCL_GETMOUSEREPORTING"); + request = MOUSE_REPORTING_OFF; + } + close(fd); + if (request >= MOUSE_REPORTING_MODE_COUNT) + { + fprintf(stderr, "mouse reporting mode %d not supported\n", (int)request); + request = MOUSE_REPORTING_OFF; + } + mouse_reporting = request; close(fd); - screen_width = s.ws_col; - screen_height = s.ws_row; } static void @@ -61,12 +86,27 @@ linux_selection(int xs, int ys, int xe, int ye, int sel_mode) s.sel.sel_mode = sel_mode; fd = open("/dev/tty0",O_RDONLY); if (check_mode(fd)) - if (ioctl(fd, TIOCLINUX, ((char*)&s)+1)<0) + { + int err = ioctl(fd, TIOCLINUX, ((char*)&s)+1); + if (err<0 && !(errno==EINVAL && (sel_mode&TIOCL_SELMOUSEREPORT))) + /* The kernel return EINVAL for TIOCL_SELMOUSEREPORT when + TIOCL_GETMOUSEREPORTING reports 0. Unfortunately this cannot be + checked without race conditions, so it is simpler to ignore the + error. + */ perror("selection: TIOCLINUX"); + } close(fd); } void +report_pointer(int x, int y, enum current_button button) +{ + linux_selection(x, y, x, y, TIOCL_SELCLEAR); + linux_selection(x, y, x, y, TIOCL_SELMOUSEREPORT + button ); +} + +void draw_pointer(int x, int y) { linux_selection(x, y, x, y, TIOCL_SELPOINTER);
signature.asc
Description: OpenPGP digital signature