1 | /* $NetBSD: tpcalib.c,v 1.11 2007/03/04 06:02:51 christos 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 AUTHOR 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 AUTHOR 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.11 2007/03/04 06:02:51 christos Exp $" ); |
32 | |
33 | #ifdef _KERNEL_OPT |
34 | #include "opt_tpcalib.h" |
35 | #endif |
36 | |
37 | #include <sys/param.h> |
38 | #include <sys/systm.h> |
39 | #include <sys/device.h> |
40 | #include <sys/kernel.h> |
41 | #include <dev/wscons/wsconsio.h> |
42 | #include <dev/wscons/tpcalibvar.h> |
43 | |
44 | #ifdef TPCALIBDEBUG |
45 | int tpcalib_debug = 0; |
46 | #define DPRINTF(arg) if (tpcalib_debug) printf arg; |
47 | #else |
48 | #define DPRINTF(arg) |
49 | #endif |
50 | |
51 | /* mra is defined in mra.c */ |
52 | extern int mra_Y_AX1_BX2_C(const int *, int, |
53 | const int *, int, const int *, int, int, int, |
54 | int *, int *, int *); |
55 | |
56 | #define SCALE (1024*256) |
57 | |
58 | int |
59 | tpcalib_init(struct tpcalib_softc *sc) |
60 | { |
61 | tpcalib_reset(sc); |
62 | return (0); |
63 | } |
64 | |
65 | void |
66 | tpcalib_reset(struct tpcalib_softc *sc) |
67 | { |
68 | /* This indicate 'raw mode'. No translation will be done. */ |
69 | sc->sc_saved.samplelen = WSMOUSE_CALIBCOORDS_RESET; |
70 | } |
71 | |
72 | void |
73 | tpcalib_trans(struct tpcalib_softc *sc, int rawx, int rawy, int *x, int *y) |
74 | { |
75 | if (sc->sc_saved.samplelen == WSMOUSE_CALIBCOORDS_RESET) { |
76 | /* This indicate 'raw mode'. No translation will be done. */ |
77 | *x = rawx; |
78 | *y = rawy; |
79 | } else { |
80 | *x = (sc->sc_ax * rawx + sc->sc_bx * rawy) / SCALE + sc->sc_cx; |
81 | *y = (sc->sc_ay * rawx + sc->sc_by * rawy) / SCALE + sc->sc_cy; |
82 | if (*x < sc->sc_minx) *x = sc->sc_minx; |
83 | if (*y < sc->sc_miny) *y = sc->sc_miny; |
84 | if (sc->sc_maxx < *x) |
85 | *x = sc->sc_maxx; |
86 | if (sc->sc_maxy < *y) |
87 | *y = sc->sc_maxy; |
88 | } |
89 | } |
90 | |
91 | int |
92 | tpcalib_ioctl(struct tpcalib_softc *sc, u_long cmd, void *data, |
93 | int flag, struct lwp *l) |
94 | { |
95 | const struct wsmouse_calibcoords *d; |
96 | int s; |
97 | |
98 | switch (cmd) { |
99 | case WSMOUSEIO_SCALIBCOORDS: |
100 | s = sizeof(struct wsmouse_calibcoord); |
101 | d = (const struct wsmouse_calibcoords *)data; |
102 | if (d->samplelen == WSMOUSE_CALIBCOORDS_RESET) { |
103 | tpcalib_reset(sc); |
104 | } else |
105 | if (mra_Y_AX1_BX2_C(&d->samples[0].x, s, |
106 | &d->samples[0].rawx, s, |
107 | &d->samples[0].rawy, s, |
108 | d->samplelen, SCALE, |
109 | &sc->sc_ax, &sc->sc_bx, &sc->sc_cx) || |
110 | mra_Y_AX1_BX2_C(&d->samples[0].y, s, |
111 | &d->samples[0].rawx, s, |
112 | &d->samples[0].rawy, s, |
113 | d->samplelen, SCALE, |
114 | &sc->sc_ay, &sc->sc_by, &sc->sc_cy)) { |
115 | printf("tpcalib: MRA error" ); |
116 | tpcalib_reset(sc); |
117 | |
118 | return (EINVAL); |
119 | } else { |
120 | sc->sc_minx = d->minx; |
121 | sc->sc_maxx = d->maxx; |
122 | sc->sc_miny = d->miny; |
123 | sc->sc_maxy = d->maxy; |
124 | sc->sc_saved = *d; |
125 | DPRINTF(("tpcalib: x=%d~%d y=%d~%d\n" , |
126 | sc->sc_minx, sc->sc_maxx, |
127 | sc->sc_miny, sc->sc_maxy)); |
128 | DPRINTF(("tpcalib: Ax=%d Bx=%d Cx=%d\n" , |
129 | sc->sc_ax, sc->sc_bx, sc->sc_cx)); |
130 | DPRINTF(("tpcalib: Ay=%d By=%d Cy=%d\n" , |
131 | sc->sc_ay, sc->sc_by, sc->sc_cy)); |
132 | } |
133 | break; |
134 | |
135 | case WSMOUSEIO_GCALIBCOORDS: |
136 | *(struct wsmouse_calibcoords *)data = sc->sc_saved; |
137 | break; |
138 | |
139 | default: |
140 | return (EPASSTHROUGH); |
141 | } |
142 | return (0); |
143 | } |
144 | |