#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "quartzCommon.h"
#include "quartz.h"
#include "darwin.h"
#include "darwinEvents.h"
#include "quartzAudio.h"
#include "pseudoramiX.h"
#define _APPLEWM_SERVER_
#include "X11/extensions/applewm.h"
#include "applewmExt.h"
#include "X11Application.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "colormapst.h"
#include "globals.h"
#include "rootlessWindow.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#define FAKE_RANDR 1
int quartzEventWriteFD = -1;
int quartzStartClients = 1;
int quartzRootless = -1;
int quartzUseSysBeep = 0;
int quartzUseAGL = 1;
int quartzEnableKeyEquivalents = 1;
int quartzServerVisible = TRUE;
int quartzServerQuitting = FALSE;
int quartzScreenIndex = 0;
int aquaMenuBarHeight = 0;
int noPseudoramiXExtension = FALSE;
QuartzModeProcsPtr quartzProcs = NULL;
const char *quartzOpenGLBundle = NULL;
#if defined(RANDR) && !defined(FAKE_RANDR)
Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
return FALSE;
}
Bool QuartzRandRSetConfig (ScreenPtr pScreen,
Rotation randr,
int rate,
RRScreenSizePtr pSize) {
return FALSE;
}
Bool QuartzRandRInit (ScreenPtr pScreen) {
rrScrPrivPtr pScrPriv;
if (!RRScreenInit (pScreen)) return FALSE;
pScrPriv = rrGetScrPriv(pScreen);
pScrPriv->rrGetInfo = QuartzRandRGetInfo;
pScrPriv->rrSetConfig = QuartzRandRSetConfig;
return TRUE;
}
#endif
Bool QuartzAddScreen(
int index,
ScreenPtr pScreen)
{
QuartzScreenPtr displayInfo = xcalloc(sizeof(QuartzScreenRec), 1);
pScreen->devPrivates[quartzScreenIndex].ptr = displayInfo;
return quartzProcs->AddScreen(index, pScreen);
}
Bool QuartzSetupScreen(
int index,
ScreenPtr pScreen)
{
if (! quartzProcs->SetupScreen(index, pScreen))
return FALSE;
if (! quartzProcs->InitCursor(pScreen))
return FALSE;
return TRUE;
}
void QuartzInitOutput(
int argc,
char **argv )
{
static unsigned long generation = 0;
if (generation != serverGeneration) {
quartzScreenIndex = AllocateScreenPrivateIndex();
generation = serverGeneration;
}
if (serverGeneration == 0) {
QuartzAudioInit();
}
if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler,
QuartzWakeupHandler,
NULL))
{
FatalError("Could not register block and wakeup handlers.");
}
quartzProcs->DisplayInit();
if (!noPseudoramiXExtension) {
PseudoramiXExtensionInit(argc, argv);
}
}
void QuartzInitInput(
int argc,
char **argv )
{
X11ApplicationSetCanQuit(1);
X11ApplicationServerReady();
if (quartzProcs->InitInput)
quartzProcs->InitInput(argc, argv);
}
#ifdef FAKE_RANDR
extern char *ConnectionInfo;
static int padlength[4] = {0, 3, 2, 1};
static void
RREditConnectionInfo (ScreenPtr pScreen)
{
xConnSetup *connSetup;
char *vendor;
xPixmapFormat *formats;
xWindowRoot *root;
xDepth *depth;
xVisualType *visual;
int screen = 0;
int d;
connSetup = (xConnSetup *) ConnectionInfo;
vendor = (char *) connSetup + sizeof (xConnSetup);
formats = (xPixmapFormat *) ((char *) vendor +
connSetup->nbytesVendor +
padlength[connSetup->nbytesVendor & 3]);
root = (xWindowRoot *) ((char *) formats +
sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
while (screen != pScreen->myNum)
{
depth = (xDepth *) ((char *) root +
sizeof (xWindowRoot));
for (d = 0; d < root->nDepths; d++)
{
visual = (xVisualType *) ((char *) depth +
sizeof (xDepth));
depth = (xDepth *) ((char *) visual +
depth->nVisuals * sizeof (xVisualType));
}
root = (xWindowRoot *) ((char *) depth);
screen++;
}
root->pixWidth = pScreen->width;
root->pixHeight = pScreen->height;
root->mmWidth = pScreen->mmWidth;
root->mmHeight = pScreen->mmHeight;
}
#endif
static void QuartzUpdateScreens(void)
{
ScreenPtr pScreen;
WindowPtr pRoot;
int x, y, width, height, sx, sy;
xEvent e;
DEBUG_LOG("QuartzUpdateScreens()\n");
if (noPseudoramiXExtension || screenInfo.numScreens != 1)
{
return;
}
pScreen = screenInfo.screens[0];
PseudoramiXResetScreens();
quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height);
dixScreenOrigins[pScreen->myNum].x = x;
dixScreenOrigins[pScreen->myNum].y = y;
pScreen->mmWidth = pScreen->mmWidth * ((double) width / pScreen->width);
pScreen->mmHeight = pScreen->mmHeight * ((double) height / pScreen->height);
pScreen->width = width;
pScreen->height = height;
#ifndef FAKE_RANDR
if(!QuartzRandRInit(pScreen))
FatalError("Failed to init RandR extension.\n");
#endif
DarwinAdjustScreenOrigins(&screenInfo);
quartzProcs->UpdateScreen(pScreen);
sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX;
sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY;
pRoot = WindowTable[pScreen->myNum];
AppleWMSetScreenOrigin(pRoot);
pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL);
pScreen->PaintWindowBackground(pRoot, &pRoot->borderClip, PW_BACKGROUND);
DefineInitialRootWindow(pRoot);
e.u.u.type = ConfigureNotify;
e.u.configureNotify.window = pRoot->drawable.id;
e.u.configureNotify.aboveSibling = None;
e.u.configureNotify.x = x - sx;
e.u.configureNotify.y = y - sy;
e.u.configureNotify.width = width;
e.u.configureNotify.height = height;
e.u.configureNotify.borderWidth = wBorderWidth(pRoot);
e.u.configureNotify.override = pRoot->overrideRedirect;
DeliverEvents(pRoot, &e, 1, NullWindow);
#ifdef FAKE_RANDR
RREditConnectionInfo(pScreen);
#endif
}
static void QuartzShow(
int x, int y )
{
int i;
if (!quartzServerVisible) {
quartzServerVisible = TRUE;
for (i = 0; i < screenInfo.numScreens; i++) {
if (screenInfo.screens[i]) {
quartzProcs->ResumeScreen(screenInfo.screens[i], x, y);
}
}
}
}
static void QuartzHide(void)
{
int i;
if (quartzServerVisible) {
for (i = 0; i < screenInfo.numScreens; i++) {
if (screenInfo.screens[i]) {
quartzProcs->SuspendScreen(screenInfo.screens[i]);
}
}
}
quartzServerVisible = FALSE;
}
static void QuartzSetRootClip(
BOOL enable)
{
int i;
if (!quartzServerVisible)
return;
for (i = 0; i < screenInfo.numScreens; i++) {
if (screenInfo.screens[i]) {
xf86SetRootClip(screenInfo.screens[i], enable);
}
}
}
void
QuartzMessageServerThread(
int type,
int argc, ...)
{
xEvent xe;
INT32 *argv;
int i, max_args;
va_list args;
memset(&xe, 0, sizeof(xe));
xe.u.u.type = type;
xe.u.clientMessage.u.l.type = type;
argv = &xe.u.clientMessage.u.l.longs0;
max_args = 4;
if (argc > 0 && argc <= max_args) {
va_start (args, argc);
for (i = 0; i < argc; i++)
argv[i] = (int) va_arg (args, int);
va_end (args);
}
DarwinEQEnqueue(&xe);
}
void QuartzProcessEvent(
xEvent *xe)
{
switch (xe->u.u.type) {
case kXDarwinControllerNotify:
DEBUG_LOG("kXDarwinControllerNotify\n");
AppleWMSendEvent(AppleWMControllerNotify,
AppleWMControllerNotifyMask,
xe->u.clientMessage.u.l.longs0,
xe->u.clientMessage.u.l.longs1);
break;
case kXDarwinPasteboardNotify:
DEBUG_LOG("kXDarwinPasteboardNotify\n");
AppleWMSendEvent(AppleWMPasteboardNotify,
AppleWMPasteboardNotifyMask,
xe->u.clientMessage.u.l.longs0,
xe->u.clientMessage.u.l.longs1);
break;
case kXDarwinActivate:
DEBUG_LOG("kXDarwinActivate\n");
QuartzShow(xe->u.keyButtonPointer.rootX,
xe->u.keyButtonPointer.rootY);
AppleWMSendEvent(AppleWMActivationNotify,
AppleWMActivationNotifyMask,
AppleWMIsActive, 0);
break;
case kXDarwinDeactivate:
DEBUG_LOG("kXDarwinDeactivate\n");
AppleWMSendEvent(AppleWMActivationNotify,
AppleWMActivationNotifyMask,
AppleWMIsInactive, 0);
QuartzHide();
break;
case kXDarwinDisplayChanged:
DEBUG_LOG("kXDarwinDisplayChanged\n");
QuartzUpdateScreens();
break;
case kXDarwinWindowState:
DEBUG_LOG("kXDarwinWindowState\n");
RootlessNativeWindowStateChanged(xe->u.clientMessage.u.l.longs0,
xe->u.clientMessage.u.l.longs1);
break;
case kXDarwinWindowMoved:
DEBUG_LOG("kXDarwinWindowMoved\n");
RootlessNativeWindowMoved ((WindowPtr)xe->u.clientMessage.u.l.longs0);
break;
case kXDarwinToggleFullscreen:
DEBUG_LOG("kXDarwinToggleFullscreen\n");
#ifdef DARWIN_DDX_MISSING
if (quartzEnableRootless) QuartzSetFullscreen(!quartzHasRoot);
else if (quartzHasRoot) QuartzHide();
else QuartzShow();
#else
#endif
break;
case kXDarwinSetRootless:
#ifdef DARWIN_DDX_MISSING
QuartzSetRootless(xe->u.clientMessage.u.l.longs0);
if (!quartzEnableRootless && !quartzHasRoot) QuartzHide();
#else
#endif
break;
case kXDarwinSetRootClip:
QuartzSetRootClip((BOOL)xe->u.clientMessage.u.l.longs0);
break;
case kXDarwinQuit:
GiveUp(0);
break;
case kXDarwinReadPasteboard:
QuartzReadPasteboard();
break;
case kXDarwinWritePasteboard:
QuartzWritePasteboard();
break;
case kXDarwinBringAllToFront:
DEBUG_LOG("kXDarwinBringAllToFront\n");
RootlessOrderAllWindows();
break;
default:
ErrorF("Unknown application defined event type %d.\n", xe->u.u.type);
}
}
void QuartzGiveUp(void)
{
#if 0
int i;
for (i = 0; i < screenInfo.numScreens; i++) {
if (screenInfo.screens[i]) {
QuartzSuspendXCursor(screenInfo.screens[i]);
}
}
#endif
if (!quartzRootless)
quartzProcs->ReleaseScreens();
}