First import
[xorg_rtime.git] / xorg-server-1.4 / hw / darwin / iokit / xfIOKit.c
blobc7ebd1c1865e12997ee3816579fa717e62f3e561
1 /**************************************************************
3 * IOKit support for the Darwin X Server
5 * HISTORY:
6 * Original port to Mac OS X Server by John Carmack
7 * Port to Darwin 1.0 by Dave Zarzycki
8 * Significantly rewritten for XFree86 4.0.1 by Torrey Lyons
10 **************************************************************/
12 * Copyright (c) 2001-2004 Torrey T. Lyons. All Rights Reserved.
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the "Software"),
16 * to deal in the Software without restriction, including without limitation
17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 * and/or sell copies of the Software, and to permit persons to whom the
19 * Software is furnished to do so, subject to the following conditions:
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
28 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
29 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 * DEALINGS IN THE SOFTWARE.
32 * Except as contained in this notice, the name(s) of the above copyright
33 * holders shall not be used in advertising or otherwise to promote the sale,
34 * use or other dealings in this Software without prior written authorization.
37 #if HAVE_XORG_CONFIG_H
38 #include <xorg-config.h>
39 #endif
41 #include <X11/X.h>
42 #include <X11/Xproto.h>
43 #include "os.h"
44 #include "servermd.h"
45 #include "inputstr.h"
46 #include "scrnintstr.h"
47 #include "mi.h"
48 #include "mibstore.h"
49 #include "mipointer.h"
50 #include "micmap.h"
51 #include "shadow.h"
53 #include <sys/types.h>
54 #include <sys/time.h>
55 #include <unistd.h>
56 #include <fcntl.h>
57 #include <pthread.h>
58 #include <assert.h>
60 #include <mach/mach_interface.h>
62 #define NO_CFPLUGIN
63 #include <IOKit/IOKitLib.h>
64 #include <IOKit/hidsystem/IOHIDShared.h>
65 #include <IOKit/graphics/IOGraphicsLib.h>
66 #include <drivers/event_status_driver.h>
68 // Define this to work around bugs in the display drivers for
69 // older PowerBook G3's. If the X server starts without this
70 // #define, you don't need it.
71 #undef OLD_POWERBOOK_G3
73 #include "darwin.h"
74 #include "xfIOKit.h"
76 // Globals
77 int xfIOKitScreenIndex = 0;
78 io_connect_t xfIOKitInputConnect = 0;
80 static pthread_t inputThread;
81 static EvGlobals * evg;
82 static mach_port_t masterPort;
83 static mach_port_t notificationPort;
84 static IONotificationPortRef NotificationPortRef;
85 static mach_port_t pmNotificationPort;
86 static io_iterator_t fbIter;
90 * XFIOKitStoreColors
91 * This is a callback from X to change the hardware colormap
92 * when using PsuedoColor.
94 static void XFIOKitStoreColors(
95 ColormapPtr pmap,
96 int numEntries,
97 xColorItem *pdefs)
99 kern_return_t kr;
100 int i;
101 IOColorEntry *newColors;
102 ScreenPtr pScreen = pmap->pScreen;
103 XFIOKitScreenPtr iokitScreen = XFIOKIT_SCREEN_PRIV(pScreen);
105 assert( newColors = (IOColorEntry *)
106 xalloc( numEntries*sizeof(IOColorEntry) ));
108 // Convert xColorItem values to IOColorEntry
109 // assume the colormap is PsuedoColor
110 // as we do not support DirectColor
111 for (i = 0; i < numEntries; i++) {
112 newColors[i].index = pdefs[i].pixel;
113 newColors[i].red = pdefs[i].red;
114 newColors[i].green = pdefs[i].green;
115 newColors[i].blue = pdefs[i].blue;
118 kr = IOFBSetCLUT( iokitScreen->fbService, 0, numEntries,
119 kSetCLUTByValue, newColors );
120 kern_assert( kr );
122 xfree( newColors );
127 * DarwinModeBell
128 * FIXME
130 void DarwinModeBell(
131 int loud,
132 DeviceIntPtr pDevice,
133 pointer ctrl,
134 int fbclass)
140 * DarwinModeGiveUp
141 * Closes the connections to IOKit services
143 void DarwinModeGiveUp( void )
145 int i;
147 // we must close the HID System first
148 // because it is a client of the framebuffer
149 NXCloseEventStatus( darwinParamConnect );
150 IOServiceClose( xfIOKitInputConnect );
151 for (i = 0; i < screenInfo.numScreens; i++) {
152 XFIOKitScreenPtr iokitScreen =
153 XFIOKIT_SCREEN_PRIV(screenInfo.screens[i]);
154 IOServiceClose( iokitScreen->fbService );
160 * ClearEvent
161 * Clear an event from the HID System event queue
163 static void ClearEvent(NXEvent * ep)
165 static NXEvent nullEvent = {NX_NULLEVENT, {0, 0 }, 0, -1, 0 };
167 *ep = nullEvent;
168 ep->data.compound.subType = ep->data.compound.misc.L[0] =
169 ep->data.compound.misc.L[1] = 0;
174 * XFIOKitHIDThread
175 * Read the HID System event queue, translate it to an X event,
176 * and queue it for processing.
178 static void *XFIOKitHIDThread(void *unused)
180 for (;;) {
181 NXEQElement *oldHead;
182 mach_msg_return_t kr;
183 mach_msg_empty_rcv_t msg;
185 kr = mach_msg((mach_msg_header_t*) &msg, MACH_RCV_MSG, 0,
186 sizeof(msg), notificationPort, 0, MACH_PORT_NULL);
187 kern_assert(kr);
189 while (evg->LLEHead != evg->LLETail) {
190 NXEvent ev;
191 xEvent xe;
193 // Extract the next event from the kernel queue
194 oldHead = (NXEQElement*)&evg->lleq[evg->LLEHead];
195 ev_lock(&oldHead->sema);
196 ev = oldHead->event;
197 ClearEvent(&oldHead->event);
198 evg->LLEHead = oldHead->next;
199 ev_unlock(&oldHead->sema);
201 memset(&xe, 0, sizeof(xe));
203 // These fields should be filled in for every event
204 xe.u.keyButtonPointer.rootX = ev.location.x;
205 xe.u.keyButtonPointer.rootY = ev.location.y;
206 xe.u.keyButtonPointer.time = GetTimeInMillis();
208 switch( ev.type ) {
209 case NX_MOUSEMOVED:
210 xe.u.u.type = MotionNotify;
211 break;
213 case NX_LMOUSEDOWN:
214 xe.u.u.type = ButtonPress;
215 xe.u.u.detail = 1;
216 break;
218 case NX_LMOUSEUP:
219 xe.u.u.type = ButtonRelease;
220 xe.u.u.detail = 1;
221 break;
223 // A newer kernel generates multi-button events with
224 // NX_SYSDEFINED. Button 2 isn't handled correctly by
225 // older kernels anyway. Just let NX_SYSDEFINED events
226 // handle these.
227 #if 0
228 case NX_RMOUSEDOWN:
229 xe.u.u.type = ButtonPress;
230 xe.u.u.detail = 2;
231 break;
233 case NX_RMOUSEUP:
234 xe.u.u.type = ButtonRelease;
235 xe.u.u.detail = 2;
236 break;
237 #endif
239 case NX_KEYDOWN:
240 xe.u.u.type = KeyPress;
241 xe.u.u.detail = ev.data.key.keyCode;
242 break;
244 case NX_KEYUP:
245 xe.u.u.type = KeyRelease;
246 xe.u.u.detail = ev.data.key.keyCode;
247 break;
249 case NX_FLAGSCHANGED:
250 xe.u.u.type = kXDarwinUpdateModifiers;
251 xe.u.clientMessage.u.l.longs0 = ev.flags;
252 break;
254 case NX_SYSDEFINED:
255 if (ev.data.compound.subType == 7) {
256 xe.u.u.type = kXDarwinUpdateButtons;
257 xe.u.clientMessage.u.l.longs0 =
258 ev.data.compound.misc.L[0];
259 xe.u.clientMessage.u.l.longs1 =
260 ev.data.compound.misc.L[1];
261 } else {
262 continue;
264 break;
266 case NX_SCROLLWHEELMOVED:
267 xe.u.u.type = kXDarwinScrollWheel;
268 xe.u.clientMessage.u.s.shorts0 =
269 ev.data.scrollWheel.deltaAxis1;
270 break;
272 default:
273 continue;
276 DarwinEQEnqueue(&xe);
280 return NULL;
285 * XFIOKitPMThread
286 * Handle power state notifications
288 static void *XFIOKitPMThread(void *arg)
290 ScreenPtr pScreen = (ScreenPtr)arg;
291 XFIOKitScreenPtr iokitScreen = XFIOKIT_SCREEN_PRIV(pScreen);
293 for (;;) {
294 mach_msg_return_t kr;
295 mach_msg_empty_rcv_t msg;
297 kr = mach_msg((mach_msg_header_t*) &msg, MACH_RCV_MSG, 0,
298 sizeof(msg), pmNotificationPort, 0, MACH_PORT_NULL);
299 kern_assert(kr);
301 // display is powering down
302 if (msg.header.msgh_id == 0) {
303 IOFBAcknowledgePM( iokitScreen->fbService );
304 xf86SetRootClip(pScreen, FALSE);
306 // display just woke up
307 else if (msg.header.msgh_id == 1) {
308 xf86SetRootClip(pScreen, TRUE);
311 return NULL;
316 * SetupFBandHID
317 * Setup an IOFramebuffer service and connect the HID system to it.
319 static Bool SetupFBandHID(
320 int index,
321 DarwinFramebufferPtr dfb,
322 XFIOKitScreenPtr iokitScreen)
324 kern_return_t kr;
325 io_service_t service;
326 io_connect_t fbService;
327 vm_address_t vram;
328 vm_size_t shmemSize;
329 int i;
330 UInt32 numModes;
331 IODisplayModeInformation modeInfo;
332 IODisplayModeID displayMode, *allModes;
333 IOIndex displayDepth;
334 IOFramebufferInformation fbInfo;
335 IOPixelInformation pixelInfo;
336 StdFBShmem_t *cshmem;
338 // find and open the IOFrameBuffer service
339 service = IOIteratorNext(fbIter);
340 if (service == 0)
341 return FALSE;
343 kr = IOServiceOpen( service, mach_task_self(),
344 kIOFBServerConnectType, &iokitScreen->fbService );
345 IOObjectRelease( service );
346 if (kr != KERN_SUCCESS) {
347 ErrorF("Failed to connect as window server to screen %i.\n", index);
348 return FALSE;
350 fbService = iokitScreen->fbService;
352 // create the slice of shared memory containing cursor state data
353 kr = IOFBCreateSharedCursor( fbService,
354 kIOFBCurrentShmemVersion,
355 32, 32 );
356 if (kr != KERN_SUCCESS)
357 return FALSE;
359 // Register for power management events for the framebuffer's device
360 kr = IOCreateReceivePort(kOSNotificationMessageID, &pmNotificationPort);
361 kern_assert(kr);
362 kr = IOConnectSetNotificationPort( fbService, 0,
363 pmNotificationPort, 0 );
364 if (kr != KERN_SUCCESS) {
365 ErrorF("Power management registration failed.\n");
368 // SET THE SCREEN PARAMETERS
369 // get the current screen resolution, refresh rate and depth
370 kr = IOFBGetCurrentDisplayModeAndDepth( fbService,
371 &displayMode,
372 &displayDepth );
373 if (kr != KERN_SUCCESS)
374 return FALSE;
376 // use the current screen resolution if the user
377 // only wants to change the refresh rate
378 if (darwinDesiredRefresh != -1 && darwinDesiredWidth == 0) {
379 kr = IOFBGetDisplayModeInformation( fbService,
380 displayMode,
381 &modeInfo );
382 if (kr != KERN_SUCCESS)
383 return FALSE;
384 darwinDesiredWidth = modeInfo.nominalWidth;
385 darwinDesiredHeight = modeInfo.nominalHeight;
388 // use the current resolution and refresh rate
389 // if the user doesn't have a preference
390 if (darwinDesiredWidth == 0) {
392 // change the pixel depth if desired
393 if (darwinDesiredDepth != -1) {
394 kr = IOFBGetDisplayModeInformation( fbService,
395 displayMode,
396 &modeInfo );
397 if (kr != KERN_SUCCESS)
398 return FALSE;
399 if (modeInfo.maxDepthIndex < darwinDesiredDepth) {
400 ErrorF("Discarding screen %i:\n", index);
401 ErrorF("Current screen resolution does not support desired pixel depth.\n");
402 return FALSE;
405 displayDepth = darwinDesiredDepth;
406 kr = IOFBSetDisplayModeAndDepth( fbService, displayMode,
407 displayDepth );
408 if (kr != KERN_SUCCESS)
409 return FALSE;
412 // look for display mode with correct resolution and refresh rate
413 } else {
415 // get an array of all supported display modes
416 kr = IOFBGetDisplayModeCount( fbService, &numModes );
417 if (kr != KERN_SUCCESS)
418 return FALSE;
419 assert(allModes = (IODisplayModeID *)
420 xalloc( numModes * sizeof(IODisplayModeID) ));
421 kr = IOFBGetDisplayModes( fbService, numModes, allModes );
422 if (kr != KERN_SUCCESS)
423 return FALSE;
425 for (i = 0; i < numModes; i++) {
426 kr = IOFBGetDisplayModeInformation( fbService, allModes[i],
427 &modeInfo );
428 if (kr != KERN_SUCCESS)
429 return FALSE;
431 if (modeInfo.flags & kDisplayModeValidFlag &&
432 modeInfo.nominalWidth == darwinDesiredWidth &&
433 modeInfo.nominalHeight == darwinDesiredHeight) {
435 if (darwinDesiredDepth == -1)
436 darwinDesiredDepth = modeInfo.maxDepthIndex;
437 if (modeInfo.maxDepthIndex < darwinDesiredDepth) {
438 ErrorF("Discarding screen %i:\n", index);
439 ErrorF("Desired screen resolution does not support desired pixel depth.\n");
440 return FALSE;
443 if ((darwinDesiredRefresh == -1 ||
444 (darwinDesiredRefresh << 16) == modeInfo.refreshRate)) {
445 displayMode = allModes[i];
446 displayDepth = darwinDesiredDepth;
447 kr = IOFBSetDisplayModeAndDepth(fbService,
448 displayMode,
449 displayDepth);
450 if (kr != KERN_SUCCESS)
451 return FALSE;
452 break;
457 xfree( allModes );
458 if (i >= numModes) {
459 ErrorF("Discarding screen %i:\n", index);
460 ErrorF("Desired screen resolution or refresh rate is not supported.\n");
461 return FALSE;
465 kr = IOFBGetPixelInformation( fbService, displayMode, displayDepth,
466 kIOFBSystemAperture, &pixelInfo );
467 if (kr != KERN_SUCCESS)
468 return FALSE;
470 #ifdef __i386__
471 /* x86 in 8bit mode currently needs fixed color map... */
472 if (pixelInfo.bitsPerComponent == 8 &&
473 pixelInfo.componentCount == 1)
475 pixelInfo.pixelType = kIOFixedCLUTPixels;
477 #endif
479 #ifdef OLD_POWERBOOK_G3
480 if (pixelInfo.pixelType == kIOCLUTPixels)
481 pixelInfo.pixelType = kIOFixedCLUTPixels;
482 #endif
484 kr = IOFBGetFramebufferInformationForAperture( fbService,
485 kIOFBSystemAperture,
486 &fbInfo );
487 if (kr != KERN_SUCCESS)
488 return FALSE;
490 // FIXME: 1x1 IOFramebuffers are sometimes used to indicate video
491 // outputs without a monitor connected to them. Since IOKit Xinerama
492 // does not really work, this often causes problems on PowerBooks.
493 // For now we explicitly check and ignore these screens.
494 if (fbInfo.activeWidth <= 1 || fbInfo.activeHeight <= 1) {
495 ErrorF("Discarding screen %i:\n", index);
496 ErrorF("Invalid width or height.\n");
497 return FALSE;
500 kr = IOConnectMapMemory( fbService, kIOFBCursorMemory,
501 mach_task_self(), (vm_address_t *) &cshmem,
502 &shmemSize, kIOMapAnywhere );
503 if (kr != KERN_SUCCESS)
504 return FALSE;
505 iokitScreen->cursorShmem = cshmem;
507 kr = IOConnectMapMemory( fbService, kIOFBSystemAperture,
508 mach_task_self(), &vram, &shmemSize,
509 kIOMapAnywhere );
510 if (kr != KERN_SUCCESS)
511 return FALSE;
513 iokitScreen->framebuffer = (void*)vram;
514 dfb->x = cshmem->screenBounds.minx;
515 dfb->y = cshmem->screenBounds.miny;
516 dfb->width = fbInfo.activeWidth;
517 dfb->height = fbInfo.activeHeight;
518 dfb->pitch = fbInfo.bytesPerRow;
519 dfb->bitsPerPixel = fbInfo.bitsPerPixel;
520 dfb->colorBitsPerPixel = pixelInfo.componentCount *
521 pixelInfo.bitsPerComponent;
522 dfb->bitsPerComponent = pixelInfo.bitsPerComponent;
524 // allocate shadow framebuffer
525 iokitScreen->shadowPtr = xalloc(dfb->pitch * dfb->height);
526 dfb->framebuffer = iokitScreen->shadowPtr;
528 // Note: Darwin kIORGBDirectPixels = X TrueColor, not DirectColor
529 if (pixelInfo.pixelType == kIORGBDirectPixels) {
530 dfb->colorType = TrueColor;
531 } else if (pixelInfo.pixelType == kIOCLUTPixels) {
532 dfb->colorType = PseudoColor;
533 } else if (pixelInfo.pixelType == kIOFixedCLUTPixels) {
534 dfb->colorType = StaticColor;
537 // Inform the HID system that the framebuffer is also connected to it.
538 kr = IOConnectAddClient( xfIOKitInputConnect, fbService );
539 kern_assert( kr );
541 // We have to have added at least one screen
542 // before we can enable the cursor.
543 kr = IOHIDSetCursorEnable(xfIOKitInputConnect, TRUE);
544 kern_assert( kr );
546 return TRUE;
551 * DarwinModeAddScreen
552 * IOKit specific initialization for each screen.
554 Bool DarwinModeAddScreen(
555 int index,
556 ScreenPtr pScreen)
558 DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
559 XFIOKitScreenPtr iokitScreen;
561 // allocate space for private per screen storage
562 iokitScreen = xalloc(sizeof(XFIOKitScreenRec));
563 XFIOKIT_SCREEN_PRIV(pScreen) = iokitScreen;
565 // setup hardware framebuffer
566 iokitScreen->fbService = 0;
567 if (! SetupFBandHID(index, dfb, iokitScreen)) {
568 if (iokitScreen->fbService) {
569 IOServiceClose(iokitScreen->fbService);
571 return FALSE;
574 return TRUE;
579 * XFIOKitShadowUpdate
580 * Update the damaged regions of the shadow framebuffer on the screen.
582 static void XFIOKitShadowUpdate(ScreenPtr pScreen,
583 shadowBufPtr pBuf)
585 DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
586 XFIOKitScreenPtr iokitScreen = XFIOKIT_SCREEN_PRIV(pScreen);
587 RegionPtr damage = &pBuf->damage;
588 int numBox = REGION_NUM_RECTS(damage);
589 BoxPtr pBox = REGION_RECTS(damage);
590 int pitch = dfb->pitch;
591 int bpp = dfb->bitsPerPixel/8;
593 // Loop through all the damaged boxes
594 while (numBox--) {
595 int width, height, offset;
596 unsigned char *src, *dst;
598 width = (pBox->x2 - pBox->x1) * bpp;
599 height = pBox->y2 - pBox->y1;
600 offset = (pBox->y1 * pitch) + (pBox->x1 * bpp);
601 src = iokitScreen->shadowPtr + offset;
602 dst = iokitScreen->framebuffer + offset;
604 while (height--) {
605 memcpy(dst, src, width);
606 dst += pitch;
607 src += pitch;
610 // Get the next box
611 pBox++;
617 * DarwinModeSetupScreen
618 * Finalize IOKit specific initialization of each screen.
620 Bool DarwinModeSetupScreen(
621 int index,
622 ScreenPtr pScreen)
624 DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
625 pthread_t pmThread;
627 // initalize cursor support
628 if (! XFIOKitInitCursor(pScreen)) {
629 return FALSE;
632 // initialize shadow framebuffer support
633 if (! shadowInit(pScreen, XFIOKitShadowUpdate, NULL)) {
634 ErrorF("Failed to initalize shadow framebuffer for screen %i.\n",
635 index);
636 return FALSE;
639 // initialize colormap handling as needed
640 if (dfb->colorType == PseudoColor) {
641 pScreen->StoreColors = XFIOKitStoreColors;
644 // initialize power manager handling
645 pthread_create( &pmThread, NULL, XFIOKitPMThread,
646 (void *) pScreen );
648 return TRUE;
653 * DarwinModeInitOutput
654 * One-time initialization of IOKit output support.
656 void DarwinModeInitOutput(
657 int argc,
658 char **argv)
660 static unsigned long generation = 0;
661 kern_return_t kr;
662 io_iterator_t iter;
663 io_service_t service;
664 vm_address_t shmem;
665 vm_size_t shmemSize;
667 ErrorF("Display mode: IOKit\n");
669 // Allocate private storage for each screen's IOKit specific info
670 if (generation != serverGeneration) {
671 xfIOKitScreenIndex = AllocateScreenPrivateIndex();
672 generation = serverGeneration;
675 kr = IOMasterPort(bootstrap_port, &masterPort);
676 kern_assert( kr );
678 // Find and open the HID System Service
679 // Do this now to be sure the Mac OS X window server is not running.
680 kr = IOServiceGetMatchingServices( masterPort,
681 IOServiceMatching( kIOHIDSystemClass ),
682 &iter );
683 kern_assert( kr );
685 assert( service = IOIteratorNext( iter ) );
687 kr = IOServiceOpen( service, mach_task_self(), kIOHIDServerConnectType,
688 &xfIOKitInputConnect );
689 if (kr != KERN_SUCCESS) {
690 ErrorF("Failed to connect to the HID System as the window server!\n");
691 #ifdef DARWIN_WITH_QUARTZ
692 FatalError("Quit the Mac OS X window server or use the -quartz option.\n");
693 #else
694 FatalError("Make sure you have quit the Mac OS X window server.\n");
695 #endif
698 IOObjectRelease( service );
699 IOObjectRelease( iter );
701 // Setup the event queue in memory shared by the kernel and X server
702 kr = IOHIDCreateSharedMemory( xfIOKitInputConnect,
703 kIOHIDCurrentShmemVersion );
704 kern_assert( kr );
706 kr = IOConnectMapMemory( xfIOKitInputConnect, kIOHIDGlobalMemory,
707 mach_task_self(), &shmem, &shmemSize,
708 kIOMapAnywhere );
709 kern_assert( kr );
711 evg = (EvGlobals *)(shmem + ((EvOffsets *)shmem)->evGlobalsOffset);
713 assert(sizeof(EvGlobals) == evg->structSize);
715 NotificationPortRef = IONotificationPortCreate( masterPort );
717 notificationPort = IONotificationPortGetMachPort(NotificationPortRef);
719 kr = IOConnectSetNotificationPort( xfIOKitInputConnect,
720 kIOHIDEventNotification,
721 notificationPort, 0 );
722 kern_assert( kr );
724 evg->movedMask |= NX_MOUSEMOVEDMASK;
726 // find number of framebuffers
727 kr = IOServiceGetMatchingServices( masterPort,
728 IOServiceMatching( IOFRAMEBUFFER_CONFORMSTO ),
729 &fbIter );
730 kern_assert( kr );
732 darwinScreensFound = 0;
733 while ((service = IOIteratorNext(fbIter))) {
734 IOObjectRelease( service );
735 darwinScreensFound++;
737 IOIteratorReset(fbIter);
742 * DarwinModeInitInput
743 * One-time initialization of IOKit input support.
745 void DarwinModeInitInput(
746 int argc,
747 char **argv)
749 kern_return_t kr;
750 int fd[2];
752 kr = IOHIDSetEventsEnable(xfIOKitInputConnect, TRUE);
753 kern_assert( kr );
755 // Start event passing thread
756 assert( pipe(fd) == 0 );
757 darwinEventReadFD = fd[0];
758 darwinEventWriteFD = fd[1];
759 fcntl(darwinEventReadFD, F_SETFL, O_NONBLOCK);
760 pthread_create(&inputThread, NULL,
761 XFIOKitHIDThread, NULL);
767 * DarwinModeProcessEvent
768 * Process IOKit specific events.
770 void DarwinModeProcessEvent(
771 xEvent *xe)
773 // No mode specific events
774 ErrorF("Unknown X event caught: %d\n", xe->u.u.type);