1*c08965e9Schrisz /* $OpenBSD: mouse.c,v 1.22 2024/10/05 13:27:16 chrisz Exp $ */ 2e0b2c52dSmickey /* $NetBSD: mouse.c,v 1.3 1999/11/15 13:47:30 ad Exp $ */ 3e0b2c52dSmickey 4e0b2c52dSmickey /*- 5e0b2c52dSmickey * Copyright (c) 1998 The NetBSD Foundation, Inc. 6e0b2c52dSmickey * All rights reserved. 7e0b2c52dSmickey * 8e0b2c52dSmickey * This code is derived from software contributed to The NetBSD Foundation 9e0b2c52dSmickey * by Juergen Hannken-Illjes. 10e0b2c52dSmickey * 11e0b2c52dSmickey * Redistribution and use in source and binary forms, with or without 12e0b2c52dSmickey * modification, are permitted provided that the following conditions 13e0b2c52dSmickey * are met: 14e0b2c52dSmickey * 1. Redistributions of source code must retain the above copyright 15e0b2c52dSmickey * notice, this list of conditions and the following disclaimer. 16e0b2c52dSmickey * 2. Redistributions in binary form must reproduce the above copyright 17e0b2c52dSmickey * notice, this list of conditions and the following disclaimer in the 18e0b2c52dSmickey * documentation and/or other materials provided with the distribution. 19e0b2c52dSmickey * 20e0b2c52dSmickey * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21e0b2c52dSmickey * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22e0b2c52dSmickey * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23e0b2c52dSmickey * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24e0b2c52dSmickey * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25e0b2c52dSmickey * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26e0b2c52dSmickey * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27e0b2c52dSmickey * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28e0b2c52dSmickey * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29e0b2c52dSmickey * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30e0b2c52dSmickey * POSSIBILITY OF SUCH DAMAGE. 31e0b2c52dSmickey */ 32e0b2c52dSmickey 33e0b2c52dSmickey #include <sys/ioctl.h> 34e0b2c52dSmickey #include <sys/time.h> 35e0b2c52dSmickey #include <dev/wscons/wsconsio.h> 36e0b2c52dSmickey #include <err.h> 37589b65e9Srobert #include <errno.h> 381222b15bSmaja #include <fcntl.h> 391222b15bSmaja #include <stdio.h> 40e0b2c52dSmickey #include "wsconsctl.h" 41d22ea701Sbru #include "mousecfg.h" 42e0b2c52dSmickey 43f7ed5097Sshadchin static u_int mstype; 44f7ed5097Sshadchin static u_int resolution; 45f7ed5097Sshadchin static u_int samplerate; 46589b65e9Srobert static int rawmode; 47589b65e9Srobert 4888e6ce2aSmatthieu struct wsmouse_calibcoords wmcoords, wmcoords_save; 49e0b2c52dSmickey 50e0b2c52dSmickey struct field mouse_field_tab[] = { 51e0b2c52dSmickey { "resolution", &resolution, FMT_UINT, FLG_WRONLY }, 52e0b2c52dSmickey { "samplerate", &samplerate, FMT_UINT, FLG_WRONLY }, 53e0b2c52dSmickey { "type", &mstype, FMT_MSTYPE, FLG_RDONLY }, 54589b65e9Srobert { "rawmode", &rawmode, FMT_UINT, FLG_MODIFY|FLG_INIT}, 55589b65e9Srobert { "scale", &wmcoords, FMT_SCALE, FLG_MODIFY|FLG_INIT}, 5677727bd5Sbru /* mouse and touchpad configuration (mousecfg): */ 5777727bd5Sbru { "reverse_scrolling", &cfg_revscroll, FMT_CFG, FLG_NORDBACK }, 5877727bd5Sbru /* touchpad-specific options: */ 59d22ea701Sbru { "tp.tapping", &cfg_tapping, FMT_CFG, FLG_NORDBACK }, 609310c18aSbru { "tp.mtbuttons", &cfg_mtbuttons, FMT_CFG, FLG_NORDBACK }, 61*c08965e9Schrisz { "tp.scaling", &cfg_scaling, FMT_CFG, FLG_NORDBACK | FLG_WRONLY }, 62d22ea701Sbru { "tp.swapsides", &cfg_swapsides, FMT_CFG, FLG_NORDBACK }, 63d22ea701Sbru { "tp.disable", &cfg_disable, FMT_CFG, FLG_NORDBACK }, 640137e658Sbru { "tp.edges", &cfg_edges, FMT_CFG, FLG_NORDBACK }, 65d22ea701Sbru { "tp.param", &cfg_param, FMT_CFG, FLG_WRONLY }, 66*c08965e9Schrisz /* Add aliases. These fields are valid for all wsmouse devices. */ 67a143f7beSbru { "param", &cfg_param, FMT_CFG, FLG_WRONLY }, 68*c08965e9Schrisz { "scaling", &cfg_scaling, FMT_CFG, FLG_NORDBACK }, 6982bc7287Smickey { NULL } 70e0b2c52dSmickey }; 71e0b2c52dSmickey 72d22ea701Sbru static int dev_index = -1; 73d22ea701Sbru 749310c18aSbru static struct wsmouse_parameters mtbtn_maxdist = { 759310c18aSbru (struct wsmouse_param[]) { { WSMOUSECFG_MTBTN_MAXDIST, 0 } }, 1 769310c18aSbru }; 779310c18aSbru 78d22ea701Sbru 79d22ea701Sbru void 80d22ea701Sbru mouse_init(int devfd, int devidx) { 81d22ea701Sbru struct field *f; 82d22ea701Sbru const char *errstr; 83d22ea701Sbru int err; 84d22ea701Sbru 85d22ea701Sbru if (dev_index == devidx) 86d22ea701Sbru return; 87d22ea701Sbru 88d22ea701Sbru if ((err = mousecfg_init(devfd, &errstr))) { 89d22ea701Sbru devidx = -1; 90d22ea701Sbru for (f = mouse_field_tab; f->name != NULL; f++) { 91d22ea701Sbru if (f->format == FMT_CFG) 92d22ea701Sbru f->flags |= FLG_DEAD; 93d22ea701Sbru } 94d22ea701Sbru warnx("mousecfg error: %s (%d)", errstr, err); 95a143f7beSbru } else if (cfg_touchpad) { 96a143f7beSbru for (f = mouse_field_tab; f->name != NULL; f++) 97a143f7beSbru if (f->format == FMT_CFG) { 98a143f7beSbru f->flags &= ~FLG_DEAD; 99a143f7beSbru } 1009310c18aSbru /* Hide the 'mtbuttons' field if the feature is unavailable. */ 1019310c18aSbru if (mousecfg_get_field(&mtbtn_maxdist) || 1029310c18aSbru mtbtn_maxdist.params[0].value < 0) { 1039310c18aSbru f = field_by_value(mouse_field_tab, &cfg_mtbuttons); 1049310c18aSbru f->flags |= FLG_DEAD; 1059310c18aSbru } 106ff9cd955Sbru } else { 107a143f7beSbru for (f = mouse_field_tab; f->name != NULL; f++) 108a143f7beSbru if (f->format == FMT_CFG) { 10977727bd5Sbru if (f->valp != &cfg_param 110*c08965e9Schrisz && f->valp != &cfg_scaling 11177727bd5Sbru && f->valp != &cfg_revscroll) 112a143f7beSbru f->flags |= FLG_DEAD; 113a143f7beSbru else 114d22ea701Sbru f->flags &= ~FLG_DEAD; 115d22ea701Sbru } 116d22ea701Sbru } 117d22ea701Sbru 118d22ea701Sbru dev_index = devidx; 119d22ea701Sbru } 120d22ea701Sbru 121e0b2c52dSmickey void 12254e3cb1dSfgsch mouse_get_values(int fd) 123e0b2c52dSmickey { 124d22ea701Sbru struct field *f; 125d22ea701Sbru 12682bc7287Smickey if (field_by_value(mouse_field_tab, &mstype)->flags & FLG_GET) 127df69c215Sderaadt if (ioctl(fd, WSMOUSEIO_GTYPE, &mstype) == -1) 128b0520bc4Smiod warn("WSMOUSEIO_GTYPE"); 129589b65e9Srobert 130589b65e9Srobert if (field_by_value(mouse_field_tab, &rawmode)->flags & FLG_GET) { 131df69c215Sderaadt if (ioctl(fd, WSMOUSEIO_GCALIBCOORDS, &wmcoords) == -1) { 132589b65e9Srobert if (errno == ENOTTY) 133589b65e9Srobert field_by_value(mouse_field_tab, 134589b65e9Srobert &rawmode)->flags |= FLG_DEAD; 135589b65e9Srobert else 136589b65e9Srobert warn("WSMOUSEIO_GCALIBCOORDS"); 137589b65e9Srobert } 138589b65e9Srobert rawmode = wmcoords.samplelen; 139589b65e9Srobert } 140589b65e9Srobert 141589b65e9Srobert if (field_by_value(mouse_field_tab, &wmcoords)->flags & FLG_GET) 142df69c215Sderaadt if (ioctl(fd, WSMOUSEIO_GCALIBCOORDS, &wmcoords) == -1) { 143589b65e9Srobert if (errno == ENOTTY) 144589b65e9Srobert field_by_value(mouse_field_tab, 145589b65e9Srobert &wmcoords)->flags |= FLG_DEAD; 146589b65e9Srobert else 147589b65e9Srobert warn("WSMOUSEIO_GCALIBCOORDS"); 148589b65e9Srobert } 149d22ea701Sbru 150d22ea701Sbru for (f = mouse_field_tab; f->name != NULL; f++) { 151a143f7beSbru if (f->format != FMT_CFG || !(f->flags & FLG_GET) 152a143f7beSbru || f->valp == &cfg_param || (f->flags & FLG_DEAD)) 153d22ea701Sbru continue; 154d22ea701Sbru if (mousecfg_get_field((struct wsmouse_parameters *) f->valp)) { 155d22ea701Sbru f->flags |= FLG_DEAD; 156d22ea701Sbru warnx("mousecfg: invalid key in '%s'", f->name); 157d22ea701Sbru } 158d22ea701Sbru } 159e0b2c52dSmickey } 160e0b2c52dSmickey 161f0cd74dfSmartynas int 16254e3cb1dSfgsch mouse_put_values(int fd) 163e0b2c52dSmickey { 164d22ea701Sbru struct field *f; 165d22ea701Sbru 16682bc7287Smickey if (field_by_value(mouse_field_tab, &resolution)->flags & FLG_SET) { 167df69c215Sderaadt if (ioctl(fd, WSMOUSEIO_SRES, &resolution) == -1) { 168b0520bc4Smiod warn("WSMOUSEIO_SRES"); 169f0cd74dfSmartynas return 1; 170e0b2c52dSmickey } 171b0520bc4Smiod } 172589b65e9Srobert if (field_by_value(mouse_field_tab, &rawmode)->flags & FLG_SET) { 173589b65e9Srobert wmcoords.samplelen = rawmode; 174df69c215Sderaadt if (ioctl(fd, WSMOUSEIO_SCALIBCOORDS, &wmcoords) == -1) { 175589b65e9Srobert if (errno == ENOTTY) { 176589b65e9Srobert field_by_value(mouse_field_tab, 177589b65e9Srobert &rawmode)->flags |= FLG_DEAD; 178589b65e9Srobert } else { 179f0cd74dfSmartynas warn("WSMOUSEIO_SCALIBCOORDS"); 180f0cd74dfSmartynas return 1; 181f0cd74dfSmartynas } 182589b65e9Srobert } 183589b65e9Srobert } 184589b65e9Srobert if (field_by_value(mouse_field_tab, &wmcoords)->flags & FLG_SET) { 185df69c215Sderaadt if (ioctl(fd, WSMOUSEIO_GCALIBCOORDS, &wmcoords_save) == -1) { 18688e6ce2aSmatthieu if (errno == ENOTTY) 18788e6ce2aSmatthieu field_by_value(mouse_field_tab, 18888e6ce2aSmatthieu &wmcoords)->flags |= FLG_DEAD; 18988e6ce2aSmatthieu else 19088e6ce2aSmatthieu warn("WSMOUSEIO_GCALIBCOORDS"); 19154e3cb1dSfgsch } 19288e6ce2aSmatthieu wmcoords.samplelen = wmcoords_save.samplelen; 193df69c215Sderaadt if (ioctl(fd, WSMOUSEIO_SCALIBCOORDS, &wmcoords) == -1) { 194589b65e9Srobert if (errno == ENOTTY) { 195589b65e9Srobert field_by_value(mouse_field_tab, 196589b65e9Srobert &wmcoords)->flags |= FLG_DEAD; 197589b65e9Srobert } else { 198f0cd74dfSmartynas warn("WSMOUSEIO_SCALIBCOORDS"); 199f0cd74dfSmartynas return 1; 200589b65e9Srobert } 201589b65e9Srobert } 202e0b2c52dSmickey } 203f0cd74dfSmartynas 204d22ea701Sbru for (f = mouse_field_tab; f->name != NULL; f++) { 205d22ea701Sbru if (f->format != FMT_CFG || !(f->flags & FLG_SET)) 206d22ea701Sbru continue; 207d22ea701Sbru if (mousecfg_put_field(fd, 208d22ea701Sbru (struct wsmouse_parameters *) f->valp)) { 209d22ea701Sbru warn("mousecfg error (%s)", f->name); 210d22ea701Sbru return 1; 211d22ea701Sbru } 212d22ea701Sbru } 213d22ea701Sbru 214f0cd74dfSmartynas return 0; 215f0cd74dfSmartynas } 2161222b15bSmaja 21754e3cb1dSfgsch char * 21854e3cb1dSfgsch mouse_next_device(int index) 2191222b15bSmaja { 22054e3cb1dSfgsch static char devname[20]; 2211222b15bSmaja 22254e3cb1dSfgsch snprintf(devname, sizeof(devname), "/dev/wsmouse%d", index); 22354e3cb1dSfgsch return (devname); 2241222b15bSmaja } 225