bsd_mouse.c revision 1450c749
1 2/* 3 * Copyright (c) 1999-2003 by The XFree86 Project, Inc. 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 shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21 * OTHER DEALINGS IN THE SOFTWARE. 22 * 23 * Except as contained in this notice, the name of the copyright holder(s) 24 * and author(s) shall not be used in advertising or otherwise to promote 25 * the sale, use or other dealings in this Software without prior written 26 * authorization from the copyright holder(s) and author(s). 27 */ 28 29#include <xorg-server.h> 30 31#include <X11/X.h> 32#include "xf86.h" 33#include "xf86Priv.h" 34#include "xf86_OSlib.h" 35#include "xf86Xinput.h" 36#include "mouse.h" 37#include "xisb.h" 38#include "mipointer.h" 39#ifdef WSCONS_SUPPORT 40#include <dev/wscons/wsconsio.h> 41#endif 42#ifdef USBMOUSE_SUPPORT 43#ifdef HAS_LIB_USB_HID 44#include <usbhid.h> 45#else 46#include "usb.h" 47#endif 48 49#include <dev/usb/usb.h> 50#ifdef USB_GET_REPORT_ID 51#define USB_NEW_HID 52#endif 53 54#define HUP_GENERIC_DESKTOP 0x0001 55#define HUP_BUTTON 0x0009 56 57#define HUG_X 0x0030 58#define HUG_Y 0x0031 59#define HUG_Z 0x0032 60#define HUG_WHEEL 0x0038 61 62#define HID_USAGE2(p,u) (((p) << 16) | u) 63 64/* The UMS mices have middle button as number 3 */ 65#define UMS_BUT(i) ((i) == 0 ? 2 : (i) == 1 ? 0 : (i) == 2 ? 1 : (i)) 66#endif /* USBMOUSE_SUPPORT */ 67 68#ifdef USBMOUSE_SUPPORT 69static void usbSigioReadInput (int fd, void *closure); 70#endif 71static const char *FindDevice(InputInfoPtr, const char *, int); 72 73#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 74/* These are for FreeBSD and DragonFly */ 75#define DEFAULT_MOUSE_DEV "/dev/mouse" 76#define DEFAULT_SYSMOUSE_DEV "/dev/sysmouse" 77#define DEFAULT_PS2_DEV "/dev/psm0" 78 79static const char *mouseDevs[] = { 80 DEFAULT_MOUSE_DEV, 81 DEFAULT_SYSMOUSE_DEV, 82 DEFAULT_PS2_DEV, 83 NULL 84}; 85#elif (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT) 86/* Only wsmouse mices are autoconfigured for now on OpenBSD */ 87#define DEFAULT_WSMOUSE_DEV "/dev/wsmouse" 88#define DEFAULT_WSMOUSE0_DEV "/dev/wsmouse0" 89 90static const char *mouseDevs[] = { 91 DEFAULT_WSMOUSE_DEV, 92 DEFAULT_WSMOUSE0_DEV, 93 NULL 94}; 95#endif 96 97static int 98SupportedInterfaces(void) 99{ 100#if defined(__NetBSD__) 101 return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_MISC; 102#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 103 return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_MISC; 104#else 105 return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO | MSE_MISC; 106#endif 107} 108 109/* Names of protocols that are handled internally here. */ 110static const char *internalNames[] = { 111#if defined(WSCONS_SUPPORT) 112 "WSMouse", 113#endif 114#if defined(USBMOUSE_SUPPORT) 115 "usb", 116#endif 117 NULL 118}; 119 120/* 121 * Names of MSC_MISC protocols that the OS supports. These are decoded by 122 * main "mouse" driver. 123 */ 124static const char *miscNames[] = { 125#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 126 "SysMouse", 127#endif 128 NULL 129}; 130 131static const char ** 132BuiltinNames(void) 133{ 134 return internalNames; 135} 136 137static Bool 138CheckProtocol(const char *protocol) 139{ 140 int i; 141 142 for (i = 0; internalNames[i]; i++) 143 if (xf86NameCmp(protocol, internalNames[i]) == 0) 144 return TRUE; 145 for (i = 0; miscNames[i]; i++) 146 if (xf86NameCmp(protocol, miscNames[i]) == 0) 147 return TRUE; 148 return FALSE; 149} 150 151static const char * 152DefaultProtocol(void) 153{ 154#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 155 return "Auto"; 156#elif (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT) 157 return "WSMouse"; 158#else 159 return NULL; 160#endif 161} 162 163#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)) && defined(MOUSE_PROTO_SYSMOUSE) 164static struct { 165 int dproto; 166 const char *name; 167} devproto[] = { 168 { MOUSE_PROTO_MS, "Microsoft" }, 169 { MOUSE_PROTO_MSC, "MouseSystems" }, 170 { MOUSE_PROTO_LOGI, "Logitech" }, 171 { MOUSE_PROTO_MM, "MMSeries" }, 172 { MOUSE_PROTO_LOGIMOUSEMAN, "MouseMan" }, 173 { MOUSE_PROTO_BUS, "BusMouse" }, 174 { MOUSE_PROTO_INPORT, "BusMouse" }, 175 { MOUSE_PROTO_PS2, "PS/2" }, 176 { MOUSE_PROTO_HITTAB, "MMHitTab" }, 177 { MOUSE_PROTO_GLIDEPOINT, "GlidePoint" }, 178 { MOUSE_PROTO_INTELLI, "Intellimouse" }, 179 { MOUSE_PROTO_THINK, "ThinkingMouse" }, 180 { MOUSE_PROTO_SYSMOUSE, "SysMouse" } 181}; 182 183static const char * 184SetupAuto(InputInfoPtr pInfo, int *protoPara) 185{ 186 int i; 187 mousehw_t hw; 188 mousemode_t mode; 189 190 if (pInfo->fd == -1) 191 return NULL; 192 193 /* set the driver operation level, if applicable */ 194 i = 1; 195 ioctl(pInfo->fd, MOUSE_SETLEVEL, &i); 196 197 /* interrogate the driver and get some intelligence on the device. */ 198 hw.iftype = MOUSE_IF_UNKNOWN; 199 hw.model = MOUSE_MODEL_GENERIC; 200 ioctl(pInfo->fd, MOUSE_GETHWINFO, &hw); 201 xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: hw.iftype is %d, hw.model is %d\n", 202 pInfo->name, hw.iftype, hw.model); 203 if (ioctl(pInfo->fd, MOUSE_GETMODE, &mode) == 0) { 204 for (i = 0; i < sizeof(devproto)/sizeof(devproto[0]); ++i) { 205 if (mode.protocol == devproto[i].dproto) { 206 /* override some parameters */ 207 if (protoPara) { 208 protoPara[4] = mode.packetsize; 209 protoPara[0] = mode.syncmask[0]; 210 protoPara[1] = mode.syncmask[1]; 211 } 212 xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n", 213 pInfo->name, devproto[i].name); 214 return devproto[i].name; 215 } 216 } 217 } 218 return NULL; 219} 220 221static void 222SetSysMouseRes(InputInfoPtr pInfo, const char *protocol, int rate, int res) 223{ 224 mousemode_t mode; 225 MouseDevPtr pMse; 226 227 pMse = pInfo->private; 228 229 mode.rate = rate > 0 ? rate : -1; 230 mode.resolution = res > 0 ? res : -1; 231 mode.accelfactor = -1; 232#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 233 if (pMse->autoProbe || 234 (protocol && xf86NameCmp(protocol, "SysMouse") == 0)) { 235 /* 236 * As the FreeBSD sysmouse driver defaults to protocol level 0 237 * everytime it is opened we enforce protocol level 1 again at 238 * this point. 239 */ 240 mode.level = 1; 241 } else 242 mode.level = -1; 243#else 244 mode.level = -1; 245#endif 246 ioctl(pInfo->fd, MOUSE_SETMODE, &mode); 247} 248#endif 249 250#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 251 252#define MOUSED_PID_FILE "/var/run/moused.pid" 253 254/* 255 * Try to check if moused is running. DEFAULT_SYSMOUSE_DEV is useless without 256 * it. There doesn't seem to be a better way of checking. 257 */ 258static Bool 259MousedRunning(void) 260{ 261 FILE *f = NULL; 262 unsigned int pid; 263 264 if ((f = fopen(MOUSED_PID_FILE, "r")) != NULL) { 265 if (fscanf(f, "%u", &pid) == 1 && pid > 0) { 266 if (kill(pid, 0) == 0) { 267 fclose(f); 268 return TRUE; 269 } 270 } 271 fclose(f); 272 } 273 return FALSE; 274} 275 276static const char * 277FindDevice(InputInfoPtr pInfo, const char *protocol, int flags) 278{ 279 int fd = -1; 280 const char **pdev, *dev = NULL; 281 Bool devMouse = FALSE; 282 struct stat devMouseStat; 283 struct stat sb; 284 285 for (pdev = mouseDevs; *pdev; pdev++) { 286 SYSCALL (fd = open(*pdev, O_RDWR | O_NONBLOCK)); 287 if (fd == -1) { 288#ifdef DEBUG 289 ErrorF("Cannot open %s (%s)\n", *pdev, strerror(errno)); 290#endif 291 } else { 292 /* 293 * /dev/mouse is held until checks for matches with other devices 294 * are done. This is so that when it points to /dev/sysmouse, 295 * the test for whether /dev/sysmouse is usable can be made. 296 */ 297 if (!strcmp(*pdev, DEFAULT_MOUSE_DEV)) { 298 if (fstat(fd, &devMouseStat) == 0) 299 devMouse = TRUE; 300 close(fd); 301 continue; 302 } else if (!strcmp(*pdev, DEFAULT_SYSMOUSE_DEV)) { 303 /* Check if /dev/mouse is the same as /dev/sysmouse. */ 304 if (devMouse && fstat(fd, &sb) == 0 && 305 devMouseStat.st_dev == sb.st_dev && 306 devMouseStat.st_ino == sb.st_ino) { 307 /* If the same, use /dev/sysmouse. */ 308 devMouse = FALSE; 309 } 310 close(fd); 311 if (MousedRunning()) 312 break; 313 else { 314#ifdef DEBUG 315 ErrorF("moused isn't running\n"); 316#endif 317 } 318 } else { 319 close(fd); 320 break; 321 } 322 } 323 } 324 325 if (*pdev) 326 dev = *pdev; 327 else if (devMouse) 328 dev = DEFAULT_MOUSE_DEV; 329 330 if (dev) { 331 /* Set the Device option. */ 332 pInfo->options = 333 xf86AddNewOption(pInfo->options, "Device", dev); 334 xf86Msg(X_INFO, "%s: Setting Device option to \"%s\"\n", 335 pInfo->name, dev); 336 } 337 338 return *pdev; 339} 340#endif 341 342#if (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT) 343 344/* Only support wsmouse configuration for now */ 345static const char * 346SetupAuto(InputInfoPtr pInfo, int *protoPara) 347{ 348 349 xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n", 350 pInfo->name, "wsmouse"); 351 return "wsmouse"; 352} 353 354static void 355SetMouseRes(InputInfoPtr pInfo, const char *protocol, int rate, int res) 356{ 357 358 xf86MsgVerb(X_INFO, 3, "%s: SetMouseRes: protocol %s rate %d res %d\n", 359 pInfo->name, protocol, rate, res); 360} 361 362static const char * 363FindDevice(InputInfoPtr pInfo, const char *protocol, int flags) 364{ 365 int fd = -1; 366 const char **pdev; 367 368 for (pdev = mouseDevs; *pdev; pdev++) { 369 SYSCALL(fd = open(*pdev, O_RDWR | O_NONBLOCK)); 370 if (fd != -1) { 371 /* Set the Device option. */ 372 pInfo->options = 373 xf86AddNewOption(pInfo->options, 374 "Device", *pdev); 375 xf86Msg(X_INFO, "%s: found Device \"%s\"\n", 376 pInfo->name, *pdev); 377 close(fd); 378 break; 379 } 380 } 381 return *pdev; 382} 383#endif /* __OpenBSD__ || __NetBSD__ && WSCONS_SUPPORT */ 384 385#ifdef WSCONS_SUPPORT 386#define NUMEVENTS 64 387 388static void 389wsconsReadInput(InputInfoPtr pInfo) 390{ 391 MouseDevPtr pMse; 392 static struct wscons_event eventList[NUMEVENTS]; 393 int n, c; 394 struct wscons_event *event = eventList; 395 unsigned char *pBuf; 396 397 pMse = pInfo->private; 398 399 XisbBlockDuration(pMse->buffer, -1); 400 pBuf = (unsigned char *)eventList; 401 n = 0; 402 while (n < sizeof(eventList) && (c = XisbRead(pMse->buffer)) >= 0) { 403 pBuf[n++] = (unsigned char)c; 404 } 405 406 if (n == 0) 407 return; 408 409 n /= sizeof(struct wscons_event); 410 while( n-- ) { 411 int buttons = pMse->lastButtons; 412 int dx = 0, dy = 0, dz = 0, dw = 0, x, y; 413 switch (event->type) { 414 case WSCONS_EVENT_MOUSE_UP: 415#define BUTBIT (1 << (event->value <= 2 ? 2 - event->value : event->value)) 416 buttons &= ~BUTBIT; 417 break; 418 case WSCONS_EVENT_MOUSE_DOWN: 419 buttons |= BUTBIT; 420 break; 421 case WSCONS_EVENT_MOUSE_DELTA_X: 422 dx = event->value; 423 break; 424 case WSCONS_EVENT_MOUSE_DELTA_Y: 425 dy = -event->value; 426 break; 427#ifdef WSCONS_EVENT_MOUSE_DELTA_Z 428 case WSCONS_EVENT_MOUSE_DELTA_Z: 429 dz = event->value; 430 break; 431#endif 432#ifdef WSCONS_EVENT_MOUSE_DELTA_W 433 case WSCONS_EVENT_MOUSE_DELTA_W: 434 dw = event->value; 435 break; 436#endif 437 case WSCONS_EVENT_MOUSE_ABSOLUTE_X: 438 miPointerGetPosition (pInfo->dev, &x, &y); 439 x = event->value; 440 miPointerSetPosition (pInfo->dev, &x, &y); 441 xf86PostMotionEvent(pInfo->dev, TRUE, 0, 2, x, y); 442 ++event; 443 continue; 444 case WSCONS_EVENT_MOUSE_ABSOLUTE_Y: 445 miPointerGetPosition (pInfo->dev, &x, &y); 446 y = event->value; 447 miPointerSetPosition (pInfo->dev, &x, &y); 448 xf86PostMotionEvent(pInfo->dev, TRUE, 0, 2, x, y); 449 ++event; 450 continue; 451#ifdef WSCONS_EVENT_MOUSE_ABSOLUTE_Z 452 case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: 453 ++event; 454 continue; 455#endif 456#ifdef WSCONS_EVENT_MOUSE_ABSOLUTE_W 457 case WSCONS_EVENT_MOUSE_ABSOLUTE_W: 458 ++event; 459 continue; 460#endif 461 default: 462 LogMessageVerbSigSafe(X_WARNING, -1, 463 "%s: bad wsmouse event type=%d\n", pInfo->name, 464 event->type); 465 ++event; 466 continue; 467 } 468 469 pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw); 470 ++event; 471 } 472 return; 473} 474 475 476/* This function is called when the protocol is "wsmouse". */ 477static Bool 478wsconsPreInit(InputInfoPtr pInfo, const char *protocol, int flags) 479{ 480 MouseDevPtr pMse = pInfo->private; 481 482 /* Setup the local input proc. */ 483 pInfo->read_input = wsconsReadInput; 484 pMse->xisbscale = sizeof(struct wscons_event); 485 486#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 487 pInfo->flags |= XI86_CONFIGURED; 488#endif 489 return TRUE; 490} 491#endif 492 493#if defined(USBMOUSE_SUPPORT) 494 495typedef struct _UsbMseRec { 496 int packetSize; 497 int iid; 498 hid_item_t loc_x; /* x locator item */ 499 hid_item_t loc_y; /* y locator item */ 500 hid_item_t loc_z; /* z (wheel) locator item */ 501 hid_item_t loc_w; /* z (wheel) locator item */ 502 hid_item_t loc_btn[MSE_MAXBUTTONS]; /* buttons locator items */ 503 unsigned char *buffer; 504} UsbMseRec, *UsbMsePtr; 505 506static int 507usbMouseProc(DeviceIntPtr pPointer, int what) 508{ 509 InputInfoPtr pInfo; 510 MouseDevPtr pMse; 511 UsbMsePtr pUsbMse; 512 unsigned char map[MSE_MAXBUTTONS + 1]; 513 int nbuttons; 514 515 pInfo = pPointer->public.devicePrivate; 516 pMse = pInfo->private; 517 pMse->device = pPointer; 518 pUsbMse = pMse->mousePriv; 519 520 switch (what) { 521 case DEVICE_INIT: 522 pPointer->public.on = FALSE; 523 524 for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons) 525 map[nbuttons + 1] = nbuttons + 1; 526 527 InitPointerDeviceStruct((DevicePtr)pPointer, 528 map, 529 min(pMse->buttons, MSE_MAXBUTTONS), 530 miPointerGetMotionEvents, 531 pMse->Ctrl, 532 miPointerGetMotionBufferSize()); 533 534 /* X valuator */ 535 xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1); 536 xf86InitValuatorDefaults(pPointer, 0); 537 /* Y valuator */ 538 xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1); 539 xf86InitValuatorDefaults(pPointer, 1); 540 xf86MotionHistoryAllocate(pInfo); 541 break; 542 543 case DEVICE_ON: 544 pInfo->fd = xf86OpenSerial(pInfo->options); 545 if (pInfo->fd == -1) 546 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); 547 else { 548 pMse->buffer = XisbNew(pInfo->fd, pUsbMse->packetSize); 549 if (!pMse->buffer) { 550 free(pMse); 551 xf86CloseSerial(pInfo->fd); 552 pInfo->fd = -1; 553 } else { 554 xf86FlushInput(pInfo->fd); 555 if (!xf86InstallSIGIOHandler (pInfo->fd, usbSigioReadInput, 556 pInfo)) 557 AddEnabledDevice(pInfo->fd); 558 } 559 } 560 pMse->lastButtons = 0; 561 pMse->lastMappedButtons = 0; 562 pMse->emulateState = 0; 563 pPointer->public.on = TRUE; 564 break; 565 566 case DEVICE_OFF: 567 case DEVICE_CLOSE: 568 if (pInfo->fd != -1) { 569 RemoveEnabledDevice(pInfo->fd); 570 if (pUsbMse->packetSize > 8 && pUsbMse->buffer) { 571 free(pUsbMse->buffer); 572 } 573 if (pMse->buffer) { 574 XisbFree(pMse->buffer); 575 pMse->buffer = NULL; 576 } 577 xf86CloseSerial(pInfo->fd); 578 pInfo->fd = -1; 579 } 580 pPointer->public.on = FALSE; 581 usleep(300000); 582 break; 583 584 default: 585 return BadValue; 586 } 587 return Success; 588} 589 590static void 591usbReadInput(InputInfoPtr pInfo) 592{ 593 MouseDevPtr pMse; 594 UsbMsePtr pUsbMse; 595 int buttons = pMse->lastButtons; 596 int dx = 0, dy = 0, dz = 0, dw = 0; 597 int n, c; 598 unsigned char *pBuf; 599 600 pMse = pInfo->private; 601 pUsbMse = pMse->mousePriv; 602 603 XisbBlockDuration(pMse->buffer, -1); 604 pBuf = pUsbMse->buffer; 605 n = 0; 606 while ((c = XisbRead(pMse->buffer)) >= 0 && n < pUsbMse->packetSize) { 607 pBuf[n++] = (unsigned char)c; 608 } 609 if (n == 0) 610 return; 611 if (n != pUsbMse->packetSize) { 612 LogMessageVerbSigSafe(X_WARNING, -1, 613 "%s: incomplete packet, size %d\n", 614 pInfo->name, n); 615 } 616 /* discard packets with an id that don't match the mouse */ 617 /* XXX this is probably not the right thing */ 618 if (pUsbMse->iid != 0) { 619 if (*pBuf++ != pUsbMse->iid) 620 return; 621 } 622 dx = hid_get_data(pBuf, &pUsbMse->loc_x); 623 dy = hid_get_data(pBuf, &pUsbMse->loc_y); 624 dz = hid_get_data(pBuf, &pUsbMse->loc_z); 625 dw = hid_get_data(pBuf, &pUsbMse->loc_w); 626 627 buttons = 0; 628 for (n = 0; n < pMse->buttons; n++) { 629 if (hid_get_data(pBuf, &pUsbMse->loc_btn[n])) 630 buttons |= (1 << UMS_BUT(n)); 631 } 632 pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw); 633 return; 634} 635 636static void 637usbSigioReadInput (int fd, void *closure) 638{ 639 usbReadInput ((InputInfoPtr) closure); 640} 641 642/* This function is called when the protocol is "usb". */ 643static Bool 644usbPreInit(InputInfoPtr pInfo, const char *protocol, int flags) 645{ 646 MouseDevPtr pMse = pInfo->private; 647 UsbMsePtr pUsbMse; 648 report_desc_t reportDesc; 649 int i; 650 651 pUsbMse = malloc(sizeof(UsbMseRec)); 652 if (pUsbMse == NULL) { 653 xf86Msg(X_ERROR, "%s: cannot allocate UsbMouseRec\n", pInfo->name); 654 free(pMse); 655 return FALSE; 656 } 657 658 pMse->protocol = protocol; 659 xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol); 660 661 /* Collect the options, and process the common options. */ 662 COLLECT_INPUT_OPTIONS(pInfo, NULL); 663 xf86ProcessCommonOptions(pInfo, pInfo->options); 664 665 /* Check if the device can be opened. */ 666 pInfo->fd = xf86OpenSerial(pInfo->options); 667 if (pInfo->fd == -1) { 668 if (xf86GetAllowMouseOpenFail()) 669 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); 670 else { 671 xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name); 672 free(pUsbMse); 673 free(pMse); 674 return FALSE; 675 } 676 } 677 /* Get USB informations */ 678 reportDesc = hid_get_report_desc(pInfo->fd); 679 /* Get packet size & iid */ 680#ifdef USB_NEW_HID 681 if (ioctl(pInfo->fd, USB_GET_REPORT_ID, &pUsbMse->iid) == -1) { 682 xf86Msg(X_ERROR, "Error ioctl USB_GET_REPORT_ID on %s : %s\n", 683 pInfo->name, strerror(errno)); 684 return FALSE; 685 } 686 pUsbMse->packetSize = hid_report_size(reportDesc, hid_input, 687 pUsbMse->iid); 688#else 689 pUsbMse->packetSize = hid_report_size(reportDesc, hid_input, 690 &pUsbMse->iid); 691#endif 692 /* Allocate buffer */ 693 if (pUsbMse->packetSize <= 8) { 694 pUsbMse->buffer = pMse->protoBuf; 695 } else { 696 pUsbMse->buffer = malloc(pUsbMse->packetSize); 697 } 698 if (pUsbMse->buffer == NULL) { 699 xf86Msg(X_ERROR, "%s: cannot allocate buffer\n", pInfo->name); 700 free(pUsbMse); 701 free(pMse); 702 xf86CloseSerial(pInfo->fd); 703 return FALSE; 704 } 705#ifdef USB_NEW_HID 706 if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), 707 hid_input, &pUsbMse->loc_x, pUsbMse->iid) < 0) { 708 xf86Msg(X_WARNING, "%s: no x locator\n", pInfo->name); 709 } 710 if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), 711 hid_input, &pUsbMse->loc_y, pUsbMse->iid) < 0) { 712 xf86Msg(X_WARNING, "%s: no y locator\n", pInfo->name); 713 } 714 if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL), 715 hid_input, &pUsbMse->loc_z, pUsbMse->iid) < 0) { 716 } 717#else 718 if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), 719 hid_input, &pUsbMse->loc_x) < 0) { 720 xf86Msg(X_WARNING, "%s: no x locator\n", pInfo->name); 721 } 722 if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), 723 hid_input, &pUsbMse->loc_y) < 0) { 724 xf86Msg(X_WARNING, "%s: no y locator\n", pInfo->name); 725 } 726 if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL), 727 hid_input, &pUsbMse->loc_z) < 0) { 728 } 729#endif 730 /* Probe for number of buttons */ 731 for (i = 1; i <= MSE_MAXBUTTONS; i++) { 732 if (!hid_locate(reportDesc, HID_USAGE2(HUP_BUTTON, i), 733 hid_input, &pUsbMse->loc_btn[i-1] 734#ifdef USB_NEW_HID 735 , pUsbMse->iid 736#endif 737 )) 738 break; 739 } 740 pMse->buttons = i-1; 741 742 xf86CloseSerial(pInfo->fd); 743 pInfo->fd = -1; 744 745 /* Private structure */ 746 pMse->mousePriv = pUsbMse; 747 748 /* Process common mouse options (like Emulate3Buttons, etc). */ 749 pMse->CommonOptions(pInfo); 750 751 /* Setup the local procs. */ 752 pInfo->device_control = usbMouseProc; 753 pInfo->read_input = usbReadInput; 754 755#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 12 756 pInfo->flags |= XI86_CONFIGURED; 757#endif 758 return TRUE; 759} 760#endif /* USBMOUSE */ 761 762static Bool 763bsdMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags) 764{ 765 /* The protocol is guaranteed to be one of the internalNames[] */ 766#ifdef WSCONS_SUPPORT 767 if (xf86NameCmp(protocol, "WSMouse") == 0) { 768 return wsconsPreInit(pInfo, protocol, flags); 769 } 770#endif 771#ifdef USBMOUSE_SUPPORT 772 if (xf86NameCmp(protocol, "usb") == 0) { 773 return usbPreInit(pInfo, protocol, flags); 774 } 775#endif 776 return TRUE; 777} 778 779OSMouseInfoPtr 780OSMouseInit(int flags) 781{ 782 OSMouseInfoPtr p; 783 784 p = calloc(sizeof(OSMouseInfoRec), 1); 785 if (!p) 786 return NULL; 787 p->SupportedInterfaces = SupportedInterfaces; 788 p->BuiltinNames = BuiltinNames; 789 p->DefaultProtocol = DefaultProtocol; 790 p->CheckProtocol = CheckProtocol; 791#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)) && defined(MOUSE_PROTO_SYSMOUSE) 792 p->SetupAuto = SetupAuto; 793 p->SetPS2Res = SetSysMouseRes; 794 p->SetBMRes = SetSysMouseRes; 795 p->SetMiscRes = SetSysMouseRes; 796#endif 797#if (defined(__OpenBSD__) || defined(__NetBSD__)) && defined(WSCONS_SUPPORT) 798 p->SetupAuto = SetupAuto; 799 p->SetMiscRes = SetMouseRes; 800#endif 801#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__NetBSD__) 802 p->FindDevice = FindDevice; 803#endif 804 p->PreInit = bsdMousePreInit; 805 return p; 806} 807