summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/darwin/bundle/quartz.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/hw/darwin/bundle/quartz.c')
-rw-r--r--xc/programs/Xserver/hw/darwin/bundle/quartz.c310
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();