diff options
Diffstat (limited to 'hw/darwin/quartz/cr')
-rw-r--r-- | hw/darwin/quartz/cr/XView.h | 42 | ||||
-rw-r--r-- | hw/darwin/quartz/cr/XView.m | 74 | ||||
-rw-r--r-- | hw/darwin/quartz/cr/cr.h | 62 | ||||
-rw-r--r-- | hw/darwin/quartz/cr/crAppleWM.m | 157 | ||||
-rw-r--r-- | hw/darwin/quartz/cr/crFrame.m | 403 | ||||
-rw-r--r-- | hw/darwin/quartz/cr/crScreen.m | 321 |
6 files changed, 1059 insertions, 0 deletions
diff --git a/hw/darwin/quartz/cr/XView.h b/hw/darwin/quartz/cr/XView.h new file mode 100644 index 000000000..666061dc1 --- /dev/null +++ b/hw/darwin/quartz/cr/XView.h @@ -0,0 +1,42 @@ +/* + * NSView subclass for Mac OS X rootless X server + * + * Copyright (c) 2001 Greg Parker. 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/cr/XView.h,v 1.1 2003/06/07 05:49:07 torrey Exp $ */ + +#import <Cocoa/Cocoa.h> + +@interface XView : NSQuickDrawView + +- (BOOL)isFlipped; +- (BOOL)isOpaque; +- (BOOL)acceptsFirstResponder; +- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent; +- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent; + +- (void)mouseDown:(NSEvent *)anEvent; + +@end diff --git a/hw/darwin/quartz/cr/XView.m b/hw/darwin/quartz/cr/XView.m new file mode 100644 index 000000000..2bf689ede --- /dev/null +++ b/hw/darwin/quartz/cr/XView.m @@ -0,0 +1,74 @@ +/* + * NSView subclass for Mac OS X rootless X server + * + * Each rootless window contains an instance of this class. + * This class handles events while drawing is handled by Carbon + * code in the rootless Aqua implementation. + * + * Copyright (c) 2001 Greg Parker. 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/cr/XView.m,v 1.2 2003/10/16 23:50:16 torrey Exp $ */ + +#import "XView.h" + + +@implementation XView + +- (BOOL)isFlipped +{ + return NO; +} + +- (BOOL)isOpaque +{ + return YES; +} + +- (BOOL)acceptsFirstResponder +{ + return YES; +} + +- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent +{ + return YES; +} + +- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent +{ + return YES; +} + +- (void)mouseDown:(NSEvent *)anEvent +{ + // Only X is allowed to restack windows. + [NSApp preventWindowOrdering]; + if (! [NSApp isActive]) { + [NSApp activateIgnoringOtherApps:YES]; + } + [[self nextResponder] mouseDown:anEvent]; +} + +@end diff --git a/hw/darwin/quartz/cr/cr.h b/hw/darwin/quartz/cr/cr.h new file mode 100644 index 000000000..74752f768 --- /dev/null +++ b/hw/darwin/quartz/cr/cr.h @@ -0,0 +1,62 @@ +/* + * Internal definitions of the Cocoa rootless implementation + */ +/* + * Copyright (c) 2003 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/cr/cr.h,v 1.3 2003/11/03 05:36:31 tsi Exp $ */ + +#ifndef _CR_H +#define _CR_H + +#ifdef __OBJC__ +#import <Cocoa/Cocoa.h> +#import "XView.h" +#else +typedef struct OpaqueNSWindow NSWindow; +typedef struct OpaqueXView XView; +#endif + +#undef BOOL +#define BOOL xBOOL +#include "screenint.h" +#include "window.h" +#undef BOOL + +// Predefined style for the window which is about to be framed +extern WindowPtr nextWindowToFrame; +extern unsigned int nextWindowStyle; + +typedef struct { + NSWindow *window; + XView *view; + GrafPtr port; + CGContextRef context; +} CRWindowRec, *CRWindowPtr; + +Bool CRInit(ScreenPtr pScreen); +void CRAppleWMInit(void); + +#endif /* _CR_H */ diff --git a/hw/darwin/quartz/cr/crAppleWM.m b/hw/darwin/quartz/cr/crAppleWM.m new file mode 100644 index 000000000..66e832b66 --- /dev/null +++ b/hw/darwin/quartz/cr/crAppleWM.m @@ -0,0 +1,157 @@ +/* + * Cocoa rootless implementation functions for AppleWM extension + */ +/* + * Copyright (c) 2003 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/cr/crAppleWM.m,v 1.1 2003/09/16 00:36:14 torrey Exp $ */ + +#include "quartzCommon.h" +#include "cr.h" + +#undef BOOL +#define BOOL xBOOL +#include "rootless.h" +#include "X.h" +#define _APPLEWM_SERVER_ +#include "applewm.h" +#include "applewmExt.h" +#undef BOOL + +#define StdDocumentStyleMask (NSTitledWindowMask | \ + NSClosableWindowMask | \ + NSMiniaturizableWindowMask | \ + NSResizableWindowMask) + +static int +CRDisableUpdate(void) +{ + return Success; +} + + +static int +CREnableUpdate(void) +{ + return Success; +} + + +static int CRSetWindowLevel( + WindowPtr pWin, + int level) +{ + CRWindowPtr crWinPtr; + + crWinPtr = (CRWindowPtr) RootlessFrameForWindow(pWin, TRUE); + if (crWinPtr == 0) + return BadWindow; + + RootlessStopDrawing(pWin, FALSE); + + [crWinPtr->window setLevel:level]; + + return Success; +} + + +static int CRFrameGetRect( + int type, + int class, + const BoxRec *outer, + const BoxRec *inner, + BoxRec *ret) +{ + return Success; +} + + +static int CRFrameHitTest( + int class, + int x, + int y, + const BoxRec *outer, + const BoxRec *inner, + int *ret) +{ + return 0; +} + + +static int CRFrameDraw( + WindowPtr pWin, + int class, + unsigned int attr, + const BoxRec *outer, + const BoxRec *inner, + unsigned int title_len, + const unsigned char *title_bytes) +{ + CRWindowPtr crWinPtr; + NSWindow *window; + Bool hasResizeIndicator; + + /* We assume the window has not yet been framed so + RootlessFrameForWindow() will cause it to be. Record the window + style so that the appropriate one will be used when it is framed. + If the window is already framed, we can't change the window + style and the following will have no effect. */ + + nextWindowToFrame = pWin; + if (class == AppleWMFrameClassDocument) + nextWindowStyle = StdDocumentStyleMask; + else + nextWindowStyle = NSBorderlessWindowMask; + + crWinPtr = (CRWindowPtr) RootlessFrameForWindow(pWin, TRUE); + if (crWinPtr == 0) + return BadWindow; + + window = crWinPtr->window; + + [window setTitle:[NSString stringWithCString:title_bytes + length:title_len]]; + + hasResizeIndicator = (attr & AppleWMFrameGrowBox) ? YES : NO; + [window setShowsResizeIndicator:hasResizeIndicator]; + + return Success; +} + + +static AppleWMProcsRec crAppleWMProcs = { + CRDisableUpdate, + CREnableUpdate, + CRSetWindowLevel, + CRFrameGetRect, + CRFrameHitTest, + CRFrameDraw +}; + + +void CRAppleWMInit(void) +{ + AppleWMExtensionInit(&crAppleWMProcs); +} diff --git a/hw/darwin/quartz/cr/crFrame.m b/hw/darwin/quartz/cr/crFrame.m new file mode 100644 index 000000000..e3e83ebc4 --- /dev/null +++ b/hw/darwin/quartz/cr/crFrame.m @@ -0,0 +1,403 @@ +/* + * Cocoa rootless implementation frame functions + */ +/* + * Copyright (c) 2001 Greg Parker. All Rights Reserved. + * Copyright (c) 2002-2003 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/cr/crFrame.m,v 1.5 2003/11/13 20:26:31 torrey Exp $ */ + +#include "quartzCommon.h" +#include "cr.h" + +#undef BOOL +#define BOOL xBOOL +#include "rootless.h" +#undef BOOL + +WindowPtr nextWindowToFrame = NULL; +unsigned int nextWindowStyle = 0; + +static void CRReshapeFrame(RootlessFrameID wid, RegionPtr pShape); + + +/* + * CRCreateFrame + * Create a new physical window. + * Rootless windows must not autodisplay! Autodisplay can cause a deadlock. + * Event thread - autodisplay: locks view hierarchy, then window + * X Server thread - window resize: locks window, then view hierarchy + * Deadlock occurs if each thread gets one lock and waits for the other. + */ +static Bool +CRCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen, + int newX, int newY, RegionPtr pShape) +{ + CRWindowPtr crWinPtr; + NSRect bounds; + NSWindow *theWindow; + XView *theView; + unsigned int theStyleMask = NSBorderlessWindowMask; + + crWinPtr = (CRWindowPtr) xalloc(sizeof(CRWindowRec)); + + bounds = NSMakeRect(newX, + NSHeight([[NSScreen mainScreen] frame]) - + newY - pFrame->height, + pFrame->width, pFrame->height); + + // Check if AppleWM has specified a style for this window + if (pFrame->win == nextWindowToFrame) { + theStyleMask = nextWindowStyle; + } + nextWindowToFrame = NULL; + + // Create an NSWindow for the new X11 window + theWindow = [[NSWindow alloc] initWithContentRect:bounds + styleMask:theStyleMask + backing:NSBackingStoreBuffered + defer:NO]; + if (!theWindow) return FALSE; + + [theWindow setBackgroundColor:[NSColor clearColor]]; // erase transparent + [theWindow setAlphaValue:1.0]; // draw opaque + [theWindow setOpaque:YES]; // changed when window is shaped + + [theWindow useOptimizedDrawing:YES]; // Has no overlapping sub-views + [theWindow setAutodisplay:NO]; // See comment above + [theWindow disableFlushWindow]; // We do all the flushing manually + [theWindow setHasShadow:YES]; // All windows have shadows + [theWindow setReleasedWhenClosed:YES]; // Default, but we want to be sure + + theView = [[XView alloc] initWithFrame:bounds]; + [theWindow setContentView:theView]; + [theWindow setInitialFirstResponder:theView]; + + [theWindow setAcceptsMouseMovedEvents:YES]; + + crWinPtr->window = theWindow; + crWinPtr->view = theView; + + [theView lockFocus]; + // Fill the window with white to make sure alpha channel is set + NSEraseRect(bounds); + crWinPtr->port = [theView qdPort]; + crWinPtr->context = [[NSGraphicsContext currentContext] graphicsPort]; + // CreateCGContextForPort(crWinPtr->port, &crWinPtr->context); + [theView unlockFocus]; + + // Store the implementation private frame ID + pFrame->wid = (RootlessFrameID) crWinPtr; + + // Reshape the frame if it was created shaped. + if (pShape != NULL) + CRReshapeFrame(pFrame->wid, pShape); + + return TRUE; +} + + +/* + * CRDestroyFrame + * Destroy a frame. + */ +static void +CRDestroyFrame(RootlessFrameID wid) +{ + CRWindowPtr crWinPtr = (CRWindowPtr) wid; + + [crWinPtr->window orderOut:nil]; + [crWinPtr->window close]; + [crWinPtr->view release]; + free(crWinPtr); +} + + +/* + * CRMoveFrame + * Move a frame on screen. + */ +static void +CRMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY) +{ + CRWindowPtr crWinPtr = (CRWindowPtr) wid; + NSPoint topLeft; + + topLeft = NSMakePoint(newX, + NSHeight([[NSScreen mainScreen] frame]) - newY); + + [crWinPtr->window setFrameTopLeftPoint:topLeft]; +} + + +/* + * CRResizeFrame + * Move and resize a frame. + */ +static void +CRResizeFrame(RootlessFrameID wid, ScreenPtr pScreen, + int newX, int newY, unsigned int newW, unsigned int newH, + unsigned int gravity) +{ + CRWindowPtr crWinPtr = (CRWindowPtr) wid; + NSRect bounds = NSMakeRect(newX, NSHeight([[NSScreen mainScreen] frame]) - + newY - newH, newW, newH); + + [crWinPtr->window setFrame:bounds display:NO]; +} + + +/* + * CRRestackFrame + * Change the frame order. Put the frame behind nextWid or on top if + * it is NULL. Unmapped frames are mapped by restacking them. + */ +static void +CRRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) +{ + CRWindowPtr crWinPtr = (CRWindowPtr) wid; + CRWindowPtr crNextWinPtr = (CRWindowPtr) nextWid; + + if (crNextWinPtr) { + int upperNum = [crNextWinPtr->window windowNumber]; + + [crWinPtr->window orderWindow:NSWindowBelow relativeTo:upperNum]; + } else { + [crWinPtr->window makeKeyAndOrderFront:nil]; + } +} + + +/* + * CRReshapeFrame + * Set the shape of a frame. + */ +static void +CRReshapeFrame(RootlessFrameID wid, RegionPtr pShape) +{ + CRWindowPtr crWinPtr = (CRWindowPtr) wid; + NSRect bounds = [crWinPtr->view frame]; + int winHeight = NSHeight(bounds); + BoxRec localBox = {0, 0, NSWidth(bounds), winHeight}; + + [crWinPtr->view lockFocus]; + + if (pShape != NULL) { + // Calculate the region outside the new shape. + REGION_INVERSE(NULL, pShape, pShape, &localBox); + } + + // If window is currently shaped we need to undo the previous shape. + if (![crWinPtr->window isOpaque]) { + [[NSColor whiteColor] set]; + NSRectFillUsingOperation(bounds, NSCompositeDestinationAtop); + } + + if (pShape != NULL) { + int count = REGION_NUM_RECTS(pShape); + BoxRec *extRects = REGION_RECTS(pShape); + BoxRec *rects, *end; + + // Make transparent if window is now shaped. + [crWinPtr->window setOpaque:NO]; + + // Clear the areas outside the window shape + [[NSColor clearColor] set]; + for (rects = extRects, end = extRects+count; rects < end; rects++) { + int rectHeight = rects->y2 - rects->y1; + NSRectFill( NSMakeRect(rects->x1, + winHeight - rects->y1 - rectHeight, + rects->x2 - rects->x1, rectHeight) ); + } + [[NSGraphicsContext currentContext] flushGraphics]; + + // force update of window shadow + [crWinPtr->window setHasShadow:NO]; + [crWinPtr->window setHasShadow:YES]; + + } else { + [crWinPtr->window setOpaque:YES]; + [[NSGraphicsContext currentContext] flushGraphics]; + } + + [crWinPtr->view unlockFocus]; +} + + +/* + * CRUnmapFrame + * Unmap a frame. + */ +static void +CRUnmapFrame(RootlessFrameID wid) +{ + CRWindowPtr crWinPtr = (CRWindowPtr) wid; + + [crWinPtr->window orderOut:nil]; +} + + +/* + * CRStartDrawing + * When a window's buffer is not being drawn to, the CoreGraphics + * window server may compress or move it. Call this routine + * to lock down the buffer during direct drawing. It returns + * a pointer to the backing buffer. + */ +static void +CRStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow) +{ + CRWindowPtr crWinPtr = (CRWindowPtr) wid; + PixMapHandle pix; + + [crWinPtr->view lockFocus]; + crWinPtr->port = [crWinPtr->view qdPort]; + LockPortBits(crWinPtr->port); + [crWinPtr->view unlockFocus]; + pix = GetPortPixMap(crWinPtr->port); + + *pixelData = GetPixBaseAddr(pix); + *bytesPerRow = GetPixRowBytes(pix) & 0x3fff; // fixme is mask needed? +} + + +/* + * CRStopDrawing + * When direct access to a window's buffer is no longer needed, this + * routine should be called to allow CoreGraphics to compress or + * move it. + */ +static void +CRStopDrawing(RootlessFrameID wid, Bool flush) +{ + CRWindowPtr crWinPtr = (CRWindowPtr) wid; + + UnlockPortBits(crWinPtr->port); + + if (flush) { + QDFlushPortBuffer(crWinPtr->port, NULL); + } +} + + +/* + * CRUpdateRegion + * Flush a region from a window's backing buffer to the screen. + */ +static void +CRUpdateRegion(RootlessFrameID wid, RegionPtr pDamage) +{ + CRWindowPtr crWinPtr = (CRWindowPtr) wid; + +#ifdef ROOTLESS_TRACK_DAMAGE + int count = REGION_NUM_RECTS(pDamage); + BoxRec *rects = REGION_RECTS(pDamage); + BoxRec *end; + + static RgnHandle rgn = NULL; + static RgnHandle box = NULL; + + if (!rgn) rgn = NewRgn(); + if (!box) box = NewRgn(); + + for (end = rects+count; rects < end; rects++) { + Rect qdRect; + qdRect.left = rects->x1; + qdRect.top = rects->y1; + qdRect.right = rects->x2; + qdRect.bottom = rects->y2; + + RectRgn(box, &qdRect); + UnionRgn(rgn, box, rgn); + } + + QDFlushPortBuffer(crWinPtr->port, rgn); + + SetEmptyRgn(rgn); + SetEmptyRgn(box); + +#else /* !ROOTLESS_TRACK_DAMAGE */ + QDFlushPortBuffer(crWinPtr->port, NULL); +#endif +} + + +/* + * CRDamageRects + * Mark damaged rectangles as requiring redisplay to screen. + */ +static void +CRDamageRects(RootlessFrameID wid, int count, const BoxRec *rects, + int shift_x, int shift_y) +{ + CRWindowPtr crWinPtr = (CRWindowPtr) wid; + const BoxRec *end; + + for (end = rects + count; rects < end; rects++) { + Rect qdRect; + qdRect.left = rects->x1 + shift_x; + qdRect.top = rects->y1 + shift_y; + qdRect.right = rects->x2 + shift_x; + qdRect.bottom = rects->y2 + shift_y; + + QDAddRectToDirtyRegion(crWinPtr->port, &qdRect); + } +} + + +static RootlessFrameProcsRec CRRootlessProcs = { + CRCreateFrame, + CRDestroyFrame, + CRMoveFrame, + CRResizeFrame, + CRRestackFrame, + CRReshapeFrame, + CRUnmapFrame, + CRStartDrawing, + CRStopDrawing, + CRUpdateRegion, + CRDamageRects, + NULL, + NULL, + NULL, + NULL +}; + + +/* + * Initialize CR implementation + */ +Bool +CRInit(ScreenPtr pScreen) +{ + RootlessInit(pScreen, &CRRootlessProcs); + + rootless_CopyBytes_threshold = 0; + rootless_FillBytes_threshold = 0; + rootless_CompositePixels_threshold = 0; + rootless_CopyWindow_threshold = 0; + + return TRUE; +} diff --git a/hw/darwin/quartz/cr/crScreen.m b/hw/darwin/quartz/cr/crScreen.m new file mode 100644 index 000000000..d259d0bac --- /dev/null +++ b/hw/darwin/quartz/cr/crScreen.m @@ -0,0 +1,321 @@ +/* + * Cocoa rootless implementation initialization + */ +/* + * Copyright (c) 2001 Greg Parker. All Rights Reserved. + * Copyright (c) 2002-2003 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/cr/crScreen.m,v 1.5 2003/11/12 20:21:52 torrey Exp $ */ + +#include "quartzCommon.h" +#include "cr.h" + +#undef BOOL +#define BOOL xBOOL +#include "darwin.h" +#include "quartz.h" +#include "quartzCursor.h" +#include "rootless.h" +#include "safeAlpha.h" +#include "pseudoramiX.h" +#include "applewmExt.h" + +#include "regionstr.h" +#include "scrnintstr.h" +#include "picturestr.h" +#include "globals.h" +#undef BOOL + +// Name of GLX bundle using AGL framework +static const char *crOpenGLBundle = "glxAGL.bundle"; + +static Class classXView = nil; + + +/* + * CRDisplayInit + * Find all screens. + * + * Multihead note: When rootless mode uses PseudoramiX, the + * X server only sees one screen; only PseudoramiX itself knows + * about all of the screens. + */ +static void +CRDisplayInit(void) +{ + ErrorF("Display mode: Rootless Quartz -- Cocoa implementation\n"); + + if (noPseudoramiXExtension) { + darwinScreensFound = [[NSScreen screens] count]; + } else { + darwinScreensFound = 1; // only PseudoramiX knows about the rest + } + + CRAppleWMInit(); +} + + +/* + * CRScreenParams + * Set the basic screen parameters. + */ +static void +CRScreenParams(int index, DarwinFramebufferPtr dfb) +{ + dfb->bitsPerComponent = CGDisplayBitsPerSample(kCGDirectMainDisplay); + dfb->bitsPerPixel = CGDisplayBitsPerPixel(kCGDirectMainDisplay); + dfb->colorBitsPerPixel = 3 * dfb->bitsPerComponent; + + if (noPseudoramiXExtension) { + NSScreen *screen = [[NSScreen screens] objectAtIndex:index]; + NSRect frame = [screen frame]; + + // set x, y so (0,0) is top left of main screen + dfb->x = NSMinX(frame); + dfb->y = NSHeight([[NSScreen mainScreen] frame]) - + NSHeight(frame) - NSMinY(frame); + + dfb->width = NSWidth(frame); + dfb->height = NSHeight(frame); + dfb->pitch = (dfb->width) * (dfb->bitsPerPixel) / 8; + + // Shift the usable part of main screen down to avoid the menu bar. + if (NSEqualRects(frame, [[NSScreen mainScreen] frame])) { + dfb->y += aquaMenuBarHeight; + dfb->height -= aquaMenuBarHeight; + } + + } else { + int i; + NSRect unionRect = NSMakeRect(0, 0, 0, 0); + NSArray *screens = [NSScreen screens]; + + // Get the union of all screens (minus the menu bar on main screen) + for (i = 0; i < [screens count]; i++) { + NSScreen *screen = [screens objectAtIndex:i]; + NSRect frame = [screen frame]; + frame.origin.y = [[NSScreen mainScreen] frame].size.height - + frame.size.height - frame.origin.y; + if (NSEqualRects([screen frame], [[NSScreen mainScreen] frame])) { + frame.origin.y += aquaMenuBarHeight; + frame.size.height -= aquaMenuBarHeight; + } + unionRect = NSUnionRect(unionRect, frame); + } + + // Use unionRect as the screen size for the X server. + dfb->x = unionRect.origin.x; + dfb->y = unionRect.origin.y; + dfb->width = unionRect.size.width; + dfb->height = unionRect.size.height; + dfb->pitch = (dfb->width) * (dfb->bitsPerPixel) / 8; + + // Tell PseudoramiX about the real screens. + // InitOutput() will move the big screen to (0,0), + // so compensate for that here. + for (i = 0; i < [screens count]; i++) { + NSScreen *screen = [screens objectAtIndex:i]; + NSRect frame = [screen frame]; + int j; + + // Skip this screen if it's a mirrored copy of an earlier screen. + for (j = 0; j < i; j++) { + if (NSEqualRects(frame, [[screens objectAtIndex:j] frame])) { + ErrorF("PseudoramiX screen %d is a mirror of screen %d.\n", + i, j); + break; + } + } + if (j < i) continue; // this screen is a mirrored copy + + frame.origin.y = [[NSScreen mainScreen] frame].size.height - + frame.size.height - frame.origin.y; + + if (NSEqualRects([screen frame], [[NSScreen mainScreen] frame])) { + frame.origin.y += aquaMenuBarHeight; + frame.size.height -= aquaMenuBarHeight; + } + + ErrorF("PseudoramiX screen %d added: %dx%d @ (%d,%d).\n", i, + (int)frame.size.width, (int)frame.size.height, + (int)frame.origin.x, (int)frame.origin.y); + + frame.origin.x -= unionRect.origin.x; + frame.origin.y -= unionRect.origin.y; + + ErrorF("PseudoramiX screen %d placed at X11 coordinate (%d,%d).\n", + i, (int)frame.origin.x, (int)frame.origin.y); + + PseudoramiXAddScreen(frame.origin.x, frame.origin.y, + frame.size.width, frame.size.height); + } + } +} + + +/* + * CRAddScreen + * Init the framebuffer and record pixmap parameters for the screen. + */ +static Bool +CRAddScreen(int index, ScreenPtr pScreen) +{ + DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen); + QuartzScreenPtr displayInfo = QUARTZ_PRIV(pScreen); + CGRect cgRect; + CGDisplayCount numDisplays; + CGDisplayCount allocatedDisplays = 0; + CGDirectDisplayID *displays = NULL; + CGDisplayErr cgErr; + + CRScreenParams(index, dfb); + + dfb->colorType = TrueColor; + + // No frame buffer - it's all in window pixmaps. + dfb->framebuffer = NULL; // malloc(dfb.pitch * dfb.height); + + // Get all CoreGraphics displays covered by this X11 display. + cgRect = CGRectMake(dfb->x, dfb->y, dfb->width, dfb->height); + do { + cgErr = CGGetDisplaysWithRect(cgRect, 0, NULL, &numDisplays); + if (cgErr) break; + allocatedDisplays = numDisplays; + displays = xrealloc(displays, + numDisplays * sizeof(CGDirectDisplayID)); + cgErr = CGGetDisplaysWithRect(cgRect, allocatedDisplays, displays, + &numDisplays); + if (cgErr != CGDisplayNoErr) break; + } while (numDisplays > allocatedDisplays); + + if (cgErr != CGDisplayNoErr || numDisplays == 0) { + ErrorF("Could not find CGDirectDisplayID(s) for X11 screen %d: %dx%d @ %d,%d.\n", + index, dfb->width, dfb->height, dfb->x, dfb->y); + return FALSE; + } + + // This X11 screen covers all CoreGraphics displays we just found. + // If there's more than one CG display, then video mirroring is on + // or PseudoramiX is on. + displayInfo->displayCount = allocatedDisplays; + displayInfo->displayIDs = displays; + + return TRUE; +} + + +/* + * CRSetupScreen + * Setup the screen for rootless access. + */ +static Bool +CRSetupScreen(int index, ScreenPtr pScreen) +{ + // Add alpha protecting replacements for fb screen functions + pScreen->PaintWindowBackground = SafeAlphaPaintWindow; + pScreen->PaintWindowBorder = SafeAlphaPaintWindow; + +#ifdef RENDER + { + PictureScreenPtr ps = GetPictureScreen(pScreen); + ps->Composite = SafeAlphaComposite; + } +#endif /* RENDER */ + + // Initialize generic rootless code + return CRInit(pScreen); +} + + +/* + * CRInitInput + * Finalize CR specific setup. + */ +static void +CRInitInput(int argc, char **argv) +{ + int i; + + rootlessGlobalOffsetX = darwinMainScreenX; + rootlessGlobalOffsetY = darwinMainScreenY; + + for (i = 0; i < screenInfo.numScreens; i++) + AppleWMSetScreenOrigin(WindowTable[i]); +} + + +/* + * CRIsX11Window + * Returns TRUE if cr is displaying this window. + */ +static Bool +CRIsX11Window(void *nsWindow, int windowNumber) +{ + NSWindow *theWindow = nsWindow; + + if (!theWindow) + return FALSE; + + if ([[theWindow contentView] isKindOfClass:classXView]) + return TRUE; + else + return FALSE; +} + + +/* + * Quartz display mode function list. + */ +static QuartzModeProcsRec crModeProcs = { + CRDisplayInit, + CRAddScreen, + CRSetupScreen, + CRInitInput, + QuartzInitCursor, + QuartzReallySetCursor, + QuartzSuspendXCursor, + QuartzResumeXCursor, + NULL, // No capture or release in rootless mode + NULL, + CRIsX11Window, + RootlessFrameForWindow, + TopLevelParent, + NULL, // No support for DRI surfaces + NULL +}; + + +/* + * QuartzModeBundleInit + * Initialize the display mode bundle after loading. + */ +Bool +QuartzModeBundleInit(void) +{ + quartzProcs = &crModeProcs; + quartzOpenGLBundle = crOpenGLBundle; + classXView = [XView class]; + return TRUE; +} |