Darwin: RIP dumpkeymap, cr, and fullscreen
Taking out the trash.
We don't need dumpkeymap since we'll be getting keymaps straight from the OS. .Xmodmap should be sufficient for any user-needed changes. If this is not
the case, please let us know, so we can address any problems you have.
fullscreen never worked AFAIK
cr isn't being used and xpr is much better.
(cherry picked from commit e41af2967e
)
This commit is contained in:
parent
13af2d1efc
commit
cc98a8e241
|
@ -9,8 +9,8 @@ if X11APP
|
|||
X11APP_SUBDIRS = apple
|
||||
endif
|
||||
|
||||
SUBDIRS = quartz utils $(X11APP_SUBDIRS)
|
||||
DIST_SUBDIRS = quartz utils apple launcher
|
||||
SUBDIRS = quartz $(X11APP_SUBDIRS)
|
||||
DIST_SUBDIRS = quartz apple
|
||||
|
||||
bin_PROGRAMS = Xquartz
|
||||
man1_MANS = Xquartz.man
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#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
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#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
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#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 */
|
|
@ -1,159 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "quartz/quartzCommon.h"
|
||||
#include "quartz/cr/cr.h"
|
||||
|
||||
#undef BOOL
|
||||
#define BOOL xBOOL
|
||||
#include "rootless.h"
|
||||
#include "X11/X.h"
|
||||
#define _APPLEWM_SERVER_
|
||||
#include "X11/extensions/applewm.h"
|
||||
#include "quartz/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);
|
||||
}
|
|
@ -1,440 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "quartz/quartzCommon.h"
|
||||
#include "quartz/cr/cr.h"
|
||||
|
||||
#undef BOOL
|
||||
#define BOOL xBOOL
|
||||
#include "rootless.h"
|
||||
#include "quartz/applewmExt.h"
|
||||
#include "windowstr.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
|
||||
#ifdef DEFER_NSWINDOW
|
||||
defer:YES];
|
||||
#else
|
||||
defer:NO];
|
||||
#endif
|
||||
|
||||
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];
|
||||
|
||||
#ifdef DEFER_NSWINDOW
|
||||
// We need the NSWindow to actually be created now.
|
||||
// If we had to defer creating it, we have to order it
|
||||
// onto the screen to force it to be created.
|
||||
|
||||
if (pFrame->win->prevSib) {
|
||||
CRWindowPtr crWinPtr = (CRWindowPtr) RootlessFrameForWindow(
|
||||
pFrame->win->prevSib, FALSE);
|
||||
int upperNum = [crWinPtr->window windowNumber];
|
||||
[theWindow orderWindow:NSWindowBelow relativeTo:upperNum];
|
||||
} else {
|
||||
[theWindow orderFront:nil];
|
||||
}
|
||||
#endif
|
||||
|
||||
[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.
|
||||
miInverse(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called to check if the frame should be reordered when it is restacked.
|
||||
*/
|
||||
Bool CRDoReorderWindow(RootlessWindowPtr pFrame)
|
||||
{
|
||||
WindowPtr pWin = pFrame->win;
|
||||
|
||||
return AppleWMDoReorderWindow(pWin);
|
||||
}
|
||||
|
||||
|
||||
static RootlessFrameProcsRec CRRootlessProcs = {
|
||||
CRCreateFrame,
|
||||
CRDestroyFrame,
|
||||
CRMoveFrame,
|
||||
CRResizeFrame,
|
||||
CRRestackFrame,
|
||||
CRReshapeFrame,
|
||||
CRUnmapFrame,
|
||||
CRStartDrawing,
|
||||
CRStopDrawing,
|
||||
CRUpdateRegion,
|
||||
CRDamageRects,
|
||||
NULL,
|
||||
CRDoReorderWindow,
|
||||
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;
|
||||
}
|
|
@ -1,382 +0,0 @@
|
|||
/*
|
||||
* Cocoa rootless implementation initialization
|
||||
*
|
||||
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
|
||||
* Copyright (c) 2002-2004 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "quartz/quartzCommon.h"
|
||||
#include "quartz/cr/cr.h"
|
||||
|
||||
#undef BOOL
|
||||
#define BOOL xBOOL
|
||||
#include "darwin.h"
|
||||
#include "quartz/quartz.h"
|
||||
#include "quartz/quartzCursor.h"
|
||||
#include "rootless.h"
|
||||
#include "safeAlpha/safeAlpha.h"
|
||||
#include "quartz/pseudoramiX.h"
|
||||
#include "quartz/applewmExt.h"
|
||||
|
||||
#include "regionstr.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "picturestr.h"
|
||||
#include "globals.h"
|
||||
#ifdef DAMAGE
|
||||
# include "damage.h"
|
||||
#endif
|
||||
#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();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CRAddPseudoramiXScreens
|
||||
* Add a single virtual screen encompassing all the physical screens
|
||||
* with PseudoramiX.
|
||||
*/
|
||||
static void
|
||||
CRAddPseudoramiXScreens(int *x, int *y, int *width, int *height)
|
||||
{
|
||||
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.
|
||||
*x = unionRect.origin.x;
|
||||
*y = unionRect.origin.y;
|
||||
*width = unionRect.size.width;
|
||||
*height = unionRect.size.height;
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
// 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 {
|
||||
CRAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->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;
|
||||
|
||||
/* Passing zero width (pitch) makes miCreateScreenResources set the
|
||||
screen pixmap to the framebuffer pointer, i.e. NULL. The generic
|
||||
rootless code takes care of making this work. */
|
||||
dfb->pitch = 0;
|
||||
dfb->framebuffer = NULL;
|
||||
|
||||
// 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 accelerated rootless drawing
|
||||
// Note that this must be done before DamageSetup().
|
||||
RootlessAccelInit(pScreen);
|
||||
|
||||
#ifdef DAMAGE
|
||||
// The Damage extension needs to wrap underneath the
|
||||
// generic rootless layer, so do it now.
|
||||
if (!DamageSetup(pScreen))
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
// Initialize generic rootless code
|
||||
return CRInit(pScreen);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CRScreenChanged
|
||||
* Configuration of displays has changed.
|
||||
*/
|
||||
static void
|
||||
CRScreenChanged(void)
|
||||
{
|
||||
QuartzMessageServerThread(kXDarwinDisplayChanged, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CRUpdateScreen
|
||||
* Update screen after configuation change.
|
||||
*/
|
||||
static void
|
||||
CRUpdateScreen(ScreenPtr pScreen)
|
||||
{
|
||||
rootlessGlobalOffsetX = darwinMainScreenX;
|
||||
rootlessGlobalOffsetY = darwinMainScreenY;
|
||||
|
||||
AppleWMSetScreenOrigin(WindowTable[pScreen->myNum]);
|
||||
|
||||
RootlessRepositionWindows(pScreen);
|
||||
RootlessUpdateScreenPixmap(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,
|
||||
CRScreenChanged,
|
||||
CRAddPseudoramiXScreens,
|
||||
CRUpdateScreen,
|
||||
CRIsX11Window,
|
||||
NULL, // Cocoa NSWindows hide themselves
|
||||
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;
|
||||
}
|
|
@ -1,571 +0,0 @@
|
|||
/*
|
||||
* Screen routines for full screen Quartz mode
|
||||
*
|
||||
* 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
|
||||
* TORREY T. LYONS 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "quartz/quartzCommon.h"
|
||||
#include "darwin.h"
|
||||
#include "quartz/quartz.h"
|
||||
#include "quartz/quartzCursor.h"
|
||||
#include "colormapst.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "micmap.h"
|
||||
#include "shadow.h"
|
||||
|
||||
// Full screen specific per screen storage structure
|
||||
typedef struct {
|
||||
CGDirectDisplayID displayID;
|
||||
CFDictionaryRef xDisplayMode;
|
||||
CFDictionaryRef aquaDisplayMode;
|
||||
CGDirectPaletteRef xPalette;
|
||||
CGDirectPaletteRef aquaPalette;
|
||||
unsigned char *framebuffer;
|
||||
unsigned char *shadowPtr;
|
||||
} FSScreenRec, *FSScreenPtr;
|
||||
|
||||
#define FULLSCREEN_PRIV(pScreen) \
|
||||
((FSScreenPtr)pScreen->devPrivates[fsScreenIndex].ptr)
|
||||
|
||||
static int fsScreenIndex;
|
||||
static CGDirectDisplayID *quartzDisplayList = NULL;
|
||||
static int quartzNumScreens = 0;
|
||||
static FSScreenPtr quartzScreens[MAXSCREENS];
|
||||
|
||||
static int darwinCmapPrivateIndex = -1;
|
||||
static unsigned long darwinCmapGeneration = 0;
|
||||
|
||||
#define CMAP_PRIV(pCmap) \
|
||||
((CGDirectPaletteRef) (pCmap)->devPrivates[darwinCmapPrivateIndex].ptr)
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
Colormap handling
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* FSInitCmapPrivates
|
||||
* Colormap privates may be allocated after the default colormap has
|
||||
* already been created for some screens. This initialization procedure
|
||||
* is called for each default colormap that is found.
|
||||
*/
|
||||
static Bool
|
||||
FSInitCmapPrivates(
|
||||
ColormapPtr pCmap)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FSCreateColormap
|
||||
* This is a callback from X after a new colormap is created.
|
||||
* We allocate a new CoreGraphics pallete for each colormap.
|
||||
*/
|
||||
static Bool
|
||||
FSCreateColormap(
|
||||
ColormapPtr pCmap)
|
||||
{
|
||||
CGDirectPaletteRef pallete;
|
||||
|
||||
// Allocate private storage for the hardware dependent colormap info.
|
||||
if (darwinCmapGeneration != serverGeneration) {
|
||||
if ((darwinCmapPrivateIndex =
|
||||
AllocateColormapPrivateIndex(FSInitCmapPrivates)) < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
darwinCmapGeneration = serverGeneration;
|
||||
}
|
||||
|
||||
pallete = CGPaletteCreateDefaultColorPalette();
|
||||
if (!pallete) return FALSE;
|
||||
|
||||
CMAP_PRIV(pCmap) = pallete;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FSDestroyColormap
|
||||
* This is called by DIX FreeColormap after it has uninstalled a colormap
|
||||
* and notified all interested parties. We deallocated the corresponding
|
||||
* CoreGraphics pallete.
|
||||
*/
|
||||
static void
|
||||
FSDestroyColormap(
|
||||
ColormapPtr pCmap)
|
||||
{
|
||||
CGPaletteRelease( CMAP_PRIV(pCmap) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FSInstallColormap
|
||||
* Set the current CoreGraphics pallete to the pallete corresponding
|
||||
* to the provided colormap.
|
||||
*/
|
||||
static void
|
||||
FSInstallColormap(
|
||||
ColormapPtr pCmap)
|
||||
{
|
||||
CGDirectPaletteRef palette = CMAP_PRIV(pCmap);
|
||||
ScreenPtr pScreen = pCmap->pScreen;
|
||||
FSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen);
|
||||
|
||||
// Inform all interested parties that the map is being changed.
|
||||
miInstallColormap(pCmap);
|
||||
|
||||
if (quartzServerVisible)
|
||||
CGDisplaySetPalette(fsDisplayInfo->displayID, palette);
|
||||
|
||||
fsDisplayInfo->xPalette = palette;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FSStoreColors
|
||||
* This is a callback from X to change the hardware colormap
|
||||
* when using PsuedoColor in full screen mode.
|
||||
*/
|
||||
static void
|
||||
FSStoreColors(
|
||||
ColormapPtr pCmap,
|
||||
int numEntries,
|
||||
xColorItem *pdefs)
|
||||
{
|
||||
CGDirectPaletteRef palette = CMAP_PRIV(pCmap);
|
||||
ScreenPtr pScreen = pCmap->pScreen;
|
||||
FSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen);
|
||||
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);
|
||||
}
|
||||
|
||||
// Update hardware colormap
|
||||
if (quartzServerVisible)
|
||||
CGDisplaySetPalette(fsDisplayInfo->displayID, palette);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
Switching between Aqua and X
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* FSCapture
|
||||
* Capture the screen so we can draw. Called directly from the main thread
|
||||
* to synchronize with hiding the menubar.
|
||||
*/
|
||||
static void FSCapture(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (quartzRootless) return;
|
||||
|
||||
for (i = 0; i < quartzNumScreens; i++) {
|
||||
FSScreenPtr fsDisplayInfo = quartzScreens[i];
|
||||
CGDirectDisplayID cgID = fsDisplayInfo->displayID;
|
||||
|
||||
if (!CGDisplayIsCaptured(cgID)) {
|
||||
CGDisplayCapture(cgID);
|
||||
fsDisplayInfo->aquaDisplayMode = CGDisplayCurrentMode(cgID);
|
||||
if (fsDisplayInfo->xDisplayMode != fsDisplayInfo->aquaDisplayMode)
|
||||
CGDisplaySwitchToMode(cgID, fsDisplayInfo->xDisplayMode);
|
||||
if (fsDisplayInfo->xPalette)
|
||||
CGDisplaySetPalette(cgID, fsDisplayInfo->xPalette);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FSRelease
|
||||
* Release the screen so others can draw.
|
||||
*/
|
||||
static void FSRelease(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (quartzRootless) return;
|
||||
|
||||
for (i = 0; i < quartzNumScreens; i++) {
|
||||
FSScreenPtr fsDisplayInfo = quartzScreens[i];
|
||||
CGDirectDisplayID cgID = fsDisplayInfo->displayID;
|
||||
|
||||
if (CGDisplayIsCaptured(cgID)) {
|
||||
if (fsDisplayInfo->xDisplayMode != fsDisplayInfo->aquaDisplayMode)
|
||||
CGDisplaySwitchToMode(cgID, fsDisplayInfo->aquaDisplayMode);
|
||||
if (fsDisplayInfo->aquaPalette)
|
||||
CGDisplaySetPalette(cgID, fsDisplayInfo->aquaPalette);
|
||||
CGDisplayRelease(cgID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FSSuspendScreen
|
||||
* Suspend X11 cursor and drawing to the screen.
|
||||
*/
|
||||
static void FSSuspendScreen(
|
||||
ScreenPtr pScreen)
|
||||
{
|
||||
QuartzSuspendXCursor(pScreen);
|
||||
xf86SetRootClip(pScreen, FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FSResumeScreen
|
||||
* Resume X11 cursor and drawing to the screen.
|
||||
*/
|
||||
static void FSResumeScreen(
|
||||
ScreenPtr pScreen,
|
||||
int x, // cursor location
|
||||
int y )
|
||||
{
|
||||
QuartzResumeXCursor(pScreen, x, y);
|
||||
xf86SetRootClip(pScreen, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
Screen initialization
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* FSDisplayInit
|
||||
* Full screen specific initialization called from InitOutput.
|
||||
*/
|
||||
static void FSDisplayInit(void)
|
||||
{
|
||||
static unsigned long generation = 0;
|
||||
CGDisplayCount quartzDisplayCount = 0;
|
||||
|
||||
ErrorF("Display mode: Full screen Quartz -- Direct Display\n");
|
||||
|
||||
// Allocate private storage for each screen's mode specific info
|
||||
if (generation != serverGeneration) {
|
||||
fsScreenIndex = AllocateScreenPrivateIndex();
|
||||
generation = serverGeneration;
|
||||
}
|
||||
|
||||
// Find all the CoreGraphics displays
|
||||
CGGetActiveDisplayList(0, NULL, &quartzDisplayCount);
|
||||
quartzDisplayList = xalloc(quartzDisplayCount * sizeof(CGDirectDisplayID));
|
||||
CGGetActiveDisplayList(quartzDisplayCount, quartzDisplayList,
|
||||
&quartzDisplayCount);
|
||||
|
||||
darwinScreensFound = quartzDisplayCount;
|
||||
atexit(FSRelease);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FSFindDisplayMode
|
||||
* Find the appropriate display mode to use in full screen mode.
|
||||
* If display mode is not the same as the current Aqua mode, switch
|
||||
* to the new mode.
|
||||
*/
|
||||
static Bool FSFindDisplayMode(
|
||||
FSScreenPtr fsDisplayInfo)
|
||||
{
|
||||
CGDirectDisplayID cgID = fsDisplayInfo->displayID;
|
||||
size_t height, width, bpp;
|
||||
boolean_t exactMatch;
|
||||
|
||||
fsDisplayInfo->aquaDisplayMode = CGDisplayCurrentMode(cgID);
|
||||
|
||||
// If no user options, use current display mode
|
||||
if (darwinDesiredWidth == 0 && darwinDesiredDepth == -1 &&
|
||||
darwinDesiredRefresh == -1)
|
||||
{
|
||||
fsDisplayInfo->xDisplayMode = fsDisplayInfo->aquaDisplayMode;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// If the user has no choice for size, use current
|
||||
if (darwinDesiredWidth == 0) {
|
||||
width = CGDisplayPixelsWide(cgID);
|
||||
height = CGDisplayPixelsHigh(cgID);
|
||||
} else {
|
||||
width = darwinDesiredWidth;
|
||||
height = darwinDesiredHeight;
|
||||
}
|
||||
|
||||
switch (darwinDesiredDepth) {
|
||||
case 0:
|
||||
bpp = 8;
|
||||
break;
|
||||
case 1:
|
||||
bpp = 16;
|
||||
break;
|
||||
case 2:
|
||||
bpp = 32;
|
||||
break;
|
||||
default:
|
||||
bpp = CGDisplayBitsPerPixel(cgID);
|
||||
}
|
||||
|
||||
if (darwinDesiredRefresh == -1) {
|
||||
fsDisplayInfo->xDisplayMode =
|
||||
CGDisplayBestModeForParameters(cgID, bpp, width, height,
|
||||
&exactMatch);
|
||||
} else {
|
||||
fsDisplayInfo->xDisplayMode =
|
||||
CGDisplayBestModeForParametersAndRefreshRate(cgID, bpp,
|
||||
width, height, darwinDesiredRefresh, &exactMatch);
|
||||
}
|
||||
if (!exactMatch) {
|
||||
fsDisplayInfo->xDisplayMode = fsDisplayInfo->aquaDisplayMode;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Switch to the new display mode
|
||||
CGDisplaySwitchToMode(cgID, fsDisplayInfo->xDisplayMode);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FSAddScreen
|
||||
* Do initialization of each screen for Quartz in full screen mode.
|
||||
*/
|
||||
static Bool FSAddScreen(
|
||||
int index,
|
||||
ScreenPtr pScreen)
|
||||
{
|
||||
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
|
||||
QuartzScreenPtr displayInfo = QUARTZ_PRIV(pScreen);
|
||||
CGDirectDisplayID cgID = quartzDisplayList[index];
|
||||
CGRect bounds;
|
||||
FSScreenPtr fsDisplayInfo;
|
||||
|
||||
// Allocate space for private per screen fullscreen specific storage.
|
||||
fsDisplayInfo = xalloc(sizeof(FSScreenRec));
|
||||
FULLSCREEN_PRIV(pScreen) = fsDisplayInfo;
|
||||
|
||||
displayInfo->displayCount = 1;
|
||||
displayInfo->displayIDs = xrealloc(displayInfo->displayIDs,
|
||||
1 * sizeof(CGDirectDisplayID));
|
||||
displayInfo->displayIDs[0] = cgID;
|
||||
|
||||
fsDisplayInfo->displayID = cgID;
|
||||
fsDisplayInfo->xDisplayMode = 0;
|
||||
fsDisplayInfo->aquaDisplayMode = 0;
|
||||
fsDisplayInfo->xPalette = 0;
|
||||
fsDisplayInfo->aquaPalette = 0;
|
||||
|
||||
// Capture full screen because X doesn't like read-only framebuffer.
|
||||
// We need to do this before we (potentially) switch the display mode.
|
||||
CGDisplayCapture(cgID);
|
||||
|
||||
if (! FSFindDisplayMode(fsDisplayInfo)) {
|
||||
ErrorF("Could not support specified display mode on screen %i.\n",
|
||||
index);
|
||||
xfree(fsDisplayInfo);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Don't need to flip y-coordinate as CoreGraphics treats (0, 0)
|
||||
// as the top left of main screen.
|
||||
bounds = CGDisplayBounds(cgID);
|
||||
dfb->x = bounds.origin.x;
|
||||
dfb->y = 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->colorType = PseudoColor;
|
||||
} else {
|
||||
dfb->colorType = StaticColor;
|
||||
}
|
||||
dfb->bitsPerComponent = 8;
|
||||
dfb->colorBitsPerPixel = 8;
|
||||
} else {
|
||||
dfb->colorType = TrueColor;
|
||||
dfb->bitsPerComponent = CGDisplayBitsPerSample(cgID);
|
||||
dfb->colorBitsPerPixel = CGDisplaySamplesPerPixel(cgID) *
|
||||
dfb->bitsPerComponent;
|
||||
}
|
||||
|
||||
fsDisplayInfo->framebuffer = CGDisplayBaseAddress(cgID);
|
||||
|
||||
// allocate shadow framebuffer
|
||||
fsDisplayInfo->shadowPtr = xalloc(dfb->pitch * dfb->height);
|
||||
dfb->framebuffer = fsDisplayInfo->shadowPtr;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FSShadowUpdate
|
||||
* Update the damaged regions of the shadow framebuffer on the display.
|
||||
*/
|
||||
static void FSShadowUpdate(
|
||||
ScreenPtr pScreen,
|
||||
shadowBufPtr pBuf)
|
||||
{
|
||||
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
|
||||
FSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen);
|
||||
RegionPtr damage = &pBuf->damage;
|
||||
int numBox = REGION_NUM_RECTS(damage);
|
||||
BoxPtr pBox = REGION_RECTS(damage);
|
||||
int pitch = dfb->pitch;
|
||||
int bpp = dfb->bitsPerPixel/8;
|
||||
|
||||
// Don't update if the X server is not visible
|
||||
if (!quartzServerVisible)
|
||||
return;
|
||||
|
||||
// Loop through all the damaged boxes
|
||||
while (numBox--) {
|
||||
int width, height, offset;
|
||||
unsigned char *src, *dst;
|
||||
|
||||
width = (pBox->x2 - pBox->x1) * bpp;
|
||||
height = pBox->y2 - pBox->y1;
|
||||
offset = (pBox->y1 * pitch) + (pBox->x1 * bpp);
|
||||
src = fsDisplayInfo->shadowPtr + offset;
|
||||
dst = fsDisplayInfo->framebuffer + offset;
|
||||
|
||||
while (height--) {
|
||||
memcpy(dst, src, width);
|
||||
dst += pitch;
|
||||
src += pitch;
|
||||
}
|
||||
|
||||
// Get the next box
|
||||
pBox++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FSSetupScreen
|
||||
* Finalize full screen specific setup of each screen.
|
||||
*/
|
||||
static Bool FSSetupScreen(
|
||||
int index,
|
||||
ScreenPtr pScreen)
|
||||
{
|
||||
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
|
||||
FSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen);
|
||||
CGDirectDisplayID cgID = fsDisplayInfo->displayID;
|
||||
|
||||
// Initialize shadow framebuffer support
|
||||
if (! shadowInit(pScreen, FSShadowUpdate, NULL)) {
|
||||
ErrorF("Failed to initalize shadow framebuffer for screen %i.\n",
|
||||
index);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dfb->colorType == PseudoColor) {
|
||||
// Initialize colormap handling
|
||||
size_t aquaBpp;
|
||||
|
||||
// If Aqua is using 8 bits we need to keep track of its pallete.
|
||||
CFNumberGetValue(CFDictionaryGetValue(fsDisplayInfo->aquaDisplayMode,
|
||||
kCGDisplayBitsPerPixel), kCFNumberLongType, &aquaBpp);
|
||||
if (aquaBpp <= 8)
|
||||
fsDisplayInfo->aquaPalette = CGPaletteCreateWithDisplay(cgID);
|
||||
|
||||
pScreen->CreateColormap = FSCreateColormap;
|
||||
pScreen->DestroyColormap = FSDestroyColormap;
|
||||
pScreen->InstallColormap = FSInstallColormap;
|
||||
pScreen->StoreColors = FSStoreColors;
|
||||
|
||||
}
|
||||
|
||||
quartzScreens[quartzNumScreens++] = fsDisplayInfo;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Quartz display mode function list.
|
||||
*/
|
||||
static QuartzModeProcsRec fsModeProcs = {
|
||||
FSDisplayInit,
|
||||
FSAddScreen,
|
||||
FSSetupScreen,
|
||||
NULL, // Not needed
|
||||
QuartzInitCursor,
|
||||
QuartzReallySetCursor,
|
||||
FSSuspendScreen,
|
||||
FSResumeScreen,
|
||||
FSCapture,
|
||||
FSRelease,
|
||||
NULL, // No dynamic screen change support
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, // No rootless code in fullscreen
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, // No support for DRI surfaces
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* QuartzModeBundleInit
|
||||
* Initialize the display mode bundle after loading.
|
||||
*/
|
||||
Bool
|
||||
QuartzModeBundleInit(void)
|
||||
{
|
||||
quartzProcs = &fsModeProcs;
|
||||
quartzOpenGLBundle = NULL; // Only Mesa support for now
|
||||
return TRUE;
|
||||
}
|
|
@ -1,654 +0,0 @@
|
|||
/**************************************************************
|
||||
*
|
||||
* Support for using the Quartz Window Manager cursor
|
||||
*
|
||||
* Copyright (c) 2001-2003 Torrey T. Lyons and 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "quartz/quartzCommon.h"
|
||||
#include "quartz/quartzCursor.h"
|
||||
#include "darwin.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "mi.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "cursorstr.h"
|
||||
#include "mipointrst.h"
|
||||
#include "globals.h"
|
||||
|
||||
// Size of the QuickDraw cursor
|
||||
#define CURSORWIDTH 16
|
||||
#define CURSORHEIGHT 16
|
||||
|
||||
typedef struct {
|
||||
int qdCursorMode;
|
||||
int qdCursorVisible;
|
||||
int useQDCursor;
|
||||
QueryBestSizeProcPtr QueryBestSize;
|
||||
miPointerSpriteFuncPtr spriteFuncs;
|
||||
} QuartzCursorScreenRec, *QuartzCursorScreenPtr;
|
||||
|
||||
static int darwinCursorScreenIndex = -1;
|
||||
static unsigned long darwinCursorGeneration = 0;
|
||||
static CursorPtr quartzLatentCursor = NULL;
|
||||
static QD_Cursor gQDArrow; // QuickDraw arrow cursor
|
||||
|
||||
// Cursor for the main thread to set (NULL = arrow cursor).
|
||||
static CCrsrHandle currentCursor = NULL;
|
||||
static pthread_mutex_t cursorMutex;
|
||||
static pthread_cond_t cursorCondition;
|
||||
|
||||
#define CURSOR_PRIV(pScreen) \
|
||||
((QuartzCursorScreenPtr)pScreen->devPrivates[darwinCursorScreenIndex].ptr)
|
||||
|
||||
#define HIDE_QD_CURSOR(pScreen, visible) \
|
||||
if (visible) { \
|
||||
int ix; \
|
||||
for (ix = 0; ix < QUARTZ_PRIV(pScreen)->displayCount; ix++) { \
|
||||
CGDisplayHideCursor(QUARTZ_PRIV(pScreen)->displayIDs[ix]); \
|
||||
} \
|
||||
visible = FALSE; \
|
||||
} ((void)0)
|
||||
|
||||
#define SHOW_QD_CURSOR(pScreen, visible) \
|
||||
{ \
|
||||
int ix; \
|
||||
for (ix = 0; ix < QUARTZ_PRIV(pScreen)->displayCount; ix++) { \
|
||||
CGDisplayShowCursor(QUARTZ_PRIV(pScreen)->displayIDs[ix]); \
|
||||
} \
|
||||
visible = TRUE; \
|
||||
} ((void)0)
|
||||
|
||||
#define CHANGE_QD_CURSOR(cursorH) \
|
||||
if (!quartzServerQuitting) { \
|
||||
/* Acquire lock and tell the main thread to change cursor */ \
|
||||
pthread_mutex_lock(&cursorMutex); \
|
||||
currentCursor = (CCrsrHandle) (cursorH); \
|
||||
QuartzMessageMainThread(kQuartzCursorUpdate, NULL, 0); \
|
||||
\
|
||||
/* Wait for the main thread to change the cursor */ \
|
||||
pthread_cond_wait(&cursorCondition, &cursorMutex); \
|
||||
pthread_mutex_unlock(&cursorMutex); \
|
||||
} ((void)0)
|
||||
|
||||
|
||||
/*
|
||||
* MakeQDCursor helpers: CTAB_ENTER, interleave
|
||||
*/
|
||||
|
||||
// Add a color entry to a ctab
|
||||
#define CTAB_ENTER(ctab, index, r, g, b) \
|
||||
ctab->ctTable[index].value = index; \
|
||||
ctab->ctTable[index].rgb.red = r; \
|
||||
ctab->ctTable[index].rgb.green = g; \
|
||||
ctab->ctTable[index].rgb.blue = b
|
||||
|
||||
// Make an unsigned short by interleaving the bits of bytes c1 and c2.
|
||||
// High bit of c1 is first; low bit of c2 is last.
|
||||
// Interleave is a built-in INTERCAL operator.
|
||||
static unsigned short
|
||||
interleave(
|
||||
unsigned char c1,
|
||||
unsigned char c2 )
|
||||
{
|
||||
return
|
||||
((c1 & 0x80) << 8) | ((c2 & 0x80) << 7) |
|
||||
((c1 & 0x40) << 7) | ((c2 & 0x40) << 6) |
|
||||
((c1 & 0x20) << 6) | ((c2 & 0x20) << 5) |
|
||||
((c1 & 0x10) << 5) | ((c2 & 0x10) << 4) |
|
||||
((c1 & 0x08) << 4) | ((c2 & 0x08) << 3) |
|
||||
((c1 & 0x04) << 3) | ((c2 & 0x04) << 2) |
|
||||
((c1 & 0x02) << 2) | ((c2 & 0x02) << 1) |
|
||||
((c1 & 0x01) << 1) | ((c2 & 0x01) << 0) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* MakeQDCursor
|
||||
* Make a QuickDraw color cursor from the given X11 cursor.
|
||||
* Warning: This code is nasty. Color cursors were meant to be read
|
||||
* from resources; constructing the structures programmatically is messy.
|
||||
*/
|
||||
/*
|
||||
QuickDraw cursor representation:
|
||||
Our color cursor is a 2 bit per pixel pixmap.
|
||||
Each pixel's bits are (source<<1 | mask) from the original X cursor pixel.
|
||||
The cursor's color table maps the colors like this:
|
||||
(2-bit value | X result | colortable | Mac result)
|
||||
00 | transparent | white | transparent (white outside mask)
|
||||
01 | back color | back color | back color
|
||||
10 | undefined | black | invert background (just for fun)
|
||||
11 | fore color | fore color | fore color
|
||||
*/
|
||||
static CCrsrHandle
|
||||
MakeQDCursor(
|
||||
CursorPtr pCursor )
|
||||
{
|
||||
CCrsrHandle result;
|
||||
CCrsrPtr curs;
|
||||
int i, w, h;
|
||||
unsigned short rowMask;
|
||||
PixMap *pix;
|
||||
ColorTable *ctab;
|
||||
unsigned short *image;
|
||||
|
||||
result = (CCrsrHandle) NewHandleClear(sizeof(CCrsr));
|
||||
if (!result) return NULL;
|
||||
HLock((Handle)result);
|
||||
curs = *result;
|
||||
|
||||
// Initialize CCrsr
|
||||
curs->crsrType = 0x8001; // 0x8000 = b&w, 0x8001 = color
|
||||
curs->crsrMap = (PixMapHandle) NewHandleClear(sizeof(PixMap));
|
||||
if (!curs->crsrMap) goto pixAllocFailed;
|
||||
HLock((Handle)curs->crsrMap);
|
||||
pix = *curs->crsrMap;
|
||||
curs->crsrData = NULL; // raw cursor image data (set below)
|
||||
curs->crsrXData = NULL; // QD's processed data
|
||||
curs->crsrXValid = 0; // zero means QD must re-process cursor data
|
||||
curs->crsrXHandle = NULL; // reserved
|
||||
memset(curs->crsr1Data, 0, CURSORWIDTH*CURSORHEIGHT/8); // b&w data
|
||||
memset(curs->crsrMask, 0, CURSORWIDTH*CURSORHEIGHT/8); // b&w & color mask
|
||||
curs->crsrHotSpot.h = min(CURSORWIDTH, pCursor->bits->xhot); // hot spot
|
||||
curs->crsrHotSpot.v = min(CURSORHEIGHT, pCursor->bits->yhot); // hot spot
|
||||
curs->crsrXTable = 0; // reserved
|
||||
curs->crsrID = GetCTSeed(); // unique ID from Color Manager
|
||||
|
||||
// Set the b&w data and mask
|
||||
w = min(pCursor->bits->width, CURSORWIDTH);
|
||||
h = min(pCursor->bits->height, CURSORHEIGHT);
|
||||
rowMask = ~((1 << (CURSORWIDTH - w)) - 1);
|
||||
for (i = 0; i < h; i++) {
|
||||
curs->crsr1Data[i] = rowMask &
|
||||
((pCursor->bits->source[i*4]<<8) | pCursor->bits->source[i*4+1]);
|
||||
curs->crsrMask[i] = rowMask &
|
||||
((pCursor->bits->mask[i*4]<<8) | pCursor->bits->mask[i*4+1]);
|
||||
}
|
||||
|
||||
// Set the color data and mask
|
||||
// crsrMap: defines bit depth and size and colortable only
|
||||
pix->rowBytes = (CURSORWIDTH * 2 / 8) | 0x8000; // last bit on means PixMap
|
||||
SetRect(&pix->bounds, 0, 0, CURSORWIDTH, CURSORHEIGHT); // see TN 1020
|
||||
pix->pixelSize = 2;
|
||||
pix->cmpCount = 1;
|
||||
pix->cmpSize = 2;
|
||||
// pix->pmTable set below
|
||||
|
||||
// crsrData is the pixel data. crsrMap's baseAddr is not used.
|
||||
curs->crsrData = NewHandleClear(CURSORWIDTH*CURSORHEIGHT * 2 / 8);
|
||||
if (!curs->crsrData) goto imageAllocFailed;
|
||||
HLock((Handle)curs->crsrData);
|
||||
image = (unsigned short *) *curs->crsrData;
|
||||
// Pixel data is just 1-bit data and mask interleaved (see above)
|
||||
for (i = 0; i < h; i++) {
|
||||
unsigned char s, m;
|
||||
s = pCursor->bits->source[i*4] & (rowMask >> 8);
|
||||
m = pCursor->bits->mask[i*4] & (rowMask >> 8);
|
||||
image[2*i] = interleave(s, m);
|
||||
s = pCursor->bits->source[i*4+1] & (rowMask & 0x00ff);
|
||||
m = pCursor->bits->mask[i*4+1] & (rowMask & 0x00ff);
|
||||
image[2*i+1] = interleave(s, m);
|
||||
}
|
||||
|
||||
// Build the color table (entries described above)
|
||||
// NewPixMap allocates a color table handle.
|
||||
pix->pmTable = (CTabHandle) NewHandleClear(sizeof(ColorTable) + 3
|
||||
* sizeof(ColorSpec));
|
||||
if (!pix->pmTable) goto ctabAllocFailed;
|
||||
HLock((Handle)pix->pmTable);
|
||||
ctab = *pix->pmTable;
|
||||
ctab->ctSeed = GetCTSeed();
|
||||
ctab->ctFlags = 0;
|
||||
ctab->ctSize = 3; // color count - 1
|
||||
CTAB_ENTER(ctab, 0, 0xffff, 0xffff, 0xffff);
|
||||
CTAB_ENTER(ctab, 1, pCursor->backRed, pCursor->backGreen,
|
||||
pCursor->backBlue);
|
||||
CTAB_ENTER(ctab, 2, 0x0000, 0x0000, 0x0000);
|
||||
CTAB_ENTER(ctab, 3, pCursor->foreRed, pCursor->foreGreen,
|
||||
pCursor->foreBlue);
|
||||
|
||||
HUnlock((Handle)pix->pmTable); // ctab
|
||||
HUnlock((Handle)curs->crsrData); // image data
|
||||
HUnlock((Handle)curs->crsrMap); // pix
|
||||
HUnlock((Handle)result); // cursor
|
||||
|
||||
return result;
|
||||
|
||||
// "What we have here is a failure to allocate"
|
||||
ctabAllocFailed:
|
||||
HUnlock((Handle)curs->crsrData);
|
||||
DisposeHandle((Handle)curs->crsrData);
|
||||
imageAllocFailed:
|
||||
HUnlock((Handle)curs->crsrMap);
|
||||
DisposeHandle((Handle)curs->crsrMap);
|
||||
pixAllocFailed:
|
||||
HUnlock((Handle)result);
|
||||
DisposeHandle((Handle)result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FreeQDCursor
|
||||
* Destroy a QuickDraw color cursor created with MakeQDCursor().
|
||||
* The cursor must not currently be on screen.
|
||||
*/
|
||||
static void FreeQDCursor(CCrsrHandle cursHandle)
|
||||
{
|
||||
CCrsrPtr curs;
|
||||
PixMap *pix;
|
||||
|
||||
HLock((Handle)cursHandle);
|
||||
curs = *cursHandle;
|
||||
HLock((Handle)curs->crsrMap);
|
||||
pix = *curs->crsrMap;
|
||||
DisposeHandle((Handle)pix->pmTable);
|
||||
HUnlock((Handle)curs->crsrMap);
|
||||
DisposeHandle((Handle)curs->crsrMap);
|
||||
DisposeHandle((Handle)curs->crsrData);
|
||||
HUnlock((Handle)cursHandle);
|
||||
DisposeHandle((Handle)cursHandle);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Pointer sprite functions
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QuartzRealizeCursor
|
||||
* Convert the X cursor representation to QuickDraw format if possible.
|
||||
*/
|
||||
Bool
|
||||
QuartzRealizeCursor(
|
||||
ScreenPtr pScreen,
|
||||
CursorPtr pCursor )
|
||||
{
|
||||
CCrsrHandle qdCursor;
|
||||
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
|
||||
|
||||
if(!pCursor || !pCursor->bits)
|
||||
return FALSE;
|
||||
|
||||
// if the cursor is too big we use a software cursor
|
||||
if ((pCursor->bits->height > CURSORHEIGHT) ||
|
||||
(pCursor->bits->width > CURSORWIDTH) || !ScreenPriv->useQDCursor)
|
||||
{
|
||||
if (quartzRootless) {
|
||||
// rootless can't use a software cursor
|
||||
return TRUE;
|
||||
} else {
|
||||
return (*ScreenPriv->spriteFuncs->RealizeCursor)
|
||||
(pScreen, pCursor);
|
||||
}
|
||||
}
|
||||
|
||||
// make new cursor image
|
||||
qdCursor = MakeQDCursor(pCursor);
|
||||
if (!qdCursor) return FALSE;
|
||||
|
||||
// save the result
|
||||
pCursor->devPriv[pScreen->myNum] = (pointer) qdCursor;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* QuartzUnrealizeCursor
|
||||
* Free the storage space associated with a realized cursor.
|
||||
*/
|
||||
Bool
|
||||
QuartzUnrealizeCursor(
|
||||
ScreenPtr pScreen,
|
||||
CursorPtr pCursor )
|
||||
{
|
||||
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
|
||||
|
||||
if ((pCursor->bits->height > CURSORHEIGHT) ||
|
||||
(pCursor->bits->width > CURSORWIDTH) || !ScreenPriv->useQDCursor)
|
||||
{
|
||||
if (quartzRootless) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return (*ScreenPriv->spriteFuncs->UnrealizeCursor)
|
||||
(pScreen, pCursor);
|
||||
}
|
||||
} else {
|
||||
CCrsrHandle oldCursor = (CCrsrHandle) pCursor->devPriv[pScreen->myNum];
|
||||
|
||||
if (currentCursor != oldCursor) {
|
||||
// This should only fail when quitting, in which case we just leak.
|
||||
FreeQDCursor(oldCursor);
|
||||
}
|
||||
pCursor->devPriv[pScreen->myNum] = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* QuartzSetCursor
|
||||
* Set the cursor sprite and position.
|
||||
* Use QuickDraw cursor if possible.
|
||||
*/
|
||||
static void
|
||||
QuartzSetCursor(
|
||||
ScreenPtr pScreen,
|
||||
CursorPtr pCursor,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
|
||||
|
||||
quartzLatentCursor = pCursor;
|
||||
|
||||
// Don't touch Mac OS cursor if X is hidden!
|
||||
if (!quartzServerVisible)
|
||||
return;
|
||||
|
||||
if (!pCursor) {
|
||||
// Remove the cursor completely.
|
||||
HIDE_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
|
||||
if (! ScreenPriv->qdCursorMode)
|
||||
(*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
|
||||
}
|
||||
else if ((pCursor->bits->height <= CURSORHEIGHT) &&
|
||||
(pCursor->bits->width <= CURSORWIDTH) && ScreenPriv->useQDCursor)
|
||||
{
|
||||
// Cursor is small enough to use QuickDraw directly.
|
||||
if (! ScreenPriv->qdCursorMode) // remove the X cursor
|
||||
(*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
|
||||
ScreenPriv->qdCursorMode = TRUE;
|
||||
|
||||
CHANGE_QD_CURSOR(pCursor->devPriv[pScreen->myNum]);
|
||||
SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
|
||||
}
|
||||
else if (quartzRootless) {
|
||||
// Rootless can't use a software cursor, so we just use Mac OS arrow.
|
||||
CHANGE_QD_CURSOR(NULL);
|
||||
SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
|
||||
}
|
||||
else {
|
||||
// Cursor is too big for QuickDraw. Use X software cursor.
|
||||
HIDE_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
|
||||
ScreenPriv->qdCursorMode = FALSE;
|
||||
(*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCursor, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* QuartzReallySetCursor
|
||||
* Set the QuickDraw cursor. Called from the main thread since changing the
|
||||
* cursor with QuickDraw is not thread safe on dual processor machines.
|
||||
*/
|
||||
void
|
||||
QuartzReallySetCursor()
|
||||
{
|
||||
pthread_mutex_lock(&cursorMutex);
|
||||
|
||||
if (currentCursor) {
|
||||
SetCCursor(currentCursor);
|
||||
} else {
|
||||
SetCursor(&gQDArrow);
|
||||
}
|
||||
|
||||
pthread_cond_signal(&cursorCondition);
|
||||
pthread_mutex_unlock(&cursorMutex);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* QuartzMoveCursor
|
||||
* Move the cursor. This is a noop for QuickDraw.
|
||||
*/
|
||||
static void
|
||||
QuartzMoveCursor(
|
||||
ScreenPtr pScreen,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
|
||||
|
||||
// only the X cursor needs to be explicitly moved
|
||||
if (!ScreenPriv->qdCursorMode)
|
||||
(*ScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, y);
|
||||
}
|
||||
|
||||
|
||||
static miPointerSpriteFuncRec quartzSpriteFuncsRec = {
|
||||
QuartzRealizeCursor,
|
||||
QuartzUnrealizeCursor,
|
||||
QuartzSetCursor,
|
||||
QuartzMoveCursor
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Pointer screen functions
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QuartzCursorOffScreen
|
||||
*/
|
||||
static Bool QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* QuartzCrossScreen
|
||||
*/
|
||||
static void QuartzCrossScreen(ScreenPtr pScreen, Bool entering)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* QuartzWarpCursor
|
||||
* Change the cursor position without generating an event or motion history.
|
||||
* The input coordinates (x,y) are in pScreen-local X11 coordinates.
|
||||
*
|
||||
*/
|
||||
static void
|
||||
QuartzWarpCursor(
|
||||
ScreenPtr pScreen,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
static int neverMoved = TRUE;
|
||||
|
||||
if (neverMoved) {
|
||||
// Don't move the cursor the first time. This is the jump-to-center
|
||||
// initialization, and it's annoying because we may still be in MacOS.
|
||||
neverMoved = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (quartzServerVisible) {
|
||||
CGDisplayErr cgErr;
|
||||
CGPoint cgPoint;
|
||||
// Only need to do this for one display. Any display will do.
|
||||
CGDirectDisplayID cgID = QUARTZ_PRIV(pScreen)->displayIDs[0];
|
||||
CGRect cgRect = CGDisplayBounds(cgID);
|
||||
|
||||
// Convert (x,y) to CoreGraphics screen-local CG coordinates.
|
||||
// This is necessary because the X11 screen and CG screen may not
|
||||
// coincide. (e.g. X11 screen may be moved to dodge the menu bar)
|
||||
|
||||
// Make point in X11 global coordinates
|
||||
cgPoint = CGPointMake(x + dixScreenOrigins[pScreen->myNum].x,
|
||||
y + dixScreenOrigins[pScreen->myNum].y);
|
||||
// Shift to CoreGraphics global screen coordinates
|
||||
cgPoint.x += darwinMainScreenX;
|
||||
cgPoint.y += darwinMainScreenY;
|
||||
// Shift to CoreGraphics screen-local coordinates
|
||||
cgPoint.x -= cgRect.origin.x;
|
||||
cgPoint.y -= cgRect.origin.y;
|
||||
|
||||
cgErr = CGDisplayMoveCursorToPoint(cgID, cgPoint);
|
||||
if (cgErr != CGDisplayNoErr) {
|
||||
ErrorF("Could not set cursor position with error code 0x%x.\n",
|
||||
cgErr);
|
||||
}
|
||||
}
|
||||
|
||||
miPointerWarpCursor(pScreen, x, y);
|
||||
miPointerUpdate();
|
||||
}
|
||||
|
||||
|
||||
static miPointerScreenFuncRec quartzScreenFuncsRec = {
|
||||
QuartzCursorOffScreen,
|
||||
QuartzCrossScreen,
|
||||
QuartzWarpCursor,
|
||||
DarwinEQPointerPost,
|
||||
DarwinEQSwitchScreen
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
Other screen functions
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* QuartzCursorQueryBestSize
|
||||
* Handle queries for best cursor size
|
||||
*/
|
||||
static void
|
||||
QuartzCursorQueryBestSize(
|
||||
int class,
|
||||
unsigned short *width,
|
||||
unsigned short *height,
|
||||
ScreenPtr pScreen)
|
||||
{
|
||||
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
|
||||
|
||||
if (class == CursorShape) {
|
||||
*width = CURSORWIDTH;
|
||||
*height = CURSORHEIGHT;
|
||||
} else {
|
||||
(*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* QuartzInitCursor
|
||||
* Initialize cursor support
|
||||
*/
|
||||
Bool
|
||||
QuartzInitCursor(
|
||||
ScreenPtr pScreen )
|
||||
{
|
||||
QuartzCursorScreenPtr ScreenPriv;
|
||||
miPointerScreenPtr PointPriv;
|
||||
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
|
||||
|
||||
// initialize software cursor handling (always needed as backup)
|
||||
if (!miDCInitialize(pScreen, &quartzScreenFuncsRec)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// allocate private storage for this screen's QuickDraw cursor info
|
||||
if (darwinCursorGeneration != serverGeneration) {
|
||||
if ((darwinCursorScreenIndex = AllocateScreenPrivateIndex()) < 0)
|
||||
return FALSE;
|
||||
darwinCursorGeneration = serverGeneration;
|
||||
}
|
||||
|
||||
ScreenPriv = xcalloc( 1, sizeof(QuartzCursorScreenRec) );
|
||||
if (!ScreenPriv) return FALSE;
|
||||
|
||||
CURSOR_PRIV(pScreen) = ScreenPriv;
|
||||
|
||||
// override some screen procedures
|
||||
ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
|
||||
pScreen->QueryBestSize = QuartzCursorQueryBestSize;
|
||||
|
||||
// initialize QuickDraw cursor handling
|
||||
GetQDGlobalsArrow(&gQDArrow);
|
||||
PointPriv = (miPointerScreenPtr)
|
||||
pScreen->devPrivates[miPointerScreenIndex].ptr;
|
||||
|
||||
ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
|
||||
PointPriv->spriteFuncs = &quartzSpriteFuncsRec;
|
||||
|
||||
if (!quartzRootless)
|
||||
ScreenPriv->useQDCursor = QuartzFSUseQDCursor(dfb->colorBitsPerPixel);
|
||||
else
|
||||
ScreenPriv->useQDCursor = TRUE;
|
||||
ScreenPriv->qdCursorMode = TRUE;
|
||||
ScreenPriv->qdCursorVisible = TRUE;
|
||||
|
||||
// initialize cursor mutex lock
|
||||
pthread_mutex_init(&cursorMutex, NULL);
|
||||
|
||||
// initialize condition for waiting
|
||||
pthread_cond_init(&cursorCondition, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// X server is hiding. Restore the Aqua cursor.
|
||||
void QuartzSuspendXCursor(
|
||||
ScreenPtr pScreen )
|
||||
{
|
||||
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
|
||||
|
||||
CHANGE_QD_CURSOR(NULL);
|
||||
SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
|
||||
}
|
||||
|
||||
|
||||
// X server is showing. Restore the X cursor.
|
||||
void QuartzResumeXCursor(
|
||||
ScreenPtr pScreen,
|
||||
int x,
|
||||
int y )
|
||||
{
|
||||
QuartzSetCursor(pScreen, quartzLatentCursor, x, y);
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* quartzCursor.h
|
||||
*
|
||||
* External interface for Quartz hardware cursor
|
||||
*
|
||||
* Copyright (c) 2001 Torrey T. Lyons and 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.
|
||||
*/
|
||||
|
||||
#ifndef QUARTZCURSOR_H
|
||||
#define QUARTZCURSOR_H
|
||||
|
||||
#include "screenint.h"
|
||||
|
||||
Bool QuartzInitCursor(ScreenPtr pScreen);
|
||||
void QuartzReallySetCursor(void);
|
||||
void QuartzSuspendXCursor(ScreenPtr pScreen);
|
||||
void QuartzResumeXCursor(ScreenPtr pScreen, int x, int y);
|
||||
|
||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||
bin_PROGRAMS = dumpkeymap
|
||||
|
||||
dumpkeymap_SOURCES = dumpkeymap.c
|
||||
|
||||
dumpkeymap_LDFLAGS = -Wl,-framework,IOKit
|
||||
|
||||
man1_MANS = dumpkeymap.man
|
||||
|
||||
EXTRA_DIST = \
|
||||
README.txt \
|
||||
dumpkeymap.man
|
|
@ -1,107 +0,0 @@
|
|||
dumpkeymap - Diagnostic dump and detailed description of .keymapping files
|
||||
Version 4
|
||||
|
||||
Copyright (C)1999,2000 by Eric Sunshine <sunshine@sunshineco.com>
|
||||
Eric Sunshine, 1 December 2000
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
This package contains the diagnostic utility dumpkeymap, as well as highly
|
||||
detailed documentation describing the internal layout of the Apple/NeXT
|
||||
.keymapping file.
|
||||
|
||||
The dumpkeymap utility displays detailed information about each .keymapping
|
||||
file mentioned on the command-line. On Apple and NeXT platforms, if no
|
||||
.keymapping files are mentioned on the command-line, then it will instead
|
||||
dissect the key mapping currently in use by the WindowServer and AppKit.
|
||||
|
||||
Documentation includes a thorough and detailed description of the internal
|
||||
layout of the .keymapping file, as well as an explanation of how to interpret
|
||||
the output of dumpkeymap.
|
||||
|
||||
The complete set of documentation is available for perusal via dumpkeymap's
|
||||
manual page (dumpkeymap.1), as well as via the command-line options described
|
||||
below.
|
||||
|
||||
--help
|
||||
Usage summary.
|
||||
--help-keymapping
|
||||
Detailed discussion of the internal format of a .keymapping file.
|
||||
--help-output
|
||||
Explanation of dumpkeymap's output.
|
||||
--help-files
|
||||
List of key mapping-related files and directories.
|
||||
--help-diagnostics
|
||||
Explanation of diagnostic messages.
|
||||
|
||||
Once the manual page is been installed, documentation can also be accessed
|
||||
with the Unix `man' command:
|
||||
|
||||
% man dumpkeymap
|
||||
|
||||
|
||||
COMPILATION
|
||||
===========
|
||||
MacOS/X, Darwin
|
||||
|
||||
cc -Wall -o dumpkeymap dumpkeymap.c -framework IOKit
|
||||
|
||||
MacOS/X DP4 (Developer Preview 4)
|
||||
|
||||
cc -Wall -o dumpkeymap dumpkeymap.c -FKernel -framework IOKit
|
||||
|
||||
MacOS/X Server, OpenStep, NextStep
|
||||
|
||||
cc -Wall -o dumpkeymap dumpkeymap.c
|
||||
|
||||
By default, dumpkeymap is configured to interface with the HID driver (Apple)
|
||||
or event-status driver (NeXT), thus allowing it to dump the key mapping which
|
||||
is currently in use by the WindowServer and AppKit. However, these facilities
|
||||
are specific to Apple/NeXT. In order to build dumpkeymap for non-Apple/NeXT
|
||||
platforms, you must define the DUMPKEYMAP_FILE_ONLY flag when compiling the
|
||||
program. This flag inhibits use of the HID and event-status drivers and
|
||||
configures dumpkeymap to work strictly with raw key mapping files.
|
||||
|
||||
For example, to compile for Linux:
|
||||
|
||||
gcc -Wall -DDUMPKEYMAP_FILE_ONLY -o dumpkeymap dumpkeymap.c
|
||||
|
||||
|
||||
INSTALLATION
|
||||
============
|
||||
Install the dumpkeymap executable image in a location mentioned in the PATH
|
||||
environment variable. Typicall locations for executable files are:
|
||||
|
||||
/usr/local/bin
|
||||
$(HOME)/bin
|
||||
|
||||
Install the manual page, dumpkeymap.1, in the `man1' subdirectory one of the
|
||||
standard manual page locations or in any other location mentioned by the
|
||||
MANPATH environment variable.
|
||||
|
||||
Typical locations for manual pages on most Unix platforms are:
|
||||
|
||||
/usr/local/man/man1
|
||||
|
||||
Typical locations for manual pages on MacOS/X, Darwin, and MacOS/X Server are:
|
||||
|
||||
/usr/local/man/man1
|
||||
/Local/Documentation/ManPages/man1
|
||||
/Network/Documentation/ManPages/man1
|
||||
|
||||
Typical locations for manual pages on OpenStep and NextStep are:
|
||||
|
||||
/usr/local/man/man1
|
||||
/LocalLibrary/Documentation/ManPages/man1
|
||||
/LocalDeveloper/Documentation/ManPages/man1
|
||||
|
||||
|
||||
CONCLUSION
|
||||
==========
|
||||
This program and its accompanying documentation were written by Eric Sunshine
|
||||
and are copyright (C)1999,2000 by Eric Sunshine <sunshine@sunshineco.com>.
|
||||
|
||||
The implementation of dumpkeymap is based upon information gathered on
|
||||
September 3, 1997 by Eric Sunshine <sunshine@sunshineco.com> and Paul S.
|
||||
McCarthy <zarnuk@zarnuk.com> during an effort to reverse engineer the format
|
||||
of the NeXT .keymapping file.
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user