XQuartz: Some motion made towards supporting fullscreen.

This commit is contained in:
Jeremy Huddleston 2008-10-08 18:39:41 -07:00
parent da73a34b12
commit 99be3d68b6
10 changed files with 257 additions and 50 deletions

View File

@ -81,6 +81,7 @@ extern int quartzHasRoot, quartzEnableRootless;
#define PREFS_FAKEBUTTONS "enable_fake_buttons"
#define PREFS_SYSBEEP "enable_system_beep"
#define PREFS_KEYEQUIVS "enable_key_equivalents"
#define PREFS_FULLSCREEN_HOTKEYS "fullscreen_hotkeys"
#define PREFS_SYNC_KEYMAP "sync_keymap"
#define PREFS_DEPTH "depth"
#define PREFS_NO_AUTH "no_auth"

View File

@ -624,16 +624,12 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) {
quartzUseSysBeep = [self prefs_get_boolean:@PREFS_SYSBEEP
default:quartzUseSysBeep];
// TODO: Add fullscreen support
//quartzEnableRootless = [self prefs_get_boolean:@PREFS_ROOTLESS
// default:quartzEnableRootless];
#ifdef DARWIN_DDX_MISSING
#if 0
quartzEnableRootless = [self prefs_get_boolean:@PREFS_ROOTLESS
default:quartzEnableRootless];
quartzFullscreenDisableHotkeys = ![self prefs_get_boolean:
@PREFS_FULLSCREEN_HOTKEYS default:
!quartzFullscreenDisableHotkeys];
quartzXpluginOptions = [self prefs_get_integer:@PREFS_XP_OPTIONS
default:quartzXpluginOptions];
#endif
darwinFakeButtons = [self prefs_get_boolean:@PREFS_FAKEBUTTONS
default:darwinFakeButtons];

View File

@ -595,10 +595,8 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
- (IBAction) enable_fullscreen_changed:sender
{
int value = ![enable_fullscreen intValue];
#ifdef DARWIN_DDX_MISSING
DarwinSendDDXEvent(kXquartzSetRootless, 1, value);
#endif
[NSApp prefs_set_boolean:@PREFS_ROOTLESS value:value];
[NSApp prefs_synchronize];
@ -606,9 +604,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
- (IBAction) toggle_fullscreen:sender
{
#ifdef DARWIN_DDX_MISSING
DarwinSendDDXEvent(kXquartzToggleFullscreen, 0);
#endif
}
- (void) set_can_quit:(OSX_BOOL)state

View File

@ -232,27 +232,20 @@ static void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, in
case kXquartzToggleFullscreen:
DEBUG_LOG("kXquartzToggleFullscreen\n");
#ifdef DARWIN_DDX_MISSING
if (quartzEnableRootless)
QuartzSetFullscreen(!quartzHasRoot);
else if (quartzHasRoot)
QuartzHide();
else
QuartzShow();
#else
// ErrorF("kXquartzToggleFullscreen not implemented\n");
#endif
QuartzShow(xe[i].u.keyButtonPointer.rootX,
xe[i].u.keyButtonPointer.rootY);
break;
case kXquartzSetRootless:
DEBUG_LOG("kXquartzSetRootless\n");
#ifdef DARWIN_DDX_MISSING
QuartzSetRootless(xe[i].u.clientMessage.u.l.longs0);
if (!quartzEnableRootless && !quartzHasRoot)
QuartzHide();
#else
// ErrorF("kXquartzSetRootless not implemented\n");
#endif
break;
case kXquartzSetRootClip:

View File

@ -61,6 +61,9 @@
#include <fcntl.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <rootlessCommon.h>
#include <Xplugin.h>
#define FAKE_RANDR 1
// Shared global variables for Quartz modes
@ -75,6 +78,7 @@ int quartzScreenIndex = 0;
int aquaMenuBarHeight = 0;
QuartzModeProcsPtr quartzProcs = NULL;
const char *quartzOpenGLBundle = NULL;
int quartzFullscreenDisableHotkeys = TRUE;
#if defined(RANDR) && !defined(FAKE_RANDR)
Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
@ -236,33 +240,27 @@ RREditConnectionInfo (ScreenPtr pScreen)
}
#endif
/*
* QuartzDisplayChangeHandler
* Adjust for screen arrangement changes.
*/
void QuartzDisplayChangedHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents)
{
static void QuartzUpdateScreens(void) {
ScreenPtr pScreen;
WindowPtr pRoot;
int x, y, width, height, sx, sy;
xEvent e;
DEBUG_LOG("QuartzDisplayChangedHandler(): noPseudoramiXExtension=%d, screenInfo.numScreens=%d\n", noPseudoramiXExtension, screenInfo.numScreens);
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. */
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);
@ -274,21 +272,20 @@ void QuartzDisplayChangedHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev,
if(!QuartzRandRInit(pScreen))
FatalError("Failed to init RandR extension.\n");
#endif
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);
miPaintWindow(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;
@ -300,12 +297,71 @@ void QuartzDisplayChangedHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev,
e.u.configureNotify.borderWidth = wBorderWidth(pRoot);
e.u.configureNotify.override = pRoot->overrideRedirect;
DeliverEvents(pRoot, &e, 1, NullWindow);
#ifdef FAKE_RANDR
RREditConnectionInfo(pScreen);
#endif
#endif
}
/*
* QuartzDisplayChangeHandler
* Adjust for screen arrangement changes.
*/
void QuartzDisplayChangedHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) {
QuartzUpdateScreens();
}
void QuartzSetFullscreen(Bool state) {
if(quartzHasRoot == state)
return;
quartzHasRoot = state;
xp_disable_update ();
if (!quartzHasRoot && !quartzEnableRootless)
RootlessHideAllWindows();
RootlessUpdateRooted(quartzHasRoot);
if (quartzHasRoot && !quartzEnableRootless)
RootlessShowAllWindows ();
/* Only update screen info when something is visible. Avoids the wm
* moving the windows out from under the menubar when it shouldn't
*/
if (quartzHasRoot || quartzEnableRootless)
QuartzUpdateScreens();
/* Somehow the menubar manages to interfere with our event stream
* in fullscreen mode, even though it's not visible.
*/
X11ApplicationShowHideMenubar(!quartzHasRoot);
xp_reenable_update ();
if (quartzFullscreenDisableHotkeys)
xp_disable_hot_keys(quartzHasRoot);
}
void QuartzSetRootless(Bool state) {
if(quartzEnableRootless == state)
return;
quartzEnableRootless = state;
if (!quartzEnableRootless && !quartzHasRoot) {
xp_disable_update();
RootlessHideAllWindows();
xp_reenable_update();
} else if (quartzEnableRootless && !quartzHasRoot) {
xp_disable_update();
RootlessShowAllWindows();
QuartzUpdateScreens();
xp_reenable_update();
}
}
/*
* QuartzShow
@ -319,14 +375,18 @@ void QuartzShow(
{
int i;
if (!quartzServerVisible) {
quartzServerVisible = TRUE;
for (i = 0; i < screenInfo.numScreens; i++) {
if (screenInfo.screens[i]) {
quartzProcs->ResumeScreen(screenInfo.screens[i], x, y);
}
if (quartzServerVisible)
return;
quartzServerVisible = TRUE;
for (i = 0; i < screenInfo.numScreens; i++) {
if (screenInfo.screens[i]) {
quartzProcs->ResumeScreen(screenInfo.screens[i], x, y);
}
}
if (!quartzEnableRootless)
QuartzSetFullscreen(TRUE);
}
@ -347,6 +407,8 @@ void QuartzHide(void)
}
}
}
QuartzSetFullscreen(FALSE);
quartzServerVisible = FALSE;
}

View File

@ -137,4 +137,7 @@ void QuartzShow(int x, int y); // (x, y) = cursor loc
void QuartzHide(void);
void QuartzSetRootClip(BOOL enable);
void QuartzSpaceChanged(uint32_t space_id);
void QuartzSetFullscreen(Bool state);
void QuartzSetRootless(Bool state);
#endif

View File

@ -59,6 +59,7 @@ extern int quartzUseSysBeep;
extern int focusOnNewWindow;
extern int quartzUseAGL;
extern int quartzEnableKeyEquivalents;
extern int quartzFullscreenDisableHotkeys;
// Other shared data
extern int quartzServerVisible;

View File

@ -274,7 +274,8 @@ Bool RootlessResolveColormap (ScreenPtr pScreen, int first_color,
void RootlessFlushWindowColormap (WindowPtr pWin);
void RootlessFlushScreenColormaps (ScreenPtr pScreen);
RootlessColormapCallback(void *data, int first_color, int n_colors, uint32_t *colors);
// xp_error
int RootlessColormapCallback(void *data, int first_color, int n_colors, uint32_t *colors);
// Move a window to its proper location on the screen.
void RootlessRepositionWindow(WindowPtr pWin);
@ -282,4 +283,13 @@ void RootlessRepositionWindow(WindowPtr pWin);
// Move the window to it's correct place in the physical stacking order.
void RootlessReorderWindow(WindowPtr pWin);
void RootlessScreenExpose (ScreenPtr pScreen);
void RootlessHideAllWindows (void);
void RootlessShowAllWindows (void);
void RootlessUpdateRooted (Bool state);
void RootlessEnableRoot (ScreenPtr pScreen);
void RootlessDisableRoot (ScreenPtr pScreen);
#endif /* _ROOTLESSCOMMON_H */

View File

@ -471,6 +471,34 @@ RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst,
return result;
}
expose_1 (WindowPtr pWin)
{
WindowPtr pChild;
if (!pWin->realized)
return;
(*pWin->drawable.pScreen->PaintWindowBackground) (pWin, &pWin->borderClip,
PW_BACKGROUND);
/* FIXME: comments in windowstr.h indicate that borderClip doesn't
include subwindow visibility. But I'm not so sure.. so we may
be exposing too much.. */
miSendExposures (pWin, &pWin->borderClip,
pWin->drawable.x, pWin->drawable.y);
for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib)
expose_1 (pChild);
}
void
RootlessScreenExpose (ScreenPtr pScreen)
{
expose_1 (WindowTable[pScreen->myNum]);
}
ColormapPtr
RootlessGetColormap (ScreenPtr pScreen)
{
@ -739,3 +767,18 @@ Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs)
return TRUE;
}
void RootlessUpdateRooted (Bool state) {
int i;
if (!state)
{
for (i = 0; i < screenInfo.numScreens; i++)
RootlessDisableRoot (screenInfo.screens[i]);
}
else
{
for (i = 0; i < screenInfo.numScreens; i++)
RootlessEnableRoot (screenInfo.screens[i]);
}
}

View File

@ -1680,3 +1680,105 @@ RootlessOrderAllWindows (void)
}
RL_DEBUG_MSG("RootlessOrderAllWindows() done");
}
void
RootlessEnableRoot (ScreenPtr pScreen)
{
WindowPtr pRoot;
pRoot = WindowTable[pScreen->myNum];
RootlessEnsureFrame (pRoot);
(*pScreen->ClearToBackground) (pRoot, 0, 0, 0, 0, TRUE);
RootlessReorderWindow (pRoot);
}
void
RootlessDisableRoot (ScreenPtr pScreen)
{
WindowPtr pRoot;
RootlessWindowRec *winRec;
pRoot = WindowTable[pScreen->myNum];
winRec = WINREC (pRoot);
if (winRec != NULL)
{
RootlessDestroyFrame (pRoot, winRec);
DeleteProperty (pRoot, xa_native_window_id ());
}
}
void
RootlessHideAllWindows (void)
{
int i;
ScreenPtr pScreen;
WindowPtr pWin;
RootlessWindowRec *winRec;
xp_window_changes wc;
if (windows_hidden)
return;
windows_hidden = TRUE;
for (i = 0; i < screenInfo.numScreens; i++)
{
pScreen = screenInfo.screens[i];
pWin = WindowTable[i];
if (pScreen == NULL || pWin == NULL)
continue;
for (pWin = pWin->firstChild; pWin != NULL; pWin = pWin->nextSib)
{
if (!pWin->realized)
continue;
RootlessStopDrawing (pWin, FALSE);
winRec = WINREC (pWin);
if (winRec != NULL)
{
wc.stack_mode = XP_UNMAPPED;
wc.sibling = 0;
configure_window ((xp_window_id)winRec->wid, XP_STACKING, &wc);
}
}
}
}
void
RootlessShowAllWindows (void)
{
int i;
ScreenPtr pScreen;
WindowPtr pWin;
RootlessWindowRec *winRec;
if (!windows_hidden)
return;
windows_hidden = FALSE;
for (i = 0; i < screenInfo.numScreens; i++)
{
pScreen = screenInfo.screens[i];
pWin = WindowTable[i];
if (pScreen == NULL || pWin == NULL)
continue;
for (pWin = pWin->firstChild; pWin != NULL; pWin = pWin->nextSib)
{
if (!pWin->realized)
continue;
winRec = RootlessEnsureFrame (pWin);
if (winRec == NULL)
continue;
RootlessReorderWindow (pWin);
}
RootlessScreenExpose (pScreen);
}
}