diff options
author | marha <marha@users.sourceforge.net> | 2011-03-04 13:54:03 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-03-04 13:54:03 +0000 |
commit | 0a5888393c68f6f7db86206d1f277232db18240b (patch) | |
tree | 9afe740e7b124ea8d2125ef7be0d42760d3b8e6a /xorg-server/hw/xquartz/xpr | |
parent | 56950d7bed70ee82186f44f9333537cdbb33c448 (diff) | |
download | vcxsrv-0a5888393c68f6f7db86206d1f277232db18240b.tar.gz vcxsrv-0a5888393c68f6f7db86206d1f277232db18240b.tar.bz2 vcxsrv-0a5888393c68f6f7db86206d1f277232db18240b.zip |
xserver xkeyboard-config mesa git update 4 Marc 2011
Diffstat (limited to 'xorg-server/hw/xquartz/xpr')
-rw-r--r-- | xorg-server/hw/xquartz/xpr/xprAppleWM.c | 322 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/xpr/xprFrame.c | 1288 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/xpr/xprScreen.c | 934 |
3 files changed, 1291 insertions, 1253 deletions
diff --git a/xorg-server/hw/xquartz/xpr/xprAppleWM.c b/xorg-server/hw/xquartz/xpr/xprAppleWM.c index 59ce6375e..21e6f98fa 100644 --- a/xorg-server/hw/xquartz/xpr/xprAppleWM.c +++ b/xorg-server/hw/xquartz/xpr/xprAppleWM.c @@ -1,160 +1,162 @@ -/*
- * Xplugin rootless implementation functions for AppleWM extension
- *
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- * Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "xpr.h"
-
-#include <X11/extensions/applewmproto.h>
-
-#include "applewmExt.h"
-#include "rootless.h"
-#include "rootlessCommon.h"
-#include <Xplugin.h>
-#include <X11/X.h>
-#include "quartz.h"
-#include "x-hash.h"
-
-static int xprSetWindowLevel(
- WindowPtr pWin,
- int level)
-{
- xp_window_id wid;
- xp_window_changes wc;
- RootlessWindowRec *winRec;
-
- // AppleWMNumWindowLevels is allowed, but is only set by the server
- // for the root window.
- if (level < 0 || level >= AppleWMNumWindowLevels) {
- return BadValue;
- }
-
- wid = x_cvt_vptr_to_uint(RootlessFrameForWindow (pWin, TRUE));
- if (wid == 0)
- return BadWindow;
-
- RootlessStopDrawing (pWin, FALSE);
- winRec = WINREC(pWin);
-
- if(!winRec)
- return BadWindow;
-
- if(XQuartzIsRootless)
- wc.window_level = normal_window_levels[level];
- else
- wc.window_level = rooted_window_levels[level];
-
- if (xp_configure_window (wid, XP_WINDOW_LEVEL, &wc) != Success) {
- return BadValue;
- }
-
- winRec->level = level;
-
- return Success;
-}
-
-#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 3
-static int xprAttachTransient(WindowPtr pWinChild, WindowPtr pWinParent) {
- xp_window_id child_wid, parent_wid;
- xp_window_changes wc;
-
- child_wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWinChild, TRUE));
- if (child_wid == 0)
- return BadWindow;
-
- if(pWinParent) {
- parent_wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWinParent, TRUE));
- if (parent_wid == 0)
- return BadWindow;
- } else {
- parent_wid = 0;
- }
-
- wc.transient_for = parent_wid;
-
- RootlessStopDrawing (pWinChild, FALSE);
-
- if (xp_configure_window(child_wid, XP_ATTACH_TRANSIENT, &wc) != Success) {
- return BadValue;
- }
-
- return Success;
-}
-#endif
-
-static int xprFrameDraw(
- WindowPtr pWin,
- int class,
- unsigned int attr,
- const BoxRec *outer,
- const BoxRec *inner,
- unsigned int title_len,
- const unsigned char *title_bytes)
-{
- xp_window_id wid;
-
- wid = x_cvt_vptr_to_uint(RootlessFrameForWindow (pWin, FALSE));
- if (wid == 0)
- return BadWindow;
-
- if (xp_frame_draw (wid, class, attr, outer, inner,
- title_len, title_bytes) != Success)
- {
- return BadValue;
- }
-
- return Success;
-}
-
-static AppleWMProcsRec xprAppleWMProcs = {
- xp_disable_update,
- xp_reenable_update,
- xprSetWindowLevel,
- xp_frame_get_rect,
- xp_frame_hit_test,
- xprFrameDraw,
-#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 3
- xp_set_dock_proxy,
- xprAttachTransient
-#elif defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 2
- xp_set_dock_proxy,
- NULL
-#else
- NULL,
- NULL
-#endif
-};
-
-
-void xprAppleWMInit(void)
-{
- AppleWMExtensionInit(&xprAppleWMProcs);
-}
+/* + * Xplugin rootless implementation functions for AppleWM extension + * + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "xpr.h" + +#include <X11/extensions/applewmproto.h> + +#include "applewmExt.h" +#include "rootless.h" +#include "rootlessCommon.h" +#include <Xplugin.h> +#include <X11/X.h> +#include "quartz.h" +#include "x-hash.h" + +static int xprSetWindowLevel( + WindowPtr pWin, + int level) +{ + xp_window_id wid; + xp_window_changes wc; + RootlessWindowRec *winRec; + + // AppleWMNumWindowLevels is allowed, but is only set by the server + // for the root window. + if (level < 0 || level >= AppleWMNumWindowLevels) { + return BadValue; + } + + wid = x_cvt_vptr_to_uint(RootlessFrameForWindow (pWin, TRUE)); + if (wid == 0) + return BadWindow; + + RootlessStopDrawing (pWin, FALSE); + winRec = WINREC(pWin); + + if(!winRec) + return BadWindow; + + if(XQuartzIsRootless) + wc.window_level = normal_window_levels[level]; + else if(XQuartzShieldingWindowLevel) + wc.window_level = XQuartzShieldingWindowLevel + 1; + else + wc.window_level = rooted_window_levels[level]; + + if (xp_configure_window (wid, XP_WINDOW_LEVEL, &wc) != Success) { + return BadValue; + } + + winRec->level = level; + + return Success; +} + +#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 3 +static int xprAttachTransient(WindowPtr pWinChild, WindowPtr pWinParent) { + xp_window_id child_wid, parent_wid; + xp_window_changes wc; + + child_wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWinChild, TRUE)); + if (child_wid == 0) + return BadWindow; + + if(pWinParent) { + parent_wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWinParent, TRUE)); + if (parent_wid == 0) + return BadWindow; + } else { + parent_wid = 0; + } + + wc.transient_for = parent_wid; + + RootlessStopDrawing (pWinChild, FALSE); + + if (xp_configure_window(child_wid, XP_ATTACH_TRANSIENT, &wc) != Success) { + return BadValue; + } + + return Success; +} +#endif + +static int xprFrameDraw( + WindowPtr pWin, + int class, + unsigned int attr, + const BoxRec *outer, + const BoxRec *inner, + unsigned int title_len, + const unsigned char *title_bytes) +{ + xp_window_id wid; + + wid = x_cvt_vptr_to_uint(RootlessFrameForWindow (pWin, FALSE)); + if (wid == 0) + return BadWindow; + + if (xp_frame_draw (wid, class, attr, outer, inner, + title_len, title_bytes) != Success) + { + return BadValue; + } + + return Success; +} + +static AppleWMProcsRec xprAppleWMProcs = { + xp_disable_update, + xp_reenable_update, + xprSetWindowLevel, + xp_frame_get_rect, + xp_frame_hit_test, + xprFrameDraw, +#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 3 + xp_set_dock_proxy, + xprAttachTransient +#elif defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 2 + xp_set_dock_proxy, + NULL +#else + NULL, + NULL +#endif +}; + + +void xprAppleWMInit(void) +{ + AppleWMExtensionInit(&xprAppleWMProcs); +} diff --git a/xorg-server/hw/xquartz/xpr/xprFrame.c b/xorg-server/hw/xquartz/xpr/xprFrame.c index fecae5a1b..15598e942 100644 --- a/xorg-server/hw/xquartz/xpr/xprFrame.c +++ b/xorg-server/hw/xquartz/xpr/xprFrame.c @@ -1,642 +1,646 @@ -/*
- * Xplugin rootless implementation frame functions
- *
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- * Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "xpr.h"
-#include "rootlessCommon.h"
-#include <Xplugin.h>
-#include "x-hash.h"
-#include "x-list.h"
-#include "applewmExt.h"
-
-#include "propertyst.h"
-#include "dix.h"
-#include <X11/Xatom.h>
-#include "windowstr.h"
-#include "quartz.h"
-
-#include "threadSafety.h"
-
-#include <pthread.h>
-
-#define DEFINE_ATOM_HELPER(func,atom_name) \
-static Atom func (void) { \
- static int generation; \
- static Atom atom; \
- if (generation != serverGeneration) { \
- generation = serverGeneration; \
- atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \
- } \
- return atom; \
-}
-
-DEFINE_ATOM_HELPER(xa_native_window_id, "_NATIVE_WINDOW_ID")
-
-/* Maps xp_window_id -> RootlessWindowRec */
-static x_hash_table *window_hash;
-static pthread_mutex_t window_hash_mutex;
-
-/* Prototypes for static functions */
-static Bool xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
- int newX, int newY, RegionPtr pShape);
-static void xprDestroyFrame(RootlessFrameID wid);
-static void xprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);
-static void xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen,
- int newX, int newY, unsigned int newW, unsigned int newH,
- unsigned int gravity);
-static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid);
-static void xprReshapeFrame(RootlessFrameID wid, RegionPtr pShape);
-static void xprUnmapFrame(RootlessFrameID wid);
-static void xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow);
-static void xprStopDrawing(RootlessFrameID wid, Bool flush);
-static void xprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage);
-static void xprDamageRects(RootlessFrameID wid, int nrects, const BoxRec *rects,
- int shift_x, int shift_y);
-static void xprSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin);
-static Bool xprDoReorderWindow(RootlessWindowPtr pFrame);
-static void xprHideWindow(RootlessFrameID wid);
-static void xprUpdateColormap(RootlessFrameID wid, ScreenPtr pScreen);
-static void xprCopyWindow(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
- int dx, int dy);
-
-
-static inline xp_error
-xprConfigureWindow(xp_window_id id, unsigned int mask,
- const xp_window_changes *values)
-{
- TA_SERVER();
-
- return xp_configure_window(id, mask, values);
-}
-
-
-static void
-xprSetNativeProperty(RootlessWindowPtr pFrame)
-{
- xp_error err;
- unsigned int native_id;
- long data;
-
- TA_SERVER();
-
- err = xp_get_native_window(x_cvt_vptr_to_uint(pFrame->wid), &native_id);
- if (err == Success)
- {
- /* FIXME: move this to AppleWM extension */
-
- data = native_id;
- dixChangeWindowProperty(serverClient, pFrame->win, xa_native_window_id(),
- XA_INTEGER, 32, PropModeReplace, 1, &data, TRUE);
- }
-}
-
-static xp_error
-xprColormapCallback(void *data, int first_color, int n_colors, uint32_t *colors)
-{
- return (RootlessResolveColormap (data, first_color, n_colors, colors) ? XP_Success : XP_BadMatch);
-}
-
-/*
- * Create and display a new frame.
- */
-static Bool
-xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
- int newX, int newY, RegionPtr pShape)
-{
- WindowPtr pWin = pFrame->win;
- xp_window_changes wc;
- unsigned int mask = 0;
- xp_error err;
-
- TA_SERVER();
-
- wc.x = newX;
- wc.y = newY;
- wc.width = pFrame->width;
- wc.height = pFrame->height;
- wc.bit_gravity = XP_GRAVITY_NONE;
- mask |= XP_BOUNDS;
-
- if (pWin->drawable.depth == 8)
- {
- wc.depth = XP_DEPTH_INDEX8;
- wc.colormap = xprColormapCallback;
- wc.colormap_data = pScreen;
- mask |= XP_COLORMAP;
- }
- else if (pWin->drawable.depth == 15)
- wc.depth = XP_DEPTH_RGB555;
- else if (pWin->drawable.depth == 24)
- wc.depth = XP_DEPTH_ARGB8888;
- else
- wc.depth = XP_DEPTH_NIL;
- mask |= XP_DEPTH;
-
- if (pShape != NULL)
- {
- wc.shape_nrects = RegionNumRects(pShape);
- wc.shape_rects = RegionRects(pShape);
- wc.shape_tx = wc.shape_ty = 0;
- mask |= XP_SHAPE;
- }
-
- pFrame->level = !IsRoot (pWin) ? AppleWMWindowLevelNormal : AppleWMNumWindowLevels;
-
- if(XQuartzIsRootless)
- wc.window_level = normal_window_levels[pFrame->level];
- else
- wc.window_level = rooted_window_levels[pFrame->level];
- mask |= XP_WINDOW_LEVEL;
-
- err = xp_create_window(mask, &wc, (xp_window_id *) &pFrame->wid);
-
- if (err != Success)
- {
- return FALSE;
- }
-
- if (window_hash == NULL)
- {
- window_hash = x_hash_table_new(NULL, NULL, NULL, NULL);
- pthread_mutex_init(&window_hash_mutex, NULL);
- }
-
- pthread_mutex_lock(&window_hash_mutex);
- x_hash_table_insert(window_hash, pFrame->wid, pFrame);
- pthread_mutex_unlock(&window_hash_mutex);
-
- xprSetNativeProperty(pFrame);
-
- return TRUE;
-}
-
-
-/*
- * Destroy a frame.
- */
-static void
-xprDestroyFrame(RootlessFrameID wid)
-{
- xp_error err;
- TA_SERVER();
-
- pthread_mutex_lock(&window_hash_mutex);
- x_hash_table_remove(window_hash, wid);
- pthread_mutex_unlock(&window_hash_mutex);
-
- err = xp_destroy_window(x_cvt_vptr_to_uint(wid));
- if (err != Success)
- FatalError("Could not destroy window %i.", (int)x_cvt_vptr_to_uint(wid));
-}
-
-
-/*
- * Move a frame on screen.
- */
-static void
-xprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY)
-{
- xp_window_changes wc;
-
- TA_SERVER();
-
- wc.x = newX;
- wc.y = newY;
- // ErrorF("xprMoveFrame(%d, %p, %d, %d)\n", wid, pScreen, newX, newY);
- xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_ORIGIN, &wc);
-}
-
-
-/*
- * Resize and move a frame.
- */
-static void
-xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen,
- int newX, int newY, unsigned int newW, unsigned int newH,
- unsigned int gravity)
-{
- xp_window_changes wc;
-
- TA_SERVER();
-
- wc.x = newX;
- wc.y = newY;
- wc.width = newW;
- wc.height = newH;
- wc.bit_gravity = gravity;
-
- /* It's unlikely that being async will save us anything here.
- But it can't hurt. */
-
- xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_BOUNDS, &wc);
-}
-
-
-/*
- * Change frame stacking.
- */
-static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) {
- xp_window_changes wc;
- unsigned int mask = XP_STACKING;
-
- TA_SERVER();
-
- /* Stack frame below nextWid it if it exists, or raise
- frame above everything otherwise. */
-
- if(nextWid == NULL) {
- wc.stack_mode = XP_MAPPED_ABOVE;
- wc.sibling = 0;
- } else {
- wc.stack_mode = XP_MAPPED_BELOW;
- wc.sibling = x_cvt_vptr_to_uint(nextWid);
- }
-
- if(window_hash) {
- RootlessWindowRec *winRec = x_hash_table_lookup(window_hash, wid, NULL);
-
- if(winRec) {
- if(XQuartzIsRootless)
- wc.window_level = normal_window_levels[winRec->level];
- else
- wc.window_level = rooted_window_levels[winRec->level];
- mask |= XP_WINDOW_LEVEL;
- }
- }
-
- xprConfigureWindow(x_cvt_vptr_to_uint(wid), mask, &wc);
-}
-
-
-/*
- * Change the frame's shape.
- */
-static void
-xprReshapeFrame(RootlessFrameID wid, RegionPtr pShape)
-{
- xp_window_changes wc;
-
- TA_SERVER();
-
- if (pShape != NULL)
- {
- wc.shape_nrects = RegionNumRects(pShape);
- wc.shape_rects = RegionRects(pShape);
- }
- else
- {
- wc.shape_nrects = -1;
- wc.shape_rects = NULL;
- }
-
- wc.shape_tx = wc.shape_ty = 0;
-
- xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_SHAPE, &wc);
-}
-
-
-/*
- * Unmap a frame.
- */
-static void
-xprUnmapFrame(RootlessFrameID wid)
-{
- xp_window_changes wc;
-
- TA_SERVER();
-
- wc.stack_mode = XP_UNMAPPED;
- wc.sibling = 0;
-
- xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_STACKING, &wc);
-}
-
-
-/*
- * Start drawing to a frame.
- * Prepare for direct access to its backing buffer.
- */
-static void
-xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
-{
- void *data[2];
- unsigned int rowbytes[2];
- xp_error err;
-
- TA_SERVER();
-
- err = xp_lock_window(x_cvt_vptr_to_uint(wid), NULL, NULL, data, rowbytes, NULL);
- if (err != Success)
- FatalError("Could not lock window %i for drawing.", (int)x_cvt_vptr_to_uint(wid));
-
- *pixelData = data[0];
- *bytesPerRow = rowbytes[0];
-}
-
-
-/*
- * Stop drawing to a frame.
- */
-static void
-xprStopDrawing(RootlessFrameID wid, Bool flush)
-{
- xp_error err;
- TA_SERVER();
-
- err = xp_unlock_window(x_cvt_vptr_to_uint(wid), flush);
- if(err != Success)
- FatalError("Could not unlock window %i after drawing.", (int)x_cvt_vptr_to_uint(wid));
-}
-
-
-/*
- * Flush drawing updates to the screen.
- */
-static void
-xprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage)
-{
- TA_SERVER();
-
- xp_flush_window(x_cvt_vptr_to_uint(wid));
-}
-
-
-/*
- * Mark damaged rectangles as requiring redisplay to screen.
- */
-static void
-xprDamageRects(RootlessFrameID wid, int nrects, const BoxRec *rects,
- int shift_x, int shift_y)
-{
- TA_SERVER();
-
- xp_mark_window(x_cvt_vptr_to_uint(wid), nrects, rects, shift_x, shift_y);
-}
-
-
-/*
- * Called after the window associated with a frame has been switched
- * to a new top-level parent.
- */
-static void
-xprSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin)
-{
- DeleteProperty(serverClient, oldWin, xa_native_window_id());
-
- TA_SERVER();
-
- xprSetNativeProperty(pFrame);
-}
-
-
-/*
- * Called to check if the frame should be reordered when it is restacked.
- */
-static Bool xprDoReorderWindow(RootlessWindowPtr pFrame)
-{
- WindowPtr pWin = pFrame->win;
-
- TA_SERVER();
-
- return AppleWMDoReorderWindow(pWin);
-}
-
-
-/*
- * Copy area in frame to another part of frame.
- * Used to accelerate scrolling.
- */
-static void
-xprCopyWindow(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
- int dx, int dy)
-{
- TA_SERVER();
-
- xp_copy_window(x_cvt_vptr_to_uint(wid), x_cvt_vptr_to_uint(wid),
- dstNrects, dstRects, dx, dy);
-}
-
-
-static RootlessFrameProcsRec xprRootlessProcs = {
- xprCreateFrame,
- xprDestroyFrame,
- xprMoveFrame,
- xprResizeFrame,
- xprRestackFrame,
- xprReshapeFrame,
- xprUnmapFrame,
- xprStartDrawing,
- xprStopDrawing,
- xprUpdateRegion,
- xprDamageRects,
- xprSwitchWindow,
- xprDoReorderWindow,
- xprHideWindow,
- xprUpdateColormap,
- xp_copy_bytes,
- xprCopyWindow
-};
-
-
-/*
- * Initialize XPR implementation
- */
-Bool
-xprInit(ScreenPtr pScreen)
-{
- RootlessInit(pScreen, &xprRootlessProcs);
-
- TA_SERVER();
-
- rootless_CopyBytes_threshold = xp_copy_bytes_threshold;
- rootless_CopyWindow_threshold = xp_scroll_area_threshold;
-
- return TRUE;
-}
-
-
-/*
- * Given the id of a physical window, try to find the top-level (or root)
- * X window that it represents.
- */
-WindowPtr
-xprGetXWindow(xp_window_id wid)
-{
- RootlessWindowRec *winRec;
-
- if (window_hash == NULL)
- return NULL;
-
- winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL);
-
- return winRec != NULL ? winRec->win : NULL;
-}
-
-#ifdef UNUSED_CODE
-/*
- * Given the id of a physical window, try to find the top-level (or root)
- * X window that it represents.
- */
-WindowPtr
-xprGetXWindowFromAppKit(int windowNumber)
-{
- RootlessWindowRec *winRec;
- Bool ret;
- xp_window_id wid;
-
- if (window_hash == NULL)
- return FALSE;
-
- /* need to lock, since this function can be called by any thread */
-
- pthread_mutex_lock(&window_hash_mutex);
-
- if (xp_lookup_native_window(windowNumber, &wid))
- ret = xprGetXWindow(wid) != NULL;
- else
- ret = FALSE;
-
- pthread_mutex_unlock(&window_hash_mutex);
-
- if (!ret) return NULL;
- winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL);
-
- return winRec != NULL ? winRec->win : NULL;
-}
-#endif
-
-/*
- * The windowNumber is an AppKit window number. Returns TRUE if xpr is
- * displaying a window with that number.
- */
-Bool
-xprIsX11Window(void *nsWindow, int windowNumber)
-{
- Bool ret;
- xp_window_id wid;
-
- if (window_hash == NULL)
- return FALSE;
-
- /* need to lock, since this function can be called by any thread */
-
- pthread_mutex_lock(&window_hash_mutex);
-
- if (xp_lookup_native_window(windowNumber, &wid))
- ret = xprGetXWindow(wid) != NULL;
- else
- ret = FALSE;
-
- pthread_mutex_unlock(&window_hash_mutex);
-
- return ret;
-}
-
-
-/*
- * xprHideWindows
- * Hide or unhide all top level windows. This is called for application hide/
- * unhide events if the window manager is not Apple-WM aware. Xplugin windows
- * do not hide or unhide themselves.
- */
-void
-xprHideWindows(Bool hide)
-{
- int screen;
- WindowPtr pRoot, pWin;
-
- TA_SERVER();
-
- for (screen = 0; screen < screenInfo.numScreens; screen++) {
- RootlessFrameID prevWid = NULL;
- pRoot = screenInfo.screens[screen]->root;
-
- for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) {
- RootlessWindowRec *winRec = WINREC(pWin);
-
- if (winRec != NULL) {
- if (hide) {
- xprUnmapFrame(winRec->wid);
- } else {
- BoxRec box;
-
- xprRestackFrame(winRec->wid, prevWid);
- prevWid = winRec->wid;
-
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = winRec->width;
- box.y2 = winRec->height;
-
- xprDamageRects(winRec->wid, 1, &box, 0, 0);
- RootlessQueueRedisplay(screenInfo.screens[screen]);
- }
- }
- }
- }
-}
-
-// XXX: identical to x_cvt_vptr_to_uint ?
-#define MAKE_WINDOW_ID(x) ((xp_window_id)((size_t)(x)))
-
-Bool no_configure_window;
-
-static inline int
-configure_window (xp_window_id id, unsigned int mask,
- const xp_window_changes *values)
-{
- if (!no_configure_window)
- return xp_configure_window (id, mask, values);
- else
- return XP_Success;
-}
-
-
-static
-void xprUpdateColormap(RootlessFrameID wid, ScreenPtr pScreen)
-{
- /* This is how we tell xp that the colormap may have changed. */
- xp_window_changes wc;
- wc.colormap = xprColormapCallback;
- wc.colormap_data = pScreen;
-
- configure_window(MAKE_WINDOW_ID(wid), XP_COLORMAP, &wc);
-}
-
-static
-void xprHideWindow(RootlessFrameID wid)
-{
- xp_window_changes wc;
- wc.stack_mode = XP_UNMAPPED;
- wc.sibling = 0;
- configure_window(MAKE_WINDOW_ID(wid), XP_STACKING, &wc);
-}
+/* + * Xplugin rootless implementation frame functions + * + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "xpr.h" +#include "rootlessCommon.h" +#include <Xplugin.h> +#include "x-hash.h" +#include "x-list.h" +#include "applewmExt.h" + +#include "propertyst.h" +#include "dix.h" +#include <X11/Xatom.h> +#include "windowstr.h" +#include "quartz.h" + +#include "threadSafety.h" + +#include <pthread.h> + +#define DEFINE_ATOM_HELPER(func,atom_name) \ +static Atom func (void) { \ + static int generation; \ + static Atom atom; \ + if (generation != serverGeneration) { \ + generation = serverGeneration; \ + atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \ + } \ + return atom; \ +} + +DEFINE_ATOM_HELPER(xa_native_window_id, "_NATIVE_WINDOW_ID") + +/* Maps xp_window_id -> RootlessWindowRec */ +static x_hash_table *window_hash; +static pthread_mutex_t window_hash_mutex; + +/* Prototypes for static functions */ +static Bool xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen, + int newX, int newY, RegionPtr pShape); +static void xprDestroyFrame(RootlessFrameID wid); +static void xprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY); +static void xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen, + int newX, int newY, unsigned int newW, unsigned int newH, + unsigned int gravity); +static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid); +static void xprReshapeFrame(RootlessFrameID wid, RegionPtr pShape); +static void xprUnmapFrame(RootlessFrameID wid); +static void xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow); +static void xprStopDrawing(RootlessFrameID wid, Bool flush); +static void xprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage); +static void xprDamageRects(RootlessFrameID wid, int nrects, const BoxRec *rects, + int shift_x, int shift_y); +static void xprSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin); +static Bool xprDoReorderWindow(RootlessWindowPtr pFrame); +static void xprHideWindow(RootlessFrameID wid); +static void xprUpdateColormap(RootlessFrameID wid, ScreenPtr pScreen); +static void xprCopyWindow(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, + int dx, int dy); + + +static inline xp_error +xprConfigureWindow(xp_window_id id, unsigned int mask, + const xp_window_changes *values) +{ + TA_SERVER(); + + return xp_configure_window(id, mask, values); +} + + +static void +xprSetNativeProperty(RootlessWindowPtr pFrame) +{ + xp_error err; + unsigned int native_id; + long data; + + TA_SERVER(); + + err = xp_get_native_window(x_cvt_vptr_to_uint(pFrame->wid), &native_id); + if (err == Success) + { + /* FIXME: move this to AppleWM extension */ + + data = native_id; + dixChangeWindowProperty(serverClient, pFrame->win, xa_native_window_id(), + XA_INTEGER, 32, PropModeReplace, 1, &data, TRUE); + } +} + +static xp_error +xprColormapCallback(void *data, int first_color, int n_colors, uint32_t *colors) +{ + return (RootlessResolveColormap (data, first_color, n_colors, colors) ? XP_Success : XP_BadMatch); +} + +/* + * Create and display a new frame. + */ +static Bool +xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen, + int newX, int newY, RegionPtr pShape) +{ + WindowPtr pWin = pFrame->win; + xp_window_changes wc; + unsigned int mask = 0; + xp_error err; + + TA_SERVER(); + + wc.x = newX; + wc.y = newY; + wc.width = pFrame->width; + wc.height = pFrame->height; + wc.bit_gravity = XP_GRAVITY_NONE; + mask |= XP_BOUNDS; + + if (pWin->drawable.depth == 8) + { + wc.depth = XP_DEPTH_INDEX8; + wc.colormap = xprColormapCallback; + wc.colormap_data = pScreen; + mask |= XP_COLORMAP; + } + else if (pWin->drawable.depth == 15) + wc.depth = XP_DEPTH_RGB555; + else if (pWin->drawable.depth == 24) + wc.depth = XP_DEPTH_ARGB8888; + else + wc.depth = XP_DEPTH_NIL; + mask |= XP_DEPTH; + + if (pShape != NULL) + { + wc.shape_nrects = RegionNumRects(pShape); + wc.shape_rects = RegionRects(pShape); + wc.shape_tx = wc.shape_ty = 0; + mask |= XP_SHAPE; + } + + pFrame->level = !IsRoot (pWin) ? AppleWMWindowLevelNormal : AppleWMNumWindowLevels; + + if(XQuartzIsRootless) + wc.window_level = normal_window_levels[pFrame->level]; + else if(XQuartzShieldingWindowLevel) + wc.window_level = XQuartzShieldingWindowLevel + 1; + else + wc.window_level = rooted_window_levels[pFrame->level]; + mask |= XP_WINDOW_LEVEL; + + err = xp_create_window(mask, &wc, (xp_window_id *) &pFrame->wid); + + if (err != Success) + { + return FALSE; + } + + if (window_hash == NULL) + { + window_hash = x_hash_table_new(NULL, NULL, NULL, NULL); + pthread_mutex_init(&window_hash_mutex, NULL); + } + + pthread_mutex_lock(&window_hash_mutex); + x_hash_table_insert(window_hash, pFrame->wid, pFrame); + pthread_mutex_unlock(&window_hash_mutex); + + xprSetNativeProperty(pFrame); + + return TRUE; +} + + +/* + * Destroy a frame. + */ +static void +xprDestroyFrame(RootlessFrameID wid) +{ + xp_error err; + TA_SERVER(); + + pthread_mutex_lock(&window_hash_mutex); + x_hash_table_remove(window_hash, wid); + pthread_mutex_unlock(&window_hash_mutex); + + err = xp_destroy_window(x_cvt_vptr_to_uint(wid)); + if (err != Success) + FatalError("Could not destroy window %i.", (int)x_cvt_vptr_to_uint(wid)); +} + + +/* + * Move a frame on screen. + */ +static void +xprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY) +{ + xp_window_changes wc; + + TA_SERVER(); + + wc.x = newX; + wc.y = newY; + // ErrorF("xprMoveFrame(%d, %p, %d, %d)\n", wid, pScreen, newX, newY); + xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_ORIGIN, &wc); +} + + +/* + * Resize and move a frame. + */ +static void +xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen, + int newX, int newY, unsigned int newW, unsigned int newH, + unsigned int gravity) +{ + xp_window_changes wc; + + TA_SERVER(); + + wc.x = newX; + wc.y = newY; + wc.width = newW; + wc.height = newH; + wc.bit_gravity = gravity; + + /* It's unlikely that being async will save us anything here. + But it can't hurt. */ + + xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_BOUNDS, &wc); +} + + +/* + * Change frame stacking. + */ +static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) { + xp_window_changes wc; + unsigned int mask = XP_STACKING; + + TA_SERVER(); + + /* Stack frame below nextWid it if it exists, or raise + frame above everything otherwise. */ + + if(nextWid == NULL) { + wc.stack_mode = XP_MAPPED_ABOVE; + wc.sibling = 0; + } else { + wc.stack_mode = XP_MAPPED_BELOW; + wc.sibling = x_cvt_vptr_to_uint(nextWid); + } + + if(window_hash) { + RootlessWindowRec *winRec = x_hash_table_lookup(window_hash, wid, NULL); + + if(winRec) { + if(XQuartzIsRootless) + wc.window_level = normal_window_levels[winRec->level]; + else if(XQuartzShieldingWindowLevel) + wc.window_level = XQuartzShieldingWindowLevel + 1; + else + wc.window_level = rooted_window_levels[winRec->level]; + mask |= XP_WINDOW_LEVEL; + } + } + + xprConfigureWindow(x_cvt_vptr_to_uint(wid), mask, &wc); +} + + +/* + * Change the frame's shape. + */ +static void +xprReshapeFrame(RootlessFrameID wid, RegionPtr pShape) +{ + xp_window_changes wc; + + TA_SERVER(); + + if (pShape != NULL) + { + wc.shape_nrects = RegionNumRects(pShape); + wc.shape_rects = RegionRects(pShape); + } + else + { + wc.shape_nrects = -1; + wc.shape_rects = NULL; + } + + wc.shape_tx = wc.shape_ty = 0; + + xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_SHAPE, &wc); +} + + +/* + * Unmap a frame. + */ +static void +xprUnmapFrame(RootlessFrameID wid) +{ + xp_window_changes wc; + + TA_SERVER(); + + wc.stack_mode = XP_UNMAPPED; + wc.sibling = 0; + + xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_STACKING, &wc); +} + + +/* + * Start drawing to a frame. + * Prepare for direct access to its backing buffer. + */ +static void +xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow) +{ + void *data[2]; + unsigned int rowbytes[2]; + xp_error err; + + TA_SERVER(); + + err = xp_lock_window(x_cvt_vptr_to_uint(wid), NULL, NULL, data, rowbytes, NULL); + if (err != Success) + FatalError("Could not lock window %i for drawing.", (int)x_cvt_vptr_to_uint(wid)); + + *pixelData = data[0]; + *bytesPerRow = rowbytes[0]; +} + + +/* + * Stop drawing to a frame. + */ +static void +xprStopDrawing(RootlessFrameID wid, Bool flush) +{ + xp_error err; + TA_SERVER(); + + err = xp_unlock_window(x_cvt_vptr_to_uint(wid), flush); + if(err != Success) + FatalError("Could not unlock window %i after drawing.", (int)x_cvt_vptr_to_uint(wid)); +} + + +/* + * Flush drawing updates to the screen. + */ +static void +xprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage) +{ + TA_SERVER(); + + xp_flush_window(x_cvt_vptr_to_uint(wid)); +} + + +/* + * Mark damaged rectangles as requiring redisplay to screen. + */ +static void +xprDamageRects(RootlessFrameID wid, int nrects, const BoxRec *rects, + int shift_x, int shift_y) +{ + TA_SERVER(); + + xp_mark_window(x_cvt_vptr_to_uint(wid), nrects, rects, shift_x, shift_y); +} + + +/* + * Called after the window associated with a frame has been switched + * to a new top-level parent. + */ +static void +xprSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin) +{ + DeleteProperty(serverClient, oldWin, xa_native_window_id()); + + TA_SERVER(); + + xprSetNativeProperty(pFrame); +} + + +/* + * Called to check if the frame should be reordered when it is restacked. + */ +static Bool xprDoReorderWindow(RootlessWindowPtr pFrame) +{ + WindowPtr pWin = pFrame->win; + + TA_SERVER(); + + return AppleWMDoReorderWindow(pWin); +} + + +/* + * Copy area in frame to another part of frame. + * Used to accelerate scrolling. + */ +static void +xprCopyWindow(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, + int dx, int dy) +{ + TA_SERVER(); + + xp_copy_window(x_cvt_vptr_to_uint(wid), x_cvt_vptr_to_uint(wid), + dstNrects, dstRects, dx, dy); +} + + +static RootlessFrameProcsRec xprRootlessProcs = { + xprCreateFrame, + xprDestroyFrame, + xprMoveFrame, + xprResizeFrame, + xprRestackFrame, + xprReshapeFrame, + xprUnmapFrame, + xprStartDrawing, + xprStopDrawing, + xprUpdateRegion, + xprDamageRects, + xprSwitchWindow, + xprDoReorderWindow, + xprHideWindow, + xprUpdateColormap, + xp_copy_bytes, + xprCopyWindow +}; + + +/* + * Initialize XPR implementation + */ +Bool +xprInit(ScreenPtr pScreen) +{ + RootlessInit(pScreen, &xprRootlessProcs); + + TA_SERVER(); + + rootless_CopyBytes_threshold = xp_copy_bytes_threshold; + rootless_CopyWindow_threshold = xp_scroll_area_threshold; + + return TRUE; +} + + +/* + * Given the id of a physical window, try to find the top-level (or root) + * X window that it represents. + */ +WindowPtr +xprGetXWindow(xp_window_id wid) +{ + RootlessWindowRec *winRec; + + if (window_hash == NULL) + return NULL; + + winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL); + + return winRec != NULL ? winRec->win : NULL; +} + +#ifdef UNUSED_CODE +/* + * Given the id of a physical window, try to find the top-level (or root) + * X window that it represents. + */ +WindowPtr +xprGetXWindowFromAppKit(int windowNumber) +{ + RootlessWindowRec *winRec; + Bool ret; + xp_window_id wid; + + if (window_hash == NULL) + return FALSE; + + /* need to lock, since this function can be called by any thread */ + + pthread_mutex_lock(&window_hash_mutex); + + if (xp_lookup_native_window(windowNumber, &wid)) + ret = xprGetXWindow(wid) != NULL; + else + ret = FALSE; + + pthread_mutex_unlock(&window_hash_mutex); + + if (!ret) return NULL; + winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL); + + return winRec != NULL ? winRec->win : NULL; +} +#endif + +/* + * The windowNumber is an AppKit window number. Returns TRUE if xpr is + * displaying a window with that number. + */ +Bool +xprIsX11Window(void *nsWindow, int windowNumber) +{ + Bool ret; + xp_window_id wid; + + if (window_hash == NULL) + return FALSE; + + /* need to lock, since this function can be called by any thread */ + + pthread_mutex_lock(&window_hash_mutex); + + if (xp_lookup_native_window(windowNumber, &wid)) + ret = xprGetXWindow(wid) != NULL; + else + ret = FALSE; + + pthread_mutex_unlock(&window_hash_mutex); + + return ret; +} + + +/* + * xprHideWindows + * Hide or unhide all top level windows. This is called for application hide/ + * unhide events if the window manager is not Apple-WM aware. Xplugin windows + * do not hide or unhide themselves. + */ +void +xprHideWindows(Bool hide) +{ + int screen; + WindowPtr pRoot, pWin; + + TA_SERVER(); + + for (screen = 0; screen < screenInfo.numScreens; screen++) { + RootlessFrameID prevWid = NULL; + pRoot = screenInfo.screens[screen]->root; + + for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) { + RootlessWindowRec *winRec = WINREC(pWin); + + if (winRec != NULL) { + if (hide) { + xprUnmapFrame(winRec->wid); + } else { + BoxRec box; + + xprRestackFrame(winRec->wid, prevWid); + prevWid = winRec->wid; + + box.x1 = 0; + box.y1 = 0; + box.x2 = winRec->width; + box.y2 = winRec->height; + + xprDamageRects(winRec->wid, 1, &box, 0, 0); + RootlessQueueRedisplay(screenInfo.screens[screen]); + } + } + } + } +} + +// XXX: identical to x_cvt_vptr_to_uint ? +#define MAKE_WINDOW_ID(x) ((xp_window_id)((size_t)(x))) + +Bool no_configure_window; + +static inline int +configure_window (xp_window_id id, unsigned int mask, + const xp_window_changes *values) +{ + if (!no_configure_window) + return xp_configure_window (id, mask, values); + else + return XP_Success; +} + + +static +void xprUpdateColormap(RootlessFrameID wid, ScreenPtr pScreen) +{ + /* This is how we tell xp that the colormap may have changed. */ + xp_window_changes wc; + wc.colormap = xprColormapCallback; + wc.colormap_data = pScreen; + + configure_window(MAKE_WINDOW_ID(wid), XP_COLORMAP, &wc); +} + +static +void xprHideWindow(RootlessFrameID wid) +{ + xp_window_changes wc; + wc.stack_mode = XP_UNMAPPED; + wc.sibling = 0; + configure_window(MAKE_WINDOW_ID(wid), XP_STACKING, &wc); +} diff --git a/xorg-server/hw/xquartz/xpr/xprScreen.c b/xorg-server/hw/xquartz/xpr/xprScreen.c index bd877d97c..972278b75 100644 --- a/xorg-server/hw/xquartz/xpr/xprScreen.c +++ b/xorg-server/hw/xquartz/xpr/xprScreen.c @@ -1,451 +1,483 @@ -/*
- * Xplugin rootless implementation screen functions
- *
- * Copyright (c) 2002 Apple Computer, Inc. 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"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#include "sanitizedCarbon.h"
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "quartzCommon.h"
-#include "inputstr.h"
-#include "quartz.h"
-#include "quartzRandR.h"
-#include "xpr.h"
-#include "xprEvent.h"
-#include "pseudoramiX.h"
-#include "darwin.h"
-#include "darwinEvents.h"
-#include "rootless.h"
-#include "dri.h"
-#include "globals.h"
-#include <Xplugin.h>
-#include "applewmExt.h"
-#include "micmap.h"
-
-#include "rootlessCommon.h"
-
-#ifdef DAMAGE
-# include "damage.h"
-#endif
-
-/* 10.4's deferred update makes X slower.. have to live with the tearing
- for now.. */
-#define XP_NO_DEFERRED_UPDATES 8
-
-// Name of GLX bundle for native OpenGL
-static const char *xprOpenGLBundle = "glxCGL.bundle";
-
-/*
- * eventHandler
- * Callback handler for Xplugin events.
- */
-static void eventHandler(unsigned int type, const void *arg,
- unsigned int arg_size, void *data) {
-
- switch (type) {
- case XP_EVENT_DISPLAY_CHANGED:
- DEBUG_LOG("XP_EVENT_DISPLAY_CHANGED\n");
- DarwinSendDDXEvent(kXquartzDisplayChanged, 0);
- break;
-
- case XP_EVENT_WINDOW_STATE_CHANGED:
- if (arg_size >= sizeof(xp_window_state_event)) {
- const xp_window_state_event *ws_arg = arg;
-
- DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: id=%d, state=%d\n", ws_arg->id, ws_arg->state);
- DarwinSendDDXEvent(kXquartzWindowState, 2,
- ws_arg->id, ws_arg->state);
- } else {
- DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: ignored\n");
- }
- break;
-
- case XP_EVENT_WINDOW_MOVED:
- DEBUG_LOG("XP_EVENT_WINDOW_MOVED\n");
- if (arg_size == sizeof(xp_window_id)) {
- xp_window_id id = * (xp_window_id *) arg;
- DarwinSendDDXEvent(kXquartzWindowMoved, 1, id);
- }
- break;
-
- case XP_EVENT_SURFACE_DESTROYED:
- DEBUG_LOG("XP_EVENT_SURFACE_DESTROYED\n");
- case XP_EVENT_SURFACE_CHANGED:
- DEBUG_LOG("XP_EVENT_SURFACE_CHANGED\n");
- 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;
-#ifdef XP_EVENT_SPACE_CHANGED
- case XP_EVENT_SPACE_CHANGED:
- DEBUG_LOG("XP_EVENT_SPACE_CHANGED\n");
- if(arg_size == sizeof(uint32_t)) {
- uint32_t space_id = *(uint32_t *)arg;
- DarwinSendDDXEvent(kXquartzSpaceChanged, 1, space_id);
- }
- break;
-#endif
- default:
- ErrorF("Unknown XP_EVENT type (%d) in xprScreen:eventHandler\n", type);
- }
-}
-
-/*
- * displayAtIndex
- * Return the display ID for a particular display index.
- */
-static CGDirectDisplayID
-displayAtIndex(int index)
-{
- CGError err;
- CGDisplayCount cnt;
- CGDirectDisplayID dpy[index+1];
-
- err = CGGetActiveDisplayList(index + 1, dpy, &cnt);
- if (err == kCGErrorSuccess && cnt == index + 1)
- return dpy[index];
- else
- return kCGNullDirectDisplay;
-}
-
-/*
- * displayScreenBounds
- * Return the bounds of a particular display.
- */
-static CGRect
-displayScreenBounds(CGDirectDisplayID id)
-{
- CGRect frame;
-
- frame = CGDisplayBounds(id);
-
- DEBUG_LOG(" %dx%d @ (%d,%d).\n",
- (int)frame.size.width, (int)frame.size.height,
- (int)frame.origin.x, (int)frame.origin.y);
-
- /* Remove menubar to help standard X11 window managers. */
- if (XQuartzIsRootless &&
- frame.origin.x == 0 && frame.origin.y == 0) {
- frame.origin.y += aquaMenuBarHeight;
- frame.size.height -= aquaMenuBarHeight;
- }
-
- DEBUG_LOG(" %dx%d @ (%d,%d).\n",
- (int)frame.size.width, (int)frame.size.height,
- (int)frame.origin.x, (int)frame.origin.y);
-
- return frame;
-}
-
-/*
- * xprAddPseudoramiXScreens
- * Add a single virtual screen encompassing all the physical screens
- * with PseudoramiX.
- */
-static void
-xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height, ScreenPtr pScreen)
-{
- CGDisplayCount i, displayCount;
- CGDirectDisplayID *displayList = NULL;
- CGRect unionRect = CGRectNull, frame;
-
- // Find all the CoreGraphics displays
- CGGetActiveDisplayList(0, NULL, &displayCount);
- DEBUG_LOG("displayCount: %d\n", (int)displayCount);
-
- if(!displayCount) {
- ErrorF("CoreGraphics has reported no connected displays. Creating a stub 800x600 display.\n");
- *x = *y = 0;
- *width = 800;
- *height = 600;
- PseudoramiXAddScreen(*x, *y, *width, *height);
- return;
- }
-
- displayList = malloc(displayCount * sizeof(CGDirectDisplayID));
- if(!displayList)
- FatalError("Unable to allocate memory for list of displays.\n");
- CGGetActiveDisplayList(displayCount, displayList, &displayCount);
- QuartzCopyDisplayIDs(pScreen, displayCount, displayList);
-
- /* Get the union of all screens */
- for (i = 0; i < displayCount; i++) {
- CGDirectDisplayID dpy = displayList[i];
- frame = displayScreenBounds(dpy);
- unionRect = CGRectUnion(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;
-
- DEBUG_LOG(" screen union origin: (%d,%d) size: (%d,%d).\n",
- *x, *y, *width, *height);
-
- /* Tell PseudoramiX about the real screens. */
- for (i = 0; i < displayCount; i++)
- {
- CGDirectDisplayID dpy = displayList[i];
-
- frame = displayScreenBounds(dpy);
- frame.origin.x -= unionRect.origin.x;
- frame.origin.y -= unionRect.origin.y;
-
- DEBUG_LOG(" placed at X11 coordinate (%d,%d).\n",
- (int)frame.origin.x, (int)frame.origin.y);
-
- PseudoramiXAddScreen(frame.origin.x, frame.origin.y,
- frame.size.width, frame.size.height);
- }
-
- free(displayList);
-}
-
-/*
- * xprDisplayInit
- * Find number of CoreGraphics displays and initialize Xplugin.
- */
-static void
-xprDisplayInit(void)
-{
- CGDisplayCount displayCount;
-
- DEBUG_LOG("");
-
- CGGetActiveDisplayList(0, NULL, &displayCount);
-
- /* With PseudoramiX, the X server only sees one screen; only PseudoramiX
- itself knows about all of the screens. */
-
- if (noPseudoramiXExtension)
- darwinScreensFound = displayCount;
- else
- darwinScreensFound = 1;
-
- if (xp_init(XP_BACKGROUND_EVENTS | XP_NO_DEFERRED_UPDATES) != Success)
- FatalError("Could not initialize the Xplugin library.");
-
- xp_select_events(XP_EVENT_DISPLAY_CHANGED
- | XP_EVENT_WINDOW_STATE_CHANGED
- | XP_EVENT_WINDOW_MOVED
-#ifdef XP_EVENT_SPACE_CHANGED
- | XP_EVENT_SPACE_CHANGED
-#endif
- | XP_EVENT_SURFACE_CHANGED
- | XP_EVENT_SURFACE_DESTROYED,
- eventHandler, NULL);
-
- AppleDRIExtensionInit();
- xprAppleWMInit();
-
- XQuartzIsRootless = XQuartzRootlessDefault;
- if (!XQuartzIsRootless)
- RootlessHideAllWindows();
-}
-
-/*
- * xprAddScreen
- * Init the framebuffer and record pixmap parameters for the screen.
- */
-static Bool
-xprAddScreen(int index, ScreenPtr pScreen)
-{
- DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
- int depth = darwinDesiredDepth;
-
- DEBUG_LOG("index=%d depth=%d\n", index, depth);
-
- if(depth == -1) {
- depth = CGDisplaySamplesPerPixel(kCGDirectMainDisplay) * CGDisplayBitsPerSample(kCGDirectMainDisplay);
- }
-
- switch(depth) {
- case 8: // pseudo-working
- dfb->visuals = PseudoColorMask;
- dfb->preferredCVC = PseudoColor;
- dfb->depth = 8;
- dfb->bitsPerRGB = 8;
- dfb->bitsPerPixel = 8;
- dfb->redMask = 0;
- dfb->greenMask = 0;
- dfb->blueMask = 0;
- break;
- case 15:
- dfb->visuals = TrueColorMask; //LARGE_VISUALS;
- dfb->preferredCVC = TrueColor;
- dfb->depth = 15;
- dfb->bitsPerRGB = 5;
- dfb->bitsPerPixel = 16;
- dfb->redMask = RM_ARGB(0,5,5,5);
- dfb->greenMask = GM_ARGB(0,5,5,5);
- dfb->blueMask = BM_ARGB(0,5,5,5);
- break;
-// case 24:
- default:
- if(depth != 24)
- ErrorF("Unsupported color depth requested. Defaulting to 24bit. (depth=%d darwinDesiredDepth=%d CGDisplaySamplesPerPixel=%d CGDisplayBitsPerSample=%d)\n", darwinDesiredDepth, depth, (int)CGDisplaySamplesPerPixel(kCGDirectMainDisplay), (int)CGDisplayBitsPerSample(kCGDirectMainDisplay));
- dfb->visuals = TrueColorMask; //LARGE_VISUALS;
- dfb->preferredCVC = TrueColor;
- dfb->depth = 24;
- dfb->bitsPerRGB = 8;
- dfb->bitsPerPixel = 32;
- dfb->redMask = RM_ARGB(0,8,8,8);
- dfb->greenMask = GM_ARGB(0,8,8,8);
- dfb->blueMask = BM_ARGB(0,8,8,8);
- break;
- }
-
- if (noPseudoramiXExtension)
- {
- CGDirectDisplayID dpy;
- CGRect frame;
-
- ErrorF("Warning: noPseudoramiXExtension!\n");
-
- dpy = displayAtIndex(index);
- QuartzCopyDisplayIDs(pScreen, 1, &dpy);
-
- frame = displayScreenBounds(dpy);
-
- dfb->x = frame.origin.x;
- dfb->y = frame.origin.y;
- dfb->width = frame.size.width;
- dfb->height = frame.size.height;
- }
- else
- {
- xprAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height, pScreen);
- }
-
- /* 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;
-
- DRIScreenInit(pScreen);
-
- return TRUE;
-}
-
-/*
- * xprSetupScreen
- * Setup the screen for rootless access.
- */
-static Bool
-xprSetupScreen(int index, ScreenPtr pScreen)
-{
-#ifdef DAMAGE
- // The Damage extension needs to wrap underneath the
- // generic rootless layer, so do it now.
- if (!DamageSetup(pScreen))
- return FALSE;
-#endif
-
- // Initialize generic rootless code
- if (!xprInit(pScreen))
- return FALSE;
-
- return DRIFinishScreenInit(pScreen);
-}
-
-/*
- * xprUpdateScreen
- * Update screen after configuation change.
- */
-static void
-xprUpdateScreen(ScreenPtr pScreen)
-{
- rootlessGlobalOffsetX = darwinMainScreenX;
- rootlessGlobalOffsetY = darwinMainScreenY;
-
- AppleWMSetScreenOrigin(pScreen->root);
-
- RootlessRepositionWindows(pScreen);
- RootlessUpdateScreenPixmap(pScreen);
-}
-
-/*
- * xprInitInput
- * Finalize xpr specific setup.
- */
-static void
-xprInitInput(int argc, char **argv)
-{
- int i;
-
- rootlessGlobalOffsetX = darwinMainScreenX;
- rootlessGlobalOffsetY = darwinMainScreenY;
-
- for (i = 0; i < screenInfo.numScreens; i++)
- AppleWMSetScreenOrigin(screenInfo.screens[i]->root);
-}
-
-/*
- * Quartz display mode function list.
- */
-static QuartzModeProcsRec xprModeProcs = {
- xprDisplayInit,
- xprAddScreen,
- xprSetupScreen,
- xprInitInput,
- QuartzInitCursor,
- QuartzSuspendXCursor,
- QuartzResumeXCursor,
- xprAddPseudoramiXScreens,
- xprUpdateScreen,
- xprIsX11Window,
- xprHideWindows,
- RootlessFrameForWindow,
- TopLevelParent,
- DRICreateSurface,
- DRIDestroySurface
-};
-
-/*
- * QuartzModeBundleInit
- * Initialize the display mode bundle after loading.
- */
-Bool
-QuartzModeBundleInit(void)
-{
- quartzProcs = &xprModeProcs;
- quartzOpenGLBundle = xprOpenGLBundle;
- return TRUE;
-}
+/* + * Xplugin rootless implementation screen functions + * + * Copyright (c) 2002 Apple Computer, Inc. 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"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ + +#include "sanitizedCarbon.h" + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "quartzCommon.h" +#include "inputstr.h" +#include "quartz.h" +#include "quartzRandR.h" +#include "xpr.h" +#include "xprEvent.h" +#include "pseudoramiX.h" +#include "darwin.h" +#include "darwinEvents.h" +#include "rootless.h" +#include "dri.h" +#include "globals.h" +#include <Xplugin.h> +#include "applewmExt.h" +#include "micmap.h" + +#include "rootlessCommon.h" + +#ifdef DAMAGE +# include "damage.h" +#endif + +/* 10.4's deferred update makes X slower.. have to live with the tearing + for now.. */ +#define XP_NO_DEFERRED_UPDATES 8 + +// Name of GLX bundle for native OpenGL +static const char *xprOpenGLBundle = "glxCGL.bundle"; + +/* + * eventHandler + * Callback handler for Xplugin events. + */ +static void eventHandler(unsigned int type, const void *arg, + unsigned int arg_size, void *data) { + + switch (type) { + case XP_EVENT_DISPLAY_CHANGED: + DEBUG_LOG("XP_EVENT_DISPLAY_CHANGED\n"); + DarwinSendDDXEvent(kXquartzDisplayChanged, 0); + break; + + case XP_EVENT_WINDOW_STATE_CHANGED: + if (arg_size >= sizeof(xp_window_state_event)) { + const xp_window_state_event *ws_arg = arg; + + DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: id=%d, state=%d\n", ws_arg->id, ws_arg->state); + DarwinSendDDXEvent(kXquartzWindowState, 2, + ws_arg->id, ws_arg->state); + } else { + DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: ignored\n"); + } + break; + + case XP_EVENT_WINDOW_MOVED: + DEBUG_LOG("XP_EVENT_WINDOW_MOVED\n"); + if (arg_size == sizeof(xp_window_id)) { + xp_window_id id = * (xp_window_id *) arg; + DarwinSendDDXEvent(kXquartzWindowMoved, 1, id); + } + break; + + case XP_EVENT_SURFACE_DESTROYED: + DEBUG_LOG("XP_EVENT_SURFACE_DESTROYED\n"); + case XP_EVENT_SURFACE_CHANGED: + DEBUG_LOG("XP_EVENT_SURFACE_CHANGED\n"); + 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; +#ifdef XP_EVENT_SPACE_CHANGED + case XP_EVENT_SPACE_CHANGED: + DEBUG_LOG("XP_EVENT_SPACE_CHANGED\n"); + if(arg_size == sizeof(uint32_t)) { + uint32_t space_id = *(uint32_t *)arg; + DarwinSendDDXEvent(kXquartzSpaceChanged, 1, space_id); + } + break; +#endif + default: + ErrorF("Unknown XP_EVENT type (%d) in xprScreen:eventHandler\n", type); + } +} + +/* + * displayAtIndex + * Return the display ID for a particular display index. + */ +static CGDirectDisplayID +displayAtIndex(int index) +{ + CGError err; + CGDisplayCount cnt; + CGDirectDisplayID dpy[index+1]; + + err = CGGetActiveDisplayList(index + 1, dpy, &cnt); + if (err == kCGErrorSuccess && cnt == index + 1) + return dpy[index]; + else + return kCGNullDirectDisplay; +} + +/* + * displayScreenBounds + * Return the bounds of a particular display. + */ +static CGRect +displayScreenBounds(CGDirectDisplayID id) +{ + CGRect frame; + + frame = CGDisplayBounds(id); + + DEBUG_LOG(" %dx%d @ (%d,%d).\n", + (int)frame.size.width, (int)frame.size.height, + (int)frame.origin.x, (int)frame.origin.y); + + /* Remove menubar to help standard X11 window managers. */ + if (XQuartzIsRootless && + frame.origin.x == 0 && frame.origin.y == 0) { + frame.origin.y += aquaMenuBarHeight; + frame.size.height -= aquaMenuBarHeight; + } + + DEBUG_LOG(" %dx%d @ (%d,%d).\n", + (int)frame.size.width, (int)frame.size.height, + (int)frame.origin.x, (int)frame.origin.y); + + return frame; +} + +/* + * xprAddPseudoramiXScreens + * Add a single virtual screen encompassing all the physical screens + * with PseudoramiX. + */ +static void +xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height, ScreenPtr pScreen) +{ + CGDisplayCount i, displayCount; + CGDirectDisplayID *displayList = NULL; + CGRect unionRect = CGRectNull, frame; + + // Find all the CoreGraphics displays + CGGetActiveDisplayList(0, NULL, &displayCount); + DEBUG_LOG("displayCount: %d\n", (int)displayCount); + + if(!displayCount) { + ErrorF("CoreGraphics has reported no connected displays. Creating a stub 800x600 display.\n"); + *x = *y = 0; + *width = 800; + *height = 600; + PseudoramiXAddScreen(*x, *y, *width, *height); + return; + } + + /* If the displays are captured, we are in a RandR game mode + * on the primary display, so we only want to include the first + * display. The others are covered by the shield window. + */ + if (CGDisplayIsCaptured(kCGDirectMainDisplay)) + displayCount = 1; + + displayList = malloc(displayCount * sizeof(CGDirectDisplayID)); + if(!displayList) + FatalError("Unable to allocate memory for list of displays.\n"); + CGGetActiveDisplayList(displayCount, displayList, &displayCount); + QuartzCopyDisplayIDs(pScreen, displayCount, displayList); + + /* Get the union of all screens */ + for (i = 0; i < displayCount; i++) { + CGDirectDisplayID dpy = displayList[i]; + frame = displayScreenBounds(dpy); + unionRect = CGRectUnion(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; + + DEBUG_LOG(" screen union origin: (%d,%d) size: (%d,%d).\n", + *x, *y, *width, *height); + + /* Tell PseudoramiX about the real screens. */ + for (i = 0; i < displayCount; i++) + { + CGDirectDisplayID dpy = displayList[i]; + + frame = displayScreenBounds(dpy); + frame.origin.x -= unionRect.origin.x; + frame.origin.y -= unionRect.origin.y; + + DEBUG_LOG(" placed at X11 coordinate (%d,%d).\n", + (int)frame.origin.x, (int)frame.origin.y); + + PseudoramiXAddScreen(frame.origin.x, frame.origin.y, + frame.size.width, frame.size.height); + } + + free(displayList); +} + +/* + * xprDisplayInit + * Find number of CoreGraphics displays and initialize Xplugin. + */ +static void +xprDisplayInit(void) +{ + CGDisplayCount displayCount; + + DEBUG_LOG(""); + + CGGetActiveDisplayList(0, NULL, &displayCount); + + /* With PseudoramiX, the X server only sees one screen; only PseudoramiX + itself knows about all of the screens. */ + + if (noPseudoramiXExtension) + darwinScreensFound = displayCount; + else + darwinScreensFound = 1; + + if (xp_init(XP_BACKGROUND_EVENTS | XP_NO_DEFERRED_UPDATES) != Success) + FatalError("Could not initialize the Xplugin library."); + + xp_select_events(XP_EVENT_DISPLAY_CHANGED + | XP_EVENT_WINDOW_STATE_CHANGED + | XP_EVENT_WINDOW_MOVED +#ifdef XP_EVENT_SPACE_CHANGED + | XP_EVENT_SPACE_CHANGED +#endif + | XP_EVENT_SURFACE_CHANGED + | XP_EVENT_SURFACE_DESTROYED, + eventHandler, NULL); + + AppleDRIExtensionInit(); + xprAppleWMInit(); + + XQuartzIsRootless = XQuartzRootlessDefault; + if (!XQuartzIsRootless) + RootlessHideAllWindows(); +} + +/* + * xprAddScreen + * Init the framebuffer and record pixmap parameters for the screen. + */ +static Bool +xprAddScreen(int index, ScreenPtr pScreen) +{ + DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen); + int depth = darwinDesiredDepth; + + DEBUG_LOG("index=%d depth=%d\n", index, depth); + + if(depth == -1) { +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + depth = CGDisplaySamplesPerPixel(kCGDirectMainDisplay) * CGDisplayBitsPerSample(kCGDirectMainDisplay); +#else + CGDisplayModeRef modeRef; + CFStringRef encStrRef; + + modeRef = CGDisplayCopyDisplayMode(kCGDirectMainDisplay); + if(!modeRef) + goto have_depth; + + encStrRef = CGDisplayModeCopyPixelEncoding(modeRef); + CFRelease(modeRef); + if(!encStrRef) + goto have_depth; + + if(CFStringCompare(encStrRef, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + depth = 24; + } else if(CFStringCompare(encStrRef, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + depth = 15; + } else if(CFStringCompare(encStrRef, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + depth = 8; + } + + CFRelease(encStrRef); +#endif + } + +have_depth: + switch(depth) { + case 8: // pseudo-working + dfb->visuals = PseudoColorMask; + dfb->preferredCVC = PseudoColor; + dfb->depth = 8; + dfb->bitsPerRGB = 8; + dfb->bitsPerPixel = 8; + dfb->redMask = 0; + dfb->greenMask = 0; + dfb->blueMask = 0; + break; + case 15: + dfb->visuals = TrueColorMask; //LARGE_VISUALS; + dfb->preferredCVC = TrueColor; + dfb->depth = 15; + dfb->bitsPerRGB = 5; + dfb->bitsPerPixel = 16; + dfb->redMask = RM_ARGB(0,5,5,5); + dfb->greenMask = GM_ARGB(0,5,5,5); + dfb->blueMask = BM_ARGB(0,5,5,5); + break; +// case 24: + default: + if(depth != 24) + ErrorF("Unsupported color depth requested. Defaulting to 24bit. (depth=%d darwinDesiredDepth=%d)\n", depth, darwinDesiredDepth); + dfb->visuals = TrueColorMask; //LARGE_VISUALS; + dfb->preferredCVC = TrueColor; + dfb->depth = 24; + dfb->bitsPerRGB = 8; + dfb->bitsPerPixel = 32; + dfb->redMask = RM_ARGB(0,8,8,8); + dfb->greenMask = GM_ARGB(0,8,8,8); + dfb->blueMask = BM_ARGB(0,8,8,8); + break; + } + + if (noPseudoramiXExtension) + { + CGDirectDisplayID dpy; + CGRect frame; + + ErrorF("Warning: noPseudoramiXExtension!\n"); + + dpy = displayAtIndex(index); + QuartzCopyDisplayIDs(pScreen, 1, &dpy); + + frame = displayScreenBounds(dpy); + + dfb->x = frame.origin.x; + dfb->y = frame.origin.y; + dfb->width = frame.size.width; + dfb->height = frame.size.height; + } + else + { + xprAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height, pScreen); + } + + /* 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; + + DRIScreenInit(pScreen); + + return TRUE; +} + +/* + * xprSetupScreen + * Setup the screen for rootless access. + */ +static Bool +xprSetupScreen(int index, ScreenPtr pScreen) +{ +#ifdef DAMAGE + // The Damage extension needs to wrap underneath the + // generic rootless layer, so do it now. + if (!DamageSetup(pScreen)) + return FALSE; +#endif + + // Initialize generic rootless code + if (!xprInit(pScreen)) + return FALSE; + + return DRIFinishScreenInit(pScreen); +} + +/* + * xprUpdateScreen + * Update screen after configuation change. + */ +static void +xprUpdateScreen(ScreenPtr pScreen) +{ + rootlessGlobalOffsetX = darwinMainScreenX; + rootlessGlobalOffsetY = darwinMainScreenY; + + AppleWMSetScreenOrigin(pScreen->root); + + RootlessRepositionWindows(pScreen); + RootlessUpdateScreenPixmap(pScreen); +} + +/* + * xprInitInput + * Finalize xpr specific setup. + */ +static void +xprInitInput(int argc, char **argv) +{ + int i; + + rootlessGlobalOffsetX = darwinMainScreenX; + rootlessGlobalOffsetY = darwinMainScreenY; + + for (i = 0; i < screenInfo.numScreens; i++) + AppleWMSetScreenOrigin(screenInfo.screens[i]->root); +} + +/* + * Quartz display mode function list. + */ +static QuartzModeProcsRec xprModeProcs = { + xprDisplayInit, + xprAddScreen, + xprSetupScreen, + xprInitInput, + QuartzInitCursor, + QuartzSuspendXCursor, + QuartzResumeXCursor, + xprAddPseudoramiXScreens, + xprUpdateScreen, + xprIsX11Window, + xprHideWindows, + RootlessFrameForWindow, + TopLevelParent, + DRICreateSurface, + DRIDestroySurface +}; + +/* + * QuartzModeBundleInit + * Initialize the display mode bundle after loading. + */ +Bool +QuartzModeBundleInit(void) +{ + quartzProcs = &xprModeProcs; + quartzOpenGLBundle = xprOpenGLBundle; + return TRUE; +} |