sun_mouse.c revision bd3a1963
1/* 2 * Copyright (c) 2004-2005, 2008-2010, Oracle and/or its affiliates. 3 * All rights reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24/* 25 * Copyright 1999-2001 The XFree86 Project, Inc. All Rights Reserved. 26 * 27 * Permission is hereby granted, free of charge, to any person obtaining a copy 28 * of this software and associated documentation files (the "Software"), to 29 * deal in the Software without restriction, including without limitation the 30 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 31 * sell copies of the Software, and to permit persons to whom the Software is 32 * furnished to do so, subject to the following conditions: 33 * 34 * The above copyright notice and this permission notice shall be included in 35 * all copies or substantial portions of the Software. 36 * 37 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 38 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 39 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 40 * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 41 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 42 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 43 * 44 * Except as contained in this notice, the name of the XFree86 Project shall 45 * not be used in advertising or otherwise to promote the sale, use or other 46 * dealings in this Software without prior written authorization from the 47 * XFree86 Project. 48 */ 49 50#ifdef HAVE_XORG_CONFIG_H 51#include <xorg-config.h> 52#endif 53 54#include "xorg-server.h" 55#include "xf86.h" 56#include "xf86_OSlib.h" 57#include "mouse.h" 58#include "xisb.h" 59#include "mipointer.h" 60#include <sys/stropts.h> 61#include <sys/vuid_event.h> 62#include <sys/msio.h> 63 64/* Wheel mouse support in VUID drivers in Solaris 9 updates & Solaris 10 */ 65#ifdef WHEEL_DEVID /* Defined in vuid_event.h if VUID wheel support present */ 66# define HAVE_VUID_WHEEL 67#endif 68#ifdef HAVE_VUID_WHEEL 69# include <sys/vuid_wheel.h> 70#endif 71 72/* Support for scaling absolute coordinates to screen size in 73 * Solaris 10 updates and beyond */ 74#if !defined(HAVE_ABSOLUTE_MOUSE_SCALING) 75# ifdef MSIOSRESOLUTION /* Defined in msio.h if scaling support present */ 76# define HAVE_ABSOLUTE_MOUSE_SCALING 77# endif 78#endif 79 80/* Names of protocols that are handled internally here. */ 81 82static const char *internalNames[] = { 83 "VUID", 84 NULL 85}; 86 87static const char *solarisMouseDevs[] = { 88 /* Device file: Protocol: */ 89 "/dev/mouse", "VUID", /* USB or SPARC */ 90#if defined(__i386) || defined(__x86) 91 "/dev/kdmouse", "PS/2", /* PS/2 */ 92#endif 93 NULL 94}; 95 96typedef struct _VuidMseRec { 97 struct _VuidMseRec *next; 98 InputInfoPtr pInfo; 99 Firm_event event; 100 unsigned char * buffer; 101 char * strmod; 102 Bool(*wrapped_device_control)(DeviceIntPtr device, int what); 103#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 104 Ms_screen_resolution absres; 105#endif 106 OsTimerPtr remove_timer; /* Callback for removal on ENODEV */ 107} VuidMseRec, *VuidMsePtr; 108 109static VuidMsePtr vuidMouseList = NULL; 110 111static int vuidMouseProc(DeviceIntPtr pPointer, int what); 112static void vuidReadInput(InputInfoPtr pInfo); 113 114#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 115static void vuidMouseSendScreenSize(ScreenPtr pScreen, VuidMsePtr pVuidMse); 116static void vuidMouseAdjustFrame(int index, int x, int y, int flags); 117 118static int vuidMouseGeneration = 0; 119 120#if HAS_DEVPRIVATEKEYREC 121static DevPrivateKeyRec vuidMouseScreenIndex; 122#else 123static int vuidMouseScreenIndex; 124#endif /* HAS_DEVPRIVATEKEYREC */ 125 126#define vuidMouseGetScreenPrivate(s) ( \ 127 dixLookupPrivate(&(s)->devPrivates, &vuidMouseScreenIndex)) 128#define vuidMouseSetScreenPrivate(s,p) \ 129 dixSetPrivate(&(s)->devPrivates, &vuidMouseScreenIndex, (void *) p) 130#endif /* HAVE_ABSOLUTE_MOUSE_SCALING */ 131 132static inline 133VuidMsePtr getVuidMsePriv(InputInfoPtr pInfo) 134{ 135 VuidMsePtr m = vuidMouseList; 136 137 while ((m != NULL) && (m->pInfo != pInfo)) { 138 m = m->next; 139 } 140 141 return m; 142} 143 144/* Called from OsTimer callback, since removing a device from the device 145 list or changing pInfo->fd while xf86Wakeup is looping through the list 146 causes server crashes */ 147static CARD32 148vuidRemoveMouse(OsTimerPtr timer, CARD32 time, pointer arg) 149{ 150 InputInfoPtr pInfo = (InputInfoPtr) arg; 151 152 xf86DisableDevice(pInfo->dev, TRUE); 153 154 return 0; /* All done, don't set to run again */ 155} 156 157/* 158 * Initialize and enable the mouse wheel, if present. 159 * 160 * Returns 1 if mouse wheel was successfully enabled. 161 * Returns 0 if an error occurred or if there is no mouse wheel. 162 */ 163static int 164vuidMouseWheelInit(InputInfoPtr pInfo) 165{ 166#ifdef HAVE_VUID_WHEEL 167 wheel_state wstate; 168 int nwheel = -1; 169 int i; 170 171 wstate.vers = VUID_WHEEL_STATE_VERS; 172 wstate.id = 0; 173 wstate.stateflags = (uint32_t) -1; 174 175 SYSCALL(i = ioctl(pInfo->fd, VUIDGWHEELCOUNT, &nwheel)); 176 if (i != 0) 177 return (0); 178 179 SYSCALL(i = ioctl(pInfo->fd, VUIDGWHEELSTATE, &wstate)); 180 if (i != 0) { 181 xf86Msg(X_WARNING, "%s: couldn't get wheel state\n", pInfo->name); 182 return (0); 183 } 184 185 wstate.stateflags |= VUID_WHEEL_STATE_ENABLED; 186 187 SYSCALL(i = ioctl(pInfo->fd, VUIDSWHEELSTATE, &wstate)); 188 if (i != 0) { 189 xf86Msg(X_WARNING, "%s: couldn't enable wheel\n", pInfo->name); 190 return (0); 191 } 192 193 return (1); 194#else 195 return (0); 196#endif 197} 198 199 200/* This function is called when the protocol is "VUID". */ 201static Bool 202vuidPreInit(InputInfoPtr pInfo, const char *protocol, int flags) 203{ 204 MouseDevPtr pMse = pInfo->private; 205 VuidMsePtr pVuidMse; 206 int buttons, i; 207 208 pVuidMse = calloc(sizeof(VuidMseRec), 1); 209 if (pVuidMse == NULL) { 210 xf86Msg(X_ERROR, "%s: cannot allocate VuidMouseRec\n", pInfo->name); 211 free(pMse); 212 return FALSE; 213 } 214 215 pVuidMse->buffer = (unsigned char *)&pVuidMse->event; 216 pVuidMse->strmod = xf86SetStrOption(pInfo->options, "StreamsModule", NULL); 217 218 /* Setup the local procs. */ 219 pVuidMse->wrapped_device_control = pInfo->device_control; 220 pInfo->device_control = vuidMouseProc; 221 pInfo->read_input = vuidReadInput; 222 223 pMse->xisbscale = sizeof(Firm_event); 224 225#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 226 pVuidMse->absres.height = pVuidMse->absres.width = 0; 227#endif 228 pVuidMse->pInfo = pInfo; 229 pVuidMse->next = vuidMouseList; 230 vuidMouseList = pVuidMse; 231 232#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 233 pInfo->flags |= XI86_CONFIGURED; 234#endif 235 return TRUE; 236} 237 238static void 239vuidFlushAbsEvents(InputInfoPtr pInfo, int absX, int absY, 240 Bool *absXset, Bool *absYset) 241{ 242#ifdef DEBUG 243 ErrorF("vuidFlushAbsEvents: %d,%d (set: %d, %d)\n", absX, absY, 244 *absXset, *absYset); 245#endif 246 if ((*absXset) && (*absYset)) { 247 xf86PostMotionEvent(pInfo->dev, 248 /* is_absolute: */ TRUE, 249 /* first_valuator: */ 0, 250 /* num_valuators: */ 2, 251 absX, absY); 252 } else if (*absXset) { 253 xf86PostMotionEvent(pInfo->dev, 254 /* is_absolute: */ TRUE, 255 /* first_valuator: */ 0, 256 /* num_valuators: */ 1, 257 absX); 258 } else if (*absYset) { 259 xf86PostMotionEvent(pInfo->dev, 260 /* is_absolute: */ TRUE, 261 /* first_valuator: */ 1, 262 /* num_valuators: */ 1, 263 absY); 264 } 265 266 *absXset = FALSE; 267 *absYset = FALSE; 268} 269 270static void 271vuidReadInput(InputInfoPtr pInfo) 272{ 273 MouseDevPtr pMse; 274 VuidMsePtr pVuidMse; 275 int buttons; 276 int dx = 0, dy = 0, dz = 0, dw = 0; 277 unsigned int n; 278 int c; 279 unsigned char *pBuf; 280 int absX = 0, absY = 0; 281 Bool absXset = FALSE, absYset = FALSE; 282 283 pMse = pInfo->private; 284 pVuidMse = getVuidMsePriv(pInfo); 285 buttons = pMse->lastButtons; 286 pBuf = pVuidMse->buffer; 287 n = 0; 288 289 do { 290 n = read(pInfo->fd, pBuf, sizeof(Firm_event)); 291 292 if (n == 0) { 293 break; 294 } else if (n == -1) { 295 switch (errno) { 296 case EAGAIN: /* Nothing to read now */ 297 n = 0; /* End loop, go on to flush events & return */ 298 continue; 299 case EINTR: /* Interrupted, try again */ 300 continue; 301 case ENODEV: /* May happen when USB mouse is unplugged */ 302 /* We use X_NONE here because it doesn't alloc since we 303 may be called from SIGIO handler */ 304 xf86MsgVerb(X_NONE, 0, 305 "%s: Device no longer present - removing.\n", 306 pInfo->name); 307 xf86RemoveEnabledDevice(pInfo); 308 pVuidMse->remove_timer = 309 TimerSet(pVuidMse->remove_timer, 0, 1, 310 vuidRemoveMouse, pInfo); 311 return; 312 default: /* All other errors */ 313 /* We use X_NONE here because it doesn't alloc since we 314 may be called from SIGIO handler */ 315 xf86MsgVerb(X_NONE, 0, "%s: Read error: %s\n", pInfo->name, 316 strerror(errno)); 317 return; 318 } 319 } else if (n != sizeof(Firm_event)) { 320 xf86Msg(X_WARNING, "%s: incomplete packet, size %d\n", 321 pInfo->name, n); 322 } 323 324#ifdef DEBUG 325 ErrorF("vuidReadInput: event type: %3d value: %5d\n", 326 pVuidMse->event.id, pVuidMse->event.value); 327#endif 328 329 if (pVuidMse->event.id >= BUT_FIRST && pVuidMse->event.id <= BUT_LAST) { 330 /* button */ 331 int butnum = pVuidMse->event.id - BUT_FIRST; 332 333 if (butnum < 3) 334 butnum = 2 - butnum; 335 if (!pVuidMse->event.value) 336 buttons &= ~(1 << butnum); 337 else 338 buttons |= (1 << butnum); 339 } else if (pVuidMse->event.id >= VLOC_FIRST && 340 pVuidMse->event.id <= VLOC_LAST) { 341 /* axis */ 342 int delta = pVuidMse->event.value; 343 switch(pVuidMse->event.id) { 344 case LOC_X_DELTA: 345 dx += delta; 346 break; 347 case LOC_Y_DELTA: 348 dy -= delta; 349 break; 350 case LOC_X_ABSOLUTE: 351 if (absXset) { 352 vuidFlushAbsEvents(pInfo, absX, absY, &absXset, &absYset); 353 } 354 absX = delta; 355 absXset = TRUE; 356 break; 357 case LOC_Y_ABSOLUTE: 358 if (absYset) { 359 vuidFlushAbsEvents(pInfo, absX, absY, &absXset, &absYset); 360 } 361 absY = delta; 362 absYset = TRUE; 363 break; 364 } 365 } 366#ifdef HAVE_VUID_WHEEL 367 else if (vuid_in_range(VUID_WHEEL, pVuidMse->event.id)) { 368 if (vuid_id_offset(pVuidMse->event.id) == 0) 369 dz -= VUID_WHEEL_GETDELTA(pVuidMse->event.value); 370 else 371 dw -= VUID_WHEEL_GETDELTA(pVuidMse->event.value); 372 } 373#endif 374#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 375 else if (pVuidMse->event.id == MOUSE_TYPE_ABSOLUTE) { 376 ScreenPtr ptrCurScreen; 377 378 /* force sending absolute resolution scaling ioctl */ 379 pVuidMse->absres.height = pVuidMse->absres.width = 0; 380 ptrCurScreen = miPointerGetScreen(pInfo->dev); 381 vuidMouseSendScreenSize(ptrCurScreen, pVuidMse); 382 } 383#endif 384 385 } while (n != 0); 386 387 if (absXset || absYset) { 388 vuidFlushAbsEvents(pInfo, absX, absY, &absXset, &absYset); 389 } 390 391 pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw); 392 return; 393} 394 395#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 396static void vuidMouseSendScreenSize(ScreenPtr pScreen, VuidMsePtr pVuidMse) 397{ 398 InputInfoPtr pInfo = pVuidMse->pInfo; 399 ScrnInfoPtr pScr = XF86SCRNINFO(pScreen); 400 int result; 401 402 if (!pScr->currentMode) 403 return; 404 405 if ((pVuidMse->absres.width != pScr->currentMode->HDisplay) || 406 (pVuidMse->absres.height != pScr->currentMode->VDisplay)) 407 { 408 pVuidMse->absres.width = pScr->currentMode->HDisplay; 409 pVuidMse->absres.height = pScr->currentMode->VDisplay; 410 411 do { 412 result = ioctl(pInfo->fd, MSIOSRESOLUTION, &(pVuidMse->absres)); 413 } while ( (result != 0) && (errno == EINTR) ); 414 415 if (result != 0) { 416 xf86Msg(X_WARNING, 417 "%s: couldn't set absolute mouse scaling resolution: %s\n", 418 pInfo->name, strerror(errno)); 419#ifdef DEBUG 420 } else { 421 xf86Msg(X_INFO, 422 "%s: absolute mouse scaling resolution set to %d x %d\n", 423 pInfo->name, 424 pVuidMse->absres.width, pVuidMse->absres.height); 425#endif 426 } 427 } 428} 429 430static void vuidMouseAdjustFrame(int index, int x, int y, int flags) 431{ 432 ScrnInfoPtr pScrn = xf86Screens[index]; 433 ScreenPtr pScreen = pScrn->pScreen; 434 xf86AdjustFrameProc *wrappedAdjustFrame 435 = (xf86AdjustFrameProc *) vuidMouseGetScreenPrivate(pScreen); 436 VuidMsePtr m; 437 ScreenPtr ptrCurScreen; 438 439 if(wrappedAdjustFrame) { 440 pScrn->AdjustFrame = wrappedAdjustFrame; 441 (*pScrn->AdjustFrame)(index, x, y, flags); 442 pScrn->AdjustFrame = vuidMouseAdjustFrame; 443 } 444 445 for (m = vuidMouseList; m != NULL ; m = m->next) { 446 ptrCurScreen = miPointerGetScreen(m->pInfo->dev); 447 if (ptrCurScreen == pScreen) 448 { 449 vuidMouseSendScreenSize(pScreen, m); 450 } 451 } 452} 453#endif /* HAVE_ABSOLUTE_MOUSE_SCALING */ 454 455 456static int 457vuidMouseProc(DeviceIntPtr pPointer, int what) 458{ 459 InputInfoPtr pInfo; 460 MouseDevPtr pMse; 461 VuidMsePtr pVuidMse; 462 int ret = Success; 463 int i; 464 465 pInfo = pPointer->public.devicePrivate; 466 pMse = pInfo->private; 467 pMse->device = pPointer; 468 469 pVuidMse = getVuidMsePriv(pInfo); 470 if (pVuidMse == NULL) { 471 return BadImplementation; 472 } 473 474 switch (what) { 475 476 case DEVICE_INIT: 477#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 478 479#if HAS_DEVPRIVATEKEYREC 480 if (!dixRegisterPrivateKey(&vuidMouseScreenIndex, PRIVATE_SCREEN, 0)) 481 return BadAlloc; 482#endif /* HAS_DEVPRIVATEKEYREC */ 483 484 if (vuidMouseGeneration != serverGeneration) { 485 for (i = 0; i < screenInfo.numScreens; i++) { 486 ScreenPtr pScreen = screenInfo.screens[i]; 487 ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen); 488 vuidMouseSetScreenPrivate(pScreen, pScrn->AdjustFrame); 489 pScrn->AdjustFrame = vuidMouseAdjustFrame; 490 } 491 vuidMouseGeneration = serverGeneration; 492 } 493#endif 494 ret = pVuidMse->wrapped_device_control(pPointer, what); 495 break; 496 497 case DEVICE_ON: 498 ret = pVuidMse->wrapped_device_control(pPointer, DEVICE_ON); 499 500 if ((ret == Success) && (pInfo->fd != -1)) { 501 int fmt = VUID_FIRM_EVENT; 502 503 if (pVuidMse->strmod) { 504 /* Check to see if module is already pushed */ 505 SYSCALL(i = ioctl(pInfo->fd, I_FIND, pVuidMse->strmod)); 506 507 if (i == 0) { /* Not already pushed */ 508 SYSCALL(i = ioctl(pInfo->fd, I_PUSH, pVuidMse->strmod)); 509 if (i < 0) { 510 xf86Msg(X_WARNING, "%s: cannot push module '%s' " 511 "onto mouse device: %s\n", pInfo->name, 512 pVuidMse->strmod, strerror(errno)); 513 free(pVuidMse->strmod); 514 pVuidMse->strmod = NULL; 515 } 516 } 517 } 518 519 SYSCALL(i = ioctl(pInfo->fd, VUIDSFORMAT, &fmt)); 520 if (i < 0) { 521 xf86Msg(X_WARNING, 522 "%s: cannot set mouse device to VUID mode: %s\n", 523 pInfo->name, strerror(errno)); 524 } 525 vuidMouseWheelInit(pInfo); 526#ifdef HAVE_ABSOLUTE_MOUSE_SCALING 527 vuidMouseSendScreenSize(screenInfo.screens[0], pVuidMse); 528#endif 529 xf86FlushInput(pInfo->fd); 530 531 /* Allocate here so we don't alloc in ReadInput which may be called 532 from SIGIO handler. */ 533 if (pVuidMse->remove_timer == NULL) { 534 pVuidMse->remove_timer = TimerSet(pVuidMse->remove_timer, 535 0, 0, NULL, NULL); 536 } 537 } 538 break; 539 540 case DEVICE_OFF: 541 case DEVICE_CLOSE: 542 if (pInfo->fd != -1) { 543 if (pVuidMse->strmod) { 544 SYSCALL(i = ioctl(pInfo->fd, I_POP, pVuidMse->strmod)); 545 if (i == -1) { 546 xf86Msg(X_WARNING, 547 "%s: cannot pop module '%s' off mouse device: %s\n", 548 pInfo->name, pVuidMse->strmod, strerror(errno)); 549 } 550 } 551 } 552 if (pVuidMse->remove_timer) { 553 TimerFree(pVuidMse->remove_timer); 554 pVuidMse->remove_timer = NULL; 555 } 556 ret = pVuidMse->wrapped_device_control(pPointer, what); 557 break; 558 559 default: /* Should never be called, but just in case */ 560 ret = pVuidMse->wrapped_device_control(pPointer, what); 561 break; 562 } 563 return ret; 564} 565 566static Bool 567sunMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags) 568{ 569 /* The protocol is guaranteed to be one of the internalNames[] */ 570 if (xf86NameCmp(protocol, "VUID") == 0) { 571 return vuidPreInit(pInfo, protocol, flags); 572 } 573 return TRUE; 574} 575 576static const char ** 577BuiltinNames(void) 578{ 579 return internalNames; 580} 581 582static Bool 583CheckProtocol(const char *protocol) 584{ 585 int i; 586 587 for (i = 0; internalNames[i]; i++) 588 if (xf86NameCmp(protocol, internalNames[i]) == 0) 589 return TRUE; 590 591 return FALSE; 592} 593 594static const char * 595DefaultProtocol(void) 596{ 597 return "Auto"; 598} 599 600static Bool 601solarisMouseAutoProbe(InputInfoPtr pInfo, const char **protocol, 602 const char **device) 603{ 604 const char **pdev, **pproto; 605 int fd = -1; 606 Bool found; 607 char *strmod; 608 609 if (*device == NULL) { 610 /* Check to see if xorg.conf or HAL specified a device to use */ 611 *device = xf86CheckStrOption(pInfo->options, "Device", NULL); 612 if (*device == NULL) { 613 *device = xf86CheckStrOption(pInfo->options, "Device", NULL); 614 } 615 } 616 617 if (*device != NULL) { 618 strmod = xf86CheckStrOption(pInfo->options, "StreamsModule", NULL); 619 if (strmod == NULL) { 620 strmod = xf86CheckStrOption(pInfo->options, "StreamsModule", NULL); 621 } 622 if (strmod) { 623 /* if a device name is already known, and a StreamsModule is 624 specified to convert events to VUID, then we don't need to 625 probe further */ 626 *protocol = "VUID"; 627 return TRUE; 628 } 629 } 630 631 632 for (pdev = solarisMouseDevs; *pdev; pdev += 2) { 633 pproto = pdev + 1; 634 if ((*protocol != NULL) && (strcmp(*protocol, "Auto") != 0) && 635 (*pproto != NULL) && (strcmp(*pproto, *protocol) != 0)) { 636 continue; 637 } 638 if ((*device != NULL) && (strcmp(*device, *pdev) != 0)) { 639 continue; 640 } 641 SYSCALL (fd = open(*pdev, O_RDWR | O_NONBLOCK)); 642 if (fd == -1) { 643#ifdef DEBUG 644 ErrorF("Cannot open %s (%s)\n", pdev, strerror(errno)); 645#endif 646 } else { 647 found = TRUE; 648 if ((*pproto != NULL) && (strcmp(*pproto, "VUID") == 0)) { 649 int i, r; 650 SYSCALL(r = ioctl(fd, VUIDGFORMAT, &i)); 651 if (r < 0) { 652 found = FALSE; 653 } 654 } 655 close(fd); 656 if (found == TRUE) { 657 if (*pproto != NULL) { 658 *protocol = *pproto; 659 } 660 *device = *pdev; 661 return TRUE; 662 } 663 } 664 } 665 return FALSE; 666} 667 668static const char * 669SetupAuto(InputInfoPtr pInfo, int *protoPara) 670{ 671 const char *pdev = NULL; 672 const char *pproto = NULL; 673 MouseDevPtr pMse = pInfo->private; 674 675 if (pInfo->fd == -1) { 676 /* probe to find device/protocol to use */ 677 if (solarisMouseAutoProbe(pInfo, &pproto, &pdev) != FALSE) { 678 /* Set the Device option. */ 679 pInfo->options = 680 xf86AddNewOption(pInfo->options, "Device", pdev); 681 xf86Msg(X_INFO, "%s: Setting Device option to \"%s\"\n", 682 pInfo->name, pdev); 683 } 684 } else if (pMse->protocolID == PROT_AUTO) { 685 pdev = xf86CheckStrOption(pInfo->options, 686 "Device", NULL); 687 solarisMouseAutoProbe(pInfo, &pproto, &pdev); 688 } 689 return pproto; 690} 691 692static const char * 693FindDevice(InputInfoPtr pInfo, const char *protocol, int flags) 694{ 695 const char *pdev = NULL; 696 const char *pproto = protocol; 697 698 if (solarisMouseAutoProbe(pInfo, &pproto, &pdev) != FALSE) { 699 /* Set the Device option. */ 700 pInfo->options = 701 xf86AddNewOption(pInfo->options, "Device", pdev); 702 xf86Msg(X_INFO, "%s: Setting Device option to \"%s\"\n", 703 pInfo->name, pdev); 704 } 705 return pdev; 706} 707 708static int 709SupportedInterfaces(void) 710{ 711 /* XXX This needs to be checked. */ 712 return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_XPS2 | MSE_MISC; 713} 714 715OSMouseInfoPtr 716OSMouseInit(int flags) 717{ 718 OSMouseInfoPtr p; 719 720 p = calloc(sizeof(OSMouseInfoRec), 1); 721 if (!p) 722 return NULL; 723 p->SupportedInterfaces = SupportedInterfaces; 724 p->BuiltinNames = BuiltinNames; 725 p->CheckProtocol = CheckProtocol; 726 p->PreInit = sunMousePreInit; 727 p->DefaultProtocol = DefaultProtocol; 728 p->SetupAuto = SetupAuto; 729 p->FindDevice = FindDevice; 730 731 return p; 732} 733 734