diff options
Diffstat (limited to 'hw/darwin/quartz/xpr')
-rw-r--r-- | hw/darwin/quartz/xpr/Xplugin.h | 591 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/appledri.c | 350 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/dri.c | 690 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/dri.h | 130 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/dristruct.h | 82 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/x-hash.c | 341 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/x-hash.h | 62 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/x-hook.c | 106 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/x-hook.h | 44 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/x-list.c | 316 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/x-list.h | 78 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/xpr.h | 47 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/xprAppleWM.c | 99 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/xprCursor.c | 420 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/xprFrame.c | 439 | ||||
-rw-r--r-- | hw/darwin/quartz/xpr/xprScreen.c | 378 |
16 files changed, 4173 insertions, 0 deletions
diff --git a/hw/darwin/quartz/xpr/Xplugin.h b/hw/darwin/quartz/xpr/Xplugin.h new file mode 100644 index 000000000..8985f7b11 --- /dev/null +++ b/hw/darwin/quartz/xpr/Xplugin.h @@ -0,0 +1,591 @@ +/* Xplugin.h -- windowing API for rootless X11 server + $Id$ + + Copyright (c) 2002 Apple Computer, Inc. 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. + + Note that these interfaces are provided solely for the use of the + X11 server. Any other uses are unsupported and strongly discouraged. */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/Xplugin.h,v 1.3 2003/06/27 20:21:42 torrey Exp $ */ + +#ifndef XPLUGIN_H +#define XPLUGIN_H 1 + +#include <stdint.h> + +/* By default we use the X server definition of BoxRec to define xp_box, + so that the compiler can silently convert between the two. But if + XP_NO_X_HEADERS is defined, we'll define it ourselves. */ + +#ifndef XP_NO_X_HEADERS +# include "miscstruct.h" + typedef BoxRec xp_box; +#else + struct xp_box_struct { + short x1, y1, x2, y2; + }; + typedef struct xp_box_struct xp_box; +#endif + +typedef unsigned int xp_resource_id; +typedef xp_resource_id xp_window_id; +typedef xp_resource_id xp_surface_id; +typedef unsigned int xp_client_id; +typedef unsigned int xp_request_type; +typedef int xp_error; +typedef int xp_bool; + + +/* Error codes that the functions declared here may return. They all + numerically match their X equivalents, i.e. the XP_ can be dropped + if <X11/X.h> has been included. */ + +enum xp_error_enum { + XP_Success = 0, + XP_BadRequest = 1, + XP_BadValue = 2, + XP_BadWindow = 3, + XP_BadMatch = 8, + XP_BadAccess = 10, + XP_BadImplementation = 17, +}; + + +/* Event types generated by the plugin. */ + +enum xp_event_type_enum { + /* The global display configuration changed somehow. */ + XP_EVENT_DISPLAY_CHANGED = 1 << 0, + + /* A window changed state. Argument is xp_window_state_event */ + XP_EVENT_WINDOW_STATE_CHANGED = 1 << 1, + + /* An async request encountered an error. Argument is of type + xp_async_error_event */ + XP_EVENT_ASYNC_ERROR = 1 << 2, + + /* Sent when a surface is destroyed as a side effect of destroying + a window. Arg is of type xp_surface_id. */ + XP_EVENT_SURFACE_DESTROYED = 1 << 3, + + /* Sent when any GL contexts pointing at the given surface need to + call xp_update_gl_context () to refresh their state (because the + window moved or was resized. Arg is of type xp_surface_id. */ + XP_EVENT_SURFACE_CHANGED = 1 << 4, + + /* Sent when a window has been moved. Arg is of type xp_window_id. */ + XP_EVENT_WINDOW_MOVED = 1 << 5, +}; + +/* Function type used to receive events. */ + +typedef void (xp_event_fun) (unsigned int type, const void *arg, + unsigned int arg_size, void *user_data); + + +/* Operation types. Used when reporting errors asynchronously. */ + +enum xp_request_type_enum { + XP_REQUEST_NIL = 0, + XP_REQUEST_DESTROY_WINDOW = 1, + XP_REQUEST_CONFIGURE_WINDOW = 2, + XP_REQUEST_FLUSH_WINDOW = 3, + XP_REQUEST_COPY_WINDOW = 4, + XP_REQUEST_UNLOCK_WINDOW = 5, + XP_REQUEST_DISABLE_UPDATE = 6, + XP_REQUEST_REENABLE_UPDATE = 7, + XP_REQUEST_HIDE_CURSOR = 8, + XP_REQUEST_SHOW_CURSOR = 9, + XP_REQUEST_FRAME_DRAW = 10, +}; + +/* Structure used to report an error asynchronously. Passed as the "arg" + of an XP_EVENT_ASYNC_ERROR event. */ + +struct xp_async_error_event_struct { + xp_request_type request_type; + xp_resource_id id; + xp_error error; +}; + +typedef struct xp_async_error_event_struct xp_async_error_event; + + +/* Possible window states. */ + +enum xp_window_state_enum { + /* The window is not in the global list of possibly-visible windows. */ + XP_WINDOW_STATE_OFFSCREEN = 1 << 0, + + /* Parts of the window may be obscured by other windows. */ + XP_WINDOW_STATE_OBSCURED = 1 << 1, +}; + +/* Structure passed as argument of an XP_EVENT_WINDOW_STATE_CHANGED event. */ + +struct xp_window_state_event_struct { + xp_window_id id; + unsigned int state; +}; + +typedef struct xp_window_state_event_struct xp_window_state_event; + + +/* Function type used to supply a colormap for indexed drawables. */ + +typedef xp_error (xp_colormap_fun) (void *data, int first_color, + int n_colors, uint32_t *colors); + + +/* Window attributes structure. Used when creating and configuring windows. + Also used when configuring surfaces attached to windows. Functions that + take one of these structures also take a bit mask defining which + fields are set to meaningful values. */ + +enum xp_window_changes_enum { + XP_ORIGIN = 1 << 0, + XP_SIZE = 1 << 1, + XP_BOUNDS = XP_ORIGIN | XP_SIZE, + XP_SHAPE = 1 << 2, + XP_STACKING = 1 << 3, + XP_DEPTH = 1 << 4, + XP_COLORMAP = 1 << 5, + XP_WINDOW_LEVEL = 1 << 6, +}; + +struct xp_window_changes_struct { + /* XP_ORIGIN */ + int x, y; + + /* XP_SIZE */ + unsigned int width, height; + int bit_gravity; /* how to resize the backing store */ + + /* XP_SHAPE */ + int shape_nrects; /* -1 = remove shape */ + xp_box *shape_rects; + int shape_tx, shape_ty; /* translation for shape */ + + /* XP_STACKING */ + int stack_mode; + xp_window_id sibling; /* may be zero; in ABOVE/BELOW modes + it may specify a relative window */ + /* XP_DEPTH, window-only */ + unsigned int depth; + + /* XP_COLORMAP, window-only */ + xp_colormap_fun *colormap; + void *colormap_data; + + /* XP_WINDOW_LEVEL, window-only */ + int window_level; +}; + +typedef struct xp_window_changes_struct xp_window_changes; + +/* Values for bit_gravity field */ + +enum xp_bit_gravity_enum { + XP_GRAVITY_NONE = 0, /* no gravity, fill everything */ + XP_GRAVITY_NORTH_WEST = 1, /* anchor to top-left corner */ + XP_GRAVITY_NORTH_EAST = 2, /* anchor to top-right corner */ + XP_GRAVITY_SOUTH_EAST = 3, /* anchor to bottom-right corner */ + XP_GRAVITY_SOUTH_WEST = 4, /* anchor to bottom-left corner */ +}; + +/* Values for stack_mode field */ + +enum xp_window_stack_mode_enum { + XP_UNMAPPED = 0, /* remove the window */ + XP_MAPPED_ABOVE = 1, /* display the window on top */ + XP_MAPPED_BELOW = 2, /* display the window at bottom */ +}; + +/* Data formats for depth field and composite functions */ + +enum xp_depth_enum { + XP_DEPTH_NIL = 0, /* null source when compositing */ + XP_DEPTH_ARGB8888, + XP_DEPTH_RGB555, + XP_DEPTH_A8, /* for masks when compositing */ + XP_DEPTH_INDEX8, +}; + +/* Options that may be passed to the xp_init () function. */ + +enum xp_init_options_enum { + /* Don't mark that this process can be in the foreground. */ + XP_IN_BACKGROUND = 1 << 0, + + /* Deliver background pointer events to this process. */ + XP_BACKGROUND_EVENTS = 1 << 1, +}; + + + +/* Miscellaneous functions */ + +/* Initialize the plugin library. Only the copy/fill/composite functions + may be called without having previously called xp_init () */ + +extern xp_error xp_init (unsigned int options); + +/* Sets the current set of requested notifications to MASK. When any of + these arrive, CALLBACK will be invoked with CALLBACK-DATA. Note that + calling this function cancels any previously requested notifications + that aren't set in MASK. */ + +extern xp_error xp_select_events (unsigned int mask, + xp_event_fun *callback, + void *callback_data); + +/* Waits for all initiated operations to complete. */ + +extern xp_error xp_synchronize (void); + +/* Causes any display update initiated through the plugin libary to be + queued until update is reenabled. Note that calls to these functions + nest. */ + +extern xp_error xp_disable_update (void); +extern xp_error xp_reenable_update (void); + + + +/* Cursor functions. */ + +/* Installs the specified cursor. ARGB-DATA should point to 32-bit + premultiplied big-endian ARGB data. The HOT-X,HOT-Y parameters + specify the offset to the cursor's hot spot from its top-left + corner. */ + +extern xp_error xp_set_cursor (unsigned int width, unsigned int height, + unsigned int hot_x, unsigned int hot_y, + const uint32_t *argb_data, + unsigned int rowbytes); + +/* Hide and show the cursor if it's owned by the current process. Calls + to these functions nest. */ + +extern xp_error xp_hide_cursor (void); +extern xp_error xp_show_cursor (void); + + + +/* Window functions. */ + +/* Create a new window as defined by MASK and VALUES. MASK must contain + XP_BOUNDS or an error is raised. The id of the newly created window + is stored in *RET-ID if this function returns XP_Success. */ + +extern xp_error xp_create_window (unsigned int mask, + const xp_window_changes *values, + xp_window_id *ret_id); + +/* Destroys the window identified by ID. */ + +extern xp_error xp_destroy_window (xp_window_id id); + +/* Reconfigures the given window according to MASK and VALUES. */ + +extern xp_error xp_configure_window (xp_window_id id, unsigned int mask, + const xp_window_changes *values); + + +/* Returns true if NATIVE-ID is a window created by the plugin library. + If so and RET-ID is non-null, stores the id of the window in *RET-ID. */ + +extern xp_bool xp_lookup_native_window (unsigned int native_id, + xp_window_id *ret_id); + +/* If ID names a window created by the plugin library, stores it's native + window id in *RET-NATIVE-ID. */ + +extern xp_error xp_get_native_window (xp_window_id id, + unsigned int *ret_native_id); + + +/* Locks the rectangle IN-RECT (or, if null, the entire window) of the + given window's backing store. Any other non-null parameters are filled + in as follows: + + DEPTH = format of returned data. Currently either XP_DEPTH_ARGB8888 + or XP_DEPTH_RGB565 (possibly with 8 bit planar alpha). Data is + always stored in native byte order. + + BITS[0] = pointer to top-left pixel of locked color data + BITS[1] = pointer to top-left of locked alpha data, or null if window + has no alpha. If the alpha data is meshed, then BITS[1] = BITS[0]. + + ROWBYTES[0,1] = size in bytes of each row of color,alpha data + + OUT-RECT = rectangle specifying the current position and size of the + locked region relative to the window origin. + + Note that an error is raised when trying to lock an already locked + window. While the window is locked, the only operations that may + be performed on it are to modify, access or flush its marked region. */ + +extern xp_error xp_lock_window (xp_window_id id, + const xp_box *in_rect, + unsigned int *depth, + void *bits[2], + unsigned int rowbytes[2], + xp_box *out_rect); + +/* Mark that the region specified by SHAPE-NRECTS, SHAPE-RECTS, + SHAPE-TX, and SHAPE-TY in the specified window has been updated, and + will need to subsequently be redisplayed. */ + +extern xp_error xp_mark_window (xp_window_id id, int shape_nrects, + const xp_box *shape_rects, + int shape_tx, int shape_ty); + +/* Unlocks the specified window. If FLUSH is true, then any marked + regions are immediately redisplayed. Note that it's an error to + unlock an already unlocked window. */ + +extern xp_error xp_unlock_window (xp_window_id id, xp_bool flush); + +/* If anything is marked in the given window for redisplay, do it now. */ + +extern xp_error xp_flush_window (xp_window_id id); + +/* Moves the contents of the region DX,DY pixels away from that specified + by DST_RECTS and DST_NRECTS in the window with SRC-ID to the + destination region in the window DST-ID. Note that currently source + and destination windows must be the same. */ + +extern xp_error xp_copy_window (xp_window_id src_id, xp_window_id dst_id, + int dst_nrects, const xp_box *dst_rects, + int dx, int dy); + +/* Returns true if the given window has any regions marked for + redisplay. */ + +extern xp_bool xp_is_window_marked (xp_window_id id); + +/* If successful returns a superset of the region marked for update in + the given window. Use xp_free_region () to release the returned data. */ + +extern xp_error xp_get_marked_shape (xp_window_id id, + int *ret_nrects, xp_box **ret_rects); + +extern void xp_free_shape (int nrects, xp_box *rects); + +/* Searches for the first window below ABOVE-ID containing the point X,Y, + and returns it's window id in *RET-ID. If no window is found, *RET-ID + is set to zero. If ABOVE-ID is zero, finds the topmost window + containing the given point. */ + +extern xp_error xp_find_window (int x, int y, xp_window_id above_id, + xp_window_id *ret_id); + +/* Returns the current origin and size of the window ID in *BOUNDS-RET if + successful. */ +extern xp_error xp_get_window_bounds (xp_window_id id, xp_box *bounds_ret); + + + +/* Window surface functions. */ + +/* Create a new VRAM surface on the specified window. If successful, + returns the identifier of the new surface in *RET-SID. */ + +extern xp_error xp_create_surface (xp_window_id id, xp_surface_id *ret_sid); + +/* Destroys the specified surface. */ + +extern xp_error xp_destroy_surface (xp_surface_id sid); + +/* Reconfigures the specified surface as defined by MASK and VALUES. + Note that specifying XP_DEPTH is an error. */ + +extern xp_error xp_configure_surface (xp_surface_id sid, unsigned int mask, + const xp_window_changes *values); + +/* If successful, places the client identifier of the current process + in *RET-CLIENT. */ + +extern xp_error xp_get_client_id (xp_client_id *ret_client); + +/* Given a valid window,surface combination created by the current + process, attempts to allow the specified external client access + to that surface. If successful, returns two integers in RET-KEY + which the client can use to import the surface into their process. */ + +extern xp_error xp_export_surface (xp_window_id wid, xp_surface_id sid, + xp_client_id client, + unsigned int ret_key[2]); + +/* Given a two integer key returned from xp_export_surface (), tries + to import the surface into the current process. If successful the + local surface identifier is stored in *SID-RET. */ + +extern xp_error xp_import_surface (const unsigned int key[2], + xp_surface_id *sid_ret); + +/* If successful, stores the number of surfaces attached to the + specified window in *RET. */ + +extern xp_error xp_get_window_surface_count (xp_window_id id, + unsigned int *ret); + +/* Attaches the CGLContextObj CGL-CTX to the specified surface. */ + +extern xp_error xp_attach_gl_context (void *cgl_ctx, xp_surface_id sid); + +/* Updates the CGLContextObj CGL-CTX to reflect any recent changes to + the surface it's attached to. */ + +extern xp_error xp_update_gl_context (void *cgl_ctx); + + + +/* Window frame functions. */ + +/* Possible arguments to xp_frame_get_rect (). */ + +enum xp_frame_rect_enum { + XP_FRAME_RECT_TITLEBAR = 1, + XP_FRAME_RECT_TRACKING = 2, + XP_FRAME_RECT_GROWBOX = 3, +}; + +/* Classes of window frame. */ + +enum xp_frame_class_enum { + XP_FRAME_CLASS_DOCUMENT = 1 << 0, + XP_FRAME_CLASS_DIALOG = 1 << 1, + XP_FRAME_CLASS_MODAL_DIALOG = 1 << 2, + XP_FRAME_CLASS_SYSTEM_MODAL_DIALOG = 1 << 3, + XP_FRAME_CLASS_UTILITY = 1 << 4, + XP_FRAME_CLASS_TOOLBAR = 1 << 5, + XP_FRAME_CLASS_MENU = 1 << 6, + XP_FRAME_CLASS_SPLASH = 1 << 7, + XP_FRAME_CLASS_BORDERLESS = 1 << 8, +}; + +/* Attributes of window frames. */ + +enum xp_frame_attr_enum { + XP_FRAME_ACTIVE = 0x0001, + XP_FRAME_URGENT = 0x0002, + XP_FRAME_TITLE = 0x0004, + XP_FRAME_PRELIGHT = 0x0008, + XP_FRAME_SHADED = 0x0010, + XP_FRAME_CLOSE_BOX = 0x0100, + XP_FRAME_COLLAPSE = 0x0200, + XP_FRAME_ZOOM = 0x0400, + XP_FRAME_ANY_BUTTON = 0x0700, + XP_FRAME_CLOSE_BOX_CLICKED = 0x0800, + XP_FRAME_COLLAPSE_BOX_CLICKED = 0x1000, + XP_FRAME_ZOOM_BOX_CLICKED = 0x2000, + XP_FRAME_ANY_CLICKED = 0x3800, + XP_FRAME_GROW_BOX = 0x4000, +}; + +#define XP_FRAME_ATTR_IS_SET(a,b) (((a) & (b)) == (b)) +#define XP_FRAME_ATTR_IS_CLICKED(a,m) ((a) & ((m) << 3)) +#define XP_FRAME_ATTR_SET_CLICKED(a,m) ((a) |= ((m) << 3)) +#define XP_FRAME_ATTR_UNSET_CLICKED(a,m) ((a) &= ~((m) << 3)) + +#define XP_FRAME_POINTER_ATTRS (XP_FRAME_PRELIGHT \ + | XP_FRAME_ANY_BUTTON \ + | XP_FRAME_ANY_CLICKED) + +extern xp_error xp_frame_get_rect (int type, int class, const xp_box *outer, + const xp_box *inner, xp_box *ret); +extern xp_error xp_frame_hit_test (int class, int x, int y, + const xp_box *outer, + const xp_box *inner, int *ret); +extern xp_error xp_frame_draw (xp_window_id wid, int class, unsigned int attr, + const xp_box *outer, const xp_box *inner, + unsigned int title_len, + const unsigned char *title_bytes); + + + +/* Memory manipulation functions. */ + +enum xp_composite_op_enum { + XP_COMPOSITE_SRC = 0, + XP_COMPOSITE_OVER, +}; + +#define XP_COMPOSITE_FUNCTION(op, src_depth, mask_depth, dest_depth) \ + (((op) << 24) | ((src_depth) << 16) \ + | ((mask_depth) << 8) | ((dest_depth) << 0)) + +#define XP_COMPOSITE_FUNCTION_OP(f) (((f) >> 24) & 255) +#define XP_COMPOSITE_FUNCTION_SRC_DEPTH(f) (((f) >> 16) & 255) +#define XP_COMPOSITE_FUNCTION_MASK_DEPTH(f) (((f) >> 8) & 255) +#define XP_COMPOSITE_FUNCTION_DEST_DEPTH(f) (((f) >> 0) & 255) + +/* Composite WIDTH by HEIGHT pixels from source and mask to destination + using a specified function (if source and destination overlap, + undefined behavior results). + + For SRC and DEST, the first element of the array is the color data. If + the second element is non-null it implies that there is alpha data + (which may be meshed or planar). Data without alpha is assumed to be + opaque. + + Passing a null SRC-ROWBYTES pointer implies that the data SRC points + to is a single element. + + Operations that are not supported will return XP_BadImplementation. */ + +extern xp_error xp_composite_pixels (unsigned int width, unsigned int height, + unsigned int function, + void *src[2], unsigned int src_rowbytes[2], + void *mask, unsigned int mask_rowbytes, + void *dest[2], unsigned int dest_rowbytes[2]); + +/* Fill HEIGHT rows of data starting at DST. Each row will have WIDTH + bytes filled with the 32-bit pattern VALUE. Each row is DST-ROWBYTES + wide in total. */ + +extern void xp_fill_bytes (unsigned int width, + unsigned int height, uint32_t value, + void *dst, unsigned int dst_rowbytes); + +/* Copy HEIGHT rows of bytes from SRC to DST. Each row will have WIDTH + bytes copied. SRC and DST may overlap, and the right thing will happen. */ + +extern void xp_copy_bytes (unsigned int width, unsigned int height, + const void *src, unsigned int src_rowbytes, + void *dst, unsigned int dst_rowbytes); + +/* Suggestions for the minimum number of bytes or pixels for which it + makes sense to use some of the xp_ functions */ + +extern unsigned int xp_fill_bytes_threshold, xp_copy_bytes_threshold, + xp_composite_area_threshold, xp_scroll_area_threshold; + + +#endif /* XPLUGIN_H */ diff --git a/hw/darwin/quartz/xpr/appledri.c b/hw/darwin/quartz/xpr/appledri.c new file mode 100644 index 000000000..3062d964a --- /dev/null +++ b/hw/darwin/quartz/xpr/appledri.c @@ -0,0 +1,350 @@ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/appledri.c,v 1.1 2003/06/30 01:45:13 torrey Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +Copyright (c) 2002 Apple Computer, Inc. +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, sub license, 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 (including the +next paragraph) 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 NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Jens Owen <jens@valinux.com> + * Rickard E. (Rik) Faith <faith@valinux.com> + * + */ + +#define NEED_REPLIES +#define NEED_EVENTS +#include "X.h" +#include "Xproto.h" +#include "misc.h" +#include "dixstruct.h" +#include "extnsionst.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "scrnintstr.h" +#include "servermd.h" +#define _APPLEDRI_SERVER_ +#include "appledristr.h" +#include "swaprep.h" +#include "dri.h" +#include "dristruct.h" + +static int DRIErrorBase = 0; + +static DISPATCH_PROC(ProcAppleDRIDispatch); +static DISPATCH_PROC(SProcAppleDRIDispatch); + +static void AppleDRIResetProc(ExtensionEntry* extEntry); + +static unsigned char DRIReqCode = 0; +static int DRIEventBase = 0; + +static void SNotifyEvent(xAppleDRINotifyEvent *from, xAppleDRINotifyEvent *to); + +typedef struct _DRIEvent *DRIEventPtr; +typedef struct _DRIEvent { + DRIEventPtr next; + ClientPtr client; + XID clientResource; + unsigned int mask; +} DRIEventRec; + + +void +AppleDRIExtensionInit(void) +{ + ExtensionEntry* extEntry; + + if (DRIExtensionInit() && + (extEntry = AddExtension(APPLEDRINAME, + AppleDRINumberEvents, + AppleDRINumberErrors, + ProcAppleDRIDispatch, + SProcAppleDRIDispatch, + AppleDRIResetProc, + StandardMinorOpcode))) { + DRIReqCode = (unsigned char)extEntry->base; + DRIErrorBase = extEntry->errorBase; + DRIEventBase = extEntry->eventBase; + EventSwapVector[DRIEventBase] = (EventSwapPtr) SNotifyEvent; + } +} + +/*ARGSUSED*/ +static void +AppleDRIResetProc ( + ExtensionEntry* extEntry +) +{ + DRIReset(); +} + +static int +ProcAppleDRIQueryVersion( + register ClientPtr client +) +{ + xAppleDRIQueryVersionReply rep; + register int n; + + REQUEST_SIZE_MATCH(xAppleDRIQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = APPLE_DRI_MAJOR_VERSION; + rep.minorVersion = APPLE_DRI_MINOR_VERSION; + rep.patchVersion = APPLE_DRI_PATCH_VERSION; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + } + WriteToClient(client, sizeof(xAppleDRIQueryVersionReply), (char *)&rep); + return (client->noClientException); +} + + +/* surfaces */ + +static int +ProcAppleDRIQueryDirectRenderingCapable( + register ClientPtr client +) +{ + xAppleDRIQueryDirectRenderingCapableReply rep; + Bool isCapable; + + REQUEST(xAppleDRIQueryDirectRenderingCapableReq); + REQUEST_SIZE_MATCH(xAppleDRIQueryDirectRenderingCapableReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if (!DRIQueryDirectRenderingCapable( screenInfo.screens[stuff->screen], + &isCapable)) { + return BadValue; + } + rep.isCapable = isCapable; + + if (!LocalClient(client)) + rep.isCapable = 0; + + WriteToClient(client, + sizeof(xAppleDRIQueryDirectRenderingCapableReply), (char *)&rep); + return (client->noClientException); +} + +static int +ProcAppleDRIAuthConnection( + register ClientPtr client +) +{ + xAppleDRIAuthConnectionReply rep; + + REQUEST(xAppleDRIAuthConnectionReq); + REQUEST_SIZE_MATCH(xAppleDRIAuthConnectionReq); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.authenticated = 1; + + if (!DRIAuthConnection( screenInfo.screens[stuff->screen], stuff->magic)) { + ErrorF("Failed to authenticate %u\n", stuff->magic); + rep.authenticated = 0; + } + WriteToClient(client, sizeof(xAppleDRIAuthConnectionReply), (char *)&rep); + return (client->noClientException); +} + +static void surface_notify( + void *_arg, + void *data +) +{ + DRISurfaceNotifyArg *arg = _arg; + int client_index = (int) data; + ClientPtr client; + xAppleDRINotifyEvent se; + + if (client_index < 0 || client_index >= currentMaxClients) + return; + + client = clients[client_index]; + if (client == NULL || client == serverClient || client->clientGone) + return; + + se.type = DRIEventBase + AppleDRISurfaceNotify; + se.kind = arg->kind; + se.arg = arg->id; + se.sequenceNumber = client->sequence; + se.time = currentTime.milliseconds; + WriteEventsToClient (client, 1, (xEvent *) &se); +} + +static int +ProcAppleDRICreateSurface( + ClientPtr client +) +{ + xAppleDRICreateSurfaceReply rep; + DrawablePtr pDrawable; + xp_surface_id sid; + unsigned int key[2]; + + REQUEST(xAppleDRICreateSurfaceReq); + REQUEST_SIZE_MATCH(xAppleDRICreateSurfaceReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if (!(pDrawable = (DrawablePtr)SecurityLookupDrawable( + (Drawable)stuff->drawable, + client, + SecurityReadAccess))) { + return BadValue; + } + + rep.key_0 = rep.key_1 = rep.uid = 0; + + if (!DRICreateSurface( screenInfo.screens[stuff->screen], + (Drawable)stuff->drawable, pDrawable, + stuff->client_id, &sid, key, + surface_notify, (void *) client->index)) { + return BadValue; + } + + rep.key_0 = key[0]; + rep.key_1 = key[1]; + rep.uid = sid; + + WriteToClient(client, sizeof(xAppleDRICreateSurfaceReply), (char *)&rep); + return (client->noClientException); +} + +static int +ProcAppleDRIDestroySurface( + register ClientPtr client +) +{ + REQUEST(xAppleDRIDestroySurfaceReq); + DrawablePtr pDrawable; + REQUEST_SIZE_MATCH(xAppleDRIDestroySurfaceReq); + + if (!(pDrawable = (DrawablePtr)SecurityLookupDrawable( + (Drawable)stuff->drawable, + client, + SecurityReadAccess))) { + return BadValue; + } + + if (!DRIDestroySurface( screenInfo.screens[stuff->screen], + (Drawable)stuff->drawable, + pDrawable, NULL, NULL)) { + return BadValue; + } + + return (client->noClientException); +} + + +/* dispatch */ + +static int +ProcAppleDRIDispatch ( + register ClientPtr client +) +{ + REQUEST(xReq); + + switch (stuff->data) + { + case X_AppleDRIQueryVersion: + return ProcAppleDRIQueryVersion(client); + case X_AppleDRIQueryDirectRenderingCapable: + return ProcAppleDRIQueryDirectRenderingCapable(client); + } + + if (!LocalClient(client)) + return DRIErrorBase + AppleDRIClientNotLocal; + + switch (stuff->data) + { + case X_AppleDRIAuthConnection: + return ProcAppleDRIAuthConnection(client); + case X_AppleDRICreateSurface: + return ProcAppleDRICreateSurface(client); + case X_AppleDRIDestroySurface: + return ProcAppleDRIDestroySurface(client); + default: + return BadRequest; + } +} + +static void +SNotifyEvent( + xAppleDRINotifyEvent *from, + xAppleDRINotifyEvent *to +) +{ + to->type = from->type; + to->kind = from->kind; + cpswaps (from->sequenceNumber, to->sequenceNumber); + cpswapl (from->time, to->time); + cpswapl (from->arg, to->arg); +} + +static int +SProcAppleDRIQueryVersion( + register ClientPtr client +) +{ + register int n; + REQUEST(xAppleDRIQueryVersionReq); + swaps(&stuff->length, n); + return ProcAppleDRIQueryVersion(client); +} + +static int +SProcAppleDRIDispatch ( + register ClientPtr client +) +{ + REQUEST(xReq); + + /* It is bound to be non-local when there is byte swapping */ + if (!LocalClient(client)) + return DRIErrorBase + AppleDRIClientNotLocal; + + /* only local clients are allowed DRI access */ + switch (stuff->data) + { + case X_AppleDRIQueryVersion: + return SProcAppleDRIQueryVersion(client); + default: + return BadRequest; + } +} diff --git a/hw/darwin/quartz/xpr/dri.c b/hw/darwin/quartz/xpr/dri.c new file mode 100644 index 000000000..aa595af85 --- /dev/null +++ b/hw/darwin/quartz/xpr/dri.c @@ -0,0 +1,690 @@ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/dri.c,v 1.1 2003/06/30 01:45:13 torrey Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +Copyright (c) 2002 Apple Computer, Inc. +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, sub license, 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 (including the +next paragraph) 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 NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. + +**************************************************************************/ + +/* + * Authors: + * Jens Owen <jens@valinux.com> + * Rickard E. (Rik) Faith <faith@valinux.com> + * + */ + +#ifdef XFree86LOADER +#include "xf86.h" +#include "xf86_ansic.h" +#else +#include <sys/time.h> +#include <unistd.h> +#endif + +#define NEED_REPLIES +#define NEED_EVENTS +#include "X.h" +#include "Xproto.h" +#include "misc.h" +#include "dixstruct.h" +#include "extnsionst.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "servermd.h" +#define _APPLEDRI_SERVER_ +#include "appledristr.h" +#include "swaprep.h" +#include "dri.h" +#include "dristruct.h" +#include "mi.h" +#include "mipointer.h" +#include "rootless.h" +#include "x-hash.h" +#include "x-hook.h" + +static int DRIScreenPrivIndex = -1; +static int DRIWindowPrivIndex = -1; + +static RESTYPE DRIDrawablePrivResType; + +static x_hash_table *surface_hash; /* maps surface ids -> drawablePrivs */ + +/* FIXME: don't hardcode this? */ +#define CG_INFO_FILE "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Resources/Info-macos.plist" + +/* Corresponds to SU Jaguar Green */ +#define CG_REQUIRED_MAJOR 1 +#define CG_REQUIRED_MINOR 157 +#define CG_REQUIRED_MICRO 11 + +/* Returns version as major.minor.micro in 10.10.10 fixed form */ +static unsigned int +get_cg_version (void) +{ + static unsigned int version; + + FILE *fh; + char *ptr; + + if (version != 0) + return version; + + /* I tried CFBundleGetVersion, but it returns zero, so.. */ + + fh = fopen (CG_INFO_FILE, "r"); + if (fh != NULL) + { + char buf[256]; + + while (fgets (buf, sizeof (buf), fh) != NULL) + { + unsigned char c; + + if (!strstr (buf, "<key>CFBundleShortVersionString</key>") + || fgets (buf, sizeof (buf), fh) == NULL) + { + continue; + } + + ptr = strstr (buf, "<string>"); + if (ptr == NULL) + continue; + + ptr += strlen ("<string>"); + + /* Now PTR points to "MAJOR.MINOR.MICRO". */ + + version = 0; + + again: + switch ((c = *ptr++)) + { + case '.': + version = version * 1024; + goto again; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + version = ((version & ~0x3ff) + + (version & 0x3ff) * 10 + (c - '0')); + goto again; + } + break; + } + + fclose (fh); + } + + return version; +} + +static Bool +test_cg_version (unsigned int major, unsigned int minor, unsigned int micro) +{ + unsigned int cg_ver = get_cg_version (); + + unsigned int cg_major = (cg_ver >> 20) & 0x3ff; + unsigned int cg_minor = (cg_ver >> 10) & 0x3ff; + unsigned int cg_micro = cg_ver & 0x3ff; + + if (cg_major > major) + return TRUE; + else if (cg_major < major) + return FALSE; + + /* cg_major == major */ + + if (cg_minor > minor) + return TRUE; + else if (cg_minor < minor) + return FALSE; + + /* cg_minor == minor */ + + if (cg_micro < micro) + return FALSE; + + return TRUE; +} + +Bool +DRIScreenInit(ScreenPtr pScreen) +{ + DRIScreenPrivPtr pDRIPriv; + int i; + + pDRIPriv = (DRIScreenPrivPtr) xcalloc(1, sizeof(DRIScreenPrivRec)); + if (!pDRIPriv) { + pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL; + return FALSE; + } + + pScreen->devPrivates[DRIScreenPrivIndex].ptr = (pointer) pDRIPriv; + pDRIPriv->directRenderingSupport = TRUE; + pDRIPriv->nrWindows = 0; + + /* Need recent cg for window access update */ + if (!test_cg_version (CG_REQUIRED_MAJOR, + CG_REQUIRED_MINOR, + CG_REQUIRED_MICRO)) + { + ErrorF ("[DRI] disabled direct rendering; requires CoreGraphics %d.%d.%d\n", + CG_REQUIRED_MAJOR, CG_REQUIRED_MINOR, CG_REQUIRED_MICRO); + + pDRIPriv->directRenderingSupport = FALSE; + + /* Note we don't nuke the dri private, since we need it for + managing indirect surfaces. */ + } + + /* Initialize drawable tables */ + for (i = 0; i < DRI_MAX_DRAWABLES; i++) { + pDRIPriv->DRIDrawables[i] = NULL; + } + + return TRUE; +} + +Bool +DRIFinishScreenInit(ScreenPtr pScreen) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + /* Allocate zero sized private area for each window. Should a window + * become a DRI window, we'll hang a DRIWindowPrivateRec off of this + * private index. + */ + if (!AllocateWindowPrivate(pScreen, DRIWindowPrivIndex, 0)) + return FALSE; + + /* Wrap DRI support */ + pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree; + pScreen->ValidateTree = DRIValidateTree; + + pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree; + pScreen->PostValidateTree = DRIPostValidateTree; + + pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures; + pScreen->WindowExposures = DRIWindowExposures; + + pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow; + pScreen->CopyWindow = DRICopyWindow; + + pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify; + pScreen->ClipNotify = DRIClipNotify; + + ErrorF("[DRI] screen %d installation complete\n", pScreen->myNum); + + return TRUE; +} + +void +DRICloseScreen(ScreenPtr pScreen) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + if (pDRIPriv && pDRIPriv->directRenderingSupport) { + xfree(pDRIPriv); + pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL; + } +} + +Bool +DRIExtensionInit(void) +{ + static unsigned long DRIGeneration = 0; + + if (DRIGeneration != serverGeneration) { + if ((DRIScreenPrivIndex = AllocateScreenPrivateIndex()) < 0) + return FALSE; + DRIGeneration = serverGeneration; + } + + /* Allocate a window private index with a zero sized private area for + * each window, then should a window become a DRI window, we'll hang + * a DRIWindowPrivateRec off of this private index. + */ + if ((DRIWindowPrivIndex = AllocateWindowPrivateIndex()) < 0) + return FALSE; + + DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete); + + return TRUE; +} + +void +DRIReset(void) +{ + /* + * This stub routine is called when the X Server recycles, resources + * allocated by DRIExtensionInit need to be managed here. + * + * Currently this routine is a stub because all the interesting resources + * are managed via the screen init process. + */ +} + +Bool +DRIQueryDirectRenderingCapable(ScreenPtr pScreen, Bool* isCapable) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + if (pDRIPriv) + *isCapable = pDRIPriv->directRenderingSupport; + else + *isCapable = FALSE; + + return TRUE; +} + +Bool +DRIAuthConnection(ScreenPtr pScreen, unsigned int magic) +{ +#if 0 + /* FIXME: something? */ + + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + if (drmAuthMagic(pDRIPriv->drmFD, magic)) return FALSE; +#endif + return TRUE; +} + +static void +DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv, WindowPtr pWin) +{ + WindowPtr pTopWin; + xp_window_changes wc; + + if (pDRIDrawablePriv->sid == 0) + return; + + pTopWin = TopLevelParent(pWin); + + wc.x = pWin->drawable.x - (pTopWin->drawable.x - pTopWin->borderWidth); + wc.y = pWin->drawable.y - (pTopWin->drawable.y - pTopWin->borderWidth); + wc.width = pWin->drawable.width + 2 * pWin->borderWidth; + wc.height = pWin->drawable.height + 2 * pWin->borderWidth; + wc.bit_gravity = XP_GRAVITY_NONE; + + wc.shape_nrects = REGION_NUM_RECTS(&pWin->clipList); + wc.shape_rects = REGION_RECTS(&pWin->clipList); + wc.shape_tx = - (pTopWin->drawable.x - pTopWin->borderWidth); + wc.shape_ty = - (pTopWin->drawable.y - pTopWin->borderWidth); + + xp_configure_surface(pDRIDrawablePriv->sid, XP_BOUNDS | XP_SHAPE, &wc); +} + +Bool +DRICreateSurface (ScreenPtr pScreen, Drawable id, + DrawablePtr pDrawable, xp_client_id client_id, + xp_surface_id *surface_id, unsigned int ret_key[2], + void (*notify) (void *arg, void *data), void *notify_data) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + DRIDrawablePrivPtr pDRIDrawablePriv; + WindowPtr pWin; + + if (pDrawable->type == DRAWABLE_WINDOW) { + pWin = (WindowPtr)pDrawable; + if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) { + pDRIDrawablePriv->refCount++; + } + else { + xp_window_id wid; + xp_surface_id sid; + xp_error err; + unsigned int key[2]; + xp_window_changes wc; + + /* allocate a DRI Window Private record */ + if (!(pDRIDrawablePriv = xalloc(sizeof(DRIDrawablePrivRec)))) { + return FALSE; + } + + /* find the physical window */ + wid = (xp_window_id) RootlessFrameForWindow (pWin, TRUE); + if (wid == 0) { + xfree (pDRIDrawablePriv); + return FALSE; + } + + /* allocate the physical surface */ + err = xp_create_surface (wid, &sid); + if (err != Success) { + xfree (pDRIDrawablePriv); + return FALSE; + } + + /* try to give the client access to the surface */ + if (client_id != 0) + { + err = xp_export_surface (wid, sid, client_id, key); + if (err != Success) { + xp_destroy_surface (sid); + xfree (pDRIDrawablePriv); + return FALSE; + } + } + + /* Make it visible */ + wc.stack_mode = XP_MAPPED_ABOVE; + wc.sibling = 0; + err = xp_configure_surface (sid, XP_STACKING, &wc); + if (err != Success) + { + xp_destroy_surface (sid); + xfree (pDRIDrawablePriv); + return FALSE; + } + + /* add it to the list of DRI drawables for this screen */ + pDRIDrawablePriv->sid = sid; + pDRIDrawablePriv->pDraw = pDrawable; + pDRIDrawablePriv->pScreen = pScreen; + pDRIDrawablePriv->refCount = 1; + pDRIDrawablePriv->drawableIndex = -1; + pDRIDrawablePriv->key[0] = key[0]; + pDRIDrawablePriv->key[1] = key[1]; + pDRIDrawablePriv->notifiers = NULL; + + /* save private off of preallocated index */ + pWin->devPrivates[DRIWindowPrivIndex].ptr = + (pointer)pDRIDrawablePriv; + + ++pDRIPriv->nrWindows; + + /* and stash it by surface id */ + if (surface_hash == NULL) + surface_hash = x_hash_table_new (NULL, NULL, NULL, NULL); + x_hash_table_insert (surface_hash, (void *) sid, pDRIDrawablePriv); + + /* track this in case this window is destroyed */ + AddResource(id, DRIDrawablePrivResType, (pointer)pWin); + + /* Initialize shape */ + DRIUpdateSurface (pDRIDrawablePriv, pWin); + } + + if (notify != NULL) { + pDRIDrawablePriv->notifiers + = x_hook_add (pDRIDrawablePriv->notifiers, + notify, notify_data); + } + + *surface_id = pDRIDrawablePriv->sid; + + if (ret_key != NULL) + { + ret_key[0] = pDRIDrawablePriv->key[0]; + ret_key[1] = pDRIDrawablePriv->key[1]; + } + } + else { /* pixmap (or for GLX 1.3, a PBuffer) */ + /* NOT_DONE */ + return FALSE; + } + + return TRUE; +} + +Bool +DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable, + void (*notify) (void *, void *), void *notify_data) +{ + DRIDrawablePrivPtr pDRIDrawablePriv; + WindowPtr pWin; + + if (pDrawable->type == DRAWABLE_WINDOW) { + pWin = (WindowPtr)pDrawable; + pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); + if (pDRIDrawablePriv != NULL) { + if (notify != NULL) + { + pDRIDrawablePriv->notifiers + = x_hook_remove (pDRIDrawablePriv->notifiers, + notify, notify_data); + } + if (--pDRIDrawablePriv->refCount <= 0) { + /* This calls back to DRIDrawablePrivDelete + which frees the private area */ + FreeResourceByType(id, DRIDrawablePrivResType, FALSE); + } + } + } + else { /* pixmap (or for GLX 1.3, a PBuffer) */ + /* NOT_DONE */ + return FALSE; + } + + return TRUE; +} + +Bool +DRIDrawablePrivDelete(pointer pResource, XID id) +{ + DrawablePtr pDrawable = (DrawablePtr)pResource; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen); + DRIDrawablePrivPtr pDRIDrawablePriv; + WindowPtr pWin; + + if (pDrawable->type == DRAWABLE_WINDOW) { + pWin = (WindowPtr)pDrawable; + pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); + + if (pDRIDrawablePriv->drawableIndex != -1) { + /* release drawable table entry */ + pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL; + } + + if (pDRIDrawablePriv->sid != 0) { + xp_destroy_surface (pDRIDrawablePriv->sid); + x_hash_table_remove (surface_hash, (void *) pDRIDrawablePriv->sid); + } + + if (pDRIDrawablePriv->notifiers != NULL) + x_hook_free (pDRIDrawablePriv->notifiers); + + xfree(pDRIDrawablePriv); + pWin->devPrivates[DRIWindowPrivIndex].ptr = NULL; + + --pDRIPriv->nrWindows; + } + else { /* pixmap (or for GLX 1.3, a PBuffer) */ + /* NOT_DONE */ + return FALSE; + } + + return TRUE; +} + +void +DRIWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr bsreg) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); + + if(pDRIDrawablePriv) { + /* FIXME: something? */ + } + + pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures; + + (*pScreen->WindowExposures)(pWin, prgn, bsreg); + + pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures; + pScreen->WindowExposures = DRIWindowExposures; + +} + +void +DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + DRIDrawablePrivPtr pDRIDrawablePriv; + + if (pDRIPriv->nrWindows > 0) { + pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW (pWin); + if (pDRIDrawablePriv != NULL) { + DRIUpdateSurface (pDRIDrawablePriv, pWin); + } + } + + /* unwrap */ + pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow; + + /* call lower layers */ + (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc); + + /* rewrap */ + pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow; + pScreen->CopyWindow = DRICopyWindow; +} + +int +DRIValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) +{ + ScreenPtr pScreen = pParent->drawable.pScreen; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + int returnValue; + + /* unwrap */ + pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree; + + /* call lower layers */ + returnValue = (*pScreen->ValidateTree)(pParent, pChild, kind); + + /* rewrap */ + pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree; + pScreen->ValidateTree = DRIValidateTree; + + return returnValue; +} + +void +DRIPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) +{ + ScreenPtr pScreen; + DRIScreenPrivPtr pDRIPriv; + + if (pParent) { + pScreen = pParent->drawable.pScreen; + } else { + pScreen = pChild->drawable.pScreen; + } + pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + if (pDRIPriv->wrap.PostValidateTree) { + /* unwrap */ + pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree; + + /* call lower layers */ + (*pScreen->PostValidateTree)(pParent, pChild, kind); + + /* rewrap */ + pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree; + pScreen->PostValidateTree = DRIPostValidateTree; + } +} + +void +DRIClipNotify(WindowPtr pWin, int dx, int dy) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + DRIDrawablePrivPtr pDRIDrawablePriv; + + if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) { + DRIUpdateSurface (pDRIDrawablePriv, pWin); + } + + if(pDRIPriv->wrap.ClipNotify) { + pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify; + + (*pScreen->ClipNotify)(pWin, dx, dy); + + pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify; + pScreen->ClipNotify = DRIClipNotify; + } +} + +/* This lets us get at the unwrapped functions so that they can correctly + * call the lower level functions, and choose whether they will be + * called at every level of recursion (eg in validatetree). + */ +DRIWrappedFuncsRec * +DRIGetWrappedFuncs(ScreenPtr pScreen) +{ + return &(DRI_SCREEN_PRIV(pScreen)->wrap); +} + +void +DRIQueryVersion(int *majorVersion, + int *minorVersion, + int *patchVersion) +{ + *majorVersion = APPLE_DRI_MAJOR_VERSION; + *minorVersion = APPLE_DRI_MINOR_VERSION; + *patchVersion = APPLE_DRI_PATCH_VERSION; +} + +void +DRISurfaceNotify (xp_surface_id id, int kind) +{ + DRIDrawablePrivPtr pDRIDrawablePriv = NULL; + DRISurfaceNotifyArg arg; + + arg.id = id; + arg.kind = kind; + + if (surface_hash != NULL) + { + pDRIDrawablePriv = x_hash_table_lookup (surface_hash, + (void *) id, NULL); + } + + if (pDRIDrawablePriv == NULL) + return; + + if (kind == AppleDRISurfaceNotifyDestroyed) + { + pDRIDrawablePriv->sid = 0; + x_hash_table_remove (surface_hash, (void *) id); + } + + x_hook_run (pDRIDrawablePriv->notifiers, &arg); + + if (kind == AppleDRISurfaceNotifyDestroyed) + { + /* Kill off the handle. */ + + FreeResourceByType (pDRIDrawablePriv->pDraw->id, + DRIDrawablePrivResType, FALSE); + } +} diff --git a/hw/darwin/quartz/xpr/dri.h b/hw/darwin/quartz/xpr/dri.h new file mode 100644 index 000000000..350f61b56 --- /dev/null +++ b/hw/darwin/quartz/xpr/dri.h @@ -0,0 +1,130 @@ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/dri.h,v 1.1 2003/06/30 01:45:13 torrey Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright (c) 2002 Apple Computer, Inc. +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, sub license, 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 (including the +next paragraph) 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 NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. + +**************************************************************************/ + +/* + * Authors: + * Jens Owen <jens@precisioninsight.com> + * + */ + +/* Prototypes for AppleDRI functions */ + +#ifndef _DRI_H_ + +#include "Xdefs.h" +#include "scrnintstr.h" +#define _APPLEDRI_SERVER_ +#include "appledri.h" +#include "Xplugin.h" + +typedef void (*ClipNotifyPtr)( WindowPtr, int, int ); + + +/* + * These functions can be wrapped by the DRI. Each of these have + * generic default funcs (initialized in DRICreateInfoRec) and can be + * overridden by the driver in its [driver]DRIScreenInit function. + */ +typedef struct { + WindowExposuresProcPtr WindowExposures; + CopyWindowProcPtr CopyWindow; + ValidateTreeProcPtr ValidateTree; + PostValidateTreeProcPtr PostValidateTree; + ClipNotifyProcPtr ClipNotify; +} DRIWrappedFuncsRec, *DRIWrappedFuncsPtr; + +typedef struct { + xp_surface_id id; + int kind; +} DRISurfaceNotifyArg; + +extern Bool DRIScreenInit(ScreenPtr pScreen); + +extern Bool DRIFinishScreenInit(ScreenPtr pScreen); + +extern void DRICloseScreen(ScreenPtr pScreen); + +extern Bool DRIExtensionInit(void); + +extern void DRIReset(void); + +extern Bool DRIQueryDirectRenderingCapable(ScreenPtr pScreen, + Bool *isCapable); + +extern Bool DRIAuthConnection(ScreenPtr pScreen, unsigned int magic); + +extern Bool DRICreateSurface(ScreenPtr pScreen, + Drawable id, + DrawablePtr pDrawable, + xp_client_id client_id, + xp_surface_id *surface_id, + unsigned int key[2], + void (*notify) (void *arg, void *data), + void *notify_data); + +extern Bool DRIDestroySurface(ScreenPtr pScreen, + Drawable id, + DrawablePtr pDrawable, + void (*notify) (void *arg, void *data), + void *notify_data); + +extern Bool DRIDrawablePrivDelete(pointer pResource, + XID id); + +extern DRIWrappedFuncsRec *DRIGetWrappedFuncs(ScreenPtr pScreen); + +extern void DRICopyWindow(WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc); + +extern int DRIValidateTree(WindowPtr pParent, + WindowPtr pChild, + VTKind kind); + +extern void DRIPostValidateTree(WindowPtr pParent, + WindowPtr pChild, + VTKind kind); + +extern void DRIClipNotify(WindowPtr pWin, + int dx, + int dy); + +extern void DRIWindowExposures(WindowPtr pWin, + RegionPtr prgn, + RegionPtr bsreg); + +extern void DRISurfaceNotify (xp_surface_id id, int kind); + +extern void DRIQueryVersion(int *majorVersion, + int *minorVersion, + int *patchVersion); + +#define _DRI_H_ + +#endif diff --git a/hw/darwin/quartz/xpr/dristruct.h b/hw/darwin/quartz/xpr/dristruct.h new file mode 100644 index 000000000..1a2949b18 --- /dev/null +++ b/hw/darwin/quartz/xpr/dristruct.h @@ -0,0 +1,82 @@ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/dristruct.h,v 1.1 2003/06/30 01:45:13 torrey Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright (c) 2002 Apple Computer, Inc. +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, sub license, 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 (including the +next paragraph) 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 NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. + +**************************************************************************/ + +/* + * Authors: + * Jens Owen <jens@precisioninsight.com> + * + */ + +#ifndef DRI_STRUCT_H +#define DRI_STRUCT_H + +#include "dri.h" +#include "x-list.h" + +#define DRI_MAX_DRAWABLES 256 + +#define DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin) \ + ((DRIWindowPrivIndex < 0) ? \ + NULL : \ + ((DRIDrawablePrivPtr)((pWin)->devPrivates[DRIWindowPrivIndex].ptr))) + +#define DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix) \ + ((DRIPixmapPrivIndex < 0) ? \ + NULL : \ + ((DRIDrawablePrivPtr)((pPix)->devPrivates[DRIWindowPrivIndex].ptr))) + +typedef struct _DRIDrawablePrivRec +{ + xp_surface_id sid; + int drawableIndex; + DrawablePtr pDraw; + ScreenPtr pScreen; + int refCount; + unsigned int key[2]; + x_list *notifiers; /* list of (FUN . DATA) */ +} DRIDrawablePrivRec, *DRIDrawablePrivPtr; + +#define DRI_SCREEN_PRIV(pScreen) \ + ((DRIScreenPrivIndex < 0) ? \ + NULL : \ + ((DRIScreenPrivPtr)((pScreen)->devPrivates[DRIScreenPrivIndex].ptr))) + +#define DRI_SCREEN_PRIV_FROM_INDEX(screenIndex) ((DRIScreenPrivPtr) \ + (screenInfo.screens[screenIndex]->devPrivates[DRIScreenPrivIndex].ptr)) + + +typedef struct _DRIScreenPrivRec +{ + Bool directRenderingSupport; + int nrWindows; + DRIWrappedFuncsRec wrap; + DrawablePtr DRIDrawables[DRI_MAX_DRAWABLES]; +} DRIScreenPrivRec, *DRIScreenPrivPtr; + +#endif /* DRI_STRUCT_H */ diff --git a/hw/darwin/quartz/xpr/x-hash.c b/hw/darwin/quartz/xpr/x-hash.c new file mode 100644 index 000000000..ad36204c5 --- /dev/null +++ b/hw/darwin/quartz/xpr/x-hash.c @@ -0,0 +1,341 @@ +/* x-hash.c - basic hash tables + $Id$ + + Copyright (c) 2002 Apple Computer, Inc. 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. */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/x-hash.c,v 1.2 2003/06/30 01:45:13 torrey Exp $ */ + +#include "x-hash.h" +#include "x-list.h" +#include <stdlib.h> +#include <assert.h> + +struct x_hash_table_struct { + int bucket_index; + int total_keys; + x_list **buckets; + + x_hash_fun *hash_key; + x_compare_fun *compare_keys; + x_destroy_fun *destroy_key; + x_destroy_fun *destroy_value; +}; + +#define ITEM_NEW(k, v) X_PFX (list_prepend) ((x_list *) (k), v) +#define ITEM_FREE(i) X_PFX (list_free_1) (i) +#define ITEM_KEY(i) ((void *) (i)->next) +#define ITEM_VALUE(i) ((i)->data) + +#define SPLIT_THRESHOLD_FACTOR 2 + +/* http://planetmath.org/?op=getobj&from=objects&name=GoodHashTablePrimes */ +static const unsigned int bucket_sizes[] = { + 29, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, + 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 12582917, + 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, + 1610612741 +}; + +#define N_BUCKET_SIZES (sizeof (bucket_sizes) / sizeof (bucket_sizes[0])) + +static inline unsigned int +hash_table_total_buckets (x_hash_table *h) +{ + return bucket_sizes[h->bucket_index]; +} + +static inline void +hash_table_destroy_item (x_hash_table *h, void *k, void *v) +{ + if (h->destroy_key != 0) + (*h->destroy_key) (k); + + if (h->destroy_value != 0) + (*h->destroy_value) (v); +} + +static inline unsigned int +hash_table_hash_key (x_hash_table *h, void *k) +{ + if (h->hash_key != 0) + return (*h->hash_key) (k); + else + return (unsigned int) k; +} + +static inline int +hash_table_compare_keys (x_hash_table *h, void *k1, void *k2) +{ + if (h->compare_keys == 0) + return k1 == k2; + else + return (*h->compare_keys) (k1, k2) == 0; +} + +static void +hash_table_split (x_hash_table *h) +{ + x_list **new, **old; + x_list *node, *item, *next; + int new_size, old_size; + unsigned int b; + int i; + + if (h->bucket_index == N_BUCKET_SIZES - 1) + return; + + old_size = hash_table_total_buckets (h); + old = h->buckets; + + h->bucket_index++; + + new_size = hash_table_total_buckets (h); + new = calloc (new_size, sizeof (x_list *)); + + if (new == 0) + { + h->bucket_index--; + return; + } + + for (i = 0; i < old_size; i++) + { + for (node = old[i]; node != 0; node = next) + { + next = node->next; + item = node->data; + + b = hash_table_hash_key (h, ITEM_KEY (item)) % new_size; + + node->next = new[b]; + new[b] = node; + } + } + + h->buckets = new; + free (old); +} + +X_EXTERN x_hash_table * +X_PFX (hash_table_new) (x_hash_fun *hash, + x_compare_fun *compare, + x_destroy_fun *key_destroy, + x_destroy_fun *value_destroy) +{ + x_hash_table *h; + + h = calloc (1, sizeof (x_hash_table)); + if (h == 0) + return 0; + + h->bucket_index = 0; + h->buckets = calloc (hash_table_total_buckets (h), sizeof (x_list *)); + + if (h->buckets == 0) + { + free (h); + return 0; + } + + h->hash_key = hash; + h->compare_keys = compare; + h->destroy_key = key_destroy; + h->destroy_value = value_destroy; + + return h; +} + +X_EXTERN void +X_PFX (hash_table_free) (x_hash_table *h) +{ + int n, i; + x_list *node, *item; + + assert (h != NULL); + + n = hash_table_total_buckets (h); + + for (i = 0; i < n; i++) + { + for (node = h->buckets[i]; node != 0; node = node->next) + { + item = node->data; + hash_table_destroy_item (h, ITEM_KEY (item), ITEM_VALUE (item)); + ITEM_FREE (item); + } + X_PFX (list_free) (h->buckets[i]); + } + + free (h->buckets); + free (h); +} + +X_EXTERN unsigned int +X_PFX (hash_table_size) (x_hash_table *h) +{ + assert (h != NULL); + + return h->total_keys; +} + +static void +hash_table_modify (x_hash_table *h, void *k, void *v, int replace) +{ + unsigned int hash_value; + x_list *node, *item; + + assert (h != NULL); + + hash_value = hash_table_hash_key (h, k); + + for (node = h->buckets[hash_value % hash_table_total_buckets (h)]; + node != 0; node = node->next) + { + item = node->data; + + if (hash_table_compare_keys (h, ITEM_KEY (item), k)) + { + if (replace) + { + hash_table_destroy_item (h, ITEM_KEY (item), + ITEM_VALUE (item)); + ITEM_KEY (item) = k; + ITEM_VALUE (item) = v; + } + else + { + hash_table_destroy_item (h, k, ITEM_VALUE (item)); + ITEM_VALUE (item) = v; + } + return; + } + } + + /* Key isn't already in the table. Insert it. */ + + if (h->total_keys + 1 + > hash_table_total_buckets (h) * SPLIT_THRESHOLD_FACTOR) + { + hash_table_split (h); + } + + hash_value = hash_value % hash_table_total_buckets (h); + h->buckets[hash_value] = X_PFX (list_prepend) (h->buckets[hash_value], + ITEM_NEW (k, v)); + h->total_keys++; +} + +X_EXTERN void +X_PFX (hash_table_insert) (x_hash_table *h, void *k, void *v) +{ + hash_table_modify (h, k, v, 0); +} + +X_EXTERN void +X_PFX (hash_table_replace) (x_hash_table *h, void *k, void *v) +{ + hash_table_modify (h, k, v, 1); +} + +X_EXTERN void +X_PFX (hash_table_remove) (x_hash_table *h, void *k) +{ + unsigned int hash_value; + x_list **ptr, *item; + + assert (h != NULL); + + hash_value = hash_table_hash_key (h, k); + + for (ptr = &h->buckets[hash_value % hash_table_total_buckets (h)]; + *ptr != 0; ptr = &((*ptr)->next)) + { + item = (*ptr)->data; + + if (hash_table_compare_keys (h, ITEM_KEY (item), k)) + { + hash_table_destroy_item (h, ITEM_KEY (item), ITEM_VALUE (item)); + ITEM_FREE (item); + item = *ptr; + *ptr = item->next; + X_PFX (list_free_1) (item); + h->total_keys--; + return; + } + } +} + +X_EXTERN void * +X_PFX (hash_table_lookup) (x_hash_table *h, void *k, void **k_ret) +{ + unsigned int hash_value; + x_list *node, *item; + + assert (h != NULL); + + hash_value = hash_table_hash_key (h, k); + + for (node = h->buckets[hash_value % hash_table_total_buckets (h)]; + node != 0; node = node->next) + { + item = node->data; + + if (hash_table_compare_keys (h, ITEM_KEY (item), k)) + { + if (k_ret != 0) + *k_ret = ITEM_KEY (item); + + return ITEM_VALUE (item); + } + } + + if (k_ret != 0) + *k_ret = 0; + + return 0; +} + +X_EXTERN void +X_PFX (hash_table_foreach) (x_hash_table *h, + x_hash_foreach_fun *fun, void *data) +{ + int i, n; + x_list *node, *item; + + assert (h != NULL); + + n = hash_table_total_buckets (h); + + for (i = 0; i < n; i++) + { + for (node = h->buckets[i]; node != 0; node = node->next) + { + item = node->data; + (*fun) (ITEM_KEY (item), ITEM_VALUE (item), data); + } + } +} diff --git a/hw/darwin/quartz/xpr/x-hash.h b/hw/darwin/quartz/xpr/x-hash.h new file mode 100644 index 000000000..2abb08cd7 --- /dev/null +++ b/hw/darwin/quartz/xpr/x-hash.h @@ -0,0 +1,62 @@ +/* x-hash.h -- basic hash table class + $Id$ + + Copyright (c) 2002 Apple Computer, Inc. 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. */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/x-hash.h,v 1.2 2003/06/30 01:45:13 torrey Exp $ */ + +#ifndef X_HASH_H +#define X_HASH_H 1 + +typedef struct x_hash_table_struct x_hash_table; + +typedef int (x_compare_fun) (const void *a, const void *b); +typedef unsigned int (x_hash_fun) (const void *k); +typedef void (x_destroy_fun) (void *x); +typedef void (x_hash_foreach_fun) (void *k, void *v, void *data); + +/* for X_PFX and X_EXTERN */ +#include "x-list.h" + +X_EXTERN x_hash_table *X_PFX (hash_table_new) (x_hash_fun *hash, + x_compare_fun *compare, + x_destroy_fun *key_destroy, + x_destroy_fun *value_destroy); +X_EXTERN void X_PFX (hash_table_free) (x_hash_table *h); + +X_EXTERN unsigned int X_PFX (hash_table_size) (x_hash_table *h); + +X_EXTERN void X_PFX (hash_table_insert) (x_hash_table *h, void *k, void *v); +X_EXTERN void X_PFX (hash_table_replace) (x_hash_table *h, void *k, void *v); +X_EXTERN void X_PFX (hash_table_remove) (x_hash_table *h, void *k); +X_EXTERN void *X_PFX (hash_table_lookup) (x_hash_table *h, + void *k, void **k_ret); +X_EXTERN void X_PFX (hash_table_foreach) (x_hash_table *h, + x_hash_foreach_fun *fun, + void *data); + +#endif /* X_HASH_H */ diff --git a/hw/darwin/quartz/xpr/x-hook.c b/hw/darwin/quartz/xpr/x-hook.c new file mode 100644 index 000000000..3414e1543 --- /dev/null +++ b/hw/darwin/quartz/xpr/x-hook.c @@ -0,0 +1,106 @@ +/* x-hook.c + $Id$ + + Copyright (c) 2003 Apple Computer, Inc. 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. */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/x-hook.c,v 1.1 2003/06/30 01:45:13 torrey Exp $ */ + +#include "x-hook.h" +#include <stdlib.h> +#include <assert.h> + +#define CELL_NEW(f,d) X_PFX (list_prepend) ((x_list *) (f), (d)) +#define CELL_FREE(c) X_PFX (list_free_1) (c) +#define CELL_FUN(c) ((x_hook_function *) ((c)->next)) +#define CELL_DATA(c) ((c)->data) + +X_EXTERN x_list * +X_PFX (hook_add) (x_list *lst, x_hook_function *fun, void *data) +{ + return X_PFX (list_prepend) (lst, CELL_NEW (fun, data)); +} + +X_EXTERN x_list * +X_PFX (hook_remove) (x_list *lst, x_hook_function *fun, void *data) +{ + x_list *node, *cell; + x_list *to_delete = NULL; + + for (node = lst; node != NULL; node = node->next) + { + cell = node->data; + if (CELL_FUN (cell) == fun && CELL_DATA (cell) == data) + to_delete = X_PFX (list_prepend) (to_delete, cell); + } + + for (node = to_delete; node != NULL; node = node->next) + { + cell = node->data; + lst = X_PFX (list_remove) (lst, cell); + CELL_FREE (cell); + } + + X_PFX (list_free) (to_delete); +} + +X_EXTERN void +X_PFX (hook_run) (x_list *lst, void *arg) +{ + x_list *node, *cell; + x_hook_function **fun; + void **data; + int length, i; + + length = X_PFX (list_length) (lst); + fun = alloca (sizeof (x_hook_function *) * length); + data = alloca (sizeof (void *) * length); + + for (i = 0, node = lst; node != NULL; node = node->next, i++) + { + cell = node->data; + fun[i] = CELL_FUN (cell); + data[i] = CELL_DATA (cell); + } + + for (i = 0; i < length; i++) + { + (*fun[i]) (arg, data[i]); + } +} + +X_EXTERN void +X_PFX (hook_free) (x_list *lst) +{ + x_list *node; + + for (node = lst; node != NULL; node = node->next) + { + CELL_FREE (node->data); + } + + X_PFX (list_free) (lst); +} diff --git a/hw/darwin/quartz/xpr/x-hook.h b/hw/darwin/quartz/xpr/x-hook.h new file mode 100644 index 000000000..14e8ca1f5 --- /dev/null +++ b/hw/darwin/quartz/xpr/x-hook.h @@ -0,0 +1,44 @@ +/* x-hook.h -- lists of function,data pairs to call. + $Id$ + + Copyright (c) 2003 Apple Computer, Inc. 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. */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/x-hook.h,v 1.1 2003/06/30 01:45:13 torrey Exp $ */ + +#ifndef X_HOOK_H +#define X_HOOK_H 1 + +#include "x-list.h" + +typedef void x_hook_function (void *arg, void *data); + +X_EXTERN x_list *X_PFX (hook_add) (x_list *lst, x_hook_function *fun, void *data); +X_EXTERN x_list *X_PFX (hook_remove) (x_list *lst, x_hook_function *fun, void *data); +X_EXTERN void X_PFX (hook_run) (x_list *lst, void *arg); +X_EXTERN void X_PFX (hook_free) (x_list *lst); + +#endif /* X_HOOK_H */ diff --git a/hw/darwin/quartz/xpr/x-list.c b/hw/darwin/quartz/xpr/x-list.c new file mode 100644 index 000000000..859a5163d --- /dev/null +++ b/hw/darwin/quartz/xpr/x-list.c @@ -0,0 +1,316 @@ +/* x-list.c + $Id$ + + Copyright (c) 2002 Apple Computer, Inc. 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. */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/x-list.c,v 1.2 2003/06/30 01:45:13 torrey Exp $ */ + +#include "x-list.h" +#include <stdlib.h> +#include <assert.h> +#include <pthread.h> + +/* Allocate in ~4k blocks */ +#define NODES_PER_BLOCK 508 + +typedef struct x_list_block_struct x_list_block; + +struct x_list_block_struct { + x_list l[NODES_PER_BLOCK]; +}; + +static x_list *freelist; + +static pthread_mutex_t freelist_lock = PTHREAD_MUTEX_INITIALIZER; + +static inline void +list_free_1 (x_list *node) +{ + node->next = freelist; + freelist = node; +} + +X_EXTERN void +X_PFX (list_free_1) (x_list *node) +{ + assert (node != NULL); + + pthread_mutex_lock (&freelist_lock); + + list_free_1 (node); + + pthread_mutex_unlock (&freelist_lock); +} + +X_EXTERN void +X_PFX (list_free) (x_list *lst) +{ + x_list *next; + + pthread_mutex_lock (&freelist_lock); + + for (; lst != NULL; lst = next) + { + next = lst->next; + list_free_1 (lst); + } + + pthread_mutex_unlock (&freelist_lock); +} + +X_EXTERN x_list * +X_PFX (list_prepend) (x_list *lst, void *data) +{ + x_list *node; + + pthread_mutex_lock (&freelist_lock); + + if (freelist == NULL) + { + x_list_block *b; + int i; + + b = malloc (sizeof (x_list_block)); + + for (i = 0; i < NODES_PER_BLOCK - 1; i++) + b->l[i].next = &(b->l[i+1]); + b->l[i].next = NULL; + + freelist = b->l; + } + + node = freelist; + freelist = node->next; + + pthread_mutex_unlock (&freelist_lock); + + node->next = lst; + node->data = data; + + return node; +} + +X_EXTERN x_list * +X_PFX (list_append) (x_list *lst, void *data) +{ + x_list *head = lst; + + if (lst == NULL) + return X_PFX (list_prepend) (NULL, data); + + while (lst->next != NULL) + lst = lst->next; + + lst->next = X_PFX (list_prepend) (NULL, data); + + return head; +} + +X_EXTERN x_list * +X_PFX (list_reverse) (x_list *lst) +{ + x_list *head = NULL, *next; + + while (lst != NULL) + { + next = lst->next; + lst->next = head; + head = lst; + lst = next; + } + + return head; +} + +X_EXTERN x_list * +X_PFX (list_find) (x_list *lst, void *data) +{ + for (; lst != NULL; lst = lst->next) + { + if (lst->data == data) + return lst; + } + + return NULL; +} + +X_EXTERN x_list * +X_PFX (list_nth) (x_list *lst, int n) +{ + while (n-- > 0 && lst != NULL) + lst = lst->next; + + return lst; +} + +X_EXTERN x_list * +X_PFX (list_filter) (x_list *lst, + int (*pred) (void *item, void *data), void *data) +{ + x_list *ret = NULL, *node; + + for (node = lst; node != NULL; node = node->next) + { + if ((*pred) (node->data, data)) + ret = X_PFX (list_prepend) (ret, node->data); + } + + return X_PFX (list_reverse) (ret); +} + +X_EXTERN x_list * +X_PFX (list_map) (x_list *lst, + void *(*fun) (void *item, void *data), void *data) +{ + x_list *ret = NULL, *node; + + for (node = lst; node != NULL; node = node->next) + { + X_PFX (list_prepend) (ret, fun (node->data, data)); + } + + return X_PFX (list_reverse) (ret); +} + +X_EXTERN x_list * +X_PFX (list_copy) (x_list *lst) +{ + x_list *copy = NULL; + + for (; lst != NULL; lst = lst->next) + { + copy = X_PFX (list_prepend) (copy, lst->data); + } + + return X_PFX (list_reverse) (copy); +} + +X_EXTERN x_list * +X_PFX (list_remove) (x_list *lst, void *data) +{ + x_list **ptr, *node; + + for (ptr = &lst; *ptr != NULL;) + { + node = *ptr; + + if (node->data == data) + { + *ptr = node->next; + X_PFX (list_free_1) (node); + } + else + ptr = &((*ptr)->next); + } + + return lst; +} + +X_EXTERN unsigned int +X_PFX (list_length) (x_list *lst) +{ + unsigned int n; + + n = 0; + for (; lst != NULL; lst = lst->next) + n++; + + return n; +} + +X_EXTERN void +X_PFX (list_foreach) (x_list *lst, + void (*fun) (void *data, void *user_data), + void *user_data) +{ + for (; lst != NULL; lst = lst->next) + { + (*fun) (lst->data, user_data); + } +} + +static x_list * +list_sort_1 (x_list *lst, int length, + int (*less) (const void *, const void *)) +{ + x_list *mid, *ptr; + x_list *out_head, *out; + int mid_point, i; + + /* This is a standard (stable) list merge sort */ + + if (length < 2) + return lst; + + /* Calculate the halfway point. Split the list into two sub-lists. */ + + mid_point = length / 2; + ptr = lst; + for (i = mid_point - 1; i > 0; i--) + ptr = ptr->next; + mid = ptr->next; + ptr->next = NULL; + + /* Sort each sub-list. */ + + lst = list_sort_1 (lst, mid_point, less); + mid = list_sort_1 (mid, length - mid_point, less); + + /* Then merge them back together. */ + + assert (lst != NULL && mid != NULL); + + if ((*less) (mid->data, lst->data)) + out = out_head = mid, mid = mid->next; + else + out = out_head = lst, lst = lst->next; + + while (lst != NULL && mid != NULL) + { + if ((*less) (mid->data, lst->data)) + out = out->next = mid, mid = mid->next; + else + out = out->next = lst, lst = lst->next; + } + + if (lst != NULL) + out->next = lst; + else + out->next = mid; + + return out_head; +} + +X_EXTERN x_list * +X_PFX (list_sort) (x_list *lst, int (*less) (const void *, const void *)) +{ + int length; + + length = X_PFX (list_length) (lst); + + return list_sort_1 (lst, length, less); +} diff --git a/hw/darwin/quartz/xpr/x-list.h b/hw/darwin/quartz/xpr/x-list.h new file mode 100644 index 000000000..a65cfcb7c --- /dev/null +++ b/hw/darwin/quartz/xpr/x-list.h @@ -0,0 +1,78 @@ +/* x-list.h -- simple list type + $Id$ + + Copyright (c) 2002 Apple Computer, Inc. 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. */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/x-list.h,v 1.2 2003/06/30 01:45:13 torrey Exp $ */ + +#ifndef X_LIST_H +#define X_LIST_H 1 + +/* This is just a cons. */ + +typedef struct x_list_struct x_list; + +struct x_list_struct { + void *data; + x_list *next; +}; + +#ifndef X_PFX +# define X_PFX(x) x_ ## x +#endif + +#ifndef X_EXTERN +# define X_EXTERN __private_extern__ +#endif + +X_EXTERN void X_PFX (list_free_1) (x_list *node); +X_EXTERN x_list *X_PFX (list_prepend) (x_list *lst, void *data); + +X_EXTERN x_list *X_PFX (list_append) (x_list *lst, void *data); +X_EXTERN x_list *X_PFX (list_remove) (x_list *lst, void *data); +X_EXTERN void X_PFX (list_free) (x_list *lst); + +X_EXTERN x_list *X_PFX (list_copy) (x_list *lst); +X_EXTERN x_list *X_PFX (list_reverse) (x_list *lst); +X_EXTERN x_list *X_PFX (list_find) (x_list *lst, void *data); +X_EXTERN x_list *X_PFX (list_nth) (x_list *lst, int n); +X_EXTERN x_list *X_PFX (list_filter) (x_list *src, + int (*pred) (void *item, void *data), + void *data); +X_EXTERN x_list *X_PFX (list_map) (x_list *src, + void *(*fun) (void *item, void *data), + void *data); + +X_EXTERN unsigned int X_PFX (list_length) (x_list *lst); +X_EXTERN void X_PFX (list_foreach) (x_list *lst, void (*fun) + (void *data, void *user_data), + void *user_data); + +X_EXTERN x_list *X_PFX (list_sort) (x_list *lst, int (*less) (const void *, + const void *)); + +#endif /* X_LIST_H */ diff --git a/hw/darwin/quartz/xpr/xpr.h b/hw/darwin/quartz/xpr/xpr.h new file mode 100644 index 000000000..3d447b226 --- /dev/null +++ b/hw/darwin/quartz/xpr/xpr.h @@ -0,0 +1,47 @@ +/* + * Xplugin rootless implementation + */ +/* + * 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/xpr.h,v 1.4 2003/11/12 20:21:52 torrey Exp $ */ + +#ifndef XPR_H +#define XPR_H + +#include "screenint.h" + +extern Bool QuartzModeBundleInit(void); + +void AppleDRIExtensionInit(void); +void xprAppleWMInit(void); +Bool xprInit(ScreenPtr pScreen); +Bool xprIsX11Window(void *nsWindow, int windowNumber); + +Bool QuartzInitCursor(ScreenPtr pScreen); +void QuartzSuspendXCursor(ScreenPtr pScreen); +void QuartzResumeXCursor(ScreenPtr pScreen, int x, int y); + +#endif /* XPR_H */ diff --git a/hw/darwin/quartz/xpr/xprAppleWM.c b/hw/darwin/quartz/xpr/xprAppleWM.c new file mode 100644 index 000000000..eca0de334 --- /dev/null +++ b/hw/darwin/quartz/xpr/xprAppleWM.c @@ -0,0 +1,99 @@ +/* + * 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/xprAppleWM.c,v 1.1 2003/09/16 00:36:15 torrey Exp $ */ + +#include "xpr.h" +#include "applewmExt.h" +#include "rootless.h" +#include "Xplugin.h" +#include "X.h" + + +static int xprSetWindowLevel( + WindowPtr pWin, + int level) +{ + xp_window_id wid; + xp_window_changes wc; + + wid = (xp_window_id) RootlessFrameForWindow (pWin, TRUE); + if (wid == 0) + return BadWindow; + + RootlessStopDrawing (pWin, FALSE); + + wc.window_level = level; + if (xp_configure_window (wid, XP_WINDOW_LEVEL, &wc) != Success) { + return BadValue; + } + + return Success; +} + + +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 = (xp_window_id) 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 +}; + + +void xprAppleWMInit(void) +{ + AppleWMExtensionInit(&xprAppleWMProcs); +} diff --git a/hw/darwin/quartz/xpr/xprCursor.c b/hw/darwin/quartz/xpr/xprCursor.c new file mode 100644 index 000000000..a3dea69e2 --- /dev/null +++ b/hw/darwin/quartz/xpr/xprCursor.c @@ -0,0 +1,420 @@ +/************************************************************** + * + * Xplugin cursor support + * + **************************************************************/ +/* + * Copyright (c) 2001 Torrey T. Lyons and Greg Parker. + * Copyright (c) 2002 Apple Computer, Inc. + * 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/xprCursor.c,v 1.2 2003/09/16 00:36:15 torrey Exp $ */ + +#include "quartzCommon.h" +#include "xpr.h" +#include "darwin.h" +#include "Xplugin.h" + +#include "mi.h" +#include "scrnintstr.h" +#include "cursorstr.h" +#include "mipointrst.h" +#include "windowstr.h" +#include "globals.h" +#include "servermd.h" +#include "dixevents.h" + +typedef struct { + int cursorVisible; + QueryBestSizeProcPtr QueryBestSize; + miPointerSpriteFuncPtr spriteFuncs; +} QuartzCursorScreenRec, *QuartzCursorScreenPtr; + +static int darwinCursorScreenIndex = -1; +static unsigned long darwinCursorGeneration = 0; + +#define CURSOR_PRIV(pScreen) \ + ((QuartzCursorScreenPtr)pScreen->devPrivates[darwinCursorScreenIndex].ptr) + + +static Bool +load_cursor(CursorPtr src, int screen) +{ + uint32_t *data; + uint32_t rowbytes; + int width, height; + int hot_x, hot_y; + + uint32_t fg_color, bg_color; + uint8_t *srow, *sptr; + uint8_t *mrow, *mptr; + uint32_t *drow, *dptr; + unsigned xcount, ycount; + + xp_error err; + + width = src->bits->width; + height = src->bits->height; + hot_x = src->bits->xhot; + hot_y = src->bits->yhot; + +#ifdef ARGB_CURSOR + if (src->bits->argb != NULL) + { + rowbytes = src->bits->width * sizeof(CARD32); + data = (uint32_t *) src->bits->argb; + } + else +#endif + { + fg_color = 0xFF00 | (src->foreRed >> 8); + fg_color <<= 16; + fg_color |= src->foreGreen & 0xFF00; + fg_color |= src->foreBlue >> 8; + + bg_color = 0xFF00 | (src->backRed >> 8); + bg_color <<= 16; + bg_color |= src->backGreen & 0xFF00; + bg_color |= src->backBlue >> 8; + + fg_color = htonl(fg_color); + bg_color = htonl(bg_color); + + /* round up to 8 pixel boundary so we can convert whole bytes */ + rowbytes = ((src->bits->width * 4) + 31) & ~31; + data = alloca(rowbytes * src->bits->height); + + if (!src->bits->emptyMask) + { + ycount = src->bits->height; + srow = src->bits->source; mrow = src->bits->mask; + drow = data; + + while (ycount-- > 0) + { + xcount = (src->bits->width + 7) / 8; + sptr = srow; mptr = mrow; + dptr = drow; + + while (xcount-- > 0) + { + uint8_t s, m; + int i; + + s = *sptr++; m = *mptr++; + for (i = 0; i < 8; i++) + { +#if BITMAP_BIT_ORDER == MSBFirst + if (m & 128) + *dptr++ = (s & 128) ? fg_color : bg_color; + else + *dptr++ = 0; + s <<= 1; m <<= 1; +#else + if (m & 1) + *dptr++ = (s & 1) ? fg_color : bg_color; + else + *dptr++ = 0; + s >>= 1; m >>= 1; +#endif + } + } + + srow += BitmapBytePad(src->bits->width); + mrow += BitmapBytePad(src->bits->width); + drow = (uint32_t *) ((char *) drow + rowbytes); + } + } + else + { + memset(data, 0, src->bits->height * rowbytes); + } + } + + err = xp_set_cursor(width, height, hot_x, hot_y, data, rowbytes); + return err == Success; +} + + +/* +=========================================================================== + + Pointer sprite functions + +=========================================================================== +*/ + +/* + * QuartzRealizeCursor + * Convert the X cursor representation to native format if possible. + */ +static Bool +QuartzRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) +{ + if(pCursor == NULL || pCursor->bits == NULL) + return FALSE; + + /* FIXME: cache ARGB8888 representation? */ + + return TRUE; +} + + +/* + * QuartzUnrealizeCursor + * Free the storage space associated with a realized cursor. + */ +static Bool +QuartzUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) +{ + return TRUE; +} + + +/* + * QuartzSetCursor + * Set the cursor sprite and position. + */ +static void +QuartzSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y) +{ + QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); + + if (!quartzServerVisible) + return; + + if (pCursor == NULL) + { + if (ScreenPriv->cursorVisible) + { + xp_hide_cursor(); + ScreenPriv->cursorVisible = FALSE; + } + } + else + { + load_cursor(pCursor, pScreen->myNum); + + if (!ScreenPriv->cursorVisible) + { + xp_show_cursor(); + ScreenPriv->cursorVisible = TRUE; + } + } +} + + +/* + * QuartzMoveCursor + * Move the cursor. This is a noop for us. + */ +static void +QuartzMoveCursor(ScreenPtr pScreen, int x, int y) +{ +} + + +static miPointerSpriteFuncRec quartzSpriteFuncsRec = { + QuartzRealizeCursor, + QuartzUnrealizeCursor, + QuartzSetCursor, + QuartzMoveCursor +}; + + +/* +=========================================================================== + + Pointer screen functions + +=========================================================================== +*/ + +/* + * QuartzCursorOffScreen + */ +static Bool +QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y) +{ + return FALSE; +} + + +/* + * QuartzCrossScreen + */ +static void +QuartzCrossScreen(ScreenPtr pScreen, Bool entering) +{ + return; +} + + +/* + * QuartzWarpCursor + * Change the cursor position without generating an event or motion history. + * The input coordinates (x,y) are in pScreen-local X11 coordinates. + * + */ +static void +QuartzWarpCursor(ScreenPtr pScreen, int x, int y) +{ + static Bool neverMoved = TRUE; + + if (neverMoved) + { + /* Don't move the cursor the first time. This is the + jump-to-center initialization, and it's annoying. */ + neverMoved = FALSE; + return; + } + + if (quartzServerVisible) + { + int sx, sy; + + sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX; + sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY; + + CGWarpMouseCursorPosition(CGPointMake(sx + x, sy + y)); + } + + miPointerWarpCursor(pScreen, x, y); + miPointerUpdate(); +} + + +static miPointerScreenFuncRec quartzScreenFuncsRec = { + QuartzCursorOffScreen, + QuartzCrossScreen, + QuartzWarpCursor, + DarwinEQPointerPost, + DarwinEQSwitchScreen +}; + + +/* +=========================================================================== + + Other screen functions + +=========================================================================== +*/ + +/* + * QuartzCursorQueryBestSize + * Handle queries for best cursor size + */ +static void +QuartzCursorQueryBestSize(int class, unsigned short *width, + unsigned short *height, ScreenPtr pScreen) +{ + QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); + + if (class == CursorShape) + { + /* FIXME: query window server? */ + *width = 32; + *height = 32; + } + else + { + (*ScreenPriv->QueryBestSize)(class, width, height, pScreen); + } +} + +/* + * QuartzInitCursor + * Initialize cursor support + */ +Bool +QuartzInitCursor(ScreenPtr pScreen) +{ + QuartzCursorScreenPtr ScreenPriv; + miPointerScreenPtr PointPriv; + + /* initialize software cursor handling (always needed as backup) */ + if (!miDCInitialize(pScreen, &quartzScreenFuncsRec)) + return FALSE; + + /* allocate private storage for this screen's QuickDraw cursor info */ + if (darwinCursorGeneration != serverGeneration) + { + if ((darwinCursorScreenIndex = AllocateScreenPrivateIndex()) < 0) + return FALSE; + + darwinCursorGeneration = serverGeneration; + } + + ScreenPriv = xcalloc(1, sizeof(QuartzCursorScreenRec)); + if (ScreenPriv == NULL) + return FALSE; + + CURSOR_PRIV(pScreen) = ScreenPriv; + + /* override some screen procedures */ + ScreenPriv->QueryBestSize = pScreen->QueryBestSize; + pScreen->QueryBestSize = QuartzCursorQueryBestSize; + + PointPriv = (miPointerScreenPtr) pScreen->devPrivates[miPointerScreenIndex].ptr; + + ScreenPriv->spriteFuncs = PointPriv->spriteFuncs; + PointPriv->spriteFuncs = &quartzSpriteFuncsRec; + + ScreenPriv->cursorVisible = TRUE; + return TRUE; +} + + +/* + * QuartzSuspendXCursor + * X server is hiding. Restore the Aqua cursor. + */ +void +QuartzSuspendXCursor(ScreenPtr pScreen) +{ +} + + +/* + * QuartzResumeXCursor + * X server is showing. Restore the X cursor. + */ +void +QuartzResumeXCursor(ScreenPtr pScreen, int x, int y) +{ + WindowPtr pWin; + CursorPtr pCursor; + + pWin = GetSpriteWindow(); + if (pWin->drawable.pScreen != pScreen) + return; + + pCursor = GetSpriteCursor(); + if (pCursor == NULL) + return; + + QuartzSetCursor(pScreen, pCursor, x, y); +} diff --git a/hw/darwin/quartz/xpr/xprFrame.c b/hw/darwin/quartz/xpr/xprFrame.c new file mode 100644 index 000000000..ae24bc42a --- /dev/null +++ b/hw/darwin/quartz/xpr/xprFrame.c @@ -0,0 +1,439 @@ +/* + * 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/xprFrame.c,v 1.4 2003/11/12 20:21:52 torrey Exp $ */ + +#include "xpr.h" +#include "rootless.h" +#include "Xplugin.h" +#include "x-hash.h" +#include "x-list.h" + +#include "propertyst.h" +#include "dix.h" +#include "Xatom.h" +#include "windowstr.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; + +static Bool no_configure_window; + + +static inline xp_error +xprConfigureWindow(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 +xprSetNativeProperty(RootlessWindowPtr pFrame) +{ + xp_error err; + unsigned int native_id; + long data; + + err = xp_get_native_window((xp_window_id) pFrame->wid, &native_id); + if (err == Success) + { + /* FIXME: move this to AppleWM extension */ + + data = native_id; + ChangeWindowProperty(pFrame->win, xa_native_window_id(), + XA_INTEGER, 32, PropModeReplace, 1, &data, TRUE); + } +} + + +/* + * Create and display a new frame. + */ +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; +#if 0 + wc.colormap = xprColormapCallback; + wc.colormap_data = pScreen; + mask |= XP_COLORMAP; +#endif + } + 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 = REGION_NUM_RECTS(pShape); + wc.shape_rects = REGION_RECTS(pShape); + wc.shape_tx = wc.shape_ty = 0; + mask |= XP_SHAPE; + } + + 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. + */ +void +xprDestroyFrame(RootlessFrameID wid) +{ + pthread_mutex_lock(&window_hash_mutex); + x_hash_table_remove(window_hash, wid); + pthread_mutex_unlock(&window_hash_mutex); + + xp_destroy_window((xp_window_id) wid); +} + + +/* + * Move a frame on screen. + */ +void +xprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY) +{ + xp_window_changes wc; + + wc.x = newX; + wc.y = newY; + + xprConfigureWindow((xp_window_id) wid, XP_ORIGIN, &wc); +} + + +/* + * Resize and move a frame. + */ +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((xp_window_id) wid, XP_BOUNDS, &wc); +} + + +/* + * Change frame stacking. + */ +void +xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) +{ + xp_window_changes wc; + + /* 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 = (xp_window_id) nextWid; + } + + xprConfigureWindow((xp_window_id) wid, XP_STACKING, &wc); +} + + +/* + * Change the frame's shape. + */ +void +xprReshapeFrame(RootlessFrameID wid, RegionPtr pShape) +{ + xp_window_changes wc; + + if (pShape != NULL) + { + wc.shape_nrects = REGION_NUM_RECTS(pShape); + wc.shape_rects = REGION_RECTS(pShape); + } + else + { + wc.shape_nrects = -1; + wc.shape_rects = NULL; + } + + wc.shape_tx = wc.shape_ty = 0; + + xprConfigureWindow((xp_window_id) wid, XP_SHAPE, &wc); +} + + +/* + * Unmap a frame. + */ +void +xprUnmapFrame(RootlessFrameID wid) +{ + xp_window_changes wc; + + wc.stack_mode = XP_UNMAPPED; + wc.sibling = 0; + + xprConfigureWindow((xp_window_id) wid, XP_STACKING, &wc); +} + + +/* + * Start drawing to a frame. + * Prepare for direct access to its backing buffer. + */ +void +xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow) +{ + void *data[2]; + unsigned int rowbytes[2]; + xp_error err; + + err = xp_lock_window((xp_window_id) wid, NULL, NULL, data, rowbytes, NULL); + if (err != Success) + FatalError("Could not lock window %i for drawing.", (int) wid); + + *pixelData = data[0]; + *bytesPerRow = rowbytes[0]; +} + + +/* + * Stop drawing to a frame. + */ +void +xprStopDrawing(RootlessFrameID wid, Bool flush) +{ + xp_unlock_window((xp_window_id) wid, flush); +} + + +/* + * Flush drawing updates to the screen. + */ +void +xprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage) +{ + xp_flush_window((xp_window_id) wid); +} + + +/* + * Mark damaged rectangles as requiring redisplay to screen. + */ +void +xprDamageRects(RootlessFrameID wid, int nrects, const BoxRec *rects, + int shift_x, int shift_y) +{ + xp_mark_window((xp_window_id) wid, nrects, rects, shift_x, shift_y); +} + + +/* + * Called after the window associated with a frame has been switched + * to a new top-level parent. + */ +void +xprSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin) +{ + DeleteProperty(oldWin, xa_native_window_id()); + + xprSetNativeProperty(pFrame); +} + + +/* + * Copy area in frame to another part of frame. + * Used to accelerate scrolling. + */ +void +xprCopyWindow(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, + int dx, int dy) +{ + xp_copy_window((xp_window_id) wid, (xp_window_id) wid, + dstNrects, dstRects, dx, dy); +} + + +static RootlessFrameProcsRec xprRootlessProcs = { + xprCreateFrame, + xprDestroyFrame, + xprMoveFrame, + xprResizeFrame, + xprRestackFrame, + xprReshapeFrame, + xprUnmapFrame, + xprStartDrawing, + xprStopDrawing, + xprUpdateRegion, + xprDamageRects, + xprSwitchWindow, + xp_copy_bytes, + xp_fill_bytes, + xp_composite_pixels, + xprCopyWindow +}; + + +/* + * Initialize XPR implementation + */ +Bool +xprInit(ScreenPtr pScreen) +{ + RootlessInit(pScreen, &xprRootlessProcs); + + rootless_CopyBytes_threshold = xp_copy_bytes_threshold; + rootless_FillBytes_threshold = xp_fill_bytes_threshold; + rootless_CompositePixels_threshold = xp_composite_area_threshold; + rootless_CopyWindow_threshold = xp_scroll_area_threshold; + + no_configure_window = FALSE; + + return TRUE; +} + + +/* + * Given the id of a physical window, try to find the top-level (or root) + * X window that it represents. + */ +static WindowPtr +xprGetXWindow(xp_window_id wid) +{ + RootlessWindowRec *winRec; + + if (window_hash == NULL) + return NULL; + + winRec = x_hash_table_lookup(window_hash, (void *) wid, NULL); + + 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(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; +} diff --git a/hw/darwin/quartz/xpr/xprScreen.c b/hw/darwin/quartz/xpr/xprScreen.c new file mode 100644 index 000000000..8090a27b1 --- /dev/null +++ b/hw/darwin/quartz/xpr/xprScreen.c @@ -0,0 +1,378 @@ +/* + * Xplugin rootless implementation screen 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. + */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/xprScreen.c,v 1.8 2003/11/12 20:21:52 torrey Exp $ */ + +#include "quartzCommon.h" +#include "quartz.h" +#include "xpr.h" +#include "pseudoramiX.h" +#include "darwin.h" +#include "rootless.h" +#include "safeAlpha.h" +#include "dri.h" +#include "globals.h" +#include "Xplugin.h" +#include "applewmExt.h" + +// 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: + QuartzMessageServerThread(kXDarwinDisplayChanged, 0); + break; + + case XP_EVENT_WINDOW_STATE_CHANGED: + if (arg_size >= sizeof(xp_window_state_event)) + { + const xp_window_state_event *ws_arg = arg; + QuartzMessageServerThread(kXDarwinWindowState, 2, + ws_arg->id, ws_arg->state); + } + break; + + case XP_EVENT_WINDOW_MOVED: + if (arg_size == sizeof(xp_window_id)) + { + xp_window_id id = * (xp_window_id *) arg; + + QuartzMessageServerThread(kXDarwinWindowMoved, 1, id); + } + break; + + case XP_EVENT_SURFACE_DESTROYED: + case XP_EVENT_SURFACE_CHANGED: + if (arg_size == sizeof(xp_surface_id)) + { + int kind; + + if (type == XP_EVENT_SURFACE_DESTROYED) + kind = AppleDRISurfaceNotifyDestroyed; + else + kind = AppleDRISurfaceNotifyChanged; + + DRISurfaceNotify(*(xp_surface_id *) arg, kind); + } + break; + } +} + + +/* + * displayScreenBounds + * 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); + + /* Remove menubar to help standard X11 window managers. */ + + if (frame.origin.x == 0 && frame.origin.y == 0) + { + frame.origin.y += aquaMenuBarHeight; + frame.size.height -= aquaMenuBarHeight; + } + + return frame; +} + + +/* + * addPseudoramiXScreens + * Add a physical screen with PseudoramiX. + */ +static void +addPseudoramiXScreens(int *x, int *y, int *width, int *height) +{ + CGDisplayCount i, displayCount; + CGDirectDisplayID *displayList = NULL; + CGRect unionRect = CGRectNull, frame; + + // Find all the CoreGraphics displays + CGGetActiveDisplayList(0, NULL, &displayCount); + displayList = xalloc(displayCount * sizeof(CGDirectDisplayID)); + CGGetActiveDisplayList(displayCount, displayList, &displayCount); + + /* 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; + + /* Tell PseudoramiX about the real screens. */ + for (i = 0; i < displayCount; i++) + { + CGDirectDisplayID dpy = displayList[i]; + + frame = displayScreenBounds(dpy); + + ErrorF("PseudoramiX screen %d added: %dx%d @ (%d,%d).\n", i, + (int)frame.size.width, (int)frame.size.height, + (int)frame.origin.x, (int)frame.origin.y); + + frame.origin.x -= unionRect.origin.x; + frame.origin.y -= unionRect.origin.y; + + ErrorF("PseudoramiX screen %d placed at X11 coordinate (%d,%d).\n", + i, (int)frame.origin.x, (int)frame.origin.y); + + PseudoramiXAddScreen(frame.origin.x, frame.origin.y, + frame.size.width, frame.size.height); + } + + xfree(displayList); +} + + +/* + * xprDisplayInit + * Find number of CoreGraphics displays and initialize Xplugin. + */ +static void +xprDisplayInit(void) +{ + CGDisplayCount displayCount; + + ErrorF("Display mode: Rootless Quartz -- Xplugin implementation\n"); + + 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_IN_BACKGROUND) != Success) + { + FatalError("Could not initialize the Xplugin library."); + } + + xp_select_events(XP_EVENT_DISPLAY_CHANGED + | XP_EVENT_WINDOW_STATE_CHANGED + | XP_EVENT_WINDOW_MOVED + | XP_EVENT_SURFACE_CHANGED + | XP_EVENT_SURFACE_DESTROYED, + eventHandler, NULL); + + AppleDRIExtensionInit(); + xprAppleWMInit(); +} + + +/* + * xprAddScreen + * Init the framebuffer and record pixmap parameters for the screen. + */ +static Bool +xprAddScreen(int index, ScreenPtr pScreen) +{ + DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen); + + /* If no specific depth chosen, look for the depth of the main display. + Else if 16bpp specified, use that. Else use 32bpp. */ + + dfb->colorType = TrueColor; + dfb->bitsPerComponent = 8; + dfb->bitsPerPixel = 32; + dfb->colorBitsPerPixel = 24; + + if (darwinDesiredDepth == -1) + { + dfb->bitsPerComponent = CGDisplayBitsPerSample(kCGDirectMainDisplay); + dfb->bitsPerPixel = CGDisplayBitsPerPixel(kCGDirectMainDisplay); + dfb->colorBitsPerPixel = + CGDisplaySamplesPerPixel(kCGDirectMainDisplay) * + dfb->bitsPerComponent; + } + else if (darwinDesiredDepth == 15) + { + dfb->bitsPerComponent = 5; + dfb->bitsPerPixel = 16; + dfb->colorBitsPerPixel = 15; + } + else if (darwinDesiredDepth == 8) + { + dfb->colorType = PseudoColor; + dfb->bitsPerComponent = 8; + dfb->bitsPerPixel = 8; + dfb->colorBitsPerPixel = 8; + } + + if (noPseudoramiXExtension) + { + CGDirectDisplayID dpy; + CGRect frame; + + dpy = displayAtIndex(index); + + frame = displayScreenBounds(dpy); + + dfb->x = frame.origin.x; + dfb->y = frame.origin.y; + dfb->width = frame.size.width; + dfb->height = frame.size.height; + } + else + { + addPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height); + } + + /* Passing zero width (pitch) makes miCreateScreenResources set the + screen pixmap to the framebuffer pointer, i.e. NULL. The generic + rootless code takes care of making this work. */ + dfb->pitch = 0; + dfb->framebuffer = NULL; + + DRIScreenInit(pScreen); + + return TRUE; +} + + +/* + * xprSetupScreen + * Setup the screen for rootless access. + */ +static Bool +xprSetupScreen(int index, ScreenPtr pScreen) +{ + // Add alpha protecting replacements for fb screen functions + pScreen->PaintWindowBackground = SafeAlphaPaintWindow; + pScreen->PaintWindowBorder = SafeAlphaPaintWindow; + +#ifdef RENDER + { + PictureScreenPtr ps = GetPictureScreen(pScreen); + ps->Composite = SafeAlphaComposite; + } +#endif /* RENDER */ + + // Initialize generic rootless code + if (!xprInit(pScreen)) + return FALSE; + + return DRIFinishScreenInit(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(WindowTable[i]); +} + + +/* + * Quartz display mode function list. + */ +static QuartzModeProcsRec xprModeProcs = { + xprDisplayInit, + xprAddScreen, + xprSetupScreen, + xprInitInput, + QuartzInitCursor, + NULL, // No need to update cursor + QuartzSuspendXCursor, + QuartzResumeXCursor, + NULL, // No capture or release in rootless mode + NULL, + xprIsX11Window, + RootlessFrameForWindow, + TopLevelParent, + DRICreateSurface, + DRIDestroySurface +}; + + +/* + * QuartzModeBundleInit + * Initialize the display mode bundle after loading. + */ +Bool +QuartzModeBundleInit(void) +{ + quartzProcs = &xprModeProcs; + quartzOpenGLBundle = xprOpenGLBundle; + return TRUE; +} |