Initial commit
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / os-support / bsd / bsd_mouse.c
blob21fe1ff18762606502bc403d80d9fb2cd34c75e2
2 /*
3 * Copyright (c) 1999-2003 by The XFree86 Project, Inc.
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:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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.
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).
29 #ifdef HAVE_XORG_CONFIG_H
30 #include <xorg-config.h>
31 #endif
33 #include <X11/X.h>
34 #include "xf86.h"
35 #include "xf86Priv.h"
36 #include "xf86_OSlib.h"
37 #include "xf86Xinput.h"
38 #include "xf86OSmouse.h"
39 #include "xisb.h"
40 #include "mipointer.h"
41 #ifdef WSCONS_SUPPORT
42 #include <dev/wscons/wsconsio.h>
43 #endif
44 #ifdef USBMOUSE_SUPPORT
45 #ifdef HAS_LIB_USB_HID
46 #include <usbhid.h>
47 #else
48 #include "usb.h"
49 #endif
51 #include <dev/usb/usb.h>
52 #ifdef USB_GET_REPORT_ID
53 #define USB_NEW_HID
54 #endif
56 #define HUP_GENERIC_DESKTOP 0x0001
57 #define HUP_BUTTON 0x0009
59 #define HUG_X 0x0030
60 #define HUG_Y 0x0031
61 #define HUG_Z 0x0032
62 #define HUG_WHEEL 0x0038
64 #define HID_USAGE2(p,u) (((p) << 16) | u)
66 /* The UMS mices have middle button as number 3 */
67 #define UMS_BUT(i) ((i) == 0 ? 2 : (i) == 1 ? 0 : (i) == 2 ? 1 : (i))
68 #endif /* USBMOUSE_SUPPORT */
70 #ifdef USBMOUSE_SUPPORT
71 static void usbSigioReadInput (int fd, void *closure);
72 #endif
74 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
75 /* These are for FreeBSD and DragonFly */
76 #define DEFAULT_MOUSE_DEV "/dev/mouse"
77 #define DEFAULT_SYSMOUSE_DEV "/dev/sysmouse"
78 #define DEFAULT_PS2_DEV "/dev/psm0"
80 static const char *mouseDevs[] = {
81 DEFAULT_MOUSE_DEV,
82 DEFAULT_SYSMOUSE_DEV,
83 DEFAULT_PS2_DEV,
84 NULL
86 #elif defined(__OpenBSD__) && defined(WSCONS_SUPPORT)
87 /* Only wsmouse mices are autoconfigured for now on OpenBSD */
88 #define DEFAULT_WSMOUSE_DEV "/dev/wsmouse"
89 #define DEFAULT_WSMOUSE0_DEV "/dev/wsmouse0"
91 static const char *mouseDevs[] = {
92 DEFAULT_WSMOUSE_DEV,
93 DEFAULT_WSMOUSE0_DEV,
94 NULL
96 #endif
98 static int
99 SupportedInterfaces(void)
101 #if defined(__NetBSD__)
102 return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO;
103 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
104 return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_MISC;
105 #else
106 return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO;
107 #endif
110 /* Names of protocols that are handled internally here. */
111 static const char *internalNames[] = {
112 #if defined(WSCONS_SUPPORT)
113 "WSMouse",
114 #endif
115 #if defined(USBMOUSE_SUPPORT)
116 "usb",
117 #endif
118 NULL
122 * Names of MSC_MISC protocols that the OS supports. These are decoded by
123 * main "mouse" driver.
125 static const char *miscNames[] = {
126 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
127 "SysMouse",
128 #endif
129 NULL
132 static const char **
133 BuiltinNames(void)
135 return internalNames;
138 static Bool
139 CheckProtocol(const char *protocol)
141 int i;
143 for (i = 0; internalNames[i]; i++)
144 if (xf86NameCmp(protocol, internalNames[i]) == 0)
145 return TRUE;
146 for (i = 0; miscNames[i]; i++)
147 if (xf86NameCmp(protocol, miscNames[i]) == 0)
148 return TRUE;
149 return FALSE;
152 static const char *
153 DefaultProtocol(void)
155 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
156 return "Auto";
157 #elif defined(__OpenBSD__) && defined(WSCONS_SUPPORT)
158 return "WSMouse";
159 #else
160 return NULL;
161 #endif
164 #if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)) && defined(MOUSE_PROTO_SYSMOUSE)
165 static struct {
166 int dproto;
167 const char *name;
168 } devproto[] = {
169 { MOUSE_PROTO_MS, "Microsoft" },
170 { MOUSE_PROTO_MSC, "MouseSystems" },
171 { MOUSE_PROTO_LOGI, "Logitech" },
172 { MOUSE_PROTO_MM, "MMSeries" },
173 { MOUSE_PROTO_LOGIMOUSEMAN, "MouseMan" },
174 { MOUSE_PROTO_BUS, "BusMouse" },
175 { MOUSE_PROTO_INPORT, "BusMouse" },
176 { MOUSE_PROTO_PS2, "PS/2" },
177 { MOUSE_PROTO_HITTAB, "MMHitTab" },
178 { MOUSE_PROTO_GLIDEPOINT, "GlidePoint" },
179 { MOUSE_PROTO_INTELLI, "Intellimouse" },
180 { MOUSE_PROTO_THINK, "ThinkingMouse" },
181 { MOUSE_PROTO_SYSMOUSE, "SysMouse" }
184 static const char *
185 SetupAuto(InputInfoPtr pInfo, int *protoPara)
187 int i;
188 mousehw_t hw;
189 mousemode_t mode;
191 if (pInfo->fd == -1)
192 return NULL;
194 /* set the driver operation level, if applicable */
195 i = 1;
196 ioctl(pInfo->fd, MOUSE_SETLEVEL, &i);
198 /* interrogate the driver and get some intelligence on the device. */
199 hw.iftype = MOUSE_IF_UNKNOWN;
200 hw.model = MOUSE_MODEL_GENERIC;
201 ioctl(pInfo->fd, MOUSE_GETHWINFO, &hw);
202 xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: hw.iftype is %d, hw.model is %d\n",
203 pInfo->name, hw.iftype, hw.model);
204 if (ioctl(pInfo->fd, MOUSE_GETMODE, &mode) == 0) {
205 for (i = 0; i < sizeof(devproto)/sizeof(devproto[0]); ++i) {
206 if (mode.protocol == devproto[i].dproto) {
207 /* override some parameters */
208 if (protoPara) {
209 protoPara[4] = mode.packetsize;
210 protoPara[0] = mode.syncmask[0];
211 protoPara[1] = mode.syncmask[1];
213 xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n",
214 pInfo->name, devproto[i].name);
215 return devproto[i].name;
219 return NULL;
222 static void
223 SetSysMouseRes(InputInfoPtr pInfo, const char *protocol, int rate, int res)
225 mousemode_t mode;
226 MouseDevPtr pMse;
228 pMse = pInfo->private;
230 mode.rate = rate > 0 ? rate : -1;
231 mode.resolution = res > 0 ? res : -1;
232 mode.accelfactor = -1;
233 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
234 if (pMse->autoProbe ||
235 (protocol && xf86NameCmp(protocol, "SysMouse") == 0)) {
237 * As the FreeBSD sysmouse driver defaults to protocol level 0
238 * everytime it is opened we enforce protocol level 1 again at
239 * this point.
241 mode.level = 1;
242 } else
243 mode.level = -1;
244 #else
245 mode.level = -1;
246 #endif
247 ioctl(pInfo->fd, MOUSE_SETMODE, &mode);
249 #endif
251 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
253 #define MOUSED_PID_FILE "/var/run/moused.pid"
256 * Try to check if moused is running. DEFAULT_SYSMOUSE_DEV is useless without
257 * it. There doesn't seem to be a better way of checking.
259 static Bool
260 MousedRunning(void)
262 FILE *f = NULL;
263 unsigned int pid;
265 if ((f = fopen(MOUSED_PID_FILE, "r")) != NULL) {
266 if (fscanf(f, "%u", &pid) == 1 && pid > 0) {
267 if (kill(pid, 0) == 0) {
268 fclose(f);
269 return TRUE;
272 fclose(f);
274 return FALSE;
277 static const char *
278 FindDevice(InputInfoPtr pInfo, const char *protocol, int flags)
280 int fd = -1;
281 const char **pdev, *dev = NULL;
282 Bool devMouse = FALSE;
283 struct stat devMouseStat;
284 struct stat sb;
286 for (pdev = mouseDevs; *pdev; pdev++) {
287 SYSCALL (fd = open(*pdev, O_RDWR | O_NONBLOCK));
288 if (fd == -1) {
289 #ifdef DEBUG
290 ErrorF("Cannot open %s (%s)\n", *pdev, strerror(errno));
291 #endif
292 } else {
294 * /dev/mouse is held until checks for matches with other devices
295 * are done. This is so that when it points to /dev/sysmouse,
296 * the test for whether /dev/sysmouse is usable can be made.
298 if (!strcmp(*pdev, DEFAULT_MOUSE_DEV)) {
299 if (fstat(fd, &devMouseStat) == 0)
300 devMouse = TRUE;
301 close(fd);
302 continue;
303 } else if (!strcmp(*pdev, DEFAULT_SYSMOUSE_DEV)) {
304 /* Check if /dev/mouse is the same as /dev/sysmouse. */
305 if (devMouse && fstat(fd, &sb) == 0 &&
306 devMouseStat.st_dev == sb.st_dev &&
307 devMouseStat.st_ino == sb.st_ino) {
308 /* If the same, use /dev/sysmouse. */
309 devMouse = FALSE;
311 close(fd);
312 if (MousedRunning())
313 break;
314 else {
315 #ifdef DEBUG
316 ErrorF("moused isn't running\n");
317 #endif
319 } else {
320 close(fd);
321 break;
326 if (*pdev)
327 dev = *pdev;
328 else if (devMouse)
329 dev = DEFAULT_MOUSE_DEV;
331 if (dev) {
332 /* Set the Device option. */
333 pInfo->conf_idev->commonOptions =
334 xf86AddNewOption(pInfo->conf_idev->commonOptions, "Device", dev);
335 xf86Msg(X_INFO, "%s: Setting Device option to \"%s\"\n",
336 pInfo->name, dev);
339 return *pdev;
341 #endif
343 #if defined(__OpenBSD__) && defined(WSCONS_SUPPORT)
345 /* Only support wsmouse configuration for now */
346 static const char *
347 SetupAuto(InputInfoPtr pInfo, int *protoPara)
350 xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n",
351 pInfo->name, "wsmouse");
352 return "wsmouse";
355 static void
356 SetMouseRes(InputInfoPtr pInfo, const char *protocol, int rate, int res)
359 xf86MsgVerb(X_INFO, 3, "%s: SetMouseRes: protocol %s rate %d res %d\n",
360 pInfo->name, protocol, rate, res);
363 static const char *
364 FindDevice(InputInfoPtr pInfo, const char *protocol, int flags)
366 int fd = -1;
367 const char **pdev;
369 for (pdev = mouseDevs; *pdev; pdev++) {
370 SYSCALL(fd = open(*pdev, O_RDWR | O_NONBLOCK));
371 if (fd != -1) {
372 /* Set the Device option. */
373 pInfo->conf_idev->commonOptions =
374 xf86AddNewOption(pInfo->conf_idev->commonOptions,
375 "Device", *pdev);
376 xf86Msg(X_INFO, "%s: found Device \"%s\"\n",
377 pInfo->name, *pdev);
378 close(fd);
379 break;
382 return *pdev;
384 #endif /* __OpenBSD__ && WSCONS_SUPPORT */
386 #ifdef WSCONS_SUPPORT
387 #define NUMEVENTS 64
389 static void
390 wsconsReadInput(InputInfoPtr pInfo)
392 MouseDevPtr pMse;
393 static struct wscons_event eventList[NUMEVENTS];
394 int n, c;
395 struct wscons_event *event = eventList;
396 unsigned char *pBuf;
398 pMse = pInfo->private;
400 XisbBlockDuration(pMse->buffer, -1);
401 pBuf = (unsigned char *)eventList;
402 n = 0;
403 while (n < sizeof(eventList) && (c = XisbRead(pMse->buffer)) >= 0) {
404 pBuf[n++] = (unsigned char)c;
407 if (n == 0)
408 return;
410 n /= sizeof(struct wscons_event);
411 while( n-- ) {
412 int buttons = pMse->lastButtons;
413 int dx = 0, dy = 0, dz = 0, dw = 0;
414 switch (event->type) {
415 case WSCONS_EVENT_MOUSE_UP:
416 #define BUTBIT (1 << (event->value <= 2 ? 2 - event->value : event->value))
417 buttons &= ~BUTBIT;
418 break;
419 case WSCONS_EVENT_MOUSE_DOWN:
420 buttons |= BUTBIT;
421 break;
422 case WSCONS_EVENT_MOUSE_DELTA_X:
423 dx = event->value;
424 break;
425 case WSCONS_EVENT_MOUSE_DELTA_Y:
426 dy = -event->value;
427 break;
428 #ifdef WSCONS_EVENT_MOUSE_DELTA_Z
429 case WSCONS_EVENT_MOUSE_DELTA_Z:
430 dz = event->value;
431 break;
432 #endif
433 default:
434 xf86Msg(X_WARNING, "%s: bad wsmouse event type=%d\n", pInfo->name,
435 event->type);
436 ++event;
437 continue;
440 pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw);
441 ++event;
443 return;
447 /* This function is called when the protocol is "wsmouse". */
448 static Bool
449 wsconsPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
451 MouseDevPtr pMse = pInfo->private;
453 pMse->protocol = protocol;
454 xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
456 /* Collect the options, and process the common options. */
457 xf86CollectInputOptions(pInfo, NULL, NULL);
458 xf86ProcessCommonOptions(pInfo, pInfo->options);
460 /* Check if the device can be opened. */
461 pInfo->fd = xf86OpenSerial(pInfo->options);
462 if (pInfo->fd == -1) {
463 if (xf86GetAllowMouseOpenFail())
464 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
465 else {
466 xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
467 xfree(pMse);
468 return FALSE;
471 xf86CloseSerial(pInfo->fd);
472 pInfo->fd = -1;
474 /* Process common mouse options (like Emulate3Buttons, etc). */
475 pMse->CommonOptions(pInfo);
477 /* Setup the local input proc. */
478 pInfo->read_input = wsconsReadInput;
479 pMse->xisbscale = sizeof(struct wscons_event);
481 pInfo->flags |= XI86_CONFIGURED;
482 return TRUE;
484 #endif
486 #if defined(USBMOUSE_SUPPORT)
488 typedef struct _UsbMseRec {
489 int packetSize;
490 int iid;
491 hid_item_t loc_x; /* x locator item */
492 hid_item_t loc_y; /* y locator item */
493 hid_item_t loc_z; /* z (wheel) locator item */
494 hid_item_t loc_btn[MSE_MAXBUTTONS]; /* buttons locator items */
495 unsigned char *buffer;
496 } UsbMseRec, *UsbMsePtr;
498 static int
499 usbMouseProc(DeviceIntPtr pPointer, int what)
501 InputInfoPtr pInfo;
502 MouseDevPtr pMse;
503 UsbMsePtr pUsbMse;
504 unsigned char map[MSE_MAXBUTTONS + 1];
505 int nbuttons;
507 pInfo = pPointer->public.devicePrivate;
508 pMse = pInfo->private;
509 pMse->device = pPointer;
510 pUsbMse = pMse->mousePriv;
512 switch (what) {
513 case DEVICE_INIT:
514 pPointer->public.on = FALSE;
516 for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons)
517 map[nbuttons + 1] = nbuttons + 1;
519 InitPointerDeviceStruct((DevicePtr)pPointer,
520 map,
521 min(pMse->buttons, MSE_MAXBUTTONS),
522 miPointerGetMotionEvents,
523 pMse->Ctrl,
524 miPointerGetMotionBufferSize());
526 /* X valuator */
527 xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1);
528 xf86InitValuatorDefaults(pPointer, 0);
529 /* Y valuator */
530 xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1);
531 xf86InitValuatorDefaults(pPointer, 1);
532 xf86MotionHistoryAllocate(pInfo);
533 break;
535 case DEVICE_ON:
536 pInfo->fd = xf86OpenSerial(pInfo->options);
537 if (pInfo->fd == -1)
538 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
539 else {
540 pMse->buffer = XisbNew(pInfo->fd, pUsbMse->packetSize);
541 if (!pMse->buffer) {
542 xfree(pMse);
543 xf86CloseSerial(pInfo->fd);
544 pInfo->fd = -1;
545 } else {
546 xf86FlushInput(pInfo->fd);
547 if (!xf86InstallSIGIOHandler (pInfo->fd, usbSigioReadInput,
548 pInfo))
549 AddEnabledDevice(pInfo->fd);
552 pMse->lastButtons = 0;
553 pMse->lastMappedButtons = 0;
554 pMse->emulateState = 0;
555 pPointer->public.on = TRUE;
556 break;
558 case DEVICE_OFF:
559 case DEVICE_CLOSE:
560 if (pInfo->fd != -1) {
561 RemoveEnabledDevice(pInfo->fd);
562 if (pUsbMse->packetSize > 8 && pUsbMse->buffer) {
563 xfree(pUsbMse->buffer);
565 if (pMse->buffer) {
566 XisbFree(pMse->buffer);
567 pMse->buffer = NULL;
569 xf86CloseSerial(pInfo->fd);
570 pInfo->fd = -1;
572 pPointer->public.on = FALSE;
573 usleep(300000);
574 break;
576 return Success;
579 static void
580 usbReadInput(InputInfoPtr pInfo)
582 MouseDevPtr pMse;
583 UsbMsePtr pUsbMse;
584 int buttons = pMse->lastButtons;
585 int dx = 0, dy = 0, dz = 0, dw = 0;
586 int n, c;
587 unsigned char *pBuf;
589 pMse = pInfo->private;
590 pUsbMse = pMse->mousePriv;
592 XisbBlockDuration(pMse->buffer, -1);
593 pBuf = pUsbMse->buffer;
594 n = 0;
595 while ((c = XisbRead(pMse->buffer)) >= 0 && n < pUsbMse->packetSize) {
596 pBuf[n++] = (unsigned char)c;
598 if (n == 0)
599 return;
600 if (n != pUsbMse->packetSize) {
601 xf86Msg(X_WARNING, "%s: incomplete packet, size %d\n", pInfo->name,
604 /* discard packets with an id that don't match the mouse */
605 /* XXX this is probably not the right thing */
606 if (pUsbMse->iid != 0) {
607 if (*pBuf++ != pUsbMse->iid)
608 return;
610 dx = hid_get_data(pBuf, &pUsbMse->loc_x);
611 dy = hid_get_data(pBuf, &pUsbMse->loc_y);
612 dz = hid_get_data(pBuf, &pUsbMse->loc_z);
614 buttons = 0;
615 for (n = 0; n < pMse->buttons; n++) {
616 if (hid_get_data(pBuf, &pUsbMse->loc_btn[n]))
617 buttons |= (1 << UMS_BUT(n));
619 pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw);
620 return;
623 static void
624 usbSigioReadInput (int fd, void *closure)
626 usbReadInput ((InputInfoPtr) closure);
629 /* This function is called when the protocol is "usb". */
630 static Bool
631 usbPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
633 MouseDevPtr pMse = pInfo->private;
634 UsbMsePtr pUsbMse;
635 report_desc_t reportDesc;
636 int i;
638 pUsbMse = xalloc(sizeof(UsbMseRec));
639 if (pUsbMse == NULL) {
640 xf86Msg(X_ERROR, "%s: cannot allocate UsbMouseRec\n", pInfo->name);
641 xfree(pMse);
642 return FALSE;
645 pMse->protocol = protocol;
646 xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
648 /* Collect the options, and process the common options. */
649 xf86CollectInputOptions(pInfo, NULL, NULL);
650 xf86ProcessCommonOptions(pInfo, pInfo->options);
652 /* Check if the device can be opened. */
653 pInfo->fd = xf86OpenSerial(pInfo->options);
654 if (pInfo->fd == -1) {
655 if (xf86GetAllowMouseOpenFail())
656 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
657 else {
658 xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
659 xfree(pUsbMse);
660 xfree(pMse);
661 return FALSE;
664 /* Get USB informations */
665 reportDesc = hid_get_report_desc(pInfo->fd);
666 /* Get packet size & iid */
667 #ifdef USB_NEW_HID
668 if (ioctl(pInfo->fd, USB_GET_REPORT_ID, &pUsbMse->iid) == -1) {
669 xf86Msg(X_ERROR, "Error ioctl USB_GET_REPORT_ID on %s : %s\n",
670 pInfo->name, strerror(errno));
671 return FALSE;
673 pUsbMse->packetSize = hid_report_size(reportDesc, hid_input,
674 pUsbMse->iid);
675 #else
676 pUsbMse->packetSize = hid_report_size(reportDesc, hid_input,
677 &pUsbMse->iid);
678 #endif
679 /* Allocate buffer */
680 if (pUsbMse->packetSize <= 8) {
681 pUsbMse->buffer = pMse->protoBuf;
682 } else {
683 pUsbMse->buffer = xalloc(pUsbMse->packetSize);
685 if (pUsbMse->buffer == NULL) {
686 xf86Msg(X_ERROR, "%s: cannot allocate buffer\n", pInfo->name);
687 xfree(pUsbMse);
688 xfree(pMse);
689 xf86CloseSerial(pInfo->fd);
690 return FALSE;
692 #ifdef USB_NEW_HID
693 if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
694 hid_input, &pUsbMse->loc_x, pUsbMse->iid) < 0) {
695 xf86Msg(X_WARNING, "%s: no x locator\n", pInfo->name);
697 if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
698 hid_input, &pUsbMse->loc_y, pUsbMse->iid) < 0) {
699 xf86Msg(X_WARNING, "%s: no y locator\n", pInfo->name);
701 if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
702 hid_input, &pUsbMse->loc_z, pUsbMse->iid) < 0) {
704 #else
705 if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
706 hid_input, &pUsbMse->loc_x) < 0) {
707 xf86Msg(X_WARNING, "%s: no x locator\n", pInfo->name);
709 if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
710 hid_input, &pUsbMse->loc_y) < 0) {
711 xf86Msg(X_WARNING, "%s: no y locator\n", pInfo->name);
713 if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL),
714 hid_input, &pUsbMse->loc_z) < 0) {
716 #endif
717 /* Probe for number of buttons */
718 for (i = 1; i <= MSE_MAXBUTTONS; i++) {
719 if (!hid_locate(reportDesc, HID_USAGE2(HUP_BUTTON, i),
720 hid_input, &pUsbMse->loc_btn[i-1]
721 #ifdef USB_NEW_HID
722 , pUsbMse->iid
723 #endif
725 break;
727 pMse->buttons = i-1;
729 xf86CloseSerial(pInfo->fd);
730 pInfo->fd = -1;
732 /* Private structure */
733 pMse->mousePriv = pUsbMse;
735 /* Process common mouse options (like Emulate3Buttons, etc). */
736 pMse->CommonOptions(pInfo);
738 /* Setup the local procs. */
739 pInfo->device_control = usbMouseProc;
740 pInfo->read_input = usbReadInput;
742 pInfo->flags |= XI86_CONFIGURED;
743 return TRUE;
745 #endif /* USBMOUSE */
747 static Bool
748 bsdMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags)
750 /* The protocol is guaranteed to be one of the internalNames[] */
751 #ifdef WSCONS_SUPPORT
752 if (xf86NameCmp(protocol, "WSMouse") == 0) {
753 return wsconsPreInit(pInfo, protocol, flags);
755 #endif
756 #ifdef USBMOUSE_SUPPORT
757 if (xf86NameCmp(protocol, "usb") == 0) {
758 return usbPreInit(pInfo, protocol, flags);
760 #endif
761 return TRUE;
764 _X_EXPORT OSMouseInfoPtr
765 xf86OSMouseInit(int flags)
767 OSMouseInfoPtr p;
769 p = xcalloc(sizeof(OSMouseInfoRec), 1);
770 if (!p)
771 return NULL;
772 p->SupportedInterfaces = SupportedInterfaces;
773 p->BuiltinNames = BuiltinNames;
774 p->DefaultProtocol = DefaultProtocol;
775 p->CheckProtocol = CheckProtocol;
776 #if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)) && defined(MOUSE_PROTO_SYSMOUSE)
777 p->SetupAuto = SetupAuto;
778 p->SetPS2Res = SetSysMouseRes;
779 p->SetBMRes = SetSysMouseRes;
780 p->SetMiscRes = SetSysMouseRes;
781 #endif
782 #if defined(__OpenBSD__) && defined(WSCONS_SUPPORT)
783 p->SetupAuto = SetupAuto;
784 p->SetMiscRes = SetMouseRes;
785 #endif
786 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__DragonFly__)
787 p->FindDevice = FindDevice;
788 #endif
789 p->PreInit = bsdMousePreInit;
790 return p;