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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * 5-Byte Mouse Protocol 28 */ 29 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" 35 36 #define LOGI_NUMBUTTONS 3 /* Number of buttons */ 37 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 */ 41 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 */ 47 48 extern void VUID_PUTNEXT(queue_t *const, uchar_t, uchar_t, uchar_t, int); 49 50 int 51 VUID_OPEN(queue_t *const qp) 52 { 53 /* 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. 58 */ 59 STATEP->nbuttons = 0; /* Don't know. */ 60 61 return (0); 62 } 63 64 static void 65 vuidm5p_sendButtonEvent(queue_t *const qp) 66 { 67 int b; 68 69 /* for each button, see if it has changed */ 70 for (b = 0; b < 3; b++) { 71 uchar_t mask = 4 >> b; 72 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)); 76 } 77 } 78 79 void 80 vuidm5p(queue_t *const qp, mblk_t *mp) 81 { 82 int r, code; 83 uchar_t *bufp; 84 85 bufp = mp->b_rptr; 86 r = MBLKL(mp); 87 88 for (r--; r >= 0; r--) { 89 code = *bufp++; 90 91 switch (STATEP->state) { 92 /* 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. 97 */ 98 default: 99 resync: 100 case LOGI_START: 101 if ((code & LOGI_NOT_BMASK) != LOGI_START_CODE) 102 break; 103 104 STATEP->state = LOGI_BUTTON; 105 STATEP->deltax = STATEP->deltay = 0; 106 STATEP->buttons = (~code) & LOGI_BMASK; 107 /* or xlate[code & ] */ 108 break; 109 110 case LOGI_BUTTON: 111 /* 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. 115 */ 116 if ((code & LOGI_NOT_BMASK) == LOGI_START_CODE) { 117 STATEP->state = LOGI_START; 118 goto resync; 119 } 120 121 /* (The cast sign extends the 8-bit value.) */ 122 STATEP->deltax += (signed char)code; 123 STATEP->state = LOGI_DELTA_X1; 124 break; 125 126 case LOGI_DELTA_X1: 127 /* 128 * The first of 2 delta y. We just add 129 * the 2 delta y together 130 */ 131 if ((code & LOGI_NOT_BMASK) == LOGI_START_CODE) { 132 STATEP->state = LOGI_START; 133 goto resync; 134 } 135 136 /* (The cast sign extends the 8-bit value.) */ 137 STATEP->deltay += (signed char)code; 138 STATEP->state = LOGI_DELTA_Y1; 139 break; 140 141 case LOGI_DELTA_Y1: 142 /* 143 * The second of 2 delta x. We just add 144 * the 2 delta x together. 145 */ 146 if ((code & LOGI_NOT_BMASK) == LOGI_START_CODE) { 147 STATEP->state = LOGI_START; 148 goto resync; 149 } 150 151 /* (The cast sign extends the 8-bit value.) */ 152 STATEP->deltax += (signed char)code; 153 STATEP->state = LOGI_DELTA_X2; 154 break; 155 156 case LOGI_DELTA_X2: 157 /* 158 * The second of 2 delta y. We just add 159 * the 2 delta y together. 160 */ 161 if ((code & LOGI_NOT_BMASK) == LOGI_START_CODE) { 162 STATEP->state = LOGI_START; 163 goto resync; 164 } 165 166 /* (The cast sign extends the 8-bit value.) */ 167 STATEP->deltay += (signed char)code; 168 STATEP->state = LOGI_START; 169 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); 175 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); 180 181 STATEP->deltax = STATEP->deltay = 0; 182 183 /* see if the buttons have changed */ 184 if (STATEP->buttons != STATEP->oldbuttons) { 185 /* buttons have changed */ 186 vuidm5p_sendButtonEvent(qp); 187 188 /* update new button state */ 189 STATEP->oldbuttons = STATEP->buttons; 190 } 191 } 192 } 193 freemsg(mp); 194 } 195