14642e01fSmrg/* 24642e01fSmrg * Xplugin rootless implementation frame functions 34642e01fSmrg * 435c4bbdfSmrg * Copyright (c) 2002-2012 Apple Computer, Inc. All rights reserved. 54642e01fSmrg * Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved. 64642e01fSmrg * 74642e01fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 84642e01fSmrg * copy of this software and associated documentation files (the "Software"), 94642e01fSmrg * to deal in the Software without restriction, including without limitation 104642e01fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 114642e01fSmrg * and/or sell copies of the Software, and to permit persons to whom the 124642e01fSmrg * Software is furnished to do so, subject to the following conditions: 134642e01fSmrg * 144642e01fSmrg * The above copyright notice and this permission notice shall be included in 154642e01fSmrg * all copies or substantial portions of the Software. 164642e01fSmrg * 174642e01fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 184642e01fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 194642e01fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 204642e01fSmrg * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 214642e01fSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 224642e01fSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 234642e01fSmrg * DEALINGS IN THE SOFTWARE. 244642e01fSmrg * 254642e01fSmrg * Except as contained in this notice, the name(s) of the above copyright 264642e01fSmrg * holders shall not be used in advertising or otherwise to promote the sale, 274642e01fSmrg * use or other dealings in this Software without prior written authorization. 284642e01fSmrg */ 294642e01fSmrg 304642e01fSmrg#ifdef HAVE_DIX_CONFIG_H 314642e01fSmrg#include <dix-config.h> 324642e01fSmrg#endif 334642e01fSmrg 344642e01fSmrg#include "xpr.h" 354642e01fSmrg#include "rootlessCommon.h" 364642e01fSmrg#include <Xplugin.h> 374642e01fSmrg#include "x-hash.h" 384642e01fSmrg#include "applewmExt.h" 394642e01fSmrg 404642e01fSmrg#include "propertyst.h" 414642e01fSmrg#include "dix.h" 424642e01fSmrg#include <X11/Xatom.h> 434642e01fSmrg#include "windowstr.h" 446747b715Smrg#include "quartz.h" 454642e01fSmrg 4635c4bbdfSmrg#include <dispatch/dispatch.h> 474642e01fSmrg 4835c4bbdfSmrg#define DEFINE_ATOM_HELPER(func, atom_name) \ 4935c4bbdfSmrg static Atom func(void) { \ 5035c4bbdfSmrg static int generation; \ 5135c4bbdfSmrg static Atom atom; \ 5235c4bbdfSmrg if (generation != serverGeneration) { \ 5335c4bbdfSmrg generation = serverGeneration; \ 5435c4bbdfSmrg atom = MakeAtom(atom_name, strlen(atom_name), TRUE); \ 5535c4bbdfSmrg } \ 5635c4bbdfSmrg return atom; \ 5735c4bbdfSmrg } 584642e01fSmrg 594642e01fSmrgDEFINE_ATOM_HELPER(xa_native_window_id, "_NATIVE_WINDOW_ID") 604642e01fSmrg 614642e01fSmrg/* Maps xp_window_id -> RootlessWindowRec */ 6235c4bbdfSmrgstatic x_hash_table * window_hash; 6335c4bbdfSmrg 6435c4bbdfSmrg/* Need to guard window_hash since xprIsX11Window can be called from any thread. */ 6535c4bbdfSmrgstatic dispatch_queue_t window_hash_serial_q; 664642e01fSmrg 674642e01fSmrg/* Prototypes for static functions */ 6835c4bbdfSmrgstatic Bool 6935c4bbdfSmrgxprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen, int newX, 7035c4bbdfSmrg int newY, 7135c4bbdfSmrg RegionPtr pShape); 7235c4bbdfSmrgstatic void 7335c4bbdfSmrgxprDestroyFrame(RootlessFrameID wid); 7435c4bbdfSmrgstatic void 7535c4bbdfSmrgxprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY); 7635c4bbdfSmrgstatic void 7735c4bbdfSmrgxprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY, 7835c4bbdfSmrg unsigned int newW, unsigned int newH, 794642e01fSmrg unsigned int gravity); 8035c4bbdfSmrgstatic void 8135c4bbdfSmrgxprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid); 8235c4bbdfSmrgstatic void 8335c4bbdfSmrgxprReshapeFrame(RootlessFrameID wid, RegionPtr pShape); 8435c4bbdfSmrgstatic void 8535c4bbdfSmrgxprUnmapFrame(RootlessFrameID wid); 8635c4bbdfSmrgstatic void 8735c4bbdfSmrgxprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow); 8835c4bbdfSmrgstatic void 8935c4bbdfSmrgxprStopDrawing(RootlessFrameID wid, Bool flush); 9035c4bbdfSmrgstatic void 9135c4bbdfSmrgxprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage); 9235c4bbdfSmrgstatic void 9335c4bbdfSmrgxprDamageRects(RootlessFrameID wid, int nrects, const BoxRec *rects, 9435c4bbdfSmrg int shift_x, 9535c4bbdfSmrg int shift_y); 9635c4bbdfSmrgstatic void 9735c4bbdfSmrgxprSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin); 9835c4bbdfSmrgstatic Bool 9935c4bbdfSmrgxprDoReorderWindow(RootlessWindowPtr pFrame); 10035c4bbdfSmrgstatic void 10135c4bbdfSmrgxprHideWindow(RootlessFrameID wid); 10235c4bbdfSmrgstatic void 10335c4bbdfSmrgxprUpdateColormap(RootlessFrameID wid, ScreenPtr pScreen); 10435c4bbdfSmrgstatic void 10535c4bbdfSmrgxprCopyWindow(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, 10635c4bbdfSmrg int dx, 10735c4bbdfSmrg int dy); 1084642e01fSmrg 1094642e01fSmrgstatic inline xp_error 1104642e01fSmrgxprConfigureWindow(xp_window_id id, unsigned int mask, 1114642e01fSmrg const xp_window_changes *values) 1124642e01fSmrg{ 1134642e01fSmrg return xp_configure_window(id, mask, values); 1144642e01fSmrg} 1154642e01fSmrg 1164642e01fSmrgstatic void 1174642e01fSmrgxprSetNativeProperty(RootlessWindowPtr pFrame) 1184642e01fSmrg{ 1194642e01fSmrg xp_error err; 1204642e01fSmrg unsigned int native_id; 1214642e01fSmrg long data; 1224642e01fSmrg 1234642e01fSmrg err = xp_get_native_window(x_cvt_vptr_to_uint(pFrame->wid), &native_id); 12435c4bbdfSmrg if (err == Success) { 1254642e01fSmrg /* FIXME: move this to AppleWM extension */ 1264642e01fSmrg 1274642e01fSmrg data = native_id; 12835c4bbdfSmrg dixChangeWindowProperty(serverClient, pFrame->win, 12935c4bbdfSmrg xa_native_window_id(), 13035c4bbdfSmrg XA_INTEGER, 32, PropModeReplace, 1, &data, 13135c4bbdfSmrg TRUE); 1324642e01fSmrg } 1334642e01fSmrg} 1344642e01fSmrg 1356747b715Smrgstatic xp_error 13635c4bbdfSmrgxprColormapCallback(void *data, int first_color, int n_colors, 13735c4bbdfSmrg uint32_t *colors) 1386747b715Smrg{ 13935c4bbdfSmrg return (RootlessResolveColormap(data, first_color, n_colors, 14035c4bbdfSmrg colors) ? XP_Success : XP_BadMatch); 1416747b715Smrg} 1424642e01fSmrg 1434642e01fSmrg/* 1444642e01fSmrg * Create and display a new frame. 1454642e01fSmrg */ 1466747b715Smrgstatic Bool 1474642e01fSmrgxprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen, 1484642e01fSmrg int newX, int newY, RegionPtr pShape) 1494642e01fSmrg{ 1504642e01fSmrg WindowPtr pWin = pFrame->win; 1514642e01fSmrg xp_window_changes wc; 1524642e01fSmrg unsigned int mask = 0; 1534642e01fSmrg xp_error err; 1544642e01fSmrg 1554642e01fSmrg wc.x = newX; 1564642e01fSmrg wc.y = newY; 1574642e01fSmrg wc.width = pFrame->width; 1584642e01fSmrg wc.height = pFrame->height; 1594642e01fSmrg wc.bit_gravity = XP_GRAVITY_NONE; 1604642e01fSmrg mask |= XP_BOUNDS; 1614642e01fSmrg 16235c4bbdfSmrg if (pWin->drawable.depth == 8) { 1634642e01fSmrg wc.depth = XP_DEPTH_INDEX8; 1646747b715Smrg wc.colormap = xprColormapCallback; 1654642e01fSmrg wc.colormap_data = pScreen; 1664642e01fSmrg mask |= XP_COLORMAP; 1674642e01fSmrg } 1684642e01fSmrg else if (pWin->drawable.depth == 15) 1694642e01fSmrg wc.depth = XP_DEPTH_RGB555; 1704642e01fSmrg else if (pWin->drawable.depth == 24) 1714642e01fSmrg wc.depth = XP_DEPTH_ARGB8888; 1724642e01fSmrg else 1734642e01fSmrg wc.depth = XP_DEPTH_NIL; 1744642e01fSmrg mask |= XP_DEPTH; 1754642e01fSmrg 17635c4bbdfSmrg if (pShape != NULL) { 1776747b715Smrg wc.shape_nrects = RegionNumRects(pShape); 1786747b715Smrg wc.shape_rects = RegionRects(pShape); 1794642e01fSmrg wc.shape_tx = wc.shape_ty = 0; 1804642e01fSmrg mask |= XP_SHAPE; 1814642e01fSmrg } 1824642e01fSmrg 18335c4bbdfSmrg pFrame->level = 18435c4bbdfSmrg !IsRoot(pWin) ? AppleWMWindowLevelNormal : AppleWMNumWindowLevels; 1856747b715Smrg 18635c4bbdfSmrg if (XQuartzIsRootless) 1876747b715Smrg wc.window_level = normal_window_levels[pFrame->level]; 18835c4bbdfSmrg else if (XQuartzShieldingWindowLevel) 1898223e2f2Smrg wc.window_level = XQuartzShieldingWindowLevel + 1; 1906747b715Smrg else 1916747b715Smrg wc.window_level = rooted_window_levels[pFrame->level]; 1926747b715Smrg mask |= XP_WINDOW_LEVEL; 1936747b715Smrg 19435c4bbdfSmrg err = xp_create_window(mask, &wc, (xp_window_id *)&pFrame->wid); 1954642e01fSmrg 19635c4bbdfSmrg if (err != Success) { 1974642e01fSmrg return FALSE; 1984642e01fSmrg } 1994642e01fSmrg 20035c4bbdfSmrg dispatch_async(window_hash_serial_q, ^ { 20135c4bbdfSmrg x_hash_table_insert(window_hash, pFrame->wid, pFrame); 20235c4bbdfSmrg }); 2034642e01fSmrg 2044642e01fSmrg xprSetNativeProperty(pFrame); 2054642e01fSmrg 2064642e01fSmrg return TRUE; 2074642e01fSmrg} 2084642e01fSmrg 2094642e01fSmrg/* 2104642e01fSmrg * Destroy a frame. 2114642e01fSmrg */ 2126747b715Smrgstatic void 2134642e01fSmrgxprDestroyFrame(RootlessFrameID wid) 2144642e01fSmrg{ 2156747b715Smrg xp_error err; 21635c4bbdfSmrg 21735c4bbdfSmrg dispatch_async(window_hash_serial_q, ^ { 21835c4bbdfSmrg x_hash_table_remove(window_hash, wid); 21935c4bbdfSmrg }); 2204642e01fSmrg 2216747b715Smrg err = xp_destroy_window(x_cvt_vptr_to_uint(wid)); 2226747b715Smrg if (err != Success) 22335c4bbdfSmrg FatalError("Could not destroy window %d (%d).", 22435c4bbdfSmrg (int)x_cvt_vptr_to_uint( 22535c4bbdfSmrg wid), (int)err); 2264642e01fSmrg} 2274642e01fSmrg 2284642e01fSmrg/* 2294642e01fSmrg * Move a frame on screen. 2304642e01fSmrg */ 2316747b715Smrgstatic void 2324642e01fSmrgxprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY) 2334642e01fSmrg{ 2344642e01fSmrg xp_window_changes wc; 2354642e01fSmrg 2364642e01fSmrg wc.x = newX; 2374642e01fSmrg wc.y = newY; 2384642e01fSmrg // ErrorF("xprMoveFrame(%d, %p, %d, %d)\n", wid, pScreen, newX, newY); 2394642e01fSmrg xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_ORIGIN, &wc); 2404642e01fSmrg} 2414642e01fSmrg 2424642e01fSmrg/* 2434642e01fSmrg * Resize and move a frame. 2444642e01fSmrg */ 2456747b715Smrgstatic void 2464642e01fSmrgxprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen, 2474642e01fSmrg int newX, int newY, unsigned int newW, unsigned int newH, 2484642e01fSmrg unsigned int gravity) 2494642e01fSmrg{ 2504642e01fSmrg xp_window_changes wc; 2514642e01fSmrg 2524642e01fSmrg wc.x = newX; 2534642e01fSmrg wc.y = newY; 2544642e01fSmrg wc.width = newW; 2554642e01fSmrg wc.height = newH; 2564642e01fSmrg wc.bit_gravity = gravity; 2574642e01fSmrg 2584642e01fSmrg /* It's unlikely that being async will save us anything here. 2594642e01fSmrg But it can't hurt. */ 2604642e01fSmrg 2614642e01fSmrg xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_BOUNDS, &wc); 2624642e01fSmrg} 2634642e01fSmrg 2644642e01fSmrg/* 2654642e01fSmrg * Change frame stacking. 2664642e01fSmrg */ 26735c4bbdfSmrgstatic void 26835c4bbdfSmrgxprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) 26935c4bbdfSmrg{ 2704642e01fSmrg xp_window_changes wc; 2716747b715Smrg unsigned int mask = XP_STACKING; 27235c4bbdfSmrg __block 27335c4bbdfSmrg RootlessWindowRec * winRec; 2744642e01fSmrg 2756747b715Smrg /* Stack frame below nextWid it if it exists, or raise 2764642e01fSmrg frame above everything otherwise. */ 2774642e01fSmrg 27835c4bbdfSmrg if (nextWid == NULL) { 2794642e01fSmrg wc.stack_mode = XP_MAPPED_ABOVE; 2804642e01fSmrg wc.sibling = 0; 28135c4bbdfSmrg } 28235c4bbdfSmrg else { 2834642e01fSmrg wc.stack_mode = XP_MAPPED_BELOW; 2844642e01fSmrg wc.sibling = x_cvt_vptr_to_uint(nextWid); 2854642e01fSmrg } 2864642e01fSmrg 28735c4bbdfSmrg dispatch_sync(window_hash_serial_q, ^ { 28835c4bbdfSmrg winRec = x_hash_table_lookup(window_hash, wid, NULL); 28935c4bbdfSmrg }); 29035c4bbdfSmrg 29135c4bbdfSmrg if (winRec) { 29235c4bbdfSmrg if (XQuartzIsRootless) 29335c4bbdfSmrg wc.window_level = normal_window_levels[winRec->level]; 29435c4bbdfSmrg else if (XQuartzShieldingWindowLevel) 29535c4bbdfSmrg wc.window_level = XQuartzShieldingWindowLevel + 1; 29635c4bbdfSmrg else 29735c4bbdfSmrg wc.window_level = rooted_window_levels[winRec->level]; 29835c4bbdfSmrg mask |= XP_WINDOW_LEVEL; 2996747b715Smrg } 3006747b715Smrg 3016747b715Smrg xprConfigureWindow(x_cvt_vptr_to_uint(wid), mask, &wc); 3024642e01fSmrg} 3034642e01fSmrg 3044642e01fSmrg/* 3054642e01fSmrg * Change the frame's shape. 3064642e01fSmrg */ 3076747b715Smrgstatic void 3084642e01fSmrgxprReshapeFrame(RootlessFrameID wid, RegionPtr pShape) 3094642e01fSmrg{ 3104642e01fSmrg xp_window_changes wc; 3114642e01fSmrg 31235c4bbdfSmrg if (pShape != NULL) { 3136747b715Smrg wc.shape_nrects = RegionNumRects(pShape); 3146747b715Smrg wc.shape_rects = RegionRects(pShape); 3154642e01fSmrg } 31635c4bbdfSmrg else { 3174642e01fSmrg wc.shape_nrects = -1; 3184642e01fSmrg wc.shape_rects = NULL; 3194642e01fSmrg } 3204642e01fSmrg 3214642e01fSmrg wc.shape_tx = wc.shape_ty = 0; 3224642e01fSmrg 3234642e01fSmrg xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_SHAPE, &wc); 3244642e01fSmrg} 3254642e01fSmrg 3264642e01fSmrg/* 3274642e01fSmrg * Unmap a frame. 3284642e01fSmrg */ 3296747b715Smrgstatic void 3304642e01fSmrgxprUnmapFrame(RootlessFrameID wid) 3314642e01fSmrg{ 3324642e01fSmrg xp_window_changes wc; 3334642e01fSmrg 3344642e01fSmrg wc.stack_mode = XP_UNMAPPED; 3354642e01fSmrg wc.sibling = 0; 3364642e01fSmrg 3374642e01fSmrg xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_STACKING, &wc); 3384642e01fSmrg} 3394642e01fSmrg 3404642e01fSmrg/* 3414642e01fSmrg * Start drawing to a frame. 3424642e01fSmrg * Prepare for direct access to its backing buffer. 3434642e01fSmrg */ 3446747b715Smrgstatic void 3454642e01fSmrgxprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow) 3464642e01fSmrg{ 3474642e01fSmrg void *data[2]; 3484642e01fSmrg unsigned int rowbytes[2]; 3494642e01fSmrg xp_error err; 3504642e01fSmrg 35135c4bbdfSmrg#ifdef DEBUG_XP_LOCK_WINDOW 35235c4bbdfSmrg ErrorF("=== LOCK %d ===\n", (int)x_cvt_vptr_to_uint(wid)); 353a1e1cf94Smrg xorg_backtrace(); 35435c4bbdfSmrg#endif 35535c4bbdfSmrg 35635c4bbdfSmrg err = xp_lock_window(x_cvt_vptr_to_uint( 35735c4bbdfSmrg wid), NULL, NULL, data, rowbytes, NULL); 3584642e01fSmrg if (err != Success) 35935c4bbdfSmrg FatalError("Could not lock window %d for drawing (%d).", 36035c4bbdfSmrg (int)x_cvt_vptr_to_uint( 36135c4bbdfSmrg wid), (int)err); 3624642e01fSmrg 363a1e1cf94Smrg#ifdef DEBUG_XP_LOCK_WINDOW 364a1e1cf94Smrg ErrorF(" bits: %p\n", *data); 365a1e1cf94Smrg#endif 366a1e1cf94Smrg 3674642e01fSmrg *pixelData = data[0]; 3684642e01fSmrg *bytesPerRow = rowbytes[0]; 3694642e01fSmrg} 3704642e01fSmrg 3714642e01fSmrg/* 3724642e01fSmrg * Stop drawing to a frame. 3734642e01fSmrg */ 3746747b715Smrgstatic void 3754642e01fSmrgxprStopDrawing(RootlessFrameID wid, Bool flush) 3764642e01fSmrg{ 3776747b715Smrg xp_error err; 37835c4bbdfSmrg 37935c4bbdfSmrg#ifdef DEBUG_XP_LOCK_WINDOW 38035c4bbdfSmrg ErrorF("=== UNLOCK %d ===\n", (int)x_cvt_vptr_to_uint(wid)); 381a1e1cf94Smrg xorg_backtrace(); 38235c4bbdfSmrg#endif 38335c4bbdfSmrg 3846747b715Smrg err = xp_unlock_window(x_cvt_vptr_to_uint(wid), flush); 385475c125cSmrg /* This should be a FatalError, but we started tripping over it. Make it a 386475c125cSmrg * FatalError after http://xquartz.macosforge.org/trac/ticket/482 is fixed. 387475c125cSmrg */ 38835c4bbdfSmrg if (err != Success) 38935c4bbdfSmrg ErrorF("Could not unlock window %d after drawing (%d).", 39035c4bbdfSmrg (int)x_cvt_vptr_to_uint( 39135c4bbdfSmrg wid), (int)err); 3924642e01fSmrg} 3934642e01fSmrg 3944642e01fSmrg/* 3954642e01fSmrg * Flush drawing updates to the screen. 3964642e01fSmrg */ 3976747b715Smrgstatic void 3984642e01fSmrgxprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage) 3994642e01fSmrg{ 4004642e01fSmrg xp_flush_window(x_cvt_vptr_to_uint(wid)); 4014642e01fSmrg} 4024642e01fSmrg 4034642e01fSmrg/* 4044642e01fSmrg * Mark damaged rectangles as requiring redisplay to screen. 4054642e01fSmrg */ 4066747b715Smrgstatic void 4074642e01fSmrgxprDamageRects(RootlessFrameID wid, int nrects, const BoxRec *rects, 4084642e01fSmrg int shift_x, int shift_y) 4094642e01fSmrg{ 4104642e01fSmrg xp_mark_window(x_cvt_vptr_to_uint(wid), nrects, rects, shift_x, shift_y); 4114642e01fSmrg} 4124642e01fSmrg 4134642e01fSmrg/* 4144642e01fSmrg * Called after the window associated with a frame has been switched 4154642e01fSmrg * to a new top-level parent. 4164642e01fSmrg */ 4176747b715Smrgstatic void 4184642e01fSmrgxprSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin) 4194642e01fSmrg{ 4204642e01fSmrg DeleteProperty(serverClient, oldWin, xa_native_window_id()); 4214642e01fSmrg 4224642e01fSmrg xprSetNativeProperty(pFrame); 4234642e01fSmrg} 4244642e01fSmrg 4254642e01fSmrg/* 4264642e01fSmrg * Called to check if the frame should be reordered when it is restacked. 4274642e01fSmrg */ 42835c4bbdfSmrgstatic Bool 42935c4bbdfSmrgxprDoReorderWindow(RootlessWindowPtr pFrame) 4304642e01fSmrg{ 4314642e01fSmrg WindowPtr pWin = pFrame->win; 4324642e01fSmrg 4334642e01fSmrg return AppleWMDoReorderWindow(pWin); 4344642e01fSmrg} 4354642e01fSmrg 4364642e01fSmrg/* 4374642e01fSmrg * Copy area in frame to another part of frame. 4384642e01fSmrg * Used to accelerate scrolling. 4394642e01fSmrg */ 4406747b715Smrgstatic void 4414642e01fSmrgxprCopyWindow(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, 4424642e01fSmrg int dx, int dy) 4434642e01fSmrg{ 4444642e01fSmrg xp_copy_window(x_cvt_vptr_to_uint(wid), x_cvt_vptr_to_uint(wid), 4454642e01fSmrg dstNrects, dstRects, dx, dy); 4464642e01fSmrg} 4474642e01fSmrg 4484642e01fSmrgstatic RootlessFrameProcsRec xprRootlessProcs = { 4494642e01fSmrg xprCreateFrame, 4504642e01fSmrg xprDestroyFrame, 4514642e01fSmrg xprMoveFrame, 4524642e01fSmrg xprResizeFrame, 4534642e01fSmrg xprRestackFrame, 4544642e01fSmrg xprReshapeFrame, 4554642e01fSmrg xprUnmapFrame, 4564642e01fSmrg xprStartDrawing, 4574642e01fSmrg xprStopDrawing, 4584642e01fSmrg xprUpdateRegion, 4594642e01fSmrg xprDamageRects, 4604642e01fSmrg xprSwitchWindow, 4614642e01fSmrg xprDoReorderWindow, 4626747b715Smrg xprHideWindow, 4636747b715Smrg xprUpdateColormap, 4644642e01fSmrg xp_copy_bytes, 4654642e01fSmrg xprCopyWindow 4664642e01fSmrg}; 4674642e01fSmrg 4684642e01fSmrg/* 4694642e01fSmrg * Initialize XPR implementation 4704642e01fSmrg */ 4714642e01fSmrgBool 4724642e01fSmrgxprInit(ScreenPtr pScreen) 4734642e01fSmrg{ 4744642e01fSmrg RootlessInit(pScreen, &xprRootlessProcs); 4754642e01fSmrg 4764642e01fSmrg rootless_CopyBytes_threshold = xp_copy_bytes_threshold; 4774642e01fSmrg rootless_CopyWindow_threshold = xp_scroll_area_threshold; 4784642e01fSmrg 47935c4bbdfSmrg assert((window_hash = x_hash_table_new(NULL, NULL, NULL, NULL))); 48035c4bbdfSmrg assert((window_hash_serial_q = 48135c4bbdfSmrg dispatch_queue_create(BUNDLE_ID_PREFIX ".X11.xpr_window_hash", 48235c4bbdfSmrg NULL))); 48335c4bbdfSmrg 4844642e01fSmrg return TRUE; 4854642e01fSmrg} 4864642e01fSmrg 4874642e01fSmrg/* 4884642e01fSmrg * Given the id of a physical window, try to find the top-level (or root) 4894642e01fSmrg * X window that it represents. 4904642e01fSmrg */ 4914642e01fSmrgWindowPtr 4924642e01fSmrgxprGetXWindow(xp_window_id wid) 4934642e01fSmrg{ 49435c4bbdfSmrg RootlessWindowRec *winRec __block; 49535c4bbdfSmrg dispatch_sync(window_hash_serial_q, ^ { 49635c4bbdfSmrg winRec = 49735c4bbdfSmrg x_hash_table_lookup(window_hash, 49835c4bbdfSmrg x_cvt_uint_to_vptr(wid), NULL); 49935c4bbdfSmrg }); 5004642e01fSmrg 5014642e01fSmrg return winRec != NULL ? winRec->win : NULL; 5024642e01fSmrg} 5034642e01fSmrg 5044642e01fSmrg/* 5054642e01fSmrg * The windowNumber is an AppKit window number. Returns TRUE if xpr is 5064642e01fSmrg * displaying a window with that number. 5074642e01fSmrg */ 5084642e01fSmrgBool 50935c4bbdfSmrgxprIsX11Window(int windowNumber) 5104642e01fSmrg{ 5114642e01fSmrg Bool ret; 5124642e01fSmrg xp_window_id wid; 5134642e01fSmrg 5144642e01fSmrg if (xp_lookup_native_window(windowNumber, &wid)) 5154642e01fSmrg ret = xprGetXWindow(wid) != NULL; 5164642e01fSmrg else 5174642e01fSmrg ret = FALSE; 5184642e01fSmrg 5194642e01fSmrg return ret; 5204642e01fSmrg} 5214642e01fSmrg 5224642e01fSmrg/* 5234642e01fSmrg * xprHideWindows 5244642e01fSmrg * Hide or unhide all top level windows. This is called for application hide/ 5254642e01fSmrg * unhide events if the window manager is not Apple-WM aware. Xplugin windows 5264642e01fSmrg * do not hide or unhide themselves. 5274642e01fSmrg */ 5284642e01fSmrgvoid 5294642e01fSmrgxprHideWindows(Bool hide) 5304642e01fSmrg{ 5314642e01fSmrg int screen; 5324642e01fSmrg WindowPtr pRoot, pWin; 5334642e01fSmrg 5344642e01fSmrg for (screen = 0; screen < screenInfo.numScreens; screen++) { 5354642e01fSmrg RootlessFrameID prevWid = NULL; 5366747b715Smrg pRoot = screenInfo.screens[screen]->root; 5374642e01fSmrg 5384642e01fSmrg for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) { 5394642e01fSmrg RootlessWindowRec *winRec = WINREC(pWin); 5404642e01fSmrg 5414642e01fSmrg if (winRec != NULL) { 5424642e01fSmrg if (hide) { 5434642e01fSmrg xprUnmapFrame(winRec->wid); 54435c4bbdfSmrg } 54535c4bbdfSmrg else { 5464642e01fSmrg BoxRec box; 5474642e01fSmrg 5484642e01fSmrg xprRestackFrame(winRec->wid, prevWid); 5494642e01fSmrg prevWid = winRec->wid; 5504642e01fSmrg 5514642e01fSmrg box.x1 = 0; 5524642e01fSmrg box.y1 = 0; 5534642e01fSmrg box.x2 = winRec->width; 5544642e01fSmrg box.y2 = winRec->height; 5554642e01fSmrg 5564642e01fSmrg xprDamageRects(winRec->wid, 1, &box, 0, 0); 5574642e01fSmrg RootlessQueueRedisplay(screenInfo.screens[screen]); 5584642e01fSmrg } 5594642e01fSmrg } 5604642e01fSmrg } 5614642e01fSmrg } 5624642e01fSmrg} 5636747b715Smrg 5646747b715Smrg// XXX: identical to x_cvt_vptr_to_uint ? 56535c4bbdfSmrg#define MAKE_WINDOW_ID(x) ((xp_window_id)((size_t)(x))) 5666747b715Smrg 5676747b715SmrgBool no_configure_window; 5686747b715Smrg 5696747b715Smrgstatic inline int 57035c4bbdfSmrgconfigure_window(xp_window_id id, unsigned int mask, 57135c4bbdfSmrg const xp_window_changes *values) 5726747b715Smrg{ 57335c4bbdfSmrg if (!no_configure_window) 57435c4bbdfSmrg return xp_configure_window(id, mask, values); 57535c4bbdfSmrg else 57635c4bbdfSmrg return XP_Success; 5776747b715Smrg} 5786747b715Smrg 5796747b715Smrgstatic 58035c4bbdfSmrgvoid 58135c4bbdfSmrgxprUpdateColormap(RootlessFrameID wid, ScreenPtr pScreen) 5826747b715Smrg{ 58335c4bbdfSmrg /* This is how we tell xp that the colormap may have changed. */ 58435c4bbdfSmrg xp_window_changes wc; 58535c4bbdfSmrg wc.colormap = xprColormapCallback; 58635c4bbdfSmrg wc.colormap_data = pScreen; 5876747b715Smrg 58835c4bbdfSmrg configure_window(MAKE_WINDOW_ID(wid), XP_COLORMAP, &wc); 5896747b715Smrg} 5906747b715Smrg 5916747b715Smrgstatic 59235c4bbdfSmrgvoid 59335c4bbdfSmrgxprHideWindow(RootlessFrameID wid) 5946747b715Smrg{ 59535c4bbdfSmrg xp_window_changes wc; 59635c4bbdfSmrg wc.stack_mode = XP_UNMAPPED; 59735c4bbdfSmrg wc.sibling = 0; 59835c4bbdfSmrg configure_window(MAKE_WINDOW_ID(wid), XP_STACKING, &wc); 5996747b715Smrg} 600