diff options
Diffstat (limited to 'xc/programs/Xserver/hw/darwin/bundle/quartz.c')
-rw-r--r-- | xc/programs/Xserver/hw/darwin/bundle/quartz.c | 310 |
1 files changed, 232 insertions, 78 deletions
diff --git a/xc/programs/Xserver/hw/darwin/bundle/quartz.c b/xc/programs/Xserver/hw/darwin/bundle/quartz.c index 3aacf6e69..761c64a4d 100644 --- a/xc/programs/Xserver/hw/darwin/bundle/quartz.c +++ b/xc/programs/Xserver/hw/darwin/bundle/quartz.c @@ -5,10 +5,11 @@ * By Gregory Robert Parker * **************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/quartz.c,v 1.9 2001/05/16 06:10:08 torrey Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/quartz.c,v 1.14 2001/08/12 00:10:01 torrey Exp $ */ // X headers #include "scrnintstr.h" +#include "colormapst.h" // System headers #include <sys/types.h> @@ -22,26 +23,57 @@ #define __PRINTCORE__ #include <ApplicationServices/ApplicationServices.h> -#include "../darwin.h" +#include "darwin.h" #include "quartz.h" #include "quartzAudio.h" #include "quartzCursor.h" +#include "rootlessAqua.h" -#define kDarwinMaxScreens 100 -static ScreenPtr darwinScreens[kDarwinMaxScreens]; -static int darwinNumScreens = 0; -static BOOL xhidden = FALSE; +BOOL serverVisible = TRUE; + +// Full screen specific per screen storage structure +typedef struct { + CGDirectDisplayID displayID; + CGDirectPaletteRef xPalette; + CGDirectPaletteRef aquaPalette; +} QuartzFSScreenRec, *QuartzFSScreenPtr; + +#define FULLSCREEN_PRIV(pScreen) \ + ((QuartzFSScreenPtr)pScreen->devPrivates[quartzFSScreenIndex].ptr) + +static int quartzFSScreenIndex; +static CGDisplayCount quartzDisplayCount = 0; +static CGDirectDisplayID *quartzDisplayList = NULL; /* - * QuartzStoreColors - * FIXME: need to implement if Quartz supports PsuedoColor + * QuartzFSStoreColors + * This is a callback from X to change the hardware colormap + * when using PsuedoColor in full screen mode. */ -static void QuartzStoreColors( - ColormapPtr pmap, - int numEntries, - xColorItem *pdefs) +static void QuartzFSStoreColors( + ColormapPtr pmap, + int numEntries, + xColorItem *pdefs) { + ScreenPtr pScreen = pmap->pScreen; + QuartzFSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen); + CGDirectPaletteRef palette = fsDisplayInfo->xPalette; + CGDeviceColor color; + int i; + + if (! palette) + return; + + for (i = 0; i < numEntries; i++) { + color.red = pdefs[i].red / 65535.0; + color.green = pdefs[i].green / 65535.0; + color.blue = pdefs[i].blue / 65535.0; + CGPaletteSetColorAtIndex(palette, color, pdefs[i].pixel); + } + + if (serverVisible) + CGDisplaySetPalette(fsDisplayInfo->displayID, palette); } /* @@ -69,12 +101,12 @@ static void *QuartzPMThread(void *arg) // computer just woke up if (msg.header.msgh_id == 1) { - if (!xhidden) { + if (serverVisible) { int i; - for (i = 0; i < darwinNumScreens; i++) { - if (darwinScreens[i]) - xf86SetRootClip(darwinScreens[i], true); + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) + xf86SetRootClip(screenInfo.screens[i], true); } } } @@ -85,40 +117,151 @@ static void *QuartzPMThread(void *arg) /* + * QuartzFSAddScreen + * Do initialization of each screen for Quartz in full screen mode. + */ +static Bool QuartzFSAddScreen( + int index, + ScreenPtr pScreen) +{ + DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen); + CGDirectDisplayID cgID = quartzDisplayList[index]; + CGRect bounds; + QuartzFSScreenPtr fsDisplayInfo; + + // allocate space for private per screen fullscreen specific storage + fsDisplayInfo = xalloc(sizeof(QuartzFSScreenRec)); + FULLSCREEN_PRIV(pScreen) = fsDisplayInfo; + + fsDisplayInfo->displayID = cgID; + fsDisplayInfo->xPalette = 0; + fsDisplayInfo->aquaPalette = 0; + + dfb->pixelInfo.bitsPerComponent = CGDisplayBitsPerSample(cgID); + dfb->pixelInfo.componentCount = CGDisplaySamplesPerPixel(cgID); +#if FALSE + // FIXME: endian and 24 bit color specific + dfb->pixelInfo.componentMasks[0] = 0x00ff0000; + dfb->pixelInfo.componentMasks[1] = 0x0000ff00; + dfb->pixelInfo.componentMasks[2] = 0x000000ff; +#endif + + bounds = CGDisplayBounds(cgID); + dfb->x = bounds.origin.x; + // flip so (0, 0) is top left of main screen + dfb->y = CGDisplayBounds(kCGDirectMainDisplay).size.height - + bounds.size.height - bounds.origin.y; + dfb->width = bounds.size.width; + dfb->height = bounds.size.height; + dfb->pitch = CGDisplayBytesPerRow(cgID); + dfb->bitsPerPixel = CGDisplayBitsPerPixel(cgID); + + if (dfb->bitsPerPixel == 8) { + if (CGDisplayCanSetPalette(cgID)) { + dfb->pixelInfo.pixelType = kIOCLUTPixels; + } else { + dfb->pixelInfo.pixelType = kIOFixedCLUTPixels; + } + dfb->colorBitsPerPixel = 8; + } else { + dfb->pixelInfo.pixelType = kIORGBDirectPixels; + dfb->colorBitsPerPixel = (dfb->pixelInfo.componentCount * + dfb->pixelInfo.bitsPerComponent); + } + + dfb->framebuffer = CGDisplayBaseAddress(cgID); + + return TRUE; +} + + +/* * QuartzAddScreen - * Quartz keeps a list of all screens for QuartzShow and QuartzHide. - * FIXME: So does ddx, use that instead. + * Do mode dependent initialization of each screen for Quartz. */ -Bool QuartzAddScreen(ScreenPtr pScreen) +Bool QuartzAddScreen( + int index, + ScreenPtr pScreen) { - if (darwinNumScreens == kDarwinMaxScreens) { - return FALSE; + // do full screen or rootless specific initialization + if (quartzRootless) { + return AquaAddScreen(index, pScreen); + } else { + return QuartzFSAddScreen(index, pScreen); + } +} + + +/* + * QuartzFSSetupScreen + * Finalize full screen specific setup of each screen. + */ +static Bool QuartzFSSetupScreen( + int index, + ScreenPtr pScreen) +{ + DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen); + QuartzFSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen); + CGDirectDisplayID cgID = fsDisplayInfo->displayID; + + if (dfb->pixelInfo.pixelType == kIOCLUTPixels) { + // initialize colormap handling + fsDisplayInfo->aquaPalette = CGPaletteCreateWithDisplay(cgID); + fsDisplayInfo->xPalette = CGPaletteCreateDefaultColorPalette(); + pScreen->StoreColors = QuartzFSStoreColors; } - darwinScreens[darwinNumScreens++] = pScreen; + // capture full screen because X doesn't like read-only framebuffer + CGDisplayCapture(cgID); + + return TRUE; +} + +/* + * QuartzSetupScreen + * Finalize mode specific setup of each screen. + */ +Bool QuartzSetupScreen( + int index, + ScreenPtr pScreen) +{ // setup cursor support - if (! QuartzInitCursor(pScreen)) { + if (! QuartzInitCursor(pScreen)) return FALSE; - } - // initialize colormap handling as needed - if (dfb.pixelInfo.pixelType == kIOCLUTPixels) { - pScreen->StoreColors = QuartzStoreColors; + // do full screen or rootless specific setup + if (quartzRootless) { + if (! AquaSetupScreen(index, pScreen)) + return FALSE; + } else { + if (! QuartzFSSetupScreen(index, pScreen)) + return FALSE; } return TRUE; } -/* +/* * QuartzCapture - * Capture the screen so we can draw. + * Capture the screen so we can draw. Called directly from the main thread + * to synchronize with hiding the menubar. */ void QuartzCapture(void) { - if (! CGDisplayIsCaptured(kCGDirectMainDisplay)) { - CGDisplayCapture(kCGDirectMainDisplay); + int i; + + for (i = 0; i < screenInfo.numScreens; i++) { + QuartzFSScreenPtr fsDisplayInfo = + FULLSCREEN_PRIV(screenInfo.screens[i]); + CGDirectDisplayID cgID = fsDisplayInfo->displayID; + + if (!CGDisplayIsCaptured(cgID) && !quartzRootless) { + CGDisplayCapture(cgID); + if (fsDisplayInfo->xPalette) + CGDisplaySetPalette(cgID, fsDisplayInfo->xPalette); + } } } @@ -129,54 +272,63 @@ void QuartzCapture(void) */ static void QuartzRelease(void) { - if (CGDisplayIsCaptured(kCGDirectMainDisplay)) { - CGDisplayRelease(kCGDirectMainDisplay); + int i; + + for (i = 0; i < screenInfo.numScreens; i++) { + QuartzFSScreenPtr fsDisplayInfo = + FULLSCREEN_PRIV(screenInfo.screens[i]); + CGDirectDisplayID cgID = fsDisplayInfo->displayID; + + if (CGDisplayIsCaptured(cgID) && !quartzRootless) { + if (fsDisplayInfo->aquaPalette) + CGDisplaySetPalette(cgID, fsDisplayInfo->aquaPalette); + CGDisplayRelease(cgID); + } + QuartzMessageMainThread(kQuartzServerHidden); } - QuartzMessageMainThread(kQuartzServerHidden); } /* - * QuartzDisplayInit - * Init the framebuffer and claim the display from CoreGraphics. + * QuartzFSDisplayInit + * Full screen specific initialization called from InitOutput. */ -static void QuartzDisplayInit(void) +static void QuartzFSDisplayInit(void) { - dfb.pixelInfo.pixelType = kIORGBDirectPixels; - dfb.pixelInfo.bitsPerComponent=CGDisplayBitsPerSample(kCGDirectMainDisplay); - dfb.pixelInfo.componentCount=CGDisplaySamplesPerPixel(kCGDirectMainDisplay); -#if FALSE - // FIXME: endian and 24 bit color specific - dfb.pixelInfo.componentMasks[0] = 0x00ff0000; - dfb.pixelInfo.componentMasks[1] = 0x0000ff00; - dfb.pixelInfo.componentMasks[2] = 0x000000ff; -#endif + static unsigned long generation = 0; - dfb.width = CGDisplayPixelsWide(kCGDirectMainDisplay); - dfb.height = CGDisplayPixelsHigh(kCGDirectMainDisplay); - dfb.pitch = CGDisplayBytesPerRow(kCGDirectMainDisplay); - dfb.bitsPerPixel = CGDisplayBitsPerPixel(kCGDirectMainDisplay); - dfb.colorBitsPerPixel = (dfb.pixelInfo.componentCount * - dfb.pixelInfo.bitsPerComponent); + // Allocate private storage for each screen's mode specific info + if (generation != serverGeneration) { + quartzFSScreenIndex = AllocateScreenPrivateIndex(); + generation = serverGeneration; + } - dfb.framebuffer = CGDisplayBaseAddress(kCGDirectMainDisplay); + // Find all the CoreGraphics displays + CGGetActiveDisplayList(0, NULL, &quartzDisplayCount); + quartzDisplayList = xalloc(quartzDisplayCount * sizeof(CGDirectDisplayID)); + CGGetActiveDisplayList(quartzDisplayCount, quartzDisplayList, + &quartzDisplayCount); - // need to capture because X doesn't like read-only framebuffer... - QuartzCapture(); + darwinScreensFound = quartzDisplayCount; atexit(QuartzRelease); } /* - * QuartzOsVendorInit + * QuartzInitOutput * Quartz display initialization. */ -void QuartzOsVendorInit(void) +void QuartzInitOutput(void) { - ErrorF("Display mode: Quartz\n"); - QuartzAudioInit(); - QuartzDisplayInit(); + + if (quartzRootless) { + ErrorF("Display mode: Rootless Quartz\n"); + AquaDisplayInit(); + } else { + ErrorF("Display mode: Full screen Quartz\n"); + QuartzFSDisplayInit(); + } } @@ -191,38 +343,40 @@ void QuartzShow( { int i; - if (xhidden) { - for (i = 0; i < darwinNumScreens; i++) { - if (darwinScreens[i]) { - xf86SetRootClip(darwinScreens[i], true); - QuartzResumeXCursor(darwinScreens[i], x, y); + if (!serverVisible) { + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + if (!quartzRootless) + xf86SetRootClip(screenInfo.screens[i], TRUE); + QuartzResumeXCursor(screenInfo.screens[i], x, y); } } } - xhidden = FALSE; + serverVisible = TRUE; } /* * QuartzHide - * Remove the X server display from the screen. Does nothing if already hidden. - * Release the screen, set X clip regions to prevent drawing, and restore the - * Aqua cursor. + * Remove the X server display from the screen. Does nothing if already + * hidden. Release the screen, set X clip regions to prevent drawing, and + * restore the Aqua cursor. */ void QuartzHide(void) { int i; - if (!xhidden) { - for (i = 0; i < darwinNumScreens; i++) { - if (darwinScreens[i]) { - QuartzSuspendXCursor(darwinScreens[i]); - xf86SetRootClip(darwinScreens[i], false); + if (serverVisible) { + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + QuartzSuspendXCursor(screenInfo.screens[i]); + if (!quartzRootless) + xf86SetRootClip(screenInfo.screens[i], FALSE); } } } QuartzRelease(); - xhidden = TRUE; + serverVisible = FALSE; } @@ -235,9 +389,9 @@ void QuartzGiveUp(void) { int i; - for (i = 0; i < darwinNumScreens; i++) { - if (darwinScreens[i]) { - QuartzSuspendXCursor(darwinScreens[i]); + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + QuartzSuspendXCursor(screenInfo.screens[i]); } } QuartzRelease(); |