diff options
author | Torrey Lyons <torrey@mrcla.com> | 2004-07-30 19:12:18 +0000 |
---|---|---|
committer | Torrey Lyons <torrey@mrcla.com> | 2004-07-30 19:12:18 +0000 |
commit | 784e4d1cc02dea837a38a4140a18013953296366 (patch) | |
tree | 02691cc01819d7e98f797a17dc74fd112c4181ea | |
parent | c2275b31adc3c4292c171055db16e00ee0e69e43 (diff) |
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).
-rw-r--r-- | hw/darwin/quartz/Preferences.h | 2 | ||||
-rw-r--r-- | hw/darwin/quartz/Preferences.m | 21 | ||||
-rw-r--r-- | hw/darwin/quartz/XServer.h | 7 | ||||
-rw-r--r-- | hw/darwin/quartz/XServer.m | 145 | ||||
-rw-r--r-- | hw/darwin/quartz/cr/crScreen.m | 182 | ||||
-rw-r--r-- | hw/darwin/quartz/fullscreen/fullscreen.c | 15 | ||||
-rw-r--r-- | hw/darwin/quartz/pseudoramiX.c | 14 | ||||
-rw-r--r-- | hw/darwin/quartz/pseudoramiX.h | 3 | ||||
-rw-r--r-- | hw/darwin/quartz/quartz.c | 91 | ||||
-rw-r--r-- | hw/darwin/quartz/quartz.h | 13 | ||||
-rw-r--r-- | hw/darwin/quartz/quartzCocoa.m | 7 | ||||
-rw-r--r-- | hw/darwin/quartz/quartzCommon.h | 9 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/xprScreen.c | 86 | ||||
-rw-r--r-- | miext/rootless/rootless.h | 13 | ||||
-rw-r--r-- | miext/rootless/rootlessCommon.c | 87 | ||||
-rw-r--r-- | miext/rootless/rootlessCommon.h | 45 | ||||
-rw-r--r-- | miext/rootless/rootlessWindow.c | 57 |
17 files changed, 541 insertions, 256 deletions
diff --git a/hw/darwin/quartz/Preferences.h b/hw/darwin/quartz/Preferences.h index feecf24d6..d8c3c2ea2 100644 --- a/hw/darwin/quartz/Preferences.h +++ b/hw/darwin/quartz/Preferences.h @@ -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; diff --git a/hw/darwin/quartz/Preferences.m b/hw/darwin/quartz/Preferences.m index cca2f695d..6c14f4982 100644 --- a/hw/darwin/quartz/Preferences.m +++ b/hw/darwin/quartz/Preferences.m @@ -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"]; diff --git a/hw/darwin/quartz/XServer.h b/hw/darwin/quartz/XServer.h index 695086bfe..707c24029 100644 --- a/hw/darwin/quartz/XServer.h +++ b/hw/darwin/quartz/XServer.h @@ -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; diff --git a/hw/darwin/quartz/XServer.m b/hw/darwin/quartz/XServer.m index 3fad95c97..c8e92cc4b 100644 --- a/hw/darwin/quartz/XServer.m +++ b/hw/darwin/quartz/XServer.m @@ -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) { diff --git a/hw/darwin/quartz/cr/crScreen.m b/hw/darwin/quartz/cr/crScreen.m index f0b7db297..175007f3f 100644 --- a/hw/darwin/quartz/cr/crScreen.m +++ b/hw/darwin/quartz/cr/crScreen.m @@ -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"), @@ -79,6 +79,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); @@ -251,6 +264,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 }; diff --git a/hw/darwin/quartz/fullscreen/fullscreen.c b/hw/darwin/quartz/fullscreen/fullscreen.c index d0702a082..426fbb200 100644 --- a/hw/darwin/quartz/fullscreen/fullscreen.c +++ b/hw/darwin/quartz/fullscreen/fullscreen.c @@ -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, // No support for DRI surfaces + NULL, + NULL, + 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; } diff --git a/hw/darwin/quartz/pseudoramiX.c b/hw/darwin/quartz/pseudoramiX.c index dad735e1d..9f71eae89 100644 --- a/hw/darwin/quartz/pseudoramiX.c +++ b/hw/darwin/quartz/pseudoramiX.c @@ -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) { diff --git a/hw/darwin/quartz/pseudoramiX.h b/hw/darwin/quartz/pseudoramiX.h index 3dcae622a..c2943369d 100644 --- a/hw/darwin/quartz/pseudoramiX.h +++ b/hw/darwin/quartz/pseudoramiX.h @@ -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); diff --git a/hw/darwin/quartz/quartz.c b/hw/darwin/quartz/quartz.c index 093b88a10..341f7778d 100644 --- a/hw/darwin/quartz/quartz.c +++ b/hw/darwin/quartz/quartz.c @@ -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; @@ -166,13 +169,78 @@ 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. * Calls mode specific screen resume to restore the X clip regions * (if needed) and the X server cursor state. */ static void QuartzShow( - int x, // cursor location + int 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 diff --git a/hw/darwin/quartz/quartz.h b/hw/darwin/quartz/quartz.h index 18f88d1f8..6620b6677 100644 --- a/hw/darwin/quartz/quartz.h +++ b/hw/darwin/quartz/quartz.h @@ -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 @@ -68,6 +68,13 @@ 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 */ typedef Bool (*IsX11WindowProc)(void *nsWindow, int windowNumber); @@ -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; diff --git a/hw/darwin/quartz/quartzCocoa.m b/hw/darwin/quartz/quartzCocoa.m index 0c671890f..3cb191f22 100644 --- a/hw/darwin/quartz/quartzCocoa.m +++ b/hw/darwin/quartz/quartzCocoa.m @@ -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) { diff --git a/hw/darwin/quartz/quartzCommon.h b/hw/darwin/quartz/quartzCommon.h index 16f654a5d..4e5abdb51 100644 --- a/hw/darwin/quartz/quartzCommon.h +++ b/hw/darwin/quartz/quartzCommon.h @@ -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 */ diff --git a/hw/darwin/quartz/xpr/xprScreen.c b/hw/darwin/quartz/xpr/xprScreen.c index e1d3cf972..ff3f3a93c 100644 --- a/hw/darwin/quartz/xpr/xprScreen.c +++ b/hw/darwin/quartz/xpr/xprScreen.c @@ -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 (type == XP_EVENT_SURFACE_DESTROYED) - kind = AppleDRISurfaceNotifyDestroyed; - else - kind = AppleDRISurfaceNotifyChanged; - - DRISurfaceNotify(*(xp_surface_id *) arg, kind); - } - break; + if (arg_size == sizeof(xp_surface_id)) + { + int kind; + + if (type == XP_EVENT_SURFACE_DESTROYED) + kind = AppleDRISurfaceNotifyDestroyed; + else + kind = AppleDRISurfaceNotifyChanged; + + 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 @@ -328,6 +330,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, diff --git a/miext/rootless/rootless.h b/miext/rootless/rootless.h index aefefcab2..1bada3865 100644 --- a/miext/rootless/rootless.h +++ b/miext/rootless/rootless.h @@ -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 */ diff --git a/miext/rootless/rootlessCommon.c b/miext/rootless/rootlessCommon.c index 85655a9e1..b24d2a226 100644 --- a/miext/rootless/rootlessCommon.c +++ b/miext/rootless/rootlessCommon.c @@ -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, ®ion); - REGION_UNINIT(pWindow->drawable.pScreen, ®ion); /* no-op */ + REGION_UNINIT(pWindow->drawable.pScreen, ®ion); /* no-op */ } @@ -318,7 +318,7 @@ RootlessDamageRect(WindowPtr pWindow, int x, int y, int w, int h) RootlessDamageRegion(pWindow, ®ion); - REGION_UNINIT(pWindow->drawable.pScreen, ®ion); /* no-op */ + REGION_UNINIT(pWindow->drawable.pScreen, ®ion); /* 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); @@ -359,6 +359,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. */ diff --git a/miext/rootless/rootlessCommon.h b/miext/rootless/rootlessCommon.h index c75c45a2e..b5fcae7f9 100644 --- a/miext/rootless/rootlessCommon.h +++ b/miext/rootless/rootlessCommon.h @@ -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 */ diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c index 165665917..e8071bf02 100644 --- a/miext/rootless/rootlessWindow.c +++ b/miext/rootless/rootlessWindow.c @@ -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" @@ -1219,6 +1219,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 * framed until they are mapped. However, a window may be framed early by the @@ -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: |