diff options
author | Philip Paeps <philip@FreeBSD.org> | 2004-10-11 07:57:08 +0000 |
---|---|---|
committer | Philip Paeps <philip@FreeBSD.org> | 2004-10-11 07:57:08 +0000 |
commit | 2a669c474a48e466102ac56f0156d2ee10e60973 (patch) | |
tree | d0b9b0b4bc5f67a9e60fd2b36cf4363f35e28629 /usr.sbin | |
parent | 570343bfec2d0c3dc59a26b1faf6b8ee281cd2a8 (diff) | |
download | src-2a669c474a48e466102ac56f0156d2ee10e60973.tar.gz src-2a669c474a48e466102ac56f0156d2ee10e60973.zip |
Add 'virtual scrolling' support to moused(8). When holding down the middle
mouse button, motions are interpreted as scrolling.
Submitted by: Jordan Sissel <psionic-AT-csh.rit.edu>
Approved by: njl
Notes
Notes:
svn path=/head/; revision=136372
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/moused/moused.8 | 7 | ||||
-rw-r--r-- | usr.sbin/moused/moused.c | 105 |
2 files changed, 109 insertions, 3 deletions
diff --git a/usr.sbin/moused/moused.8 b/usr.sbin/moused/moused.8 index 130e2686bbcc..db8abc265c24 100644 --- a/usr.sbin/moused/moused.8 +++ b/usr.sbin/moused/moused.8 @@ -43,6 +43,7 @@ .Op Fl F Ar rate .Op Fl r Ar resolution .Op Fl S Ar baudrate +.Op Fl V Op Fl U Ar distance .Op Fl a Ar X Ns Op , Ns Ar Y .Op Fl C Ar threshold .Op Fl m Ar N=M @@ -156,6 +157,12 @@ mode. .It Fl S Ar baudrate Select the baudrate for the serial port (1200 to 9600). Not all serial mice support this option. +.It Fl V +Enable ``Virtual Scrolling'', with this option set, holding the middle mouse +button down will cause motion to be interpreted as scrolling. Use the +.Fl U +option to set the distance the mouse must move before the scrolling mode is +activated. .It Fl a Ar X Ns Op , Ns Ar Y Accelerate or decelerate the mouse input. This is a linear acceleration only. diff --git a/usr.sbin/moused/moused.c b/usr.sbin/moused/moused.c index 2866f0e28eec..7a6fd4b10801 100644 --- a/usr.sbin/moused/moused.c +++ b/usr.sbin/moused/moused.c @@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$"); #define MAX_BUTTON2TIMEOUT 2000 /* 2 seconds */ #define DFLT_CLICKTHRESHOLD 500 /* 0.5 second */ #define DFLT_BUTTON2TIMEOUT 100 /* 0.1 second */ +#define DFLT_SCROLLTHRESHOLD 3 /* 3 pixels */ /* Abort 3-button emulation delay after this many movement events. */ #define BUTTON2_MAXMOVE 3 @@ -97,11 +98,12 @@ __FBSDID("$FreeBSD$"); #define ClearDTR 0x0004 #define ClearRTS 0x0008 #define NoPnP 0x0010 +#define VirtualScroll 0x0020 #define ID_NONE 0 #define ID_PORT 1 #define ID_IF 2 -#define ID_TYPE 4 +#define ID_TYPE 4 #define ID_MODEL 8 #define ID_ALL (ID_PORT | ID_IF | ID_TYPE | ID_MODEL) @@ -159,6 +161,13 @@ int identify = ID_NONE; int extioctl = FALSE; char *pidfile = "/var/run/moused.pid"; +#define SCROLL_NOTSCROLLING 0 +#define SCROLL_PREPARE 1 +#define SCROLL_SCROLLING 2 + +static int scroll_state; +static int scroll_movement; + /* local variables */ /* interface (the table must be ordered by MOUSE_IF_XXX in mouse.h) */ @@ -380,6 +389,7 @@ static struct rodentparam { mousemode_t mode; /* protocol information */ float accelx; /* Acceleration in the X axis */ float accely; /* Acceleration in the Y axis */ + int scrollthreshold; /* Movement distance before virtual scrolling */ } rodent = { .flags = 0, .portname = NULL, @@ -398,6 +408,7 @@ static struct rodentparam { .button2timeout = DFLT_BUTTON2TIMEOUT, .accelx = 1.0, .accely = 1.0, + .scrollthreshold = DFLT_SCROLLTHRESHOLD, }; /* button status */ @@ -509,7 +520,7 @@ main(int argc, char *argv[]) for (i = 0; i < MOUSE_MAXBUTTON; ++i) mstate[i] = &bstate[i]; - while ((c = getopt(argc, argv, "3C:DE:F:I:PRS:a:cdfhi:l:m:p:r:st:w:z:")) != -1) + while ((c = getopt(argc, argv, "3C:DE:F:I:PRS:VU:a:cdfhi:l:m:p:r:st:w:z:")) != -1) switch(c) { case '3': @@ -714,6 +725,17 @@ main(int argc, char *argv[]) warnx("no such mouse type `%s'", optarg); usage(); + case 'V': + rodent.flags |= VirtualScroll; + break; + case 'U': + rodent.scrollthreshold = atoi(optarg); + if (rodent.scrollthreshold < 0) { + warnx("invalid argument `%s'", optarg); + usage(); + } + break; + case 'h': case '?': default: @@ -967,6 +989,50 @@ moused(void) } if ((flags = r_protocol(b, &action0)) == 0) continue; + + if (rodent.flags & VirtualScroll) { + /* Allow middle button drags to scroll up and down */ + if (action0.button == MOUSE_BUTTON2DOWN) { + if (scroll_state == SCROLL_NOTSCROLLING) { + scroll_state = SCROLL_PREPARE; + debug("PREPARING TO SCROLL"); + } + debug("[BUTTON2] flags:%08x buttons:%08x obuttons:%08x", + action.flags, action.button, action.obutton); + } else { + debug("[NOTBUTTON2] flags:%08x buttons:%08x obuttons:%08x", + action.flags, action.button, action.obutton); + + /* This isn't a middle button down... move along... */ + if (scroll_state == SCROLL_SCROLLING) { + /* + * We were scrolling, someone let go of button 2. + * Now turn autoscroll off. + */ + scroll_state = SCROLL_NOTSCROLLING; + debug("DONE WITH SCROLLING / %d", scroll_state); + } else if (scroll_state == SCROLL_PREPARE) { + mousestatus_t newaction = action0; + + /* We were preparing to scroll, but we never moved... */ + r_timestamp(&action0); + r_statetrans(&action0, &newaction, + A(newaction.button & MOUSE_BUTTON1DOWN, + action0.button & MOUSE_BUTTON3DOWN)); + + /* Send middle down */ + newaction.button = MOUSE_BUTTON2DOWN; + r_click(&newaction); + + /* Send middle up */ + r_timestamp(&newaction); + newaction.obutton = newaction.button; + newaction.button = action0.button; + r_click(&newaction); + } + } + } + r_timestamp(&action0); r_statetrans(&action0, &action, A(action0.button & MOUSE_BUTTON1DOWN, @@ -984,8 +1050,41 @@ moused(void) debug("activity : buttons 0x%08x dx %d dy %d dz %d", action2.button, action2.dx, action2.dy, action2.dz); + if (rodent.flags & VirtualScroll) { + /* + * If *only* the middle button is pressed AND we are moving + * the stick/trackpoint/nipple, scroll! + */ + if (scroll_state == SCROLL_PREPARE) { + /* Ok, Set we're really scrolling now.... */ + if (action2.dy || action2.dx) + scroll_state = SCROLL_SCROLLING; + } + if (scroll_state == SCROLL_SCROLLING) { + scroll_movement += action2.dy; + debug("SCROLL: %d", scroll_movement); + + if (scroll_movement < -rodent.scrollthreshold) { + /* Scroll down */ + action2.dz = -1; + scroll_movement = 0; + } + else if (scroll_movement > rodent.scrollthreshold) { + /* Scroll up */ + action2.dz = 1; + scroll_movement = 0; + } + + /* Don't move while scrolling */ + action2.dx = action2.dy = 0; + } + } + if (extioctl) { - r_click(&action2); + /* Defer clicks until we aren't VirtualScroll'ing. */ + if (scroll_state == SCROLL_NOTSCROLLING) + r_click(&action2); + if (action2.flags & MOUSE_POSCHANGED) { mouse.operation = MOUSE_MOTION_EVENT; mouse.u.data.buttons = action2.button; |