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/dev/misc/syscons/sysmouse.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 /*-
    2  * (MPSAFE)
    3  *
    4  * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer as
   12  *    the first lines of this file unmodified.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  *
   28  * $FreeBSD: src/sys/dev/syscons/sysmouse.c,v 1.2.2.2 2001/07/16 05:21:24 yokota Exp $
   29  */
   30 
   31 /* MPSAFE NOTE: This file uses the tty_token mostly for the linesw access and
   32  *              for the internal mouse structures. The latter ones could be protected
   33  *              by a local lock.
   34  */
   35 #include "opt_syscons.h"
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/conf.h>
   40 #include <sys/proc.h>
   41 #include <sys/priv.h>
   42 #include <sys/tty.h>
   43 #include <sys/kernel.h>
   44 #include <sys/thread2.h>
   45 
   46 #include <machine/console.h>
   47 #include <sys/mouse.h>
   48 
   49 #include "syscons.h"
   50 
   51 #ifndef SC_NO_SYSMOUSE
   52 
   53 #define CDEV_MAJOR      12              /* major number, shared with syscons */
   54 #define SC_MOUSE        128             /* minor number */
   55 
   56 static d_open_t         smopen;
   57 static d_close_t        smclose;
   58 static d_ioctl_t        smioctl;
   59 
   60 static struct dev_ops sm_ops = {
   61         { "sysmouse", 0, D_TTY },
   62         .d_open =       smopen,
   63         .d_close =      smclose,
   64         .d_read =       ttyread,
   65         .d_ioctl =      smioctl,
   66         .d_kqfilter =   ttykqfilter,
   67         .d_revoke =     ttyrevoke
   68 };
   69 
   70 /* local variables */
   71 static struct tty       *sysmouse_tty;
   72 static int              mouse_level;    /* sysmouse protocol level */
   73 static mousestatus_t    mouse_status;
   74 
   75 static void             smstart(struct tty *tp);
   76 static int              smparam(struct tty *tp, struct termios *t);
   77 
   78 static int
   79 smopen(struct dev_open_args *ap)
   80 {
   81         cdev_t dev = ap->a_head.a_dev;
   82         struct tty *tp;
   83         int ret;
   84 
   85         DPRINTF(5, ("smopen: dev:%d,%d, vty:%d\n",
   86                 major(dev), minor(dev), SC_VTY(dev)));
   87 
   88 #if 0
   89         if (SC_VTY(dev) != SC_MOUSE)
   90                 return ENXIO;
   91 #endif
   92 
   93         lwkt_gettoken(&tty_token);
   94         tp = dev->si_tty = ttymalloc(dev->si_tty);
   95         if (!(tp->t_state & TS_ISOPEN)) {
   96                 sysmouse_tty = tp;
   97                 tp->t_oproc = smstart;
   98                 tp->t_param = smparam;
   99                 tp->t_stop = nottystop;
  100                 tp->t_dev = dev;
  101                 ttychars(tp);
  102                 tp->t_iflag = 0;
  103                 tp->t_oflag = 0;
  104                 tp->t_lflag = 0;
  105                 tp->t_cflag = TTYDEF_CFLAG;
  106                 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
  107                 smparam(tp, &tp->t_termios);
  108                 (*linesw[tp->t_line].l_modem)(tp, 1);
  109         } else if (tp->t_state & TS_XCLUDE && priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) {
  110                 lwkt_reltoken(&tty_token);
  111                 return EBUSY;
  112         }
  113 
  114         ret = (*linesw[tp->t_line].l_open)(dev, tp);
  115         lwkt_reltoken(&tty_token);
  116         return ret;
  117 }
  118 
  119 static int
  120 smclose(struct dev_close_args *ap)
  121 {
  122         cdev_t dev = ap->a_head.a_dev;
  123         struct tty *tp;
  124 
  125         tp = dev->si_tty;
  126         crit_enter();
  127         lwkt_gettoken(&tty_token);
  128         mouse_level = 0;
  129         (*linesw[tp->t_line].l_close)(tp, ap->a_fflag);
  130         ttyclose(tp);
  131         lwkt_reltoken(&tty_token);
  132         crit_exit();
  133 
  134         return 0;
  135 }
  136 
  137 static void
  138 smstart(struct tty *tp)
  139 {
  140         struct clist *rbp;
  141         u_char buf[PCBURST];
  142 
  143         crit_enter();
  144         lwkt_gettoken(&tty_token);
  145         if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) {
  146                 tp->t_state |= TS_BUSY;
  147                 rbp = &tp->t_outq;
  148                 while (rbp->c_cc)
  149                         q_to_b(rbp, buf, PCBURST);
  150                 tp->t_state &= ~TS_BUSY;
  151                 ttwwakeup(tp);
  152         }
  153         lwkt_reltoken(&tty_token);
  154         crit_exit();
  155 }
  156 
  157 static int
  158 smparam(struct tty *tp, struct termios *t)
  159 {
  160         lwkt_gettoken(&tty_token);
  161         tp->t_ispeed = t->c_ispeed;
  162         tp->t_ospeed = t->c_ospeed;
  163         tp->t_cflag = t->c_cflag;
  164         lwkt_reltoken(&tty_token);
  165         return 0;
  166 }
  167 
  168 static int
  169 smioctl(struct dev_ioctl_args *ap)
  170 {
  171         cdev_t dev = ap->a_head.a_dev;
  172         struct tty *tp;
  173         mousehw_t *hw;
  174         mousemode_t *mode;
  175         int error;
  176 
  177         lwkt_gettoken(&tty_token);
  178         tp = dev->si_tty;
  179 
  180         switch (ap->a_cmd) {
  181         case MOUSE_GETHWINFO:   /* get device information */
  182                 hw = (mousehw_t *)ap->a_data;
  183                 hw->buttons = 10;               /* XXX unknown */
  184                 hw->iftype = MOUSE_IF_SYSMOUSE;
  185                 hw->type = MOUSE_MOUSE;
  186                 hw->model = MOUSE_MODEL_GENERIC;
  187                 hw->hwid = 0;
  188                 lwkt_reltoken(&tty_token);
  189                 return 0;
  190 
  191         case MOUSE_GETMODE:     /* get protocol/mode */
  192                 mode = (mousemode_t *)ap->a_data;
  193                 mode->level = mouse_level;
  194                 switch (mode->level) {
  195                 case 0: /* emulate MouseSystems protocol */
  196                         mode->protocol = MOUSE_PROTO_MSC;
  197                         mode->rate = -1;                /* unknown */
  198                         mode->resolution = -1;  /* unknown */
  199                         mode->accelfactor = 0;  /* disabled */
  200                         mode->packetsize = MOUSE_MSC_PACKETSIZE;
  201                         mode->syncmask[0] = MOUSE_MSC_SYNCMASK;
  202                         mode->syncmask[1] = MOUSE_MSC_SYNC;
  203                         break;
  204 
  205                 case 1: /* sysmouse protocol */
  206                         mode->protocol = MOUSE_PROTO_SYSMOUSE;
  207                         mode->rate = -1;
  208                         mode->resolution = -1;
  209                         mode->accelfactor = 0;
  210                         mode->packetsize = MOUSE_SYS_PACKETSIZE;
  211                         mode->syncmask[0] = MOUSE_SYS_SYNCMASK;
  212                         mode->syncmask[1] = MOUSE_SYS_SYNC;
  213                         break;
  214                 }
  215                 lwkt_reltoken(&tty_token);
  216                 return 0;
  217 
  218         case MOUSE_SETMODE:     /* set protocol/mode */
  219                 mode = (mousemode_t *)ap->a_data;
  220                 if (mode->level == -1)
  221                         ;       /* don't change the current setting */
  222                 else if ((mode->level < 0) || (mode->level > 1)) {
  223                         lwkt_reltoken(&tty_token);
  224                         return EINVAL;
  225                 } else {
  226                         mouse_level = mode->level;
  227                 }
  228                 lwkt_reltoken(&tty_token);
  229                 return 0;
  230 
  231         case MOUSE_GETLEVEL:    /* get operation level */
  232                 *(int *)ap->a_data = mouse_level;
  233                 lwkt_reltoken(&tty_token);
  234                 return 0;
  235 
  236         case MOUSE_SETLEVEL:    /* set operation level */
  237                 if ((*(int *)ap->a_data  < 0) || (*(int *)ap->a_data > 1)) {
  238                         lwkt_reltoken(&tty_token);
  239                         return EINVAL;
  240                 }
  241                 mouse_level = *(int *)ap->a_data;
  242                 lwkt_reltoken(&tty_token);
  243                 return 0;
  244 
  245         case MOUSE_GETSTATUS:   /* get accumulated mouse events */
  246                 crit_enter();
  247                 *(mousestatus_t *)ap->a_data = mouse_status;
  248                 mouse_status.flags = 0;
  249                 mouse_status.obutton = mouse_status.button;
  250                 mouse_status.dx = 0;
  251                 mouse_status.dy = 0;
  252                 mouse_status.dz = 0;
  253                 crit_exit();
  254                 lwkt_reltoken(&tty_token);
  255                 return 0;
  256 
  257 #if 0 /* notyet */
  258         case MOUSE_GETVARS:     /* get internal mouse variables */
  259         case MOUSE_SETVARS:     /* set internal mouse variables */
  260                 lwkt_reltoken(&tty_token);
  261                 return ENODEV;
  262 #endif
  263 
  264         case MOUSE_READSTATE:   /* read status from the device */
  265         case MOUSE_READDATA:    /* read data from the device */
  266                 lwkt_reltoken(&tty_token);
  267                 return ENODEV;
  268         }
  269 
  270         error = (*linesw[tp->t_line].l_ioctl)(tp, ap->a_cmd, ap->a_data, ap->a_fflag, ap->a_cred);
  271         if (error != ENOIOCTL) {
  272                 lwkt_reltoken(&tty_token);
  273                 return error;
  274         }
  275         error = ttioctl(tp, ap->a_cmd, ap->a_data, ap->a_fflag);
  276         if (error != ENOIOCTL) {
  277                 lwkt_reltoken(&tty_token);
  278                 return error;
  279         }
  280         lwkt_reltoken(&tty_token);
  281         return ENOTTY;
  282 }
  283 
  284 static void
  285 sm_attach_mouse(void *unused)
  286 {
  287         cdev_t dev;
  288 
  289         dev = make_dev(&sm_ops, SC_MOUSE, UID_ROOT, GID_WHEEL,
  290                        0600, "sysmouse");
  291         /* sysmouse doesn't have scr_stat */
  292 }
  293 
  294 SYSINIT(sysmouse, SI_SUB_DRIVERS, SI_ORDER_MIDDLE + CDEV_MAJOR,
  295         sm_attach_mouse, NULL)
  296 
  297 int
  298 sysmouse_event(mouse_info_t *info)
  299 {
  300         /* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */
  301         static int butmap[8] = {
  302             MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
  303             MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
  304             MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP,
  305             MOUSE_MSC_BUTTON3UP,
  306             MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP,
  307             MOUSE_MSC_BUTTON2UP,
  308             MOUSE_MSC_BUTTON1UP,
  309             0,
  310         };
  311         u_char buf[8];
  312         int x, y, z;
  313         int i;
  314 
  315         lwkt_gettoken(&tty_token);
  316         switch (info->operation) {
  317         case MOUSE_ACTION:
  318                 mouse_status.button = info->u.data.buttons;
  319                 /* FALL THROUGH */
  320         case MOUSE_MOTION_EVENT:
  321                 x = info->u.data.x;
  322                 y = info->u.data.y;
  323                 z = info->u.data.z;
  324                 break;
  325         case MOUSE_BUTTON_EVENT:
  326                 x = y = z = 0;
  327                 if (info->u.event.value > 0)
  328                         mouse_status.button |= info->u.event.id;
  329                 else
  330                         mouse_status.button &= ~info->u.event.id;
  331                 break;
  332         default:
  333                 lwkt_reltoken(&tty_token);
  334                 return 0;
  335         }
  336 
  337         mouse_status.dx += x;
  338         mouse_status.dy += y;
  339         mouse_status.dz += z;
  340         mouse_status.flags |= ((x || y || z) ? MOUSE_POSCHANGED : 0)
  341                               | (mouse_status.obutton ^ mouse_status.button);
  342         if (mouse_status.flags == 0) {
  343                 lwkt_reltoken(&tty_token);
  344                 return 0;
  345         }
  346 
  347         if ((sysmouse_tty == NULL) || !(sysmouse_tty->t_state & TS_ISOPEN)) {
  348                 lwkt_reltoken(&tty_token);
  349                 return mouse_status.flags;
  350         }
  351 
  352         /* the first five bytes are compatible with MouseSystems' */
  353         buf[0] = MOUSE_MSC_SYNC
  354                  | butmap[mouse_status.button & MOUSE_STDBUTTONS];
  355         x = imax(imin(x, 255), -256);
  356         buf[1] = x >> 1;
  357         buf[3] = x - buf[1];
  358         y = -imax(imin(y, 255), -256);
  359         buf[2] = y >> 1;
  360         buf[4] = y - buf[2];
  361         for (i = 0; i < MOUSE_MSC_PACKETSIZE; ++i)
  362                 (*linesw[sysmouse_tty->t_line].l_rint)(buf[i], sysmouse_tty);
  363         if (mouse_level >= 1) {
  364                 /* extended part */
  365                 z = imax(imin(z, 127), -128);
  366                 buf[5] = (z >> 1) & 0x7f;
  367                 buf[6] = (z - (z >> 1)) & 0x7f;
  368                 /* buttons 4-10 */
  369                 buf[7] = (~mouse_status.button >> 3) & 0x7f;
  370                 for (i = MOUSE_MSC_PACKETSIZE; i < MOUSE_SYS_PACKETSIZE; ++i)
  371                         (*linesw[sysmouse_tty->t_line].l_rint)(buf[i],
  372                                                                sysmouse_tty);
  373         }
  374 
  375         lwkt_reltoken(&tty_token);
  376         return mouse_status.flags;
  377 }
  378 
  379 #endif /* !SC_NO_SYSMOUSE */

Cache object: 4916fc646f1347d6a55035669fc6b3f1


[ 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.