Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/vuidmice/vuidmice.c
+++ new/usr/src/uts/common/io/vuidmice/vuidmice.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26
27 27 /*
28 28 * VUIDMICE module: put mouse events into vuid format
29 29 */
30 30
31 31 #include <sys/param.h>
32 32 #include <sys/stream.h>
33 33 #include <sys/stropts.h>
34 34 #include <sys/strsun.h>
35 35 #include <sys/errno.h>
36 36 #include <sys/debug.h>
37 37 #include <sys/cmn_err.h>
38 38 #include <sys/sad.h>
39 39 #include <sys/vuid_event.h>
40 40 #include "vuidmice.h"
41 41 #include <sys/vuid_wheel.h>
42 42 #include <sys/msio.h>
43 43
44 44 #include <sys/conf.h>
45 45 #include <sys/modctl.h>
46 46
47 47 #include <sys/kmem.h>
48 48 #include <sys/ddi.h>
49 49 #include <sys/sunddi.h>
50 50
51 51 static int vuidmice_open(queue_t *const, const dev_t *const,
52 52 const int, const int, const cred_t *const);
53 53 static int vuidmice_close(queue_t *const, const int, const cred_t *const);
54 54 static int vuidmice_rput(queue_t *const, mblk_t *);
55 55 static int vuidmice_rsrv(queue_t *const);
56 56 static int vuidmice_wput(queue_t *const, mblk_t *);
57 57 static void vuidmice_miocdata(queue_t *const, mblk_t *);
58 58 static int vuidmice_handle_wheel_resolution_ioctl(queue_t *const,
59 59 mblk_t *, int);
60 60
61 61 static int vuidmice_service_wheel_info(mblk_t *);
62 62 static int vuidmice_service_wheel_state(queue_t *, mblk_t *, uint_t);
63 63
64 64 void VUID_QUEUE(queue_t *const, mblk_t *);
65 65 int VUID_OPEN(queue_t *const);
66 66 void VUID_CLOSE(queue_t *const);
67 67
68 68 static kmutex_t vuidmice_lock;
69 69
70 70 static struct module_info vuidmice_iinfo = {
71 71 0,
72 72 VUID_NAME,
73 73 0,
74 74 INFPSZ,
75 75 1000,
76 76 100
77 77 };
78 78
79 79 static struct qinit vuidmice_rinit = {
80 80 vuidmice_rput,
81 81 vuidmice_rsrv,
82 82 vuidmice_open,
83 83 vuidmice_close,
84 84 NULL,
85 85 &vuidmice_iinfo,
86 86 NULL
87 87 };
88 88
89 89 static struct module_info vuidmice_oinfo = {
90 90 0,
91 91 VUID_NAME,
92 92 0,
93 93 INFPSZ,
94 94 1000,
95 95 100
96 96 };
97 97
98 98 static struct qinit vuidmice_winit = {
99 99 vuidmice_wput,
100 100 NULL,
101 101 NULL,
102 102 NULL,
103 103 NULL,
104 104 &vuidmice_oinfo,
105 105 NULL
106 106 };
107 107
108 108 struct streamtab vuidmice_info = {
109 109 &vuidmice_rinit,
110 110 &vuidmice_winit,
111 111 NULL,
112 112 NULL
113 113 };
114 114
115 115 /*
116 116 * This is the loadable module wrapper.
117 117 */
118 118
119 119 /*
120 120 * D_MTQPAIR effectively makes the module single threaded.
121 121 * There can be only one thread active in the module at any time.
122 122 * It may be a read or write thread.
123 123 */
124 124 #define VUIDMICE_CONF_FLAG (D_MP | D_MTQPAIR)
125 125
126 126 static struct fmodsw fsw = {
127 127 VUID_NAME,
128 128 &vuidmice_info,
129 129 VUIDMICE_CONF_FLAG
130 130 };
131 131
132 132 static struct modlstrmod modlstrmod = {
↓ open down ↓ |
132 lines elided |
↑ open up ↑ |
133 133 &mod_strmodops,
134 134 "mouse events to vuid events",
135 135 &fsw
136 136 };
137 137
138 138 /*
139 139 * Module linkage information for the kernel.
140 140 */
141 141 static struct modlinkage modlinkage = {
142 142 MODREV_1,
143 - &modlstrmod,
144 - NULL
143 + { &modlstrmod, NULL }
145 144 };
146 145
147 146 static int module_open = 0; /* allow only one open of this module */
148 147
149 148 int
150 149 _init(void)
151 150 {
152 151 register int rc;
153 152
154 153 mutex_init(&vuidmice_lock, NULL, MUTEX_DEFAULT, NULL);
155 154 if ((rc = mod_install(&modlinkage)) != 0) {
156 155 mutex_destroy(&vuidmice_lock);
157 156 }
158 157 return (rc);
159 158 }
160 159
161 160 int
162 161 _fini(void)
163 162 {
164 163 register int rc;
165 164
166 165 if ((rc = mod_remove(&modlinkage)) == 0)
167 166 mutex_destroy(&vuidmice_lock);
168 167 return (rc);
169 168 }
170 169
171 170 int
172 171 _info(struct modinfo *modinfop)
173 172 {
174 173 return (mod_info(&modlinkage, modinfop));
175 174 }
176 175
177 176
178 177 /* ARGSUSED1 */
179 178 static int
180 179 vuidmice_open(queue_t *const qp, const dev_t *const devp,
181 180 const int oflag, const int sflag, const cred_t *const crp)
182 181 {
183 182 if (qp->q_ptr != NULL)
184 183 return (0); /* reopen */
185 184
186 185 mutex_enter(&vuidmice_lock);
187 186
188 187 /* Allow only 1 open of this module */
189 188 if (module_open) {
190 189 mutex_exit(&vuidmice_lock);
191 190 return (EBUSY);
192 191 }
193 192
194 193 module_open++;
195 194 mutex_exit(&vuidmice_lock);
196 195
197 196 /*
198 197 * Both the read and write queues share the same state structures.
199 198 */
200 199 qp->q_ptr = kmem_zalloc(sizeof (struct MouseStateInfo), KM_SLEEP);
201 200 WR(qp)->q_ptr = qp->q_ptr;
202 201
203 202 /* initialize state */
204 203 STATEP->format = VUID_NATIVE;
205 204
206 205 qprocson(qp);
207 206
208 207 #ifdef VUID_OPEN
209 208 if (VUID_OPEN(qp) != 0) {
210 209 qprocsoff(qp);
211 210
212 211 mutex_enter(&vuidmice_lock);
213 212 module_open--;
214 213 mutex_exit(&vuidmice_lock);
215 214 kmem_free(qp->q_ptr, sizeof (struct MouseStateInfo));
216 215 qp->q_ptr = NULL;
217 216 return (ENXIO);
218 217 }
219 218 #endif
220 219
221 220 return (0);
222 221 }
223 222
224 223 /* ARGSUSED1 */
225 224 static int
226 225 vuidmice_close(queue_t *const qp, const int flag, const cred_t *const crp)
227 226 {
228 227 ASSERT(qp != NULL);
229 228
230 229 qprocsoff(qp);
231 230 flushq(qp, FLUSHALL);
232 231 flushq(OTHERQ(qp), FLUSHALL);
233 232
234 233 #ifdef VUID_CLOSE
235 234 VUID_CLOSE(qp);
236 235 #endif
237 236 mutex_enter(&vuidmice_lock);
238 237 module_open--;
239 238 mutex_exit(&vuidmice_lock);
240 239 kmem_free(qp->q_ptr, sizeof (struct MouseStateInfo));
241 240 qp->q_ptr = NULL;
242 241
243 242 return (0);
244 243 }
245 244
246 245 /*
247 246 * Put procedure for input from driver end of stream (read queue).
248 247 */
249 248 static int
250 249 vuidmice_rput(queue_t *const qp, mblk_t *mp)
251 250 {
252 251 ASSERT(qp != NULL);
253 252 ASSERT(mp != NULL);
254 253
255 254 /*
256 255 * Handle all the related high priority messages here, hence
257 256 * should spend the least amount of time here.
258 257 */
259 258
260 259 if (DB_TYPE(mp) == M_DATA) {
261 260 if ((int)STATEP->format == VUID_FIRM_EVENT)
262 261 return (putq(qp, mp)); /* queue message & return */
263 262 } else if (DB_TYPE(mp) == M_FLUSH) {
264 263 if (*mp->b_rptr & FLUSHR)
265 264 flushq(qp, FLUSHALL);
266 265 }
267 266
268 267 putnext(qp, mp); /* pass it on */
269 268 return (0);
270 269 }
271 270
272 271 static int
273 272 vuidmice_rsrv(queue_t *const qp)
274 273 {
275 274 register mblk_t *mp;
276 275
277 276 ASSERT(qp != NULL);
278 277
279 278 while ((mp = getq(qp)) != NULL) {
280 279 ASSERT(DB_TYPE(mp) == M_DATA);
281 280
282 281 if (!canputnext(qp))
283 282 return (putbq(qp, mp)); /* read side is blocked */
284 283
285 284 switch (DB_TYPE(mp)) {
286 285 case M_DATA:
287 286 if ((int)STATEP->format == VUID_FIRM_EVENT)
288 287 (void) VUID_QUEUE(qp, mp);
289 288 else
290 289 (void) putnext(qp, mp);
291 290 break;
292 291
293 292 default:
294 293 cmn_err(CE_WARN,
295 294 "vuidmice_rsrv: bad message type (0x%x)\n",
296 295 DB_TYPE(mp));
297 296
298 297 (void) putnext(qp, mp);
299 298 break;
300 299 }
301 300 }
302 301 return (0);
303 302 }
304 303
305 304 /*
306 305 * Put procedure for write from user end of stream (write queue).
307 306 */
308 307 static int
309 308 vuidmice_wput(queue_t *const qp, mblk_t *mp)
310 309 {
311 310 int error = 0;
312 311
313 312 ASSERT(qp != NULL);
314 313 ASSERT(mp != NULL);
315 314
316 315 /*
317 316 * Handle all the related high priority messages here, hence
318 317 * should spend the least amount of time here.
319 318 */
320 319 switch (DB_TYPE(mp)) { /* handle hi pri messages here */
321 320 case M_FLUSH:
322 321 if (*mp->b_rptr & FLUSHW)
323 322 flushq(qp, FLUSHALL);
324 323 putnext(qp, mp); /* pass it on */
325 324 return (0);
326 325
327 326 case M_IOCTL: {
328 327 struct iocblk *iocbp = (void *)mp->b_rptr;
329 328
330 329 switch (iocbp->ioc_cmd) {
331 330 case VUIDSFORMAT:
332 331
333 332 /*
334 333 * VUIDSFORMAT is known to the stream head and thus
335 334 * is guaranteed to be an I_STR ioctl.
336 335 */
337 336 if (iocbp->ioc_count == TRANSPARENT) {
338 337 miocnak(qp, mp, 0, EINVAL);
339 338 return (0);
340 339 } else {
341 340 int format_type;
342 341
343 342 error = miocpullup(mp, sizeof (int));
344 343 if (error != 0) {
345 344 miocnak(qp, mp, 0, error);
346 345 return (0);
347 346 }
348 347
349 348 format_type =
350 349 *(int *)(void *)mp->b_cont->b_rptr;
351 350 STATEP->format = (uchar_t)format_type;
352 351 iocbp->ioc_rval = 0;
353 352 iocbp->ioc_count = 0;
354 353 iocbp->ioc_error = 0;
355 354 mp->b_datap->db_type = M_IOCACK;
356 355 }
357 356
358 357 /* return buffer to pool ASAP */
359 358 if (mp->b_cont) {
360 359 freemsg(mp->b_cont);
361 360 mp->b_cont = NULL;
362 361 }
363 362
364 363 qreply(qp, mp);
365 364 return (0);
366 365
367 366 case VUIDGFORMAT:
368 367
369 368 /* return buffer to pool ASAP */
370 369 if (mp->b_cont) {
371 370 freemsg(mp->b_cont); /* over written below */
372 371 mp->b_cont = NULL;
373 372 }
374 373
375 374 /*
376 375 * VUIDGFORMAT is known to the stream head and thus
377 376 * is guaranteed to be an I_STR ioctl.
378 377 */
379 378 if (iocbp->ioc_count == TRANSPARENT) {
380 379 miocnak(qp, mp, 0, EINVAL);
381 380 return (0);
382 381 }
383 382
384 383 mp->b_cont = allocb(sizeof (int), BPRI_MED);
385 384 if (mp->b_cont == NULL) {
386 385 miocnak(qp, mp, 0, EAGAIN);
387 386 return (0);
388 387 }
389 388
390 389 *(int *)(void *)mp->b_cont->b_rptr =
391 390 (int)STATEP->format;
392 391 mp->b_cont->b_wptr += sizeof (int);
393 392
394 393 iocbp->ioc_count = sizeof (int);
395 394 mp->b_datap->db_type = M_IOCACK;
396 395 qreply(qp, mp);
397 396 return (0);
398 397
399 398 case VUID_NATIVE:
400 399 case VUIDSADDR:
401 400 case VUIDGADDR:
402 401 miocnak(qp, mp, 0, ENOTTY);
403 402 return (0);
404 403
405 404 case MSIOBUTTONS:
406 405 /* return buffer to pool ASAP */
407 406 if (mp->b_cont) {
408 407 freemsg(mp->b_cont); /* over written below */
409 408 mp->b_cont = NULL;
410 409 }
411 410
412 411 /*
413 412 * MSIOBUTTONS is known to streamio.c and this
414 413 * is assume to be non-I_STR & non-TRANSPARENT ioctl
415 414 */
416 415
417 416 if (iocbp->ioc_count == TRANSPARENT) {
418 417 miocnak(qp, mp, 0, EINVAL);
419 418 return (0);
420 419 }
421 420
422 421 if (STATEP->nbuttons == 0) {
423 422 miocnak(qp, mp, 0, EINVAL);
424 423 return (0);
425 424 }
426 425
427 426 mp->b_cont = allocb(sizeof (int), BPRI_MED);
428 427 if (mp->b_cont == NULL) {
429 428 miocnak(qp, mp, 0, EAGAIN);
430 429 return (0);
431 430 }
432 431
433 432 *(int *)(void *)mp->b_cont->b_rptr =
434 433 (int)STATEP->nbuttons;
435 434 mp->b_cont->b_wptr += sizeof (int);
436 435
437 436 iocbp->ioc_count = sizeof (int);
438 437 mp->b_datap->db_type = M_IOCACK;
439 438 qreply(qp, mp);
440 439 return (0);
441 440
442 441 /*
443 442 * New IOCTL support. Since it's explicitly mentioned
444 443 * that you can't add more ioctls to stream head's
445 444 * hard coded list, we have to do the transparent
446 445 * ioctl processing which is not very exciting.
447 446 */
448 447 case VUIDGWHEELCOUNT:
449 448 case VUIDGWHEELINFO:
450 449 case VUIDGWHEELSTATE:
451 450 case VUIDSWHEELSTATE:
452 451 case MSIOSRESOLUTION:
453 452 error = vuidmice_handle_wheel_resolution_ioctl(qp,
454 453 mp, iocbp->ioc_cmd);
455 454 if (!error) {
456 455 return (0);
457 456 } else {
458 457 miocnak(qp, mp, 0, error);
459 458 return (0);
460 459 }
461 460 default:
462 461 putnext(qp, mp); /* nothing to process here */
463 462
464 463 return (0);
465 464 }
466 465
467 466 } /* End of case M_IOCTL */
468 467
469 468 case M_IOCDATA:
470 469 vuidmice_miocdata(qp, mp);
471 470
472 471 return (0);
473 472 default:
474 473 putnext(qp, mp); /* pass it on */
475 474 return (0);
476 475 }
477 476 /*NOTREACHED*/
478 477 }
479 478
480 479 void
481 480 VUID_PUTNEXT(queue_t *const qp, uchar_t event_id, uchar_t event_pair_type,
482 481 uchar_t event_pair, int event_value)
483 482 {
484 483 int strikes = 1;
485 484 mblk_t *bp;
486 485 Firm_event *fep;
487 486
488 487 /*
489 488 * Give this event 3 chances to allocate blocks,
490 489 * otherwise discard this mouse event. 3 Strikes and you're out.
491 490 */
492 491 while ((bp = allocb((int)sizeof (Firm_event), BPRI_HI)) == NULL) {
493 492 if (++strikes > 3)
494 493 return;
495 494 drv_usecwait(10);
496 495 }
497 496
498 497 fep = (void *)bp->b_wptr;
499 498 fep->id = vuid_id_addr(VKEY_FIRST) | vuid_id_offset(event_id);
500 499
501 500 fep->pair_type = event_pair_type;
502 501 fep->pair = event_pair;
503 502 fep->value = event_value;
504 503 uniqtime32(&fep->time);
505 504 bp->b_wptr += sizeof (Firm_event);
506 505
507 506 if (canput(qp->q_next))
508 507 putnext(qp, bp);
509 508 else
510 509 (void) putbq(qp, bp); /* read side is blocked */
511 510 }
512 511
513 512
514 513 /*
515 514 * vuidmice_miocdata
516 515 * M_IOCDATA processing for IOCTL's: VUIDGWHEELCOUNT, VUIDGWHEELINFO,
517 516 * VUIDGWHEELSTATE, VUIDSWHEELSTATE & MSIOSRESOLUTION.
518 517 */
519 518 static void
520 519 vuidmice_miocdata(queue_t *qp, mblk_t *mp)
521 520 {
522 521 struct copyresp *copyresp;
523 522 struct iocblk *iocbp;
524 523 mblk_t *ioctmp;
525 524 mblk_t *datap;
526 525 Mouse_iocstate_t *Mouseioc;
527 526 size_t size;
528 527 int err = 0;
529 528
530 529
531 530 copyresp = (void *)mp->b_rptr;
532 531 iocbp = (void *)mp->b_rptr;
533 532
534 533 if (copyresp->cp_rval) {
535 534 err = EAGAIN;
536 535
537 536 goto err;
538 537 }
539 538 switch (copyresp->cp_cmd) {
540 539 case VUIDGWHEELCOUNT:
541 540 mp->b_datap->db_type = M_IOCACK;
542 541 mp->b_wptr = mp->b_rptr + sizeof (struct iocblk);
543 542 iocbp->ioc_error = 0;
544 543 iocbp->ioc_count = 0;
545 544 iocbp->ioc_rval = 0;
546 545 if (mp->b_cont != NULL) {
547 546 freemsg(mp->b_cont);
548 547 mp->b_cont = NULL;
549 548 }
550 549
551 550 break;
552 551 case VUIDGWHEELINFO:
553 552 case VUIDGWHEELSTATE:
554 553 ioctmp = copyresp->cp_private;
555 554 Mouseioc = (void *)ioctmp->b_rptr;
556 555 if (Mouseioc->ioc_state == GETSTRUCT) {
557 556 if (mp->b_cont == NULL) {
558 557 err = EINVAL;
559 558
560 559 break;
561 560 }
562 561 datap = mp->b_cont;
563 562 if (copyresp->cp_cmd == VUIDGWHEELSTATE) {
564 563 err = vuidmice_service_wheel_state(qp, datap,
565 564 VUIDGWHEELSTATE);
566 565 } else {
567 566 err = vuidmice_service_wheel_info(datap);
568 567 }
569 568 if (err) {
570 569 break;
571 570 }
572 571
573 572 if (copyresp->cp_cmd == VUIDGWHEELSTATE) {
574 573 size = sizeof (wheel_state);
575 574 } else {
576 575 size = sizeof (wheel_info);
577 576 }
578 577
579 578 Mouseioc->ioc_state = GETRESULT;
580 579 ASSERT(Mouseioc->u_addr != NULL);
581 580 mcopyout(mp, ioctmp, size, Mouseioc->u_addr, NULL);
582 581 } else if (Mouseioc->ioc_state == GETRESULT) {
583 582 freemsg(ioctmp);
584 583 mp->b_datap->db_type = M_IOCACK;
585 584 mp->b_wptr = mp->b_rptr + sizeof (struct iocblk);
586 585 iocbp->ioc_error = 0;
587 586 iocbp->ioc_count = 0;
588 587 iocbp->ioc_rval = 0;
589 588 if (mp->b_cont != NULL) {
590 589 freemsg(mp->b_cont);
591 590 mp->b_cont = NULL;
592 591 }
593 592 }
594 593
595 594 break;
596 595 case VUIDSWHEELSTATE:
597 596 case MSIOSRESOLUTION:
598 597 ioctmp = copyresp->cp_private;
599 598 Mouseioc = (void *)ioctmp->b_rptr;
600 599 if (mp->b_cont == NULL) {
601 600 err = EINVAL;
602 601
603 602 break;
604 603 }
605 604 datap = mp->b_cont;
606 605
607 606 if (copyresp->cp_cmd == VUIDSWHEELSTATE) {
608 607 err = vuidmice_service_wheel_state(qp,
609 608 datap, VUIDSWHEELSTATE);
610 609 }
611 610
612 611 if (err) {
613 612 break;
614 613 }
615 614
616 615 if (mp->b_cont) {
617 616 freemsg(mp->b_cont);
618 617 mp->b_cont = NULL;
619 618 }
620 619 freemsg(ioctmp);
621 620 iocbp->ioc_count = 0;
622 621 iocbp->ioc_error = 0;
623 622 iocbp->ioc_rval = 0;
624 623 mp->b_datap->db_type = M_IOCACK;
625 624
626 625 break;
627 626 default:
628 627 err = EINVAL;
629 628
630 629 break;
631 630 }
632 631
633 632 err:
634 633 if (err) {
635 634 mp->b_datap->db_type = M_IOCNAK;
636 635 if (mp->b_cont) {
637 636 freemsg(mp->b_cont);
638 637 mp->b_cont = NULL;
639 638 }
640 639 if (copyresp->cp_private) {
641 640 freemsg(copyresp->cp_private);
642 641 copyresp->cp_private = NULL;
643 642 }
644 643 iocbp->ioc_count = 0;
645 644 iocbp->ioc_error = err;
646 645 }
647 646 qreply(qp, mp);
648 647 }
649 648
650 649
651 650 /*
652 651 * vuidmice_handle_wheel_resolution_ioctl
653 652 * Handle wheel mouse and MSIOSRESOLUTION ioctls.
654 653 *
655 654 * Here we also support non-transparent way of these ioctls
656 655 * just like usb mouse driver does, so the consms module is
657 656 * very simple to deal with these ioctls.
658 657 */
659 658 static int
660 659 vuidmice_handle_wheel_resolution_ioctl(queue_t *qp, mblk_t *mp, int cmd)
661 660 {
662 661 int err = 0;
663 662 Mouse_iocstate_t *Mouseioc;
664 663 caddr_t useraddr;
665 664 size_t size;
666 665 mblk_t *ioctmp;
667 666 mblk_t *datap;
668 667
669 668 struct iocblk *iocbp = (void *)mp->b_rptr;
670 669
671 670 if (iocbp->ioc_count == TRANSPARENT) {
672 671 if (mp->b_cont == NULL)
673 672 return (EINVAL);
674 673 useraddr = *((caddr_t *)(void *)mp->b_cont->b_rptr);
675 674 switch (cmd) {
676 675 case VUIDGWHEELCOUNT:
677 676 size = sizeof (int);
678 677 if ((datap = allocb(sizeof (int), BPRI_HI)) == NULL)
679 678 return (EAGAIN);
680 679 *((int *)(void *)datap->b_wptr) =
681 680 STATEP->vuid_mouse_mode;
682 681 mcopyout(mp, NULL, size, NULL, datap);
683 682 qreply(qp, mp);
684 683
685 684 return (err);
686 685 case VUIDGWHEELINFO:
687 686 size = sizeof (wheel_info);
688 687 break;
689 688
690 689 case VUIDSWHEELSTATE:
691 690 case VUIDGWHEELSTATE:
692 691 size = sizeof (wheel_state);
693 692 break;
694 693
695 694 case MSIOSRESOLUTION:
696 695 size = sizeof (Ms_screen_resolution);
697 696 break;
698 697 }
699 698
700 699 if ((ioctmp = allocb(sizeof (Mouse_iocstate_t),
701 700 BPRI_MED)) == NULL)
702 701 return (EAGAIN);
703 702 Mouseioc = (void *)ioctmp->b_rptr;
704 703 Mouseioc->ioc_state = GETSTRUCT;
705 704 Mouseioc->u_addr = useraddr;
706 705 ioctmp->b_wptr = ioctmp->b_rptr + sizeof (Mouse_iocstate_t);
707 706 mcopyin(mp, ioctmp, size, NULL);
708 707 qreply(qp, mp);
709 708
710 709 return (err);
711 710 } else {
712 711 switch (cmd) {
713 712 case VUIDGWHEELCOUNT:
714 713 if (mp->b_cont) {
715 714 freemsg(mp->b_cont);
716 715 mp->b_cont = NULL;
717 716 }
718 717 if ((datap = allocb(sizeof (int), BPRI_HI)) == NULL) {
719 718 err = EAGAIN;
720 719 break;
721 720 }
722 721 *((int *)(void *)datap->b_wptr) =
723 722 STATEP->vuid_mouse_mode;
724 723 datap->b_wptr += sizeof (int);
725 724 mp->b_cont = datap;
726 725 break;
727 726
728 727 case VUIDGWHEELINFO:
729 728 if (mp->b_cont == NULL ||
730 729 iocbp->ioc_count != sizeof (wheel_info)) {
731 730 err = EINVAL;
732 731 break;
733 732 }
734 733 datap = mp->b_cont;
735 734 err = vuidmice_service_wheel_info(datap);
736 735 break;
737 736
738 737 case VUIDSWHEELSTATE:
739 738 case VUIDGWHEELSTATE:
740 739 if (mp->b_cont == NULL ||
741 740 iocbp->ioc_count != sizeof (wheel_state)) {
742 741 err = EINVAL;
743 742 break;
744 743 }
745 744 datap = mp->b_cont;
746 745 err = vuidmice_service_wheel_state(qp, datap, cmd);
747 746 break;
748 747
749 748 case MSIOSRESOLUTION:
750 749 /*
751 750 * Now we just make Xserver and
752 751 * the virtual mouse happy. Of course,
753 752 * the screen resolution value may
754 753 * be used later for absolute PS/2 mouse.
755 754 */
756 755 err = 0;
757 756 break;
758 757 }
759 758
760 759 if (!err) {
761 760 mp->b_datap->db_type = M_IOCACK;
762 761 iocbp->ioc_rval = 0;
763 762 iocbp->ioc_error = 0;
764 763 qreply(qp, mp);
765 764 }
766 765
767 766 return (err);
768 767 }
769 768 }
770 769
771 770 static int
772 771 vuidmice_service_wheel_info(register mblk_t *datap)
773 772 {
774 773 wheel_info *wi;
775 774 int err = 0;
776 775
777 776 wi = (void *)datap->b_rptr;
778 777 if (wi->vers != VUID_WHEEL_INFO_VERS) {
779 778 err = EINVAL;
780 779 return (err);
781 780 }
782 781
783 782 if (wi->id > (VUIDMICE_NUM_WHEELS - 1)) {
784 783 err = EINVAL;
785 784 return (err);
786 785 }
787 786 wi->format = (wi->id == VUIDMICE_VERTICAL_WHEEL_ID) ?
788 787 VUID_WHEEL_FORMAT_VERTICAL : VUID_WHEEL_FORMAT_HORIZONTAL;
789 788
790 789 return (err);
791 790 }
792 791
793 792
794 793 static int
795 794 vuidmice_service_wheel_state(register queue_t *qp,
796 795 register mblk_t *datap,
797 796 register uint_t cmd)
798 797 {
799 798 wheel_state *ws;
800 799 uint_t err = 0;
801 800
802 801 ws = (void *)datap->b_rptr;
803 802 if (ws->vers != VUID_WHEEL_STATE_VERS) {
804 803 err = EINVAL;
805 804 return (err);
806 805 }
807 806
808 807 if (ws->id > (VUIDMICE_NUM_WHEELS - 1)) {
809 808 err = EINVAL;
810 809 return (err);
811 810 }
812 811
813 812 switch (cmd) {
814 813 case VUIDGWHEELSTATE:
815 814 ws->stateflags =
816 815 (STATEP->wheel_state_bf >> ws->id) & 1;
817 816
818 817 break;
819 818 case VUIDSWHEELSTATE:
820 819 STATEP->wheel_state_bf = (ws->stateflags << ws->id) |
821 820 (STATEP->wheel_state_bf & ~(1 << ws->id));
822 821
823 822 break;
824 823 default:
825 824 err = EINVAL;
826 825
827 826 return (err);
828 827 }
829 828
830 829 return (err);
831 830 }
↓ open down ↓ |
677 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX