1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * 5-Byte Mouse Protocol 30 */ 31 32 #include <sys/param.h> 33 #include <sys/stream.h> 34 #include <sys/strsun.h> 35 #include <sys/vuid_event.h> 36 #include <sys/vuidmice.h> 37 38 #define LOGI_NUMBUTTONS 3 /* Number of buttons */ 39 40 #define LOGI_BMASK (uchar_t)7 /* Button mask in packet */ 41 #define LOGI_NOT_BMASK (uchar_t)(~LOGI_BMASK) /* Rest of the bits */ 42 #define LOGI_START_CODE (uchar_t)(0x80) /* Start code in char */ 43 44 #define LOGI_START 0 /* Beginning of packet */ 45 #define LOGI_BUTTON 1 /* Got button status */ 46 #define LOGI_DELTA_X1 2 /* First of 2 delta X */ 47 #define LOGI_DELTA_Y1 3 /* First of 2 delta Y */ 48 #define LOGI_DELTA_X2 4 /* Second of 2 delta X */ 49 50 extern void VUID_PUTNEXT(queue_t *const, uchar_t, uchar_t, uchar_t, int); 51 52 int 53 VUID_OPEN(queue_t *const qp) 54 { 55 /* 56 * The current kdmconfig tables imply that this module can be used 57 * for both 2- and 3- button mice, so based on that evidence we 58 * can't assume a constant. I don't know whether it's possible 59 * to autodetect. 60 */ 61 STATEP->nbuttons = 0; /* Don't know. */ 62 63 return (0); 64 } 65 66 static void 67 vuidm5p_sendButtonEvent(queue_t *const qp) 68 { 69 int b; 70 71 /* for each button, see if it has changed */ 72 for (b = 0; b < 3; b++) { 73 uchar_t mask = 4 >> b; 74 75 if ((STATEP->buttons&mask) != (STATEP->oldbuttons&mask)) 76 VUID_PUTNEXT(qp, BUT(b+1), FE_PAIR_NONE, 0, 77 (STATEP->buttons & mask ? 1 : 0)); 78 } 79 } 80 81 void 82 vuidm5p(queue_t *const qp, mblk_t *mp) 83 { 84 int r, code; 85 uchar_t *bufp; 86 87 bufp = mp->b_rptr; 88 r = MBLKL(mp); 89 90 for (r--; r >= 0; r--) { 91 code = *bufp++; 92 93 switch (STATEP->state) { 94 /* 95 * Start state. We stay here if the start code is not 96 * received thus forcing us back into sync. When we 97 * get a start code the button mask comes with it 98 * forcing us to the next state. 99 */ 100 default: 101 resync: 102 case LOGI_START: 103 if ((code & LOGI_NOT_BMASK) != LOGI_START_CODE) 104 break; 105 106 STATEP->state = LOGI_BUTTON; 107 STATEP->deltax = STATEP->deltay = 0; 108 STATEP->buttons = (~code) & LOGI_BMASK; 109 /* or xlate[code & ] */ 110 break; 111 112 case LOGI_BUTTON: 113 /* 114 * We receive the first of 2 delta x which forces us 115 * to the next state. We just add the values of each 116 * delta x together. 117 */ 118 if ((code & LOGI_NOT_BMASK) == LOGI_START_CODE) { 119 STATEP->state = LOGI_START; 120 goto resync; 121 } 122 123 /* (The cast sign extends the 8-bit value.) */ 124 STATEP->deltax += (signed char)code; 125 STATEP->state = LOGI_DELTA_X1; 126 break; 127 128 case LOGI_DELTA_X1: 129 /* 130 * The first of 2 delta y. We just add 131 * the 2 delta y together 132 */ 133 if ((code & LOGI_NOT_BMASK) == LOGI_START_CODE) { 134 STATEP->state = LOGI_START; 135 goto resync; 136 } 137 138 /* (The cast sign extends the 8-bit value.) */ 139 STATEP->deltay += (signed char)code; 140 STATEP->state = LOGI_DELTA_Y1; 141 break; 142 143 case LOGI_DELTA_Y1: 144 /* 145 * The second of 2 delta x. We just add 146 * the 2 delta x together. 147 */ 148 if ((code & LOGI_NOT_BMASK) == LOGI_START_CODE) { 149 STATEP->state = LOGI_START; 150 goto resync; 151 } 152 153 /* (The cast sign extends the 8-bit value.) */ 154 STATEP->deltax += (signed char)code; 155 STATEP->state = LOGI_DELTA_X2; 156 break; 157 158 case LOGI_DELTA_X2: 159 /* 160 * The second of 2 delta y. We just add 161 * the 2 delta y together. 162 */ 163 if ((code & LOGI_NOT_BMASK) == LOGI_START_CODE) { 164 STATEP->state = LOGI_START; 165 goto resync; 166 } 167 168 /* (The cast sign extends the 8-bit value.) */ 169 STATEP->deltay += (signed char)code; 170 STATEP->state = LOGI_START; 171 172 /* check if motion has occurred and send event(s)... */ 173 if (STATEP->deltax) 174 VUID_PUTNEXT(qp, 175 (uchar_t)LOC_X_DELTA, FE_PAIR_ABSOLUTE, 176 (uchar_t)LOC_X_ABSOLUTE, STATEP->deltax); 177 178 if (STATEP->deltay) 179 VUID_PUTNEXT(qp, 180 (uchar_t)LOC_Y_DELTA, FE_PAIR_ABSOLUTE, 181 (uchar_t)LOC_Y_ABSOLUTE, STATEP->deltay); 182 183 STATEP->deltax = STATEP->deltay = 0; 184 185 /* see if the buttons have changed */ 186 if (STATEP->buttons != STATEP->oldbuttons) { 187 /* buttons have changed */ 188 vuidm5p_sendButtonEvent(qp); 189 190 /* update new button state */ 191 STATEP->oldbuttons = STATEP->buttons; 192 } 193 } 194 } 195 freemsg(mp); 196 } 197