Merge many XDarwin improvements:

- Fix launch of X clients by double clicking in the Finder when there is a
    space in the path (Torrey T. Lyons).
- Interpret scroll wheel mouse events correctly when shift is held down
    (Benjamin Burke).
- Add option to always use Mac command key equivalents (John Harper and
    Torrey T. Lyons).
- Add support for dynamic screen configuration changes in rootless mode
    (John Harper and Torrey T. Lyons).
- Add documentation on generic rootless layer (Torrey T. Lyons).
This commit is contained in:
Torrey Lyons 2004-07-30 19:12:18 +00:00
parent c2275b31ad
commit 784e4d1cc0
17 changed files with 539 additions and 254 deletions

View File

@ -84,6 +84,7 @@
+ (void)setModeWindow:(BOOL)newModeWindow;
+ (void)setStartupHelp:(BOOL)newStartupHelp;
+ (void)setSystemBeep:(BOOL)newSystemBeep;
+ (void)setEnableKeyEquivalents:(BOOL)newKeyEquivs;
+ (void)setXinerama:(BOOL)newXinerama;
+ (void)setAddToPath:(BOOL)newAddToPath;
+ (void)setAddToPathString:(NSString *)newAddToPathString;
@ -110,6 +111,7 @@
+ (BOOL)modeWindow;
+ (BOOL)startupHelp;
+ (BOOL)systemBeep;
+ (BOOL)enableKeyEquivalents;
+ (BOOL)xinerama;
+ (BOOL)addToPath;
+ (NSString *)addToPathString;

View File

@ -4,7 +4,7 @@
// This class keeps track of the user preferences.
//
/*
* Copyright (c) 2002-2003 Torrey T. Lyons. 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
@ -30,7 +30,7 @@
* sale, use or other dealings in this Software without prior written
* authorization.
*/
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/Preferences.m,v 1.3 2003/05/14 05:27:56 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/Preferences.m,v 1.5 2004/06/08 22:58:10 torrey Exp $ */
#import "quartzCommon.h"
@ -49,6 +49,9 @@
#define STR(s) #s
#define XSTRPATH(s) STR(s)
// Keys for user defaults dictionary
static NSString *X11EnableKeyEquivalentsKey = @"EnableKeyEquivalents";
@implementation Preferences
@ -70,6 +73,7 @@
[NSNumber numberWithInt:0], @"SwitchKeyCode",
[NSNumber numberWithInt:(NSCommandKeyMask | NSAlternateKeyMask)],
@"SwitchModifiers", @"NO", @"UseSystemBeep",
@"YES", X11EnableKeyEquivalentsKey,
@"YES", @"DockSwitch",
@"NO", @"AllowMouseAccelChange",
[NSNumber numberWithInt:qdCursor_Not8Bit], @"UseQDCursor",
@ -391,6 +395,14 @@
quartzUseSysBeep = newSystemBeep;
}
+ (void)setEnableKeyEquivalents:(BOOL)newKeyEquivs
{
[[NSUserDefaults standardUserDefaults] setBool:newKeyEquivs
forKey:X11EnableKeyEquivalentsKey];
// Update the setting used by the X server thread
quartzEnableKeyEquivalents = newKeyEquivs;
}
+ (void)setXinerama:(BOOL)newXinerama
{
[[NSUserDefaults standardUserDefaults] setBool:newXinerama
@ -537,6 +549,11 @@
return [[NSUserDefaults standardUserDefaults] boolForKey:@"UseSystemBeep"];
}
+ (BOOL)enableKeyEquivalents
{
return [[NSUserDefaults standardUserDefaults] boolForKey:X11EnableKeyEquivalentsKey];
}
+ (BOOL)xinerama
{
return [[NSUserDefaults standardUserDefaults] boolForKey:@"Xinerama"];

View File

@ -29,7 +29,7 @@
* sale, use or other dealings in this Software without prior written
* authorization.
*/
/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/XServer.h,v 1.17 2003/11/24 05:39:01 torrey Exp $ */
/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/XServer.h,v 1.2 2004/04/23 19:15:17 eich Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XServer.h,v 1.16 2003/11/23 06:04:01 torrey Exp $ */
#define BOOL xBOOL
@ -39,7 +39,7 @@
#import <Cocoa/Cocoa.h>
@interface XServer : NSObject {
// server state
// Server state
int serverState;
NSRecursiveLock *serverLock;
NSMutableArray *pendingClients;
@ -49,6 +49,7 @@
BOOL quitWithoutQuery;
BOOL pendingAppQuitReply;
UInt32 mouseState;
unsigned short swallowedKey;
BOOL sendServerEvents;
BOOL x11Active;
@ -73,7 +74,7 @@
- (BOOL)translateEvent:(NSEvent *)anEvent;
- (BOOL)getMousePosition:(xEvent *)xe fromEvent:(NSEvent *)anEvent;
+ (void)append:(NSString *)value toEnv:(NSString *)name;
- (NSString *)makeSafePath:(NSString *)path;
- (BOOL)loadDisplayBundle;
- (void)startX;

View File

@ -34,7 +34,7 @@
* sale, use or other dealings in this Software without prior written
* authorization.
*/
/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/XServer.m,v 1.20 2003/11/27 01:59:53 torrey Exp $ */
/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/XServer.m,v 1.2 2004/04/23 19:15:17 eich Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XServer.m,v 1.19 2003/11/24 05:39:01 torrey Exp $ */
#include "quartzCommon.h"
@ -83,11 +83,11 @@ typedef struct {
} shellList_t;
static shellList_t const shellList[] = {
{ "csh", shell_C }, // standard C shell
{ "tcsh", shell_C }, // ... needs no introduction
{ "sh", shell_Bourne }, // standard Bourne shell
{ "zsh", shell_Bourne }, // Z shell
{ "bash", shell_Bourne }, // GNU Bourne again shell
{ "csh", shell_C }, // standard C shell
{ "tcsh", shell_C }, // ... needs no introduction
{ "sh", shell_Bourne }, // standard Bourne shell
{ "zsh", shell_Bourne }, // Z shell
{ "bash", shell_Bourne }, // GNU Bourne again shell
{ NULL, shell_Unknown }
};
@ -267,6 +267,7 @@ static io_connect_t root_port;
xe.u.u.type = ButtonRelease;
xe.u.u.detail = 1;
break;
case NSLeftMouseDown:
[self getMousePosition:&xe fromEvent:anEvent];
if (quartzRootless) {
@ -286,6 +287,7 @@ static io_connect_t root_port;
xe.u.u.type = ButtonPress;
xe.u.u.detail = 1;
break;
case NSMouseMoved:
case NSLeftMouseDragged:
case NSRightMouseDragged:
@ -293,6 +295,7 @@ static io_connect_t root_port;
[self getMousePosition:&xe fromEvent:anEvent];
xe.u.u.type = MotionNotify;
break;
case NSSystemDefined:
{
long hwButtons = [anEvent data2];
@ -309,36 +312,56 @@ static io_connect_t root_port;
xe.u.clientMessage.u.l.longs1 =[anEvent data2];
break;
}
case NSScrollWheel:
[self getMousePosition:&xe fromEvent:anEvent];
xe.u.u.type = kXDarwinScrollWheel;
xe.u.clientMessage.u.s.shorts0 = [anEvent deltaY];
xe.u.clientMessage.u.s.shorts0 = [anEvent deltaX] +
[anEvent deltaY];
break;
case NSKeyDown:
case NSKeyUp:
if (!x11Active)
if (!x11Active) {
swallowedKey = 0;
return NO;
// If the mouse is not on the valid X display area,
// we don't send the X server key events.
if (![self getMousePosition:&xe fromEvent:nil])
return NO;
if (type == NSKeyDown)
xe.u.u.type = KeyPress;
else
xe.u.u.type = KeyRelease;
}
if (type == NSKeyDown) {
// If the mouse is not on the valid X display area,
// don't send the X server key events.
if (![self getMousePosition:&xe fromEvent:nil]) {
swallowedKey = [anEvent keyCode];
return NO;
}
// See if there are any global shortcuts for this key combo.
if (quartzEnableKeyEquivalents
&& [[NSApp mainMenu] performKeyEquivalent:anEvent])
{
swallowedKey = [anEvent keyCode];
return YES;
}
} else {
// If the down key event was a valid key combo,
// don't pass the up event to X11.
if (swallowedKey != 0 && [anEvent keyCode] == swallowedKey) {
swallowedKey = 0;
return NO;
}
}
xe.u.u.type = (type == NSKeyDown) ? KeyPress : KeyRelease;
xe.u.u.detail = [anEvent keyCode];
break;
case NSFlagsChanged:
if (!x11Active)
return NO;
[self getMousePosition:&xe fromEvent:nil];
xe.u.u.type = kXDarwinUpdateModifiers;
xe.u.clientMessage.u.l.longs0 = flags;
break;
case NSOtherMouseDown: // undocumented MouseDown
case NSOtherMouseUp: // undocumented MouseUp
// Hide these from AppKit to avoid its log messages
return YES;
default:
return NO;
}
@ -395,14 +418,33 @@ static io_connect_t root_port;
}
}
// Append a string to the given enviroment variable
+ (void)append:(NSString*)value toEnv:(NSString*)name
// Make a safe path
//
// Return the path in single quotes in case there are problematic characters in it.
// We still have to worry about there being single quotes in the path. So, replace
// all instances of the ' character in the path with '\''.
- (NSString *)makeSafePath:(NSString *)path
{
setenv([name cString],
[[[NSString stringWithCString:getenv([name cString])]
stringByAppendingString:value] cString],1);
NSMutableString *safePath = [NSMutableString stringWithString:path];
NSRange aRange = NSMakeRange(0, [safePath length]);
while (aRange.length) {
aRange = [safePath rangeOfString:@"'" options:0 range:aRange];
if (!aRange.length)
break;
[safePath replaceCharactersInRange:aRange
withString:@"\'\\'\'"];
aRange.location += 4;
aRange.length = [safePath length] - aRange.location;
}
safePath = [NSMutableString stringWithFormat:@"'%@'", safePath];
return safePath;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Block SIGPIPE
@ -488,13 +530,21 @@ static io_connect_t root_port;
if (![self loadDisplayBundle])
[NSApp terminate:nil];
// In rootless mode register to receive notification of key window changes
if (quartzRootless) {
// We need to track whether the key window is an X11 window
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(windowBecameKey:)
name:NSWindowDidBecomeKeyNotification
object:nil];
// Request notification of screen layout changes even when this
// is not the active application
[[NSDistributedNotificationCenter defaultCenter]
addObserver:self
selector:@selector(applicationDidChangeScreenParameters:)
name:NSApplicationDidChangeScreenParametersNotification
object:nil];
}
// Start the X server thread
@ -581,8 +631,7 @@ static io_connect_t root_port;
{
struct passwd *passwdUser;
NSString *shellPath, *dashShellName, *commandStr, *startXPath;
NSMutableString *safeStartXPath;
NSRange aRange;
NSString *safeStartXPath;
NSBundle *thisBundle;
const char *shellPathStr, *newargv[3], *shellNameStr;
int fd[2], outFD, length, shellType, i;
@ -645,11 +694,11 @@ static io_connect_t root_port;
// Inside the new process:
if (fd[0] != STDIN_FILENO) {
dup2(fd[0], STDIN_FILENO); // Take stdin from pipe
dup2(fd[0], STDIN_FILENO); // Take stdin from pipe
close(fd[0]);
}
close(fd[1]); // Close write end of pipe
if (outFD == STDOUT_FILENO) { // Setup stdout and stderr
close(fd[1]); // Close write end of pipe
if (outFD == STDOUT_FILENO) { // Setup stdout and stderr
dup2(outFD, STDERR_FILENO);
} else if (outFD == STDERR_FILENO) {
dup2(outFD, STDOUT_FILENO);
@ -685,28 +734,14 @@ static io_connect_t root_port;
return NO;
}
// We will run the startXClients script with the path in single quotes
// in case there are problematic characters in the path. We still have
// to worry about there being single quotes in the path. So, replace
// all instances of the ' character in startXPath with '\''.
safeStartXPath = [NSMutableString stringWithString:startXPath];
aRange = NSMakeRange(0, [safeStartXPath length]);
while (aRange.length) {
aRange = [safeStartXPath rangeOfString:@"'" options:0 range:aRange];
if (!aRange.length)
break;
[safeStartXPath replaceCharactersInRange:aRange
withString:@"\'\\'\'"];
aRange.location += 4;
aRange.length = [safeStartXPath length] - aRange.location;
}
safeStartXPath = [self makeSafePath:startXPath];
if ([Preferences addToPath]) {
commandStr = [NSString stringWithFormat:@"'%@' :%d %@\n",
commandStr = [NSString stringWithFormat:@"%@ :%d %@\n",
safeStartXPath, [Preferences display],
[Preferences addToPathString]];
} else {
commandStr = [NSString stringWithFormat:@"'%@' :%d\n",
commandStr = [NSString stringWithFormat:@"%@ :%d\n",
safeStartXPath, [Preferences display]];
}
@ -726,7 +761,7 @@ static io_connect_t root_port;
// FIXME: This should be unified with startXClients
- (void)runClient:(NSString *)filename
{
const char *command = [filename UTF8String];
const char *command = [[self makeSafePath:filename] UTF8String];
const char *shell;
const char *argv[5];
int child1, child2 = 0;
@ -1177,10 +1212,10 @@ static io_connect_t root_port;
- (void)activateX11:(BOOL)state
{
if (state) {
QuartzMessageServerThread(kXDarwinActivate, 0);
QuartzMessageServerThread(kXDarwinActivate, 0);
}
else {
QuartzMessageServerThread(kXDarwinDeactivate, 0);
QuartzMessageServerThread(kXDarwinDeactivate, 0);
}
x11Active = state;
@ -1311,6 +1346,12 @@ static io_connect_t root_port;
* Application Delegate Methods
*/
- (void)applicationDidChangeScreenParameters:(NSNotification *)aNotification
{
if (quartzProcs->ScreenChanged)
quartzProcs->ScreenChanged();
}
- (void)applicationDidHide:(NSNotification *)aNotification
{
if ((AppleWMSelectedEvents() & AppleWMControllerNotifyMask) != 0) {

View File

@ -1,10 +1,10 @@
/* $XdotOrg$ */
/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/cr/crScreen.m,v 1.2 2004/04/23 19:15:51 eich Exp $ */
/*
* Cocoa rootless implementation initialization
*/
/*
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
* Copyright (c) 2002-2003 Torrey T. Lyons. 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"),
@ -78,6 +78,79 @@ CRDisplayInit(void)
}
/*
* 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.
@ -100,7 +173,6 @@ CRScreenParams(int index, DarwinFramebufferPtr dfb)
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])) {
@ -109,69 +181,7 @@ CRScreenParams(int index, DarwinFramebufferPtr dfb)
}
} 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);
}
CRAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height);
}
}
@ -195,8 +205,11 @@ CRAddScreen(int index, ScreenPtr pScreen)
dfb->colorType = TrueColor;
// No frame buffer - it's all in window pixmaps.
dfb->framebuffer = NULL; // malloc(dfb.pitch * dfb.height);
/* 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);
@ -250,6 +263,34 @@ CRSetupScreen(int index, ScreenPtr 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.
@ -300,11 +341,14 @@ static QuartzModeProcsRec crModeProcs = {
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, // No support for DRI surfaces
NULL
};

View File

@ -25,7 +25,7 @@
* holders shall not be used in advertising or otherwise to promote the sale,
* use or other dealings in this Software without prior written authorization.
*/
/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c,v 1.1.4.1 2003/12/06 13:24:23 kaleb Exp $ */
/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c,v 1.2 2004/04/23 19:16:21 eich Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c,v 1.3 2003/11/27 01:59:53 torrey Exp $ */
#include "quartzCommon.h"
@ -261,7 +261,7 @@ static void FSSuspendScreen(
*/
static void FSResumeScreen(
ScreenPtr pScreen,
int x, // cursor location
int x, // cursor location
int y )
{
QuartzResumeXCursor(pScreen, x, y);
@ -537,18 +537,21 @@ static QuartzModeProcsRec fsModeProcs = {
FSDisplayInit,
FSAddScreen,
FSSetupScreen,
NULL, // Not needed
NULL, // Not needed
QuartzInitCursor,
QuartzReallySetCursor,
FSSuspendScreen,
FSResumeScreen,
FSCapture,
FSRelease,
NULL, // No rootless code in fullscreen
NULL, // No dynamic screen change support
NULL,
NULL,
NULL, // No rootless code in fullscreen
NULL,
NULL,
NULL,
NULL, // No support for DRI surfaces
NULL, // No support for DRI surfaces
NULL
};
@ -561,6 +564,6 @@ Bool
QuartzModeBundleInit(void)
{
quartzProcs = &fsModeProcs;
quartzOpenGLBundle = NULL; // Only Mesa support for now
quartzOpenGLBundle = NULL; // Only Mesa support for now
return TRUE;
}

View File

@ -32,7 +32,7 @@ shall not be used in advertising or otherwise to promote the sale, use or other
dealings in this Software without prior written authorization from Digital
Equipment Corporation.
******************************************************************/
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/pseudoramiX.c,v 1.2 2002/10/16 21:13:33 dawes Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/pseudoramiX.c,v 1.4 2004/07/02 01:30:33 torrey Exp $ */
#include "pseudoramiX.h"
@ -111,11 +111,15 @@ void PseudoramiXExtensionInit(int argc, char *argv[])
if (noPseudoramiXExtension) return;
/* Even with only one screen we need to enable PseudoramiX to allow
dynamic screen configuration changes. */
#if 0
if (pseudoramiXNumScreens == 1) {
// Only one screen - disable Xinerama extension.
noPseudoramiXExtension = TRUE;
return;
}
#endif
// The server must not run the PanoramiX operations.
noPanoramiXExtension = TRUE;
@ -142,12 +146,18 @@ void PseudoramiXExtensionInit(int argc, char *argv[])
}
static void PseudoramiXResetProc(ExtensionEntry *extEntry)
void PseudoramiXResetScreens(void)
{
pseudoramiXNumScreens = 0;
}
static void PseudoramiXResetProc(ExtensionEntry *extEntry)
{
PseudoramiXResetScreens();
}
// was PanoramiX
static int ProcPseudoramiXQueryVersion(ClientPtr client)
{

View File

@ -1,9 +1,10 @@
/*
* Minimal implementation of PanoramiX/Xinerama
*/
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/pseudoramiX.h,v 1.1 2002/03/28 02:21:18 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/pseudoramiX.h,v 1.3 2004/07/02 01:30:33 torrey Exp $ */
extern int noPseudoramiXExtension;
void PseudoramiXAddScreen(int x, int y, int w, int h);
void PseudoramiXExtensionInit(int argc, char *argv[]);
void PseudoramiXResetScreens(void);

View File

@ -1,11 +1,11 @@
/* $XdotOrg$ */
/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/quartz.c,v 1.2 2004/04/23 19:15:17 eich Exp $ */
/**************************************************************
*
* Quartz-specific support for the Darwin X Server
*
**************************************************************/
/*
* Copyright (c) 2001-2003 Greg Parker and Torrey T. Lyons.
* Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -30,7 +30,7 @@
* holders shall not be used in advertising or otherwise to promote the sale,
* use or other dealings in this Software without prior written authorization.
*/
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartz.c,v 1.13 2003/11/12 20:21:51 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartz.c,v 1.16 2004/07/02 01:30:33 torrey Exp $ */
#include "quartzCommon.h"
#include "quartz.h"
@ -43,7 +43,9 @@
// X headers
#include "scrnintstr.h"
#include "windowstr.h"
#include "colormapst.h"
#include "globals.h"
// System headers
#include <sys/types.h>
@ -57,6 +59,7 @@ int quartzStartClients = 1;
int quartzRootless = -1;
int quartzUseSysBeep = 0;
int quartzUseAGL = 1;
int quartzEnableKeyEquivalents = 1;
int quartzServerVisible = TRUE;
int quartzServerQuitting = FALSE;
int quartzScreenIndex = 0;
@ -165,6 +168,71 @@ void DarwinModeInitInput(
}
/*
* QuartzUpdateScreens
* Adjust for screen arrangement changes.
*/
static void QuartzUpdateScreens(void)
{
ScreenPtr pScreen;
WindowPtr pRoot;
int x, y, width, height, sx, sy;
xEvent e;
if (noPseudoramiXExtension || screenInfo.numScreens != 1)
{
/* FIXME: if not using Xinerama, we have multiple screens, and
to do this properly may need to add or remove screens. Which
isn't possible. So don't do anything. Another reason why
we default to running with Xinerama. */
return;
}
pScreen = screenInfo.screens[0];
PseudoramiXResetScreens();
quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height);
dixScreenOrigins[pScreen->myNum].x = x;
dixScreenOrigins[pScreen->myNum].y = y;
pScreen->mmWidth = pScreen->mmWidth * ((double) width / pScreen->width);
pScreen->mmHeight = pScreen->mmHeight * ((double) height / pScreen->height);
pScreen->width = width;
pScreen->height = height;
/* FIXME: should probably do something with RandR here. */
DarwinAdjustScreenOrigins(&screenInfo);
quartzProcs->UpdateScreen(pScreen);
sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX;
sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY;
/* Adjust the root window. */
pRoot = WindowTable[pScreen->myNum];
AppleWMSetScreenOrigin(pRoot);
pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL);
pScreen->PaintWindowBackground(pRoot, &pRoot->borderClip, PW_BACKGROUND);
// QuartzIgnoreNextWarpCursor();
DefineInitialRootWindow(pRoot);
/* Send an event for the root reconfigure */
e.u.u.type = ConfigureNotify;
e.u.configureNotify.window = pRoot->drawable.id;
e.u.configureNotify.aboveSibling = None;
e.u.configureNotify.x = x - sx;
e.u.configureNotify.y = y - sy;
e.u.configureNotify.width = width;
e.u.configureNotify.height = height;
e.u.configureNotify.borderWidth = wBorderWidth(pRoot);
e.u.configureNotify.override = pRoot->overrideRedirect;
DeliverEvents(pRoot, &e, 1, NullWindow);
/* FIXME: Should we use RREditConnectionInfo(pScreen)? */
}
/*
* QuartzShow
* Show the X server on screen. Does nothing if already shown.
@ -172,7 +240,7 @@ void DarwinModeInitInput(
* (if needed) and the X server cursor state.
*/
static void QuartzShow(
int x, // cursor location
int x, // cursor location
int y )
{
int i;
@ -252,10 +320,10 @@ QuartzMessageServerThread(
max_args = 4;
if (argc > 0 && argc <= max_args) {
va_start (args, argc);
for (i = 0; i < argc; i++)
argv[i] = (int) va_arg (args, int);
va_end (args);
va_start (args, argc);
for (i = 0; i < argc; i++)
argv[i] = (int) va_arg (args, int);
va_end (args);
}
DarwinEQEnqueue(&xe);
@ -308,8 +376,8 @@ void DarwinModeProcessEvent(
case kXDarwinControllerNotify:
AppleWMSendEvent(AppleWMControllerNotify,
AppleWMControllerNotifyMask,
xe->u.clientMessage.u.l.longs0,
xe->u.clientMessage.u.l.longs1);
xe->u.clientMessage.u.l.longs0,
xe->u.clientMessage.u.l.longs1);
break;
case kXDarwinPasteboardNotify:
@ -320,6 +388,9 @@ void DarwinModeProcessEvent(
break;
case kXDarwinDisplayChanged:
QuartzUpdateScreens();
break;
case kXDarwinWindowState:
case kXDarwinWindowMoved:
// FIXME: Not implemented yet

View File

@ -30,7 +30,7 @@
* holders shall not be used in advertising or otherwise to promote the sale,
* use or other dealings in this Software without prior written authorization.
*/
/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/quartz.h,v 1.8 2003/11/27 01:59:53 torrey Exp $ */
/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/quartz.h,v 1.2 2004/04/23 19:15:17 eich Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartz.h,v 1.7 2003/11/12 20:21:51 torrey Exp $ */
#ifndef _QUARTZ_H
@ -67,6 +67,13 @@ typedef void (*ResumeScreenProc)(ScreenPtr pScreen, int x, int y);
typedef void (*CaptureScreensProc)(void);
typedef void (*ReleaseScreensProc)(void);
/*
* Screen state change support
*/
typedef void (*ScreenChangedProc)(void);
typedef void (*AddPseudoramiXScreensProc)(int *x, int *y, int *width, int *height);
typedef void (*UpdateScreenProc)(ScreenPtr pScreen);
/*
* Rootless helper functions
*/
@ -104,6 +111,10 @@ typedef struct _QuartzModeProcs {
CaptureScreensProc CaptureScreens; // Only called in fullscreen
ReleaseScreensProc ReleaseScreens; // Only called in fullscreen
ScreenChangedProc ScreenChanged;
AddPseudoramiXScreensProc AddPseudoramiXScreens;
UpdateScreenProc UpdateScreen;
IsX11WindowProc IsX11Window;
HideWindowsProc HideWindows;

View File

@ -1,4 +1,4 @@
/* $XdotOrg$ */
/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/quartzCocoa.m,v 1.2 2004/04/23 19:15:17 eich Exp $ */
/**************************************************************
*
* Quartz-specific support for the Darwin X Server
@ -9,7 +9,7 @@
*
**************************************************************/
/*
* Copyright (c) 2001-2003 Torrey T. Lyons and Greg Parker.
* Copyright (c) 2001-2004 Torrey T. Lyons and Greg Parker.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -34,7 +34,7 @@
* 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/quartzCocoa.m,v 1.3 2003/01/19 06:52:54 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzCocoa.m,v 1.5 2004/06/08 22:58:10 torrey Exp $ */
#include "quartzCommon.h"
@ -65,6 +65,7 @@ void QuartzReadPreferences(void)
darwinFakeMouse3Mask = [Preferences button3Mask];
darwinMouseAccelChange = [Preferences mouseAccelChange];
quartzUseSysBeep = [Preferences systemBeep];
quartzEnableKeyEquivalents = [Preferences enableKeyEquivalents];
// quartzRootless has already been set
if (quartzRootless) {

View File

@ -1,4 +1,4 @@
/* $XdotOrg$ */
/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/quartzCommon.h,v 1.2 2004/04/23 19:15:17 eich Exp $ */
/*
* quartzCommon.h
*
@ -7,7 +7,7 @@
* This file should be included before any X11 or IOKit headers
* so that it can avoid symbol conflicts.
*
* Copyright (c) 2001-2003 Torrey T. Lyons and Greg Parker.
* Copyright (c) 2001-2004 Torrey T. Lyons and Greg Parker.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -32,7 +32,7 @@
* 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/quartzCommon.h,v 1.13 2003/10/16 23:50:10 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzCommon.h,v 1.15 2004/06/08 22:58:10 torrey Exp $ */
#ifndef _QUARTZCOMMON_H
#define _QUARTZCOMMON_H
@ -70,6 +70,7 @@ extern int quartzStartClients;
extern int quartzRootless;
extern int quartzUseSysBeep;
extern int quartzUseAGL;
extern int quartzEnableKeyEquivalents;
// Other shared data
extern int quartzServerVisible;
@ -104,4 +105,4 @@ enum {
kQuartzSetCanQuit
};
#endif /* _QUARTZCOMMON_H */
#endif /* _QUARTZCOMMON_H */

View File

@ -1,10 +1,10 @@
/* $XdotOrg$ */
/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/xpr/xprScreen.c,v 1.2 2004/04/23 19:16:52 eich Exp $ */
/*
* Xplugin rootless implementation screen functions
*/
/*
* Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
* Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
* Copyright (c) 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"),
@ -28,7 +28,7 @@
* 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/xpr/xprScreen.c,v 1.8 2003/11/12 20:21:52 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/xprScreen.c,v 1.11 2004/07/15 18:53:25 torrey Exp $ */
#include "quartzCommon.h"
#include "quartz.h"
@ -57,41 +57,42 @@ eventHandler(unsigned int type, const void *arg,
switch (type)
{
case XP_EVENT_DISPLAY_CHANGED:
QuartzMessageServerThread(kXDarwinDisplayChanged, 0);
break;
QuartzMessageServerThread(kXDarwinDisplayChanged, 0);
break;
case XP_EVENT_WINDOW_STATE_CHANGED:
if (arg_size >= sizeof(xp_window_state_event))
if (arg_size >= sizeof(xp_window_state_event))
{
const xp_window_state_event *ws_arg = arg;
QuartzMessageServerThread(kXDarwinWindowState, 2,
const xp_window_state_event *ws_arg = arg;
QuartzMessageServerThread(kXDarwinWindowState, 2,
ws_arg->id, ws_arg->state);
}
break;
}
break;
case XP_EVENT_WINDOW_MOVED:
if (arg_size == sizeof(xp_window_id))
{
xp_window_id id = * (xp_window_id *) arg;
if (arg_size == sizeof(xp_window_id))
{
xp_window_id id = * (xp_window_id *) arg;
QuartzMessageServerThread(kXDarwinWindowMoved, 1, id);
}
break;
QuartzMessageServerThread(kXDarwinWindowMoved, 1, id);
}
break;
case XP_EVENT_SURFACE_DESTROYED:
case XP_EVENT_SURFACE_CHANGED:
if (arg_size == sizeof(xp_surface_id))
{
int kind;
if (arg_size == sizeof(xp_surface_id))
{
int kind;
if (type == XP_EVENT_SURFACE_DESTROYED)
kind = AppleDRISurfaceNotifyDestroyed;
else
kind = AppleDRISurfaceNotifyChanged;
if (type == XP_EVENT_SURFACE_DESTROYED)
kind = AppleDRISurfaceNotifyDestroyed;
else
kind = AppleDRISurfaceNotifyChanged;
DRISurfaceNotify(*(xp_surface_id *) arg, kind);
}
break;
DRISurfaceNotify(*(xp_surface_id *) arg, kind);
}
break;
}
}
@ -139,11 +140,12 @@ displayScreenBounds(CGDirectDisplayID id)
/*
* addPseudoramiXScreens
* Add a physical screen with PseudoramiX.
* xprAddPseudoramiXScreens
* Add a single virtual screen encompassing all the physical screens
* with PseudoramiX.
*/
static void
addPseudoramiXScreens(int *x, int *y, int *width, int *height)
xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height)
{
CGDisplayCount i, displayCount;
CGDirectDisplayID *displayList = NULL;
@ -286,7 +288,7 @@ xprAddScreen(int index, ScreenPtr pScreen)
}
else
{
addPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height);
xprAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height);
}
/* Passing zero width (pitch) makes miCreateScreenResources set the
@ -327,6 +329,23 @@ xprSetupScreen(int index, ScreenPtr pScreen)
}
/*
* xprUpdateScreen
* Update screen after configuation change.
*/
static void
xprUpdateScreen(ScreenPtr pScreen)
{
rootlessGlobalOffsetX = darwinMainScreenX;
rootlessGlobalOffsetY = darwinMainScreenY;
AppleWMSetScreenOrigin(WindowTable[pScreen->myNum]);
RootlessRepositionWindows(pScreen);
RootlessUpdateScreenPixmap(pScreen);
}
/*
* xprInitInput
* Finalize xpr specific setup.
@ -358,6 +377,9 @@ static QuartzModeProcsRec xprModeProcs = {
QuartzResumeXCursor,
NULL, // No capture or release in rootless mode
NULL,
NULL, // Xplugin sends screen change events directly
xprAddPseudoramiXScreens,
xprUpdateScreen,
xprIsX11Window,
xprHideWindows,
RootlessFrameForWindow,

View File

@ -27,7 +27,7 @@
* 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/miext/rootless/rootless.h,v 1.5 2003/10/18 00:00:34 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/miext/rootless/rootless.h,v 1.7 2004/07/02 01:30:33 torrey Exp $ */
#ifndef _ROOTLESS_H
#define _ROOTLESS_H
@ -395,5 +395,16 @@ void RootlessStartDrawing(WindowPtr pWindow);
*/
void RootlessStopDrawing(WindowPtr pWindow, Bool flush);
/*
* Alocate a new screen pixmap.
* miCreateScreenResources does not do this properly with a null
* framebuffer pointer.
*/
void RootlessUpdateScreenPixmap(ScreenPtr pScreen);
/*
* Reposition all windows on a screen to their correct positions.
*/
void RootlessRepositionWindows(ScreenPtr pScreen);
#endif /* _ROOTLESS_H */

View File

@ -28,7 +28,7 @@
* 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/miext/rootless/rootlessCommon.c,v 1.4tsi Exp $ */
/* $XFree86: xc/programs/Xserver/miext/rootless/rootlessCommon.c,v 1.6 2004/07/02 01:30:33 torrey Exp $ */
#include "rootlessCommon.h"
@ -166,8 +166,8 @@ void RootlessStopDrawing(WindowPtr pWindow, Bool flush)
}
if (flush && winRec->is_reorder_pending) {
winRec->is_reorder_pending = FALSE;
RootlessReorderWindow(pWindow);
winRec->is_reorder_pending = FALSE;
RootlessReorderWindow(pWindow);
}
}
@ -190,11 +190,11 @@ RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion)
pTop = TopLevelParent(pWindow);
if (pTop == NULL)
return;
return;
winRec = WINREC(pTop);
if (winRec == NULL)
return;
return;
/* We need to intersect the drawn region with the clip of the window
to avoid marking places we didn't actually draw (which can cause
@ -208,43 +208,43 @@ RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion)
b2 = REGION_EXTENTS(pScreen, pRegion);
if (EXTENTCHECK(b1, b2)) {
/* Regions may overlap. */
/* Regions may overlap. */
if (REGION_NUM_RECTS(pRegion) == 1) {
int in;
if (REGION_NUM_RECTS(pRegion) == 1) {
int in;
/* Damaged region only has a single rect, so we can
just compare that against the region */
/* Damaged region only has a single rect, so we can
just compare that against the region */
in = RECT_IN_REGION(pScreen, &pWindow->borderClip,
in = RECT_IN_REGION(pScreen, &pWindow->borderClip,
REGION_RECTS (pRegion));
if (in == rgnIN) {
/* clip totally contains pRegion */
if (in == rgnIN) {
/* clip totally contains pRegion */
#ifdef ROOTLESS_TRACK_DAMAGE
REGION_UNION(pScreen, &winRec->damage,
&winRec->damage, (pRegion));
&winRec->damage, (pRegion));
#else
SCREENREC(pScreen)->imp->DamageRects(winRec->wid,
SCREENREC(pScreen)->imp->DamageRects(winRec->wid,
REGION_NUM_RECTS(pRegion),
REGION_RECTS(pRegion),
-winRec->x, -winRec->y);
REGION_RECTS(pRegion),
-winRec->x, -winRec->y);
#endif
RootlessQueueRedisplay(pTop->drawable.pScreen);
goto out;
}
else if (in == rgnOUT) {
/* clip doesn't contain pRegion */
RootlessQueueRedisplay(pTop->drawable.pScreen);
goto out;
}
else if (in == rgnOUT) {
/* clip doesn't contain pRegion */
goto out;
}
}
goto out;
}
}
/* clip overlaps pRegion, need to intersect */
/* clip overlaps pRegion, need to intersect */
REGION_NULL(pScreen, &clipped);
REGION_INTERSECT(pScreen, &clipped, &pWindow->borderClip, pRegion);
REGION_NULL(pScreen, &clipped);
REGION_INTERSECT(pScreen, &clipped, &pWindow->borderClip, pRegion);
#ifdef ROOTLESS_TRACK_DAMAGE
REGION_UNION(pScreen, &winRec->damage,
@ -256,9 +256,9 @@ RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion)
-winRec->x, -winRec->y);
#endif
REGION_UNINIT(pScreen, &clipped);
REGION_UNINIT(pScreen, &clipped);
RootlessQueueRedisplay(pTop->drawable.pScreen);
RootlessQueueRedisplay(pTop->drawable.pScreen);
}
out:
@ -291,7 +291,7 @@ RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox)
RootlessDamageRegion(pWindow, &region);
REGION_UNINIT(pWindow->drawable.pScreen, &region); /* no-op */
REGION_UNINIT(pWindow->drawable.pScreen, &region); /* no-op */
}
@ -318,7 +318,7 @@ RootlessDamageRect(WindowPtr pWindow, int x, int y, int w, int h)
RootlessDamageRegion(pWindow, &region);
REGION_UNINIT(pWindow->drawable.pScreen, &region); /* no-op */
REGION_UNINIT(pWindow->drawable.pScreen, &region); /* no-op */
}
@ -350,7 +350,7 @@ RootlessRedisplay(WindowPtr pWindow)
REGION_EMPTY(pScreen, &winRec->damage);
}
#else /* !ROOTLESS_TRACK_DAMAGE */
#else /* !ROOTLESS_TRACK_DAMAGE */
RootlessStopDrawing(pWindow, TRUE);
@ -358,6 +358,27 @@ RootlessRedisplay(WindowPtr pWindow)
}
/*
* RootlessRepositionWindows
* Reposition all windows on a screen to their correct positions.
*/
void
RootlessRepositionWindows(ScreenPtr pScreen)
{
WindowPtr root = WindowTable[pScreen->myNum];
WindowPtr win;
if (root != NULL) {
RootlessRepositionWindow(root);
for (win = root->firstChild; win; win = win->nextSib) {
if (WINREC(win) != NULL)
RootlessRepositionWindow(win);
}
}
}
/*
* RootlessRedisplayScreen
* Walk every window on a screen and redisplay the damaged regions.

View File

@ -3,7 +3,7 @@
*/
/*
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
* Copyright (c) 2002-2003 Torrey T. Lyons. 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"),
@ -27,7 +27,7 @@
* 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/miext/rootless/rootlessCommon.h,v 1.3 2003/06/30 01:45:13 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/miext/rootless/rootlessCommon.h,v 1.5 2004/07/02 01:30:33 torrey Exp $ */
#ifndef _ROOTLESSCOMMON_H
#define _ROOTLESSCOMMON_H
@ -139,10 +139,10 @@ typedef struct _RootlessScreenRec {
// Call a rootless implementation function.
// Many rootless implementation functions are allowed to be NULL.
#define CallFrameProc(pScreen, proc, params) \
if (SCREENREC(pScreen)->frameProcs.proc) { \
RL_DEBUG_MSG("calling frame proc " #proc " "); \
SCREENREC(pScreen)->frameProcs.proc params; \
#define CallFrameProc(pScreen, proc, params) \
if (SCREENREC(pScreen)->frameProcs.proc) { \
RL_DEBUG_MSG("calling frame proc " #proc " "); \
SCREENREC(pScreen)->frameProcs.proc params; \
}
@ -217,19 +217,19 @@ extern RegionRec rootlessHugeRoot;
* Can't access the bits before the first word of the drawable's data in
* rootless mode, so make sure our base address is always 32-bit aligned.
*/
#define SetPixmapBaseToScreen(pix, _x, _y) { \
PixmapPtr _pPix = (PixmapPtr) (pix); \
_pPix->devPrivate.ptr = (char *) (_pPix->devPrivate.ptr) - \
((int)(_x) * _pPix->drawable.bitsPerPixel/8 + \
(int)(_y) * _pPix->devKind); \
if (_pPix->drawable.bitsPerPixel != FB_UNIT) { \
unsigned _diff = ((unsigned) _pPix->devPrivate.ptr) & \
(FB_UNIT / CHAR_BIT - 1); \
_pPix->devPrivate.ptr = (char *) (_pPix->devPrivate.ptr) - \
_diff; \
_pPix->drawable.x = _diff / \
(_pPix->drawable.bitsPerPixel / CHAR_BIT); \
} \
#define SetPixmapBaseToScreen(pix, _x, _y) { \
PixmapPtr _pPix = (PixmapPtr) (pix); \
_pPix->devPrivate.ptr = (char *) (_pPix->devPrivate.ptr) - \
((int)(_x) * _pPix->drawable.bitsPerPixel/8 + \
(int)(_y) * _pPix->devKind); \
if (_pPix->drawable.bitsPerPixel != FB_UNIT) { \
unsigned _diff = ((unsigned) _pPix->devPrivate.ptr) & \
(FB_UNIT / CHAR_BIT - 1); \
_pPix->devPrivate.ptr = (char *) (_pPix->devPrivate.ptr) - \
_diff; \
_pPix->drawable.x = _diff / \
(_pPix->drawable.bitsPerPixel / CHAR_BIT); \
} \
}
@ -246,9 +246,12 @@ void RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox);
void RootlessRedisplay(WindowPtr pWindow);
void RootlessRedisplayScreen(ScreenPtr pScreen);
void RootlessQueueRedisplay (ScreenPtr pScreen);
void RootlessQueueRedisplay(ScreenPtr pScreen);
// Move a window to its proper location on the screen.
void RootlessRepositionWindow(WindowPtr pWin);
// Move the window to it's correct place in the physical stacking order.
void RootlessReorderWindow (WindowPtr pWin);
void RootlessReorderWindow(WindowPtr pWin);
#endif /* _ROOTLESSCOMMON_H */

View File

@ -1,10 +1,10 @@
/* $XdotOrg$ */
/* $XdotOrg: xc/programs/Xserver/miext/rootless/rootlessWindow.c,v 1.2 2004/04/23 19:54:27 eich Exp $ */
/*
* Rootless window management
*/
/*
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
* Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
* Copyright (c) 2002-2004 Torrey T. Lyons. All Rights Reserved.
* Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -29,7 +29,7 @@
* 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/miext/rootless/rootlessWindow.c,v 1.10 2003/11/13 20:26:31 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/miext/rootless/rootlessWindow.c,v 1.12 2004/07/02 01:30:33 torrey Exp $ */
#include "rootlessCommon.h"
#include "rootlessWindow.h"
@ -1218,6 +1218,31 @@ RootlessResizeWindow(WindowPtr pWin, int x, int y,
}
/*
* RootlessRepositionWindow
* Called by the implementation when a window needs to be repositioned to
* its correct location on the screen. This routine is typically needed
* due to changes in the underlying window system, such as a screen layout
* change.
*/
void
RootlessRepositionWindow(WindowPtr pWin)
{
RootlessWindowRec *winRec = WINREC(pWin);
ScreenPtr pScreen = pWin->drawable.pScreen;
if (winRec == NULL)
return;
RootlessStopDrawing(pWin, FALSE);
SCREENREC(pScreen)->imp->MoveFrame(winRec->wid, pScreen,
winRec->x + SCREEN_TO_GLOBAL_X,
winRec->y + SCREEN_TO_GLOBAL_Y);
RootlessReorderWindow(pWin);
}
/*
* RootlessReparentWindow
* Called after a window has been reparented. Generally windows are not
@ -1236,9 +1261,9 @@ RootlessReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
/* Check that window is not top-level now, but used to be. */
if (IsRoot(pWin) || IsRoot(pWin->parent)
|| IsTopLevel(pWin) || winRec == NULL)
|| IsTopLevel(pWin) || winRec == NULL)
{
goto out;
goto out;
}
/* If the formerly top-level window has a frame, we want to give the
@ -1249,20 +1274,20 @@ RootlessReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
assert(pTopWin != pWin);
if (WINREC(pTopWin) != NULL) {
/* We're screwed. */
RootlessDestroyFrame(pWin, winRec);
/* We're screwed. */
RootlessDestroyFrame(pWin, winRec);
} else {
if (!pTopWin->realized && pWin->realized) {
if (!pTopWin->realized && pWin->realized) {
SCREENREC(pScreen)->imp->UnmapFrame(winRec->wid);
}
}
/* Switch the frame record from one to the other. */
/* Switch the frame record from one to the other. */
WINREC(pWin) = NULL;
WINREC(pTopWin) = winRec;
WINREC(pWin) = NULL;
WINREC(pTopWin) = winRec;
RootlessInitializeFrame(pTopWin, winRec);
RootlessReshapeFrame(pTopWin);
RootlessInitializeFrame(pTopWin, winRec);
RootlessReshapeFrame(pTopWin);
SCREENREC(pScreen)->imp->ResizeFrame(winRec->wid, pScreen,
winRec->x + SCREEN_TO_GLOBAL_X,
@ -1274,8 +1299,8 @@ RootlessReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
SCREENREC(pScreen)->imp->SwitchWindow(winRec, pWin);
}
if (pTopWin->realized && !pWin->realized)
winRec->is_reorder_pending = TRUE;
if (pTopWin->realized && !pWin->realized)
winRec->is_reorder_pending = TRUE;
}
out: