sysmouse.c revision 199881
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: head/sys/dev/syscons/sysmouse.c 199881 2009-11-28 16:25:55Z ed $"); 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> 4066834Sphk#include <sys/consio.h> 4166860Sphk#include <sys/mouse.h> 4256043Syokota 4356043Syokota#include <dev/syscons/syscons.h> 4456043Syokota 4556043Syokota#ifndef SC_NO_SYSMOUSE 4656043Syokota 4756043Syokota/* local variables */ 4856043Syokotastatic struct tty *sysmouse_tty; 4956043Syokotastatic int mouse_level; /* sysmouse protocol level */ 5056043Syokotastatic mousestatus_t mouse_status; 5156043Syokota 52181905Sedstatic void 53181905Sedsmdev_close(struct tty *tp) 5456043Syokota{ 5556043Syokota mouse_level = 0; 5656043Syokota} 5756043Syokota 5856043Syokotastatic int 59181905Sedsmdev_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) 6056043Syokota{ 6156043Syokota mousehw_t *hw; 6256043Syokota mousemode_t *mode; 6356043Syokota 6456043Syokota switch (cmd) { 6556043Syokota 6656043Syokota case MOUSE_GETHWINFO: /* get device information */ 6756043Syokota hw = (mousehw_t *)data; 6856043Syokota hw->buttons = 10; /* XXX unknown */ 6956043Syokota hw->iftype = MOUSE_IF_SYSMOUSE; 7056043Syokota hw->type = MOUSE_MOUSE; 7156043Syokota hw->model = MOUSE_MODEL_GENERIC; 7256043Syokota hw->hwid = 0; 7356043Syokota return 0; 7456043Syokota 7556043Syokota case MOUSE_GETMODE: /* get protocol/mode */ 7656043Syokota mode = (mousemode_t *)data; 7756043Syokota mode->level = mouse_level; 7856043Syokota switch (mode->level) { 7956043Syokota case 0: /* emulate MouseSystems protocol */ 8056043Syokota mode->protocol = MOUSE_PROTO_MSC; 8156043Syokota mode->rate = -1; /* unknown */ 8256043Syokota mode->resolution = -1; /* unknown */ 8356043Syokota mode->accelfactor = 0; /* disabled */ 8456043Syokota mode->packetsize = MOUSE_MSC_PACKETSIZE; 8556043Syokota mode->syncmask[0] = MOUSE_MSC_SYNCMASK; 8656043Syokota mode->syncmask[1] = MOUSE_MSC_SYNC; 8756043Syokota break; 8856043Syokota 8956043Syokota case 1: /* sysmouse protocol */ 9056043Syokota mode->protocol = MOUSE_PROTO_SYSMOUSE; 9156043Syokota mode->rate = -1; 9256043Syokota mode->resolution = -1; 9356043Syokota mode->accelfactor = 0; 9456043Syokota mode->packetsize = MOUSE_SYS_PACKETSIZE; 9556043Syokota mode->syncmask[0] = MOUSE_SYS_SYNCMASK; 9656043Syokota mode->syncmask[1] = MOUSE_SYS_SYNC; 9756043Syokota break; 9856043Syokota } 9956043Syokota return 0; 10056043Syokota 10156043Syokota case MOUSE_SETMODE: /* set protocol/mode */ 10256043Syokota mode = (mousemode_t *)data; 10365129Syokota if (mode->level == -1) 10465129Syokota ; /* don't change the current setting */ 10565129Syokota else if ((mode->level < 0) || (mode->level > 1)) 10656043Syokota return EINVAL; 10765129Syokota else 10865129Syokota mouse_level = mode->level; 10956043Syokota return 0; 11056043Syokota 11156043Syokota case MOUSE_GETLEVEL: /* get operation level */ 11256043Syokota *(int *)data = mouse_level; 11356043Syokota return 0; 11456043Syokota 11556043Syokota case MOUSE_SETLEVEL: /* set operation level */ 11656043Syokota if ((*(int *)data < 0) || (*(int *)data > 1)) 11756043Syokota return EINVAL; 11856043Syokota mouse_level = *(int *)data; 11956043Syokota return 0; 12056043Syokota 12156043Syokota case MOUSE_GETSTATUS: /* get accumulated mouse events */ 12256043Syokota *(mousestatus_t *)data = mouse_status; 12356043Syokota mouse_status.flags = 0; 12456043Syokota mouse_status.obutton = mouse_status.button; 12556043Syokota mouse_status.dx = 0; 12656043Syokota mouse_status.dy = 0; 12756043Syokota mouse_status.dz = 0; 12856043Syokota return 0; 12956043Syokota 130153072Sru#ifdef notyet 13156043Syokota case MOUSE_GETVARS: /* get internal mouse variables */ 13256043Syokota case MOUSE_SETVARS: /* set internal mouse variables */ 13356043Syokota return ENODEV; 13456043Syokota#endif 13556043Syokota 13656043Syokota case MOUSE_READSTATE: /* read status from the device */ 13756043Syokota case MOUSE_READDATA: /* read data from the device */ 13856043Syokota return ENODEV; 13956043Syokota } 14056043Syokota 141181905Sed return (ENOIOCTL); 14256043Syokota} 14356043Syokota 144181905Sedstatic int 145181905Sedsmdev_param(struct tty *tp, struct termios *t) 14656043Syokota{ 14756043Syokota 148181905Sed /* 149181905Sed * Set the output baud rate to zero. The mouse device supports 150181905Sed * no output, so we don't want to waste buffers. 151181905Sed */ 152184771Sed t->c_ispeed = TTYDEF_SPEED; 153181905Sed t->c_ospeed = B0; 154136505Sphk 155181905Sed return (0); 15656043Syokota} 15756043Syokota 158181905Sedstatic struct ttydevsw smdev_ttydevsw = { 159181905Sed .tsw_flags = TF_NOPREFIX, 160181905Sed .tsw_close = smdev_close, 161181905Sed .tsw_ioctl = smdev_ioctl, 162181905Sed .tsw_param = smdev_param, 163181905Sed}; 164181905Sed 165181905Sedstatic void 166181905Sedsm_attach_mouse(void *unused) 167181905Sed{ 168193018Sed sysmouse_tty = tty_alloc(&smdev_ttydevsw, NULL); 169181905Sed tty_makedev(sysmouse_tty, NULL, "sysmouse"); 170181905Sed} 171181905Sed 172177253SrwatsonSYSINIT(sysmouse, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sm_attach_mouse, NULL); 17356043Syokota 17456043Syokotaint 17556043Syokotasysmouse_event(mouse_info_t *info) 17656043Syokota{ 17756043Syokota /* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */ 17856043Syokota static int butmap[8] = { 17956043Syokota MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP, 18056043Syokota MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP, 18156043Syokota MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP, 18256043Syokota MOUSE_MSC_BUTTON3UP, 18356043Syokota MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP, 18456043Syokota MOUSE_MSC_BUTTON2UP, 18556043Syokota MOUSE_MSC_BUTTON1UP, 18656043Syokota 0, 18756043Syokota }; 18856043Syokota u_char buf[8]; 18956043Syokota int x, y, z; 190182109Sed int i, flags = 0; 19156043Syokota 192182109Sed tty_lock(sysmouse_tty); 193182109Sed 19456043Syokota switch (info->operation) { 19556043Syokota case MOUSE_ACTION: 19656043Syokota mouse_status.button = info->u.data.buttons; 19756043Syokota /* FALL THROUGH */ 19856043Syokota case MOUSE_MOTION_EVENT: 19956043Syokota x = info->u.data.x; 20056043Syokota y = info->u.data.y; 20156043Syokota z = info->u.data.z; 20256043Syokota break; 20356043Syokota case MOUSE_BUTTON_EVENT: 20456043Syokota x = y = z = 0; 20556043Syokota if (info->u.event.value > 0) 20656043Syokota mouse_status.button |= info->u.event.id; 20756043Syokota else 20856043Syokota mouse_status.button &= ~info->u.event.id; 20956043Syokota break; 21056043Syokota default: 211182109Sed goto done; 21256043Syokota } 21356043Syokota 21456043Syokota mouse_status.dx += x; 21556043Syokota mouse_status.dy += y; 21656043Syokota mouse_status.dz += z; 21756043Syokota mouse_status.flags |= ((x || y || z) ? MOUSE_POSCHANGED : 0) 21856043Syokota | (mouse_status.obutton ^ mouse_status.button); 219182109Sed flags = mouse_status.flags; 220182109Sed if (flags == 0 || !tty_opened(sysmouse_tty)) 221182109Sed goto done; 22256043Syokota 22356043Syokota /* the first five bytes are compatible with MouseSystems' */ 22456043Syokota buf[0] = MOUSE_MSC_SYNC 22556043Syokota | butmap[mouse_status.button & MOUSE_STDBUTTONS]; 22656043Syokota x = imax(imin(x, 255), -256); 22756043Syokota buf[1] = x >> 1; 22856043Syokota buf[3] = x - buf[1]; 22956043Syokota y = -imax(imin(y, 255), -256); 23056043Syokota buf[2] = y >> 1; 23156043Syokota buf[4] = y - buf[2]; 23256043Syokota for (i = 0; i < MOUSE_MSC_PACKETSIZE; ++i) 233181905Sed ttydisc_rint(sysmouse_tty, buf[i], 0); 23456043Syokota if (mouse_level >= 1) { 23556043Syokota /* extended part */ 23656043Syokota z = imax(imin(z, 127), -128); 23756043Syokota buf[5] = (z >> 1) & 0x7f; 23856043Syokota buf[6] = (z - (z >> 1)) & 0x7f; 23956043Syokota /* buttons 4-10 */ 24056043Syokota buf[7] = (~mouse_status.button >> 3) & 0x7f; 24156043Syokota for (i = MOUSE_MSC_PACKETSIZE; i < MOUSE_SYS_PACKETSIZE; ++i) 242181905Sed ttydisc_rint(sysmouse_tty, buf[i], 0); 24356043Syokota } 244181905Sed ttydisc_rint_done(sysmouse_tty); 24556043Syokota 246182109Seddone: tty_unlock(sysmouse_tty); 247182109Sed return (flags); 24856043Syokota} 24956043Syokota 25056043Syokota#endif /* !SC_NO_SYSMOUSE */ 251