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