The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/port/devmouse.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #include        "u.h"
    2 #include        "../port/lib.h"
    3 #include        "mem.h"
    4 #include        "dat.h"
    5 #include        "fns.h"
    6 #include        "../port/error.h"
    7 
    8 #define Image   IMAGE
    9 #include        <draw.h>
   10 #include        <memdraw.h>
   11 #include        <cursor.h>
   12 #include        "screen.h"
   13 
   14 enum {
   15         ScrollUp = 0x08,
   16         ScrollDown = 0x10,
   17         ScrollLeft = 0x20,
   18         ScrollRight = 0x40,
   19 };
   20 
   21 typedef struct Mouseinfo        Mouseinfo;
   22 typedef struct Mousestate       Mousestate;
   23 
   24 struct Mousestate
   25 {
   26         Point   xy;             /* mouse.xy */
   27         int     buttons;        /* mouse.buttons */
   28         ulong   counter;        /* increments every update */
   29         ulong   msec;           /* time of last event */
   30 };
   31 
   32 struct Mouseinfo
   33 {
   34         Lock;
   35         Mousestate;
   36         int     dx;
   37         int     dy;
   38         int     track;          /* dx & dy updated */
   39         int     redraw;         /* update cursor on screen */
   40         ulong   lastcounter;    /* value when /dev/mouse read */
   41         ulong   lastresize;
   42         ulong   resize;
   43         Rendez  r;
   44         Ref;
   45         QLock;
   46         int     open;
   47         int     inopen;
   48         int     acceleration;
   49         int     maxacc;
   50         Mousestate      queue[16];      /* circular buffer of click events */
   51         int     ri;             /* read index into queue */
   52         int     wi;             /* write index into queue */
   53         uchar   qfull;          /* queue is full */
   54 };
   55 
   56 enum
   57 {
   58         CMbuttonmap,
   59         CMscrollswap,
   60         CMswap,
   61         CMwildcard,
   62 };
   63 
   64 static Cmdtab mousectlmsg[] =
   65 {
   66         CMbuttonmap,    "buttonmap",    0,
   67         CMscrollswap,   "scrollswap",   0,
   68         CMswap,         "swap",         1,
   69         CMwildcard,     "*",            0,
   70 };
   71 
   72 Mouseinfo       mouse;
   73 Cursorinfo      cursor;
   74 int             mouseshifted;
   75 int             kbdbuttons;
   76 void            (*kbdmouse)(int);
   77 Cursor          curs;
   78 
   79 void    Cursortocursor(Cursor*);
   80 int     mousechanged(void*);
   81 
   82 static void mouseclock(void);
   83 static void xkbdmouse(int);
   84 
   85 enum{
   86         Qdir,
   87         Qcursor,
   88         Qmouse,
   89         Qmousein,
   90         Qmousectl,
   91 };
   92 
   93 static Dirtab mousedir[]={
   94         ".",    {Qdir, 0, QTDIR},       0,                      DMDIR|0555,
   95         "cursor",       {Qcursor},      0,                      0666,
   96         "mouse",        {Qmouse},       0,                      0666,
   97         "mousein",      {Qmousein},     0,                      0220,
   98         "mousectl",     {Qmousectl},    0,                      0220,
   99 };
  100 
  101 static uchar buttonmap[8] = {
  102         0, 1, 2, 3, 4, 5, 6, 7,
  103 };
  104 static int mouseswap;
  105 static int scrollswap;
  106 static ulong mousetime;
  107 
  108 extern Memimage* gscreen;
  109 extern ulong kerndate;
  110 
  111 static void
  112 mousereset(void)
  113 {
  114         if(!conf.monitor)
  115                 return;
  116 
  117         curs = arrow;
  118         Cursortocursor(&arrow);
  119         /* redraw cursor about 30 times per second */
  120         addclock0link(mouseclock, 33);
  121 }
  122 
  123 static void
  124 mousefromkbd(int buttons)
  125 {
  126         kbdbuttons = buttons;
  127         mousetrack(0, 0, 0, TK2MS(MACHP(0)->ticks));
  128 }
  129 
  130 static int
  131 mousedevgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp)
  132 {
  133         int rc;
  134 
  135         rc = devgen(c, name, tab, ntab, i, dp);
  136         if(rc != -1)
  137                 dp->atime = mousetime;
  138         return rc;
  139 }
  140 
  141 static void
  142 mouseinit(void)
  143 {
  144         if(!conf.monitor)
  145                 return;
  146 
  147         curs = arrow;
  148         Cursortocursor(&arrow);
  149         cursoron(1);
  150         kbdmouse = mousefromkbd;
  151         mousetime = seconds();
  152 }
  153 
  154 static Chan*
  155 mouseattach(char *spec)
  156 {
  157         if(!conf.monitor)
  158                 error(Egreg);
  159         return devattach('m', spec);
  160 }
  161 
  162 static Walkqid*
  163 mousewalk(Chan *c, Chan *nc, char **name, int nname)
  164 {
  165         Walkqid *wq;
  166 
  167         /*
  168          * We use devgen() and not mousedevgen() here
  169          * see "Ugly problem" in dev.c/devwalk()
  170          */
  171         wq = devwalk(c, nc, name, nname, mousedir, nelem(mousedir), devgen);
  172         if(wq != nil && wq->clone != c && wq->clone != nil && (wq->clone->qid.type&QTDIR)==0)
  173                 incref(&mouse);
  174         return wq;
  175 }
  176 
  177 static int
  178 mousestat(Chan *c, uchar *db, int n)
  179 {
  180         return devstat(c, db, n, mousedir, nelem(mousedir), mousedevgen);
  181 }
  182 
  183 static Chan*
  184 mouseopen(Chan *c, int omode)
  185 {
  186         switch((ulong)c->qid.path){
  187         case Qdir:
  188                 if(omode != OREAD)
  189                         error(Eperm);
  190                 break;
  191         case Qmouse:
  192                 lock(&mouse);
  193                 if(mouse.open){
  194                         unlock(&mouse);
  195                         error(Einuse);
  196                 }
  197                 mouse.open = 1;
  198                 mouse.ref++;
  199                 mouse.lastresize = mouse.resize;
  200                 unlock(&mouse);
  201                 break;
  202         case Qmousein:
  203                 if(!iseve())
  204                         error(Eperm);
  205                 lock(&mouse);
  206                 if(mouse.inopen){
  207                         unlock(&mouse);
  208                         error(Einuse);
  209                 }
  210                 mouse.inopen = 1;
  211                 unlock(&mouse);
  212                 break;
  213         default:
  214                 incref(&mouse);
  215         }
  216         c->mode = openmode(omode);
  217         c->flag |= COPEN;
  218         c->offset = 0;
  219         return c;
  220 }
  221 
  222 static void
  223 mousecreate(Chan*, char*, int, ulong)
  224 {
  225         if(!conf.monitor)
  226                 error(Egreg);
  227         error(Eperm);
  228 }
  229 
  230 static void
  231 mouseclose(Chan *c)
  232 {
  233         if((c->qid.type&QTDIR)==0 && (c->flag&COPEN)){
  234                 lock(&mouse);
  235                 if(c->qid.path == Qmouse)
  236                         mouse.open = 0;
  237                 else if(c->qid.path == Qmousein){
  238                         mouse.inopen = 0;
  239                         unlock(&mouse);
  240                         return;
  241                 }
  242                 if(--mouse.ref == 0){
  243                         cursoroff(1);
  244                         curs = arrow;
  245                         Cursortocursor(&arrow);
  246                         cursoron(1);
  247                 }
  248                 unlock(&mouse);
  249         }
  250 }
  251 
  252 
  253 static long
  254 mouseread(Chan *c, void *va, long n, vlong off)
  255 {
  256         char buf[1+4*12+1];
  257         uchar *p;
  258         static int map[8] = {0, 4, 2, 6, 1, 5, 3, 7 };
  259         ulong offset = off;
  260         Mousestate m;
  261         int b;
  262 
  263         p = va;
  264         switch((ulong)c->qid.path){
  265         case Qdir:
  266                 return devdirread(c, va, n, mousedir, nelem(mousedir), mousedevgen);
  267 
  268         case Qcursor:
  269                 if(offset != 0)
  270                         return 0;
  271                 if(n < 2*4+2*2*16)
  272                         error(Eshort);
  273                 n = 2*4+2*2*16;
  274                 lock(&cursor);
  275                 BPLONG(p+0, curs.offset.x);
  276                 BPLONG(p+4, curs.offset.y);
  277                 memmove(p+8, curs.clr, 2*16);
  278                 memmove(p+40, curs.set, 2*16);
  279                 unlock(&cursor);
  280                 return n;
  281 
  282         case Qmouse:
  283                 while(mousechanged(0) == 0)
  284                         sleep(&mouse.r, mousechanged, 0);
  285 
  286                 mouse.qfull = 0;
  287                 mousetime = seconds();
  288 
  289                 /*
  290                  * No lock of the indices is necessary here, because ri is only
  291                  * updated by us, and there is only one mouse reader
  292                  * at a time.  I suppose that more than one process
  293                  * could try to read the fd at one time, but such behavior
  294                  * is degenerate and already violates the calling
  295                  * conventions for sleep above.
  296                  */
  297                 if(mouse.ri != mouse.wi) {
  298                         m = mouse.queue[mouse.ri];
  299                         if(++mouse.ri == nelem(mouse.queue))
  300                                 mouse.ri = 0;
  301                 } else {
  302                         while(!canlock(&cursor))
  303                                 tsleep(&up->sleep, return0, 0, TK2MS(1));
  304 
  305                         m = mouse.Mousestate;
  306                         unlock(&cursor);
  307                 }
  308 
  309                 b = buttonmap[m.buttons&7];
  310                 /* put buttons 4 and 5 back in */
  311                 b |= m.buttons & (3<<3);
  312                 if (scrollswap)
  313                         if (b == 8)
  314                                 b = 16;
  315                         else if (b == 16)
  316                                 b = 8;
  317                 sprint(buf, "m%11d %11d %11d %11lud ",
  318                         m.xy.x, m.xy.y,
  319                         b,
  320                         m.msec);
  321                 mouse.lastcounter = m.counter;
  322                 if(n > 1+4*12)
  323                         n = 1+4*12;
  324                 if(mouse.lastresize != mouse.resize){
  325                         mouse.lastresize = mouse.resize;
  326                         buf[0] = 'r';
  327                 }
  328                 memmove(va, buf, n);
  329                 return n;
  330         }
  331         return 0;
  332 }
  333 
  334 static void
  335 setbuttonmap(char* map)
  336 {
  337         int i, x, one, two, three;
  338 
  339         one = two = three = 0;
  340         for(i = 0; i < 3; i++){
  341                 if(map[i] == 0)
  342                         error(Ebadarg);
  343                 if(map[i] == '1'){
  344                         if(one)
  345                                 error(Ebadarg);
  346                         one = 1<<i;
  347                 }
  348                 else if(map[i] == '2'){
  349                         if(two)
  350                                 error(Ebadarg);
  351                         two = 1<<i;
  352                 }
  353                 else if(map[i] == '3'){
  354                         if(three)
  355                                 error(Ebadarg);
  356                         three = 1<<i;
  357                 }
  358                 else
  359                         error(Ebadarg);
  360         }
  361         if(map[i])
  362                 error(Ebadarg);
  363 
  364         memset(buttonmap, 0, 8);
  365         for(i = 0; i < 8; i++){
  366                 x = 0;
  367                 if(i & 1)
  368                         x |= one;
  369                 if(i & 2)
  370                         x |= two;
  371                 if(i & 4)
  372                         x |= three;
  373                 buttonmap[x] = i;
  374         }
  375 }
  376 
  377 static long
  378 mousewrite(Chan *c, void *va, long n, vlong)
  379 {
  380         char *p;
  381         Point pt;
  382         Cmdbuf *cb;
  383         Cmdtab *ct;
  384         char buf[64];
  385         int b, msec;
  386 
  387         p = va;
  388         switch((ulong)c->qid.path){
  389         case Qdir:
  390                 error(Eisdir);
  391 
  392         case Qcursor:
  393                 cursoroff(1);
  394                 if(n < 2*4+2*2*16){
  395                         curs = arrow;
  396                         Cursortocursor(&arrow);
  397                 }else{
  398                         n = 2*4+2*2*16;
  399                         curs.offset.x = BGLONG(p+0);
  400                         curs.offset.y = BGLONG(p+4);
  401                         memmove(curs.clr, p+8, 2*16);
  402                         memmove(curs.set, p+40, 2*16);
  403                         Cursortocursor(&curs);
  404                 }
  405                 qlock(&mouse);
  406                 mouse.redraw = 1;
  407                 mouseclock();
  408                 qunlock(&mouse);
  409                 cursoron(1);
  410                 return n;
  411 
  412         case Qmousectl:
  413                 cb = parsecmd(va, n);
  414                 if(waserror()){
  415                         free(cb);
  416                         nexterror();
  417                 }
  418 
  419                 ct = lookupcmd(cb, mousectlmsg, nelem(mousectlmsg));
  420 
  421                 switch(ct->index){
  422                 case CMswap:
  423                         if(mouseswap)
  424                                 setbuttonmap("123");
  425                         else
  426                                 setbuttonmap("321");
  427                         mouseswap ^= 1;
  428                         break;
  429 
  430                 case CMscrollswap:
  431                         scrollswap ^= 1;
  432                         break;
  433 
  434                 case CMbuttonmap:
  435                         if(cb->nf == 1)
  436                                 setbuttonmap("123");
  437                         else
  438                                 setbuttonmap(cb->f[1]);
  439                         break;
  440 
  441                 case CMwildcard:
  442                         mousectl(cb);
  443                         break;
  444                 }
  445 
  446                 free(cb);
  447                 poperror();
  448                 return n;
  449 
  450         case Qmousein:
  451                 if(n > sizeof buf-1)
  452                         n = sizeof buf -1;
  453                 memmove(buf, va, n);
  454                 buf[n] = 0;
  455                 p = 0;
  456                 pt.x = strtol(buf+1, &p, 0);
  457                 if(p == 0)
  458                         error(Eshort);
  459                 pt.y = strtol(p, &p, 0);
  460                 if(p == 0)
  461                         error(Eshort);
  462                 b = strtol(p, &p, 0);
  463                 msec = strtol(p, &p, 0);
  464                 if(msec == 0)
  465                         msec = TK2MS(MACHP(0)->ticks);
  466                 mousetrack(pt.x, pt.y, b, msec);
  467                 return n;
  468 
  469         case Qmouse:
  470                 if(n > sizeof buf-1)
  471                         n = sizeof buf -1;
  472                 memmove(buf, va, n);
  473                 buf[n] = 0;
  474                 p = 0;
  475                 pt.x = strtoul(buf+1, &p, 0);
  476                 if(p == 0)
  477                         error(Eshort);
  478                 pt.y = strtoul(p, 0, 0);
  479                 qlock(&mouse);
  480                 if(ptinrect(pt, gscreen->r)){
  481                         mouse.xy = pt;
  482                         mouse.redraw = 1;
  483                         mouse.track = 1;
  484                         mouseclock();
  485                 }
  486                 qunlock(&mouse);
  487                 return n;
  488         }
  489 
  490         error(Egreg);
  491         return -1;
  492 }
  493 
  494 Dev mousedevtab = {
  495         'm',
  496         "mouse",
  497 
  498         mousereset,
  499         mouseinit,
  500         devshutdown,
  501         mouseattach,
  502         mousewalk,
  503         mousestat,
  504         mouseopen,
  505         mousecreate,
  506         mouseclose,
  507         mouseread,
  508         devbread,
  509         mousewrite,
  510         devbwrite,
  511         devremove,
  512         devwstat,
  513 };
  514 
  515 void
  516 Cursortocursor(Cursor *c)
  517 {
  518         lock(&cursor);
  519         memmove(&cursor.Cursor, c, sizeof(Cursor));
  520         setcursor(c);
  521         unlock(&cursor);
  522 }
  523 
  524 
  525 /*
  526  *  called by the clock routine to redraw the cursor
  527  */
  528 static void
  529 mouseclock(void)
  530 {
  531         if(mouse.track){
  532                 mousetrack(mouse.dx, mouse.dy, mouse.buttons, TK2MS(MACHP(0)->ticks));
  533                 mouse.track = 0;
  534                 mouse.dx = 0;
  535                 mouse.dy = 0;
  536         }
  537         if(mouse.redraw && canlock(&cursor)){
  538                 mouse.redraw = 0;
  539                 cursoroff(0);
  540                 mouse.redraw = cursoron(0);
  541                 unlock(&cursor);
  542         }
  543         drawactive(0);
  544 }
  545 
  546 static int
  547 scale(int x)
  548 {
  549         int sign = 1;
  550 
  551         if(x < 0){
  552                 sign = -1;
  553                 x = -x;
  554         }
  555         switch(x){
  556         case 0:
  557         case 1:
  558         case 2:
  559         case 3:
  560                 break;
  561         case 4:
  562                 x = 6 + (mouse.acceleration>>2);
  563                 break;
  564         case 5:
  565                 x = 9 + (mouse.acceleration>>1);
  566                 break;
  567         default:
  568                 x *= mouse.maxacc;
  569                 break;
  570         }
  571         return sign*x;
  572 }
  573 
  574 /*
  575  *  called at interrupt level to update the structure and
  576  *  awaken any waiting procs.
  577  */
  578 void
  579 mousetrack(int dx, int dy, int b, int msec)
  580 {
  581         int x, y, lastb;
  582 
  583         if(gscreen==nil)
  584                 return;
  585 
  586         if(mouse.acceleration){
  587                 dx = scale(dx);
  588                 dy = scale(dy);
  589         }
  590         x = mouse.xy.x + dx;
  591         if(x < gscreen->clipr.min.x)
  592                 x = gscreen->clipr.min.x;
  593         if(x >= gscreen->clipr.max.x)
  594                 x = gscreen->clipr.max.x;
  595         y = mouse.xy.y + dy;
  596         if(y < gscreen->clipr.min.y)
  597                 y = gscreen->clipr.min.y;
  598         if(y >= gscreen->clipr.max.y)
  599                 y = gscreen->clipr.max.y;
  600 
  601         lastb = mouse.buttons;
  602         mouse.xy = Pt(x, y);
  603         mouse.buttons = b|kbdbuttons;
  604         mouse.redraw = 1;
  605         mouse.counter++;
  606         mouse.msec = msec;
  607 
  608         /*
  609          * if the queue fills, we discard the entire queue and don't
  610          * queue any more events until a reader polls the mouse.
  611          */
  612         if(!mouse.qfull && lastb != b) {        /* add to ring */
  613                 mouse.queue[mouse.wi] = mouse.Mousestate;
  614                 if(++mouse.wi == nelem(mouse.queue))
  615                         mouse.wi = 0;
  616                 if(mouse.wi == mouse.ri)
  617                         mouse.qfull = 1;
  618         }
  619         wakeup(&mouse.r);
  620         drawactive(1);
  621 }
  622 
  623 /*
  624  *  microsoft 3 button, 7 bit bytes
  625  *
  626  *      byte 0 -        1  L  R Y7 Y6 X7 X6
  627  *      byte 1 -        0 X5 X4 X3 X2 X1 X0
  628  *      byte 2 -        0 Y5 Y4 Y3 Y2 Y1 Y0
  629  *      byte 3 -        0  M  x  x  x  x  x     (optional)
  630  *
  631  *  shift & right button is the same as middle button (for 2 button mice)
  632  */
  633 int
  634 m3mouseputc(Queue*, int c)
  635 {
  636         static uchar msg[3];
  637         static int nb;
  638         static int middle;
  639         static uchar b[] = { 0, 4, 1, 5, 0, 2, 1, 3 };
  640         short x;
  641         int dx, dy, newbuttons;
  642         static ulong lasttick;
  643         ulong m;
  644 
  645         /* Resynchronize in stream with timing. */
  646         m = MACHP(0)->ticks;
  647         if(TK2SEC(m - lasttick) > 2)
  648                 nb = 0;
  649         lasttick = m;
  650 
  651         if(nb==0){
  652                 /*
  653                  * an extra byte comes for middle button motion.
  654                  * only two possible values for the extra byte.
  655                  */
  656                 if(c == 0x00 || c == 0x20){
  657                         /* an extra byte gets sent for the middle button */
  658                         middle = (c&0x20) ? 2 : 0;
  659                         newbuttons = (mouse.buttons & ~2) | middle;
  660                         mousetrack(0, 0, newbuttons, TK2MS(MACHP(0)->ticks));
  661                         return 0;
  662                 }
  663         }
  664         msg[nb] = c;
  665         if(++nb == 3){
  666                 nb = 0;
  667                 newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)];
  668                 x = (msg[0]&0x3)<<14;
  669                 dx = (x>>8) | msg[1];
  670                 x = (msg[0]&0xc)<<12;
  671                 dy = (x>>8) | msg[2];
  672                 mousetrack(dx, dy, newbuttons, TK2MS(MACHP(0)->ticks));
  673         }
  674         return 0;
  675 }
  676 
  677 /*
  678  * microsoft intellimouse 3 buttons + scroll
  679  *      byte 0 -        1  L  R Y7 Y6 X7 X6
  680  *      byte 1 -        0 X5 X4 X3 X2 X1 X0
  681  *      byte 2 -        0 Y5 Y4 Y3 Y2 Y1 Y0
  682  *      byte 3 -        0  0  M  %  %  %  %
  683  *
  684  *      %: 0xf => U , 0x1 => D
  685  *
  686  *      L: left
  687  *      R: right
  688  *      U: up
  689  *      D: down
  690  */
  691 int
  692 m5mouseputc(Queue*, int c)
  693 {
  694         static uchar msg[3];
  695         static int nb;
  696         static ulong lasttick;
  697         ulong m;
  698 
  699         /* Resynchronize in stream with timing. */
  700         m = MACHP(0)->ticks;
  701         if(TK2SEC(m - lasttick) > 2)
  702                 nb = 0;
  703         lasttick = m;
  704 
  705         msg[nb++] = c & 0x7f;
  706         if (nb == 4) {
  707                 schar dx,dy,newbuttons;
  708                 dx = msg[1] | (msg[0] & 0x3) << 6;
  709                 dy = msg[2] | (msg[0] & 0xc) << 4;
  710                 newbuttons =
  711                         (msg[0] & 0x10) >> (mouseshifted ? 3 : 2)
  712                         | (msg[0] & 0x20) >> 5
  713                         | ( msg[3] == 0x10 ? 0x02 :
  714                             msg[3] == 0x0f ? ScrollUp :
  715                             msg[3] == 0x01 ? ScrollDown : 0 );
  716                 mousetrack(dx, dy, newbuttons, TK2MS(MACHP(0)->ticks));
  717                 nb = 0;
  718         }
  719         return 0;
  720 }
  721 
  722 /*
  723  *  Logitech 5 byte packed binary mouse format, 8 bit bytes
  724  *
  725  *  shift & right button is the same as middle button (for 2 button mice)
  726  */
  727 int
  728 mouseputc(Queue*, int c)
  729 {
  730         static short msg[5];
  731         static int nb;
  732         static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7, 0, 2, 2, 6, 1, 3, 3, 7};
  733         int dx, dy, newbuttons;
  734         static ulong lasttick;
  735         ulong m;
  736 
  737         /* Resynchronize in stream with timing. */
  738         m = MACHP(0)->ticks;
  739         if(TK2SEC(m - lasttick) > 2)
  740                 nb = 0;
  741         lasttick = m;
  742 
  743         if((c&0xF0) == 0x80)
  744                 nb=0;
  745         msg[nb] = c;
  746         if(c & 0x80)
  747                 msg[nb] |= ~0xFF;       /* sign extend */
  748         if(++nb == 5){
  749                 newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)];
  750                 dx = msg[1]+msg[3];
  751                 dy = -(msg[2]+msg[4]);
  752                 mousetrack(dx, dy, newbuttons, TK2MS(MACHP(0)->ticks));
  753                 nb = 0;
  754         }
  755         return 0;
  756 }
  757 
  758 int
  759 mousechanged(void*)
  760 {
  761         return mouse.lastcounter != mouse.counter ||
  762                 mouse.lastresize != mouse.resize;
  763 }
  764 
  765 Point
  766 mousexy(void)
  767 {
  768         return mouse.xy;
  769 }
  770 
  771 void
  772 mouseaccelerate(int x)
  773 {
  774         mouse.acceleration = x;
  775         if(mouse.acceleration < 3)
  776                 mouse.maxacc = 2;
  777         else
  778                 mouse.maxacc = mouse.acceleration;
  779 }
  780 
  781 /*
  782  * notify reader that screen has been resized
  783  */
  784 void
  785 mouseresize(void)
  786 {
  787         mouse.resize++;
  788         wakeup(&mouse.r);
  789 }
  790 

Cache object: 784ba505ac0b85a28e1a64f029cad44e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.