diff options
Diffstat (limited to 'nx-X11/programs/Xserver/hw/darwin/quartz/quartz.c')
-rw-r--r-- | nx-X11/programs/Xserver/hw/darwin/quartz/quartz.c | 426 |
1 files changed, 426 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/hw/darwin/quartz/quartz.c b/nx-X11/programs/Xserver/hw/darwin/quartz/quartz.c new file mode 100644 index 000000000..7a0155f98 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/darwin/quartz/quartz.c @@ -0,0 +1,426 @@ +/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/quartz.c,v 1.4 2005/07/01 22:43:07 daniels Exp $ */ +/************************************************************** + * + * Quartz-specific support for the Darwin X Server + * + **************************************************************/ +/* + * Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartz.c,v 1.16 2004/07/02 01:30:33 torrey Exp $ */ + +#include "quartzCommon.h" +#include "quartz.h" +#include "darwin.h" +#include "quartzAudio.h" +#include "pseudoramiX.h" +#define _APPLEWM_SERVER_ +#include "applewm.h" +#include "applewmExt.h" + +// X headers +#include "scrnintstr.h" +#include "windowstr.h" +#include "colormapst.h" +#include "globals.h" + +// System headers +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <IOKit/pwr_mgt/IOPMLib.h> + +// Shared global variables for Quartz modes +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 = TRUE; +QuartzModeProcsPtr quartzProcs = NULL; +const char *quartzOpenGLBundle = NULL; + +/* +=========================================================================== + + Screen functions + +=========================================================================== +*/ + +/* + * DarwinModeAddScreen + * Do mode dependent initialization of each screen for Quartz. + */ +Bool DarwinModeAddScreen( + int index, + ScreenPtr pScreen) +{ + // allocate space for private per screen Quartz specific storage + QuartzScreenPtr displayInfo = xcalloc(sizeof(QuartzScreenRec), 1); + QUARTZ_PRIV(pScreen) = displayInfo; + + // do Quartz mode specific initialization + return quartzProcs->AddScreen(index, pScreen); +} + + +/* + * DarwinModeSetupScreen + * Finalize mode specific setup of each screen. + */ +Bool DarwinModeSetupScreen( + int index, + ScreenPtr pScreen) +{ + // do Quartz mode specific setup + if (! quartzProcs->SetupScreen(index, pScreen)) + return FALSE; + + // setup cursor support + if (! quartzProcs->InitCursor(pScreen)) + return FALSE; + + return TRUE; +} + + +/* + * DarwinModeInitOutput + * Quartz display initialization. + */ +void DarwinModeInitOutput( + int argc, + char **argv ) +{ + static unsigned long generation = 0; + + // Allocate private storage for each screen's Quartz specific info + if (generation != serverGeneration) { + quartzScreenIndex = AllocateScreenPrivateIndex(); + generation = serverGeneration; + } + + if (serverGeneration == 0) { + QuartzAudioInit(); + } + + if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler, + QuartzWakeupHandler, + NULL)) + { + FatalError("Could not register block and wakeup handlers."); + } + + // Do display mode specific initialization + quartzProcs->DisplayInit(); + + // Init PseudoramiX implementation of Xinerama. + // This should be in InitExtensions, but that causes link errors + // for servers that don't link in pseudoramiX.c. + if (!noPseudoramiXExtension) { + PseudoramiXExtensionInit(argc, argv); + } +} + + +/* + * DarwinModeInitInput + * Inform the main thread the X server is ready to handle events. + */ +void DarwinModeInitInput( + int argc, + char **argv ) +{ + QuartzMessageMainThread(kQuartzServerStarted, NULL, 0); + + // Do final display mode specific initialization before handling events + if (quartzProcs->InitInput) + quartzProcs->InitInput(argc, argv); +} + + +/* + * QuartzUpdateScreens + * Adjust for screen arrangement changes. + */ +static void QuartzUpdateScreens(void) +{ + ScreenPtr pScreen; + WindowPtr pRoot; + int x, y, width, height, sx, sy; + xEvent e; + + if (noPseudoramiXExtension || screenInfo.numScreens != 1) + { + /* FIXME: if not using Xinerama, we have multiple screens, and + to do this properly may need to add or remove screens. Which + isn't possible. So don't do anything. Another reason why + we default to running with Xinerama. */ + + 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; + + /* FIXME: should probably do something with RandR here. */ + + DarwinAdjustScreenOrigins(&screenInfo); + quartzProcs->UpdateScreen(pScreen); + + sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX; + sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY; + + /* Adjust the root window. */ + pRoot = WindowTable[pScreen->myNum]; + AppleWMSetScreenOrigin(pRoot); + pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL); + pScreen->PaintWindowBackground(pRoot, &pRoot->borderClip, PW_BACKGROUND); +// QuartzIgnoreNextWarpCursor(); + DefineInitialRootWindow(pRoot); + + /* Send an event for the root reconfigure */ + 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); + + /* FIXME: Should we use RREditConnectionInfo(pScreen)? */ +} + + +/* + * QuartzShow + * Show the X server on screen. Does nothing if already shown. + * Calls mode specific screen resume to restore the X clip regions + * (if needed) and the X server cursor state. + */ +static void QuartzShow( + int x, // cursor location + 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); + } + } + } +} + + +/* + * QuartzHide + * Remove the X server display from the screen. Does nothing if already + * hidden. Calls mode specific screen suspend to set X clip regions to + * prevent drawing (if needed) and restore the Aqua cursor. + */ +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; + QuartzMessageMainThread(kQuartzServerHidden, NULL, 0); +} + + +/* + * QuartzSetRootClip + * Enable or disable rendering to the X screen. + */ +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); + } + } +} + + +/* + * QuartzMessageServerThread + * Send the X server thread a message by placing it on the event queue. + */ +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); +} + + +/* + * DarwinModeProcessEvent + * Process Quartz specific events. + */ +void DarwinModeProcessEvent( + xEvent *xe) +{ + switch (xe->u.u.type) { + + case kXDarwinActivate: + QuartzShow(xe->u.keyButtonPointer.rootX, + xe->u.keyButtonPointer.rootY); + AppleWMSendEvent(AppleWMActivationNotify, + AppleWMActivationNotifyMask, + AppleWMIsActive, 0); + break; + + case kXDarwinDeactivate: + AppleWMSendEvent(AppleWMActivationNotify, + AppleWMActivationNotifyMask, + AppleWMIsInactive, 0); + QuartzHide(); + 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; + + /* + * AppleWM events + */ + case kXDarwinControllerNotify: + AppleWMSendEvent(AppleWMControllerNotify, + AppleWMControllerNotifyMask, + xe->u.clientMessage.u.l.longs0, + xe->u.clientMessage.u.l.longs1); + break; + + case kXDarwinPasteboardNotify: + AppleWMSendEvent(AppleWMPasteboardNotify, + AppleWMPasteboardNotifyMask, + xe->u.clientMessage.u.l.longs0, + xe->u.clientMessage.u.l.longs1); + break; + + case kXDarwinDisplayChanged: + QuartzUpdateScreens(); + break; + + case kXDarwinWindowState: + case kXDarwinWindowMoved: + // FIXME: Not implemented yet + break; + + default: + ErrorF("Unknown application defined event type %d.\n", + xe->u.u.type); + } +} + + +/* + * DarwinModeGiveUp + * Cleanup before X server shutdown + * Release the screen and restore the Aqua cursor. + */ +void DarwinModeGiveUp(void) +{ +#if 0 +// Trying to switch cursors when quitting causes deadlock + int i; + + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + QuartzSuspendXCursor(screenInfo.screens[i]); + } + } +#endif + + if (!quartzRootless) + quartzProcs->ReleaseScreens(); +} |