Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / uts / common / io / vuidmice / vuidm5p.c
blob70a5cfe52c5406c639440153796640ba0e17c19f
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * 5-Byte Mouse Protocol
30 #include <sys/param.h>
31 #include <sys/stream.h>
32 #include <sys/strsun.h>
33 #include <sys/vuid_event.h>
34 #include "vuidmice.h"
36 #define LOGI_NUMBUTTONS 3 /* Number of buttons */
38 #define LOGI_BMASK (uchar_t)7 /* Button mask in packet */
39 #define LOGI_NOT_BMASK (uchar_t)(~LOGI_BMASK) /* Rest of the bits */
40 #define LOGI_START_CODE (uchar_t)(0x80) /* Start code in char */
42 #define LOGI_START 0 /* Beginning of packet */
43 #define LOGI_BUTTON 1 /* Got button status */
44 #define LOGI_DELTA_X1 2 /* First of 2 delta X */
45 #define LOGI_DELTA_Y1 3 /* First of 2 delta Y */
46 #define LOGI_DELTA_X2 4 /* Second of 2 delta X */
48 extern void VUID_PUTNEXT(queue_t *const, uchar_t, uchar_t, uchar_t, int);
50 int
51 VUID_OPEN(queue_t *const qp)
54 * The current kdmconfig tables imply that this module can be used
55 * for both 2- and 3- button mice, so based on that evidence we
56 * can't assume a constant. I don't know whether it's possible
57 * to autodetect.
59 STATEP->nbuttons = 0; /* Don't know. */
61 return (0);
64 static void
65 vuidm5p_sendButtonEvent(queue_t *const qp)
67 int b;
69 /* for each button, see if it has changed */
70 for (b = 0; b < 3; b++) {
71 uchar_t mask = 4 >> b;
73 if ((STATEP->buttons&mask) != (STATEP->oldbuttons&mask))
74 VUID_PUTNEXT(qp, BUT(b+1), FE_PAIR_NONE, 0,
75 (STATEP->buttons & mask ? 1 : 0));
79 void
80 vuidm5p(queue_t *const qp, mblk_t *mp)
82 int r, code;
83 uchar_t *bufp;
85 bufp = mp->b_rptr;
86 r = MBLKL(mp);
88 for (r--; r >= 0; r--) {
89 code = *bufp++;
91 switch (STATEP->state) {
93 * Start state. We stay here if the start code is not
94 * received thus forcing us back into sync. When we
95 * get a start code the button mask comes with it
96 * forcing us to the next state.
98 default:
99 resync:
100 case LOGI_START:
101 if ((code & LOGI_NOT_BMASK) != LOGI_START_CODE)
102 break;
104 STATEP->state = LOGI_BUTTON;
105 STATEP->deltax = STATEP->deltay = 0;
106 STATEP->buttons = (~code) & LOGI_BMASK;
107 /* or xlate[code & ] */
108 break;
110 case LOGI_BUTTON:
112 * We receive the first of 2 delta x which forces us
113 * to the next state. We just add the values of each
114 * delta x together.
116 if ((code & LOGI_NOT_BMASK) == LOGI_START_CODE) {
117 STATEP->state = LOGI_START;
118 goto resync;
121 /* (The cast sign extends the 8-bit value.) */
122 STATEP->deltax += (signed char)code;
123 STATEP->state = LOGI_DELTA_X1;
124 break;
126 case LOGI_DELTA_X1:
128 * The first of 2 delta y. We just add
129 * the 2 delta y together
131 if ((code & LOGI_NOT_BMASK) == LOGI_START_CODE) {
132 STATEP->state = LOGI_START;
133 goto resync;
136 /* (The cast sign extends the 8-bit value.) */
137 STATEP->deltay += (signed char)code;
138 STATEP->state = LOGI_DELTA_Y1;
139 break;
141 case LOGI_DELTA_Y1:
143 * The second of 2 delta x. We just add
144 * the 2 delta x together.
146 if ((code & LOGI_NOT_BMASK) == LOGI_START_CODE) {
147 STATEP->state = LOGI_START;
148 goto resync;
151 /* (The cast sign extends the 8-bit value.) */
152 STATEP->deltax += (signed char)code;
153 STATEP->state = LOGI_DELTA_X2;
154 break;
156 case LOGI_DELTA_X2:
158 * The second of 2 delta y. We just add
159 * the 2 delta y together.
161 if ((code & LOGI_NOT_BMASK) == LOGI_START_CODE) {
162 STATEP->state = LOGI_START;
163 goto resync;
166 /* (The cast sign extends the 8-bit value.) */
167 STATEP->deltay += (signed char)code;
168 STATEP->state = LOGI_START;
170 /* check if motion has occurred and send event(s)... */
171 if (STATEP->deltax)
172 VUID_PUTNEXT(qp,
173 (uchar_t)LOC_X_DELTA, FE_PAIR_ABSOLUTE,
174 (uchar_t)LOC_X_ABSOLUTE, STATEP->deltax);
176 if (STATEP->deltay)
177 VUID_PUTNEXT(qp,
178 (uchar_t)LOC_Y_DELTA, FE_PAIR_ABSOLUTE,
179 (uchar_t)LOC_Y_ABSOLUTE, STATEP->deltay);
181 STATEP->deltax = STATEP->deltay = 0;
183 /* see if the buttons have changed */
184 if (STATEP->buttons != STATEP->oldbuttons) {
185 /* buttons have changed */
186 vuidm5p_sendButtonEvent(qp);
188 /* update new button state */
189 STATEP->oldbuttons = STATEP->buttons;
193 freemsg(mp);