1 /* $NetBSD: tpcalib.c,v 1.3 2005/02/27 00:27:52 perry Exp $ */ 2 3 /* 4 * Copyright (c) 1999-2003 TAKEMURA Shin All rights reserved. 5 * Copyright (c) 1999 PocketBSD Project. 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. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 */ 29 30 #include <sys/cdefs.h> 31 __KERNEL_RCSID(0, "$NetBSD: tpcalib.c,v 1.3 2005/02/27 00:27:52 perry Exp $"); 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/device.h> 36 #include <sys/kernel.h> 37 #include <dev/wscons/wsconsio.h> 38 #include <dev/wscons/tpcalibvar.h> 39 40 #define TPCALIBDEBUG 41 #ifdef TPCALIBDEBUG 42 int tpcalib_debug = 0; 43 #define DPRINTF(arg) if (tpcalib_debug) printf arg; 44 #else 45 #define DPRINTF(arg) 46 #endif 47 48 /* mra is defined in mra.c */ 49 extern int mra_Y_AX1_BX2_C(int *, int, int *, int, int *, int, int, int, int *, 50 int *, int *); 51 52 #define SCALE (1024*256) 53 54 int 55 tpcalib_init(struct tpcalib_softc *sc) 56 { 57 tpcalib_reset(sc); 58 return (0); 59 } 60 61 void 62 tpcalib_reset(struct tpcalib_softc *sc) 63 { 64 /* This indicate 'raw mode'. No translation will be done. */ 65 sc->sc_saved.samplelen = WSMOUSE_CALIBCOORDS_RESET; 66 } 67 68 void 69 tpcalib_trans(struct tpcalib_softc *sc, int rawx, int rawy, int *x, int *y) 70 { 71 if (sc->sc_saved.samplelen == WSMOUSE_CALIBCOORDS_RESET) { 72 /* This indicate 'raw mode'. No translation will be done. */ 73 *x = rawx; 74 *y = rawy; 75 } else { 76 *x = (sc->sc_ax * rawx + sc->sc_bx * rawy) / SCALE + sc->sc_cx; 77 *y = (sc->sc_ay * rawx + sc->sc_by * rawy) / SCALE + sc->sc_cy; 78 if (*x < sc->sc_minx) *x = sc->sc_minx; 79 if (*y < sc->sc_miny) *y = sc->sc_miny; 80 if (sc->sc_maxx < *x) 81 *x = sc->sc_maxx; 82 if (sc->sc_maxy < *y) 83 *y = sc->sc_maxy; 84 } 85 } 86 87 int 88 tpcalib_ioctl(struct tpcalib_softc *sc, u_long cmd, caddr_t data, int flag, 89 struct proc *p) 90 { 91 struct wsmouse_calibcoords *d; 92 int s; 93 94 switch (cmd) { 95 case WSMOUSEIO_SCALIBCOORDS: 96 s = sizeof(struct wsmouse_calibcoord); 97 d = (struct wsmouse_calibcoords *)data; 98 if (d->samplelen == WSMOUSE_CALIBCOORDS_RESET) { 99 tpcalib_reset(sc); 100 } else 101 if (mra_Y_AX1_BX2_C(&d->samples[0].x, s, 102 &d->samples[0].rawx, s, 103 &d->samples[0].rawy, s, 104 d->samplelen, SCALE, 105 &sc->sc_ax, &sc->sc_bx, &sc->sc_cx) || 106 mra_Y_AX1_BX2_C(&d->samples[0].y, s, 107 &d->samples[0].rawx, s, 108 &d->samples[0].rawy, s, 109 d->samplelen, SCALE, 110 &sc->sc_ay, &sc->sc_by, &sc->sc_cy)) { 111 printf("tpcalib: MRA error"); 112 tpcalib_reset(sc); 113 114 return (EINVAL); 115 } else { 116 sc->sc_minx = d->minx; 117 sc->sc_maxx = d->maxx; 118 sc->sc_miny = d->miny; 119 sc->sc_maxy = d->maxy; 120 sc->sc_saved = *d; 121 DPRINTF(("tpcalib: x=%d~%d y=%d~%d\n", 122 sc->sc_minx, sc->sc_maxx, 123 sc->sc_miny, sc->sc_maxy)); 124 DPRINTF(("tpcalib: Ax=%d Bx=%d Cx=%d\n", 125 sc->sc_ax, sc->sc_bx, sc->sc_cx)); 126 DPRINTF(("tpcalib: Ay=%d By=%d Cy=%d\n", 127 sc->sc_ay, sc->sc_by, sc->sc_cy)); 128 } 129 break; 130 131 case WSMOUSEIO_GCALIBCOORDS: 132 d = (struct wsmouse_calibcoords *)data; 133 *d = sc->sc_saved; 134 break; 135 136 default: 137 return (EPASSTHROUGH); 138 } 139 return (0); 140 } 141