156043Syokota/*- 256043Syokota * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 356043Syokota * All rights reserved. 456043Syokota * 556043Syokota * Redistribution and use in source and binary forms, with or without 656043Syokota * modification, are permitted provided that the following conditions 756043Syokota * are met: 856043Syokota * 1. Redistributions of source code must retain the above copyright 956043Syokota * notice, this list of conditions and the following disclaimer as 1056043Syokota * the first lines of this file unmodified. 1156043Syokota * 2. Redistributions in binary form must reproduce the above copyright 1256043Syokota * notice, this list of conditions and the following disclaimer in the 1356043Syokota * documentation and/or other materials provided with the distribution. 1456043Syokota * 1556043Syokota * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 1656043Syokota * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1756043Syokota * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1856043Syokota * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 1956043Syokota * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2056043Syokota * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2156043Syokota * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2256043Syokota * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2356043Syokota * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2456043Syokota * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2556043Syokota * 2656043Syokota */ 2756043Syokota 28119420Sobrien#include <sys/cdefs.h> 29119420Sobrien__FBSDID("$FreeBSD: releng/11.0/sys/dev/syscons/sysmouse.c 267965 2014-06-27 17:50:33Z emaste $"); 30119420Sobrien 3156043Syokota#include "opt_syscons.h" 3256043Syokota 3356043Syokota#include <sys/param.h> 3456043Syokota#include <sys/systm.h> 35164033Srwatson#include <sys/priv.h> 36181905Sed#include <sys/serial.h> 3756043Syokota#include <sys/tty.h> 38199881Sed#include <sys/ttydefaults.h> 3956043Syokota#include <sys/kernel.h> 40267965Semaste#include <sys/cons.h> 4166834Sphk#include <sys/consio.h> 4266860Sphk#include <sys/mouse.h> 4356043Syokota 4456043Syokota#include <dev/syscons/syscons.h> 4556043Syokota 4656043Syokota#ifndef SC_NO_SYSMOUSE 4756043Syokota 4856043Syokota/* local variables */ 4956043Syokotastatic struct tty *sysmouse_tty; 5056043Syokotastatic int mouse_level; /* sysmouse protocol level */ 5156043Syokotastatic mousestatus_t mouse_status; 5256043Syokota 53181905Sedstatic void 54181905Sedsmdev_close(struct tty *tp) 5556043Syokota{ 5656043Syokota mouse_level = 0; 5756043Syokota} 5856043Syokota 5956043Syokotastatic int 60181905Sedsmdev_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) 6156043Syokota{ 6256043Syokota mousehw_t *hw; 6356043Syokota mousemode_t *mode; 6456043Syokota 6556043Syokota switch (cmd) { 6656043Syokota 6756043Syokota case MOUSE_GETHWINFO: /* get device information */ 6856043Syokota hw = (mousehw_t *)data; 6956043Syokota hw->buttons = 10; /* XXX unknown */ 7056043Syokota hw->iftype = MOUSE_IF_SYSMOUSE; 7156043Syokota hw->type = MOUSE_MOUSE; 7256043Syokota hw->model = MOUSE_MODEL_GENERIC; 7356043Syokota hw->hwid = 0; 7456043Syokota return 0; 7556043Syokota 7656043Syokota case MOUSE_GETMODE: /* get protocol/mode */ 7756043Syokota mode = (mousemode_t *)data; 7856043Syokota mode->level = mouse_level; 7956043Syokota switch (mode->level) { 8056043Syokota case 0: /* emulate MouseSystems protocol */ 8156043Syokota mode->protocol = MOUSE_PROTO_MSC; 8256043Syokota mode->rate = -1; /* unknown */ 8356043Syokota mode->resolution = -1; /* unknown */ 8456043Syokota mode->accelfactor = 0; /* disabled */ 8556043Syokota mode->packetsize = MOUSE_MSC_PACKETSIZE; 8656043Syokota mode->syncmask[0] = MOUSE_MSC_SYNCMASK; 8756043Syokota mode->syncmask[1] = MOUSE_MSC_SYNC; 8856043Syokota break; 8956043Syokota 9056043Syokota case 1: /* sysmouse protocol */ 9156043Syokota mode->protocol = MOUSE_PROTO_SYSMOUSE; 9256043Syokota mode->rate = -1; 9356043Syokota mode->resolution = -1; 9456043Syokota mode->accelfactor = 0; 9556043Syokota mode->packetsize = MOUSE_SYS_PACKETSIZE; 9656043Syokota mode->syncmask[0] = MOUSE_SYS_SYNCMASK; 9756043Syokota mode->syncmask[1] = MOUSE_SYS_SYNC; 9856043Syokota break; 9956043Syokota } 10056043Syokota return 0; 10156043Syokota 10256043Syokota case MOUSE_SETMODE: /* set protocol/mode */ 10356043Syokota mode = (mousemode_t *)data; 10465129Syokota if (mode->level == -1) 10565129Syokota ; /* don't change the current setting */ 10665129Syokota else if ((mode->level < 0) || (mode->level > 1)) 10756043Syokota return EINVAL; 10865129Syokota else 10965129Syokota mouse_level = mode->level; 11056043Syokota return 0; 11156043Syokota 11256043Syokota case MOUSE_GETLEVEL: /* get operation level */ 11356043Syokota *(int *)data = mouse_level; 11456043Syokota return 0; 11556043Syokota 11656043Syokota case MOUSE_SETLEVEL: /* set operation level */ 11756043Syokota if ((*(int *)data < 0) || (*(int *)data > 1)) 11856043Syokota return EINVAL; 11956043Syokota mouse_level = *(int *)data; 12056043Syokota return 0; 12156043Syokota 12256043Syokota case MOUSE_GETSTATUS: /* get accumulated mouse events */ 12356043Syokota *(mousestatus_t *)data = mouse_status; 12456043Syokota mouse_status.flags = 0; 12556043Syokota mouse_status.obutton = mouse_status.button; 12656043Syokota mouse_status.dx = 0; 12756043Syokota mouse_status.dy = 0; 12856043Syokota mouse_status.dz = 0; 12956043Syokota return 0; 13056043Syokota 131153072Sru#ifdef notyet 13256043Syokota case MOUSE_GETVARS: /* get internal mouse variables */ 13356043Syokota case MOUSE_SETVARS: /* set internal mouse variables */ 13456043Syokota return ENODEV; 13556043Syokota#endif 13656043Syokota 13756043Syokota case MOUSE_READSTATE: /* read status from the device */ 13856043Syokota case MOUSE_READDATA: /* read data from the device */ 13956043Syokota return ENODEV; 14056043Syokota } 14156043Syokota 142181905Sed return (ENOIOCTL); 14356043Syokota} 14456043Syokota 145181905Sedstatic int 146181905Sedsmdev_param(struct tty *tp, struct termios *t) 14756043Syokota{ 14856043Syokota 149181905Sed /* 150181905Sed * Set the output baud rate to zero. The mouse device supports 151181905Sed * no output, so we don't want to waste buffers. 152181905Sed */ 153184771Sed t->c_ispeed = TTYDEF_SPEED; 154181905Sed t->c_ospeed = B0; 155136505Sphk 156181905Sed return (0); 15756043Syokota} 15856043Syokota 159181905Sedstatic struct ttydevsw smdev_ttydevsw = { 160181905Sed .tsw_flags = TF_NOPREFIX, 161181905Sed .tsw_close = smdev_close, 162181905Sed .tsw_ioctl = smdev_ioctl, 163181905Sed .tsw_param = smdev_param, 164181905Sed}; 165181905Sed 166181905Sedstatic void 167181905Sedsm_attach_mouse(void *unused) 168181905Sed{ 169267965Semaste if (!vty_enabled(VTY_SC)) 170267625Sray return; 171193018Sed sysmouse_tty = tty_alloc(&smdev_ttydevsw, NULL); 172181905Sed tty_makedev(sysmouse_tty, NULL, "sysmouse"); 173181905Sed} 174181905Sed 175177253SrwatsonSYSINIT(sysmouse, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sm_attach_mouse, NULL); 17656043Syokota 17756043Syokotaint 17856043Syokotasysmouse_event(mouse_info_t *info) 17956043Syokota{ 18056043Syokota /* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */ 18156043Syokota static int butmap[8] = { 18256043Syokota MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP, 18356043Syokota MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP, 18456043Syokota MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP, 18556043Syokota MOUSE_MSC_BUTTON3UP, 18656043Syokota MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP, 18756043Syokota MOUSE_MSC_BUTTON2UP, 18856043Syokota MOUSE_MSC_BUTTON1UP, 18956043Syokota 0, 19056043Syokota }; 19156043Syokota u_char buf[8]; 19256043Syokota int x, y, z; 193182109Sed int i, flags = 0; 19456043Syokota 195182109Sed tty_lock(sysmouse_tty); 196182109Sed 19756043Syokota switch (info->operation) { 19856043Syokota case MOUSE_ACTION: 19956043Syokota mouse_status.button = info->u.data.buttons; 20056043Syokota /* FALL THROUGH */ 20156043Syokota case MOUSE_MOTION_EVENT: 20256043Syokota x = info->u.data.x; 20356043Syokota y = info->u.data.y; 20456043Syokota z = info->u.data.z; 20556043Syokota break; 20656043Syokota case MOUSE_BUTTON_EVENT: 20756043Syokota x = y = z = 0; 20856043Syokota if (info->u.event.value > 0) 20956043Syokota mouse_status.button |= info->u.event.id; 21056043Syokota else 21156043Syokota mouse_status.button &= ~info->u.event.id; 21256043Syokota break; 21356043Syokota default: 214182109Sed goto done; 21556043Syokota } 21656043Syokota 21756043Syokota mouse_status.dx += x; 21856043Syokota mouse_status.dy += y; 21956043Syokota mouse_status.dz += z; 22056043Syokota mouse_status.flags |= ((x || y || z) ? MOUSE_POSCHANGED : 0) 22156043Syokota | (mouse_status.obutton ^ mouse_status.button); 222182109Sed flags = mouse_status.flags; 223182109Sed if (flags == 0 || !tty_opened(sysmouse_tty)) 224182109Sed goto done; 22556043Syokota 22656043Syokota /* the first five bytes are compatible with MouseSystems' */ 22756043Syokota buf[0] = MOUSE_MSC_SYNC 22856043Syokota | butmap[mouse_status.button & MOUSE_STDBUTTONS]; 22956043Syokota x = imax(imin(x, 255), -256); 23056043Syokota buf[1] = x >> 1; 23156043Syokota buf[3] = x - buf[1]; 23256043Syokota y = -imax(imin(y, 255), -256); 23356043Syokota buf[2] = y >> 1; 23456043Syokota buf[4] = y - buf[2]; 23556043Syokota for (i = 0; i < MOUSE_MSC_PACKETSIZE; ++i) 236181905Sed ttydisc_rint(sysmouse_tty, buf[i], 0); 23756043Syokota if (mouse_level >= 1) { 23856043Syokota /* extended part */ 23956043Syokota z = imax(imin(z, 127), -128); 24056043Syokota buf[5] = (z >> 1) & 0x7f; 24156043Syokota buf[6] = (z - (z >> 1)) & 0x7f; 24256043Syokota /* buttons 4-10 */ 24356043Syokota buf[7] = (~mouse_status.button >> 3) & 0x7f; 24456043Syokota for (i = MOUSE_MSC_PACKETSIZE; i < MOUSE_SYS_PACKETSIZE; ++i) 245181905Sed ttydisc_rint(sysmouse_tty, buf[i], 0); 24656043Syokota } 247181905Sed ttydisc_rint_done(sysmouse_tty); 24856043Syokota 249182109Seddone: tty_unlock(sysmouse_tty); 250182109Sed return (flags); 25156043Syokota} 25256043Syokota 25356043Syokota#endif /* !SC_NO_SYSMOUSE */ 254