indent butchered Objective-C formatting. This patch was created by: 1) Reverting the indent changes in hw/xquartz 2) Editing X11Application.m and chaning some #ifdef logic to work with uncrustify 3) Hand edited some (c) notifications 4) Opened all XQuartz sources in XCode and re-indented (^I) 5) Ran uncrustify with this configuration (as close to the indent rules as I could get): tok_split_gte=false utf8_byte=true utf8_force=true indent_cmt_with_tabs=false indent_align_string=false indent_braces=false indent_braces_no_func=false indent_braces_no_class=false indent_braces_no_struct=false indent_brace_parent=false indent_namespace=false indent_extern=false indent_class=false indent_class_colon=false indent_else_if=false indent_var_def_cont=false indent_func_call_param=false indent_func_def_param=false indent_func_proto_param=false indent_func_class_param=false indent_func_ctor_var_param=false indent_template_param=false indent_func_param_double=false indent_relative_single_line_comments=false indent_col1_comment=false indent_access_spec_body=false indent_paren_nl=false indent_comma_paren=false indent_bool_paren=false indent_first_bool_expr=false indent_square_nl=false indent_preserve_sql=false indent_align_assign=true sp_balance_nested_parens=false align_keep_tabs=false align_with_tabs=false align_on_tabstop=false align_number_left=false align_func_params=false align_same_func_call_params=false align_var_def_colon=true align_var_def_attribute=true align_var_def_inline=true align_right_cmt_mix=false align_on_operator=false align_mix_var_proto=false align_single_line_func=false align_single_line_brace=false align_nl_cont=false align_left_shift=true align_oc_decl_colon=true nl_collapse_empty_body=true nl_assign_leave_one_liners=true nl_class_leave_one_liners=true nl_enum_leave_one_liners=true nl_getset_leave_one_liners=true nl_func_leave_one_liners=true nl_if_leave_one_liners=true nl_multi_line_cond=false nl_multi_line_define=false nl_before_case=true nl_after_case=true nl_after_return=false nl_after_semicolon=true nl_after_brace_open=true nl_after_brace_open_cmt=false nl_after_vbrace_open=false nl_after_vbrace_open_empty=false nl_after_brace_close=false nl_after_vbrace_close=false nl_define_macro=false nl_squeeze_ifdef=false nl_ds_struct_enum_cmt=false nl_ds_struct_enum_close_brace=false nl_create_if_one_liner=false nl_create_for_one_liner=false nl_create_while_one_liner=false ls_for_split_full=false ls_func_split_full=false nl_after_multiline_comment=false eat_blanks_after_open_brace=false eat_blanks_before_close_brace=false mod_full_brace_if_chain=false mod_pawn_semicolon=false mod_full_paren_if_bool=false mod_remove_extra_semicolon=false mod_sort_import=false mod_sort_using=false mod_sort_include=false mod_move_case_break=false mod_remove_empty_return=false cmt_indent_multi=true cmt_c_group=false cmt_c_nl_start=false cmt_c_nl_end=false cmt_cpp_group=false cmt_cpp_nl_start=false cmt_cpp_nl_end=false cmt_cpp_to_c=false cmt_star_cont=false cmt_multi_check_last=true cmt_insert_before_preproc=false pp_indent_at_level=false pp_region_indent_code=false pp_if_indent_code=false pp_define_at_level=false indent_columns=4 indent_brace=0 indent_switch_case=0 align_struct_init_span=2 align_pp_define_gap=0 align_pp_define_span=2 align_oc_msg_colon_span=16 nl_end_of_file_min=1 nl_func_var_def_blk=0 code_width=78 nl_max=2 newlines=auto indent_with_tabs=0 sp_arith=force sp_assign=force sp_assign_default=force sp_before_assign=force sp_after_assign=force sp_enum_assign=force sp_enum_before_assign=force sp_enum_after_assign=force sp_pp_stringify=add sp_bool=force sp_compare=force sp_inside_paren=remove sp_paren_paren=remove sp_paren_brace=force sp_before_ptr_star=ignore sp_before_unnamed_ptr_star=force sp_before_byref=force sp_before_unnamed_byref=force sp_after_byref=remove sp_after_type=force sp_before_sparen=force sp_inside_sparen=remove sp_inside_sparen_close=remove sp_after_sparen=force sp_sparen_brace=force sp_special_semi=force sp_before_semi=remove sp_after_semi=force sp_after_semi_for=force sp_after_semi_for_empty=remove sp_before_square=remove sp_inside_square=remove sp_after_comma=force sp_before_comma=remove sp_paren_comma=force sp_before_ellipsis=force sp_after_class_colon=force sp_before_class_colon=force sp_before_case_colon=remove sp_after_cast=remove sp_inside_paren_cast=remove sp_sizeof_paren=remove sp_inside_braces_enum=force sp_inside_braces_struct=force sp_inside_braces=force sp_inside_braces_empty=remove sp_func_proto_paren=remove sp_func_def_paren=remove sp_inside_fparens=remove sp_inside_fparen=remove sp_square_fparen=remove sp_fparen_brace=force sp_func_call_paren=remove sp_func_call_paren_empty=remove sp_return_paren=force sp_attribute_paren=remove sp_defined_paren=remove sp_macro=force sp_macro_func=force sp_else_brace=force sp_brace_else=force sp_brace_typedef=force sp_not=remove sp_inv=remove nl_start_of_file=remove nl_end_of_file=force nl_assign_square=remove nl_after_square_assign=remove nl_fcall_brace=remove nl_enum_brace=remove nl_struct_brace=remove nl_union_brace=remove nl_if_brace=remove nl_brace_else=force nl_elseif_brace=remove nl_else_brace=remove nl_else_if=remove nl_for_brace=remove nl_do_brace=remove nl_brace_while=remove nl_switch_brace=remove nl_case_colon_brace=force nl_func_type_name=force nl_func_type_name_class=force nl_func_proto_type_name=force nl_func_paren=remove nl_func_def_paren=remove nl_func_decl_start=remove nl_func_def_start=remove nl_func_decl_args=remove nl_func_decl_end=remove nl_func_def_end=remove nl_func_decl_end_single=remove nl_func_def_end_single=remove nl_func_decl_empty=remove nl_func_def_empty=remove nl_fdef_brace=force nl_return_expr=remove nl_before_if=ignore nl_after_if=ignore nl_before_for=ignore nl_after_for=ignore nl_before_while=ignore nl_after_while=ignore nl_before_switch=ignore nl_after_switch=ignore nl_before_do=ignore nl_after_do=ignore pp_space=remove Signed-off-by: Jeremy Huddleston <jeremyhu@apple.com>
625 lines
17 KiB
C
625 lines
17 KiB
C
/*
|
|
* Xplugin rootless implementation frame functions
|
|
*
|
|
* Copyright (c) 2002-2012 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 "applewmExt.h"
|
|
|
|
#include "propertyst.h"
|
|
#include "dix.h"
|
|
#include <X11/Xatom.h>
|
|
#include "windowstr.h"
|
|
#include "quartz.h"
|
|
|
|
#ifdef HAVE_LIBDISPATCH
|
|
#include <dispatch/dispatch.h>
|
|
#else
|
|
#include <pthread.h>
|
|
#endif
|
|
|
|
#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;
|
|
|
|
/* Need to guard window_hash since xprIsX11Window can be called from any thread. */
|
|
#ifdef HAVE_LIBDISPATCH
|
|
static dispatch_queue_t window_hash_serial_q;
|
|
#else
|
|
static pthread_rwlock_t window_hash_rwlock;
|
|
#endif
|
|
|
|
/* 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)
|
|
{
|
|
return xp_configure_window(id, mask, values);
|
|
}
|
|
|
|
static void
|
|
xprSetNativeProperty(RootlessWindowPtr pFrame)
|
|
{
|
|
xp_error err;
|
|
unsigned int native_id;
|
|
long data;
|
|
|
|
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;
|
|
|
|
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;
|
|
}
|
|
|
|
#ifdef HAVE_LIBDISPATCH
|
|
dispatch_async(window_hash_serial_q, ^ {
|
|
x_hash_table_insert(window_hash, pFrame->wid, pFrame);
|
|
});
|
|
#else
|
|
pthread_rwlock_wrlock(&window_hash_rwlock);
|
|
x_hash_table_insert(window_hash, pFrame->wid, pFrame);
|
|
pthread_rwlock_wrlock(&window_hash_rwlock);
|
|
#endif
|
|
|
|
xprSetNativeProperty(pFrame);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
* Destroy a frame.
|
|
*/
|
|
static void
|
|
xprDestroyFrame(RootlessFrameID wid)
|
|
{
|
|
xp_error err;
|
|
|
|
#ifdef HAVE_LIBDISPATCH
|
|
dispatch_async(window_hash_serial_q, ^ {
|
|
x_hash_table_remove(window_hash, wid);
|
|
});
|
|
#else
|
|
pthread_rwlock_wrlock(&window_hash_rwlock);
|
|
x_hash_table_remove(window_hash, wid);
|
|
pthread_rwlock_unlock(&window_hash_rwlock);
|
|
#endif
|
|
|
|
err = xp_destroy_window(x_cvt_vptr_to_uint(wid));
|
|
if (err != Success)
|
|
FatalError("Could not destroy window %d (%d).",
|
|
(int)x_cvt_vptr_to_uint(
|
|
wid), (int)err);
|
|
}
|
|
|
|
/*
|
|
* Move a frame on screen.
|
|
*/
|
|
static void
|
|
xprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY)
|
|
{
|
|
xp_window_changes wc;
|
|
|
|
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;
|
|
|
|
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;
|
|
#ifdef HAVE_LIBDISPATCH
|
|
__block
|
|
#endif
|
|
RootlessWindowRec * winRec;
|
|
|
|
/* 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);
|
|
}
|
|
|
|
#ifdef HAVE_LIBDISPATCH
|
|
dispatch_sync(window_hash_serial_q, ^ {
|
|
winRec = x_hash_table_lookup(window_hash, wid, NULL);
|
|
});
|
|
#else
|
|
pthread_rwlock_rdlock(&window_hash_rwlock);
|
|
winRec = x_hash_table_lookup(window_hash, wid, NULL);
|
|
pthread_rwlock_unlock(&window_hash_rwlock);
|
|
#endif
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
err = xp_lock_window(x_cvt_vptr_to_uint(
|
|
wid), NULL, NULL, data, rowbytes, NULL);
|
|
if (err != Success)
|
|
FatalError("Could not lock window %d for drawing (%d).",
|
|
(int)x_cvt_vptr_to_uint(
|
|
wid), (int)err);
|
|
|
|
*pixelData = data[0];
|
|
*bytesPerRow = rowbytes[0];
|
|
}
|
|
|
|
/*
|
|
* Stop drawing to a frame.
|
|
*/
|
|
static void
|
|
xprStopDrawing(RootlessFrameID wid, Bool flush)
|
|
{
|
|
xp_error err;
|
|
|
|
err = xp_unlock_window(x_cvt_vptr_to_uint(wid), flush);
|
|
/* This should be a FatalError, but we started tripping over it. Make it a
|
|
* FatalError after http://xquartz.macosforge.org/trac/ticket/482 is fixed.
|
|
*/
|
|
if (err != Success)
|
|
ErrorF("Could not unlock window %d after drawing (%d).",
|
|
(int)x_cvt_vptr_to_uint(
|
|
wid), (int)err);
|
|
}
|
|
|
|
/*
|
|
* Flush drawing updates to the screen.
|
|
*/
|
|
static void
|
|
xprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage)
|
|
{
|
|
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)
|
|
{
|
|
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());
|
|
|
|
xprSetNativeProperty(pFrame);
|
|
}
|
|
|
|
/*
|
|
* Called to check if the frame should be reordered when it is restacked.
|
|
*/
|
|
static Bool
|
|
xprDoReorderWindow(RootlessWindowPtr pFrame)
|
|
{
|
|
WindowPtr pWin = pFrame->win;
|
|
|
|
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)
|
|
{
|
|
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);
|
|
|
|
rootless_CopyBytes_threshold = xp_copy_bytes_threshold;
|
|
rootless_CopyWindow_threshold = xp_scroll_area_threshold;
|
|
|
|
assert((window_hash = x_hash_table_new(NULL, NULL, NULL, NULL)));
|
|
#ifdef HAVE_LIBDISPATCH
|
|
assert((window_hash_serial_q =
|
|
dispatch_queue_create(BUNDLE_ID_PREFIX ".X11.xpr_window_hash",
|
|
NULL)));
|
|
#else
|
|
assert(0 == pthread_rwlock_init(&window_hash_rwlock, NULL));
|
|
#endif
|
|
|
|
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)
|
|
{
|
|
#ifdef HAVE_LIBDISPATCH
|
|
RootlessWindowRec *winRec __block;
|
|
dispatch_sync(window_hash_serial_q, ^ {
|
|
winRec =
|
|
x_hash_table_lookup(window_hash,
|
|
x_cvt_uint_to_vptr(wid), NULL);
|
|
});
|
|
#else
|
|
RootlessWindowRec *winRec;
|
|
pthread_rwlock_rdlock(&window_hash_rwlock);
|
|
winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL);
|
|
pthread_rwlock_unlock(&window_hash_rwlock);
|
|
#endif
|
|
|
|
return winRec != NULL ? winRec->win : NULL;
|
|
}
|
|
|
|
/*
|
|
* The windowNumber is an AppKit window number. Returns TRUE if xpr is
|
|
* displaying a window with that number.
|
|
*/
|
|
Bool
|
|
xprIsX11Window(int windowNumber)
|
|
{
|
|
Bool ret;
|
|
xp_window_id wid;
|
|
|
|
if (xp_lookup_native_window(windowNumber, &wid))
|
|
ret = xprGetXWindow(wid) != NULL;
|
|
else
|
|
ret = FALSE;
|
|
|
|
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;
|
|
|
|
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);
|
|
}
|