Initial revision

This commit is contained in:
Kaleb Keithley 2003-11-25 19:29:01 +00:00
parent d461855a73
commit 90f1536dd3
91 changed files with 27196 additions and 0 deletions

1155
GL/apple/aglGlx.c Normal file

File diff suppressed because it is too large Load Diff

1341
GL/apple/indirect.c Normal file

File diff suppressed because it is too large Load Diff

10
Xext/appgroup.h Normal file
View File

@ -0,0 +1,10 @@
/* $XFree86: xc/programs/Xserver/Xext/appgroup.h,v 1.1 2003/07/16 01:38:28 dawes Exp $ */
void XagClientStateChange(
CallbackListPtr* pcbl,
pointer nulldata,
pointer calldata);
int ProcXagCreate (
register ClientPtr client);
int ProcXagDestroy(
register ClientPtr client);

78
Xext/panoramiXh.h Normal file
View File

@ -0,0 +1,78 @@
/* $XFree86: xc/programs/Xserver/Xext/panoramiXh.h,v 1.3 2003/11/17 22:20:26 dawes Exp $ */
/*
* Server dispatcher function replacements
*/
extern int PanoramiXCreateWindow(ClientPtr client);
extern int PanoramiXChangeWindowAttributes(ClientPtr client);
extern int PanoramiXDestroyWindow(ClientPtr client);
extern int PanoramiXDestroySubwindows(ClientPtr client);
extern int PanoramiXChangeSaveSet(ClientPtr client);
extern int PanoramiXReparentWindow(ClientPtr client);
extern int PanoramiXMapWindow(ClientPtr client);
extern int PanoramiXMapSubwindows(ClientPtr client);
extern int PanoramiXUnmapWindow(ClientPtr client);
extern int PanoramiXUnmapSubwindows(ClientPtr client);
extern int PanoramiXConfigureWindow(ClientPtr client);
extern int PanoramiXCirculateWindow(ClientPtr client);
extern int PanoramiXGetGeometry(ClientPtr client);
extern int PanoramiXTranslateCoords(ClientPtr client);
extern int PanoramiXCreatePixmap(ClientPtr client);
extern int PanoramiXFreePixmap(ClientPtr client);
extern int PanoramiXCreateGC(ClientPtr client);
extern int PanoramiXChangeGC(ClientPtr client);
extern int PanoramiXCopyGC(ClientPtr client);
extern int PanoramiXCopyColormapAndFree(ClientPtr client);
extern int PanoramiXSetDashes(ClientPtr client);
extern int PanoramiXSetClipRectangles(ClientPtr client);
extern int PanoramiXFreeGC(ClientPtr client);
extern int PanoramiXClearToBackground(ClientPtr client);
extern int PanoramiXCopyArea(ClientPtr client);
extern int PanoramiXCopyPlane(ClientPtr client);
extern int PanoramiXPolyPoint(ClientPtr client);
extern int PanoramiXPolyLine(ClientPtr client);
extern int PanoramiXPolySegment(ClientPtr client);
extern int PanoramiXPolyRectangle(ClientPtr client);
extern int PanoramiXPolyArc(ClientPtr client);
extern int PanoramiXFillPoly(ClientPtr client);
extern int PanoramiXPolyFillArc(ClientPtr client);
extern int PanoramiXPolyFillRectangle(ClientPtr client);
extern int PanoramiXPutImage(ClientPtr client);
extern int PanoramiXGetImage(ClientPtr client);
extern int PanoramiXPolyText8(ClientPtr client);
extern int PanoramiXPolyText16(ClientPtr client);
extern int PanoramiXImageText8(ClientPtr client);
extern int PanoramiXImageText16(ClientPtr client);
extern int PanoramiXCreateColormap(ClientPtr client);
extern int PanoramiXFreeColormap(ClientPtr client);
extern int PanoramiXInstallColormap(ClientPtr client);
extern int PanoramiXUninstallColormap(ClientPtr client);
extern int PanoramiXAllocColor(ClientPtr client);
extern int PanoramiXAllocNamedColor(ClientPtr client);
extern int PanoramiXAllocColorCells(ClientPtr client);
extern int PanoramiXStoreNamedColor(ClientPtr client);
extern int PanoramiXFreeColors(ClientPtr client);
extern int PanoramiXStoreColors(ClientPtr client);
extern int PanoramiXAllocColorPlanes(ClientPtr client);
#define PROC_EXTERN(pfunc) extern int pfunc(ClientPtr)
PROC_EXTERN(ProcPanoramiXQueryVersion);
PROC_EXTERN(ProcPanoramiXGetState);
PROC_EXTERN(ProcPanoramiXGetScreenCount);
PROC_EXTERN(ProcPanoramiXGetScreenSize);
PROC_EXTERN(ProcXineramaQueryScreens);
PROC_EXTERN(ProcXineramaIsActive);
extern Bool XineramaCreateGC(GCPtr pGC);
extern int SProcPanoramiXDispatch(ClientPtr client);
extern char *ConnectionInfo;
extern int connBlockScreenStart;
extern xConnSetupPrefix connSetupPrefix;
extern ScreenInfo *GlobalScrInfo;
extern int (* SavedProcVector[256]) (ClientPtr client);

3
Xext/xvdisp.h Normal file
View File

@ -0,0 +1,3 @@
/* $XFree86: xc/programs/Xserver/Xext/xvdisp.h,v 1.1 2003/07/16 01:38:31 dawes Exp $ */
extern void XineramifyXv(void);

10
cfb/cfbtab.h Normal file
View File

@ -0,0 +1,10 @@
/* $XFree86: xc/programs/Xserver/cfb/cfbtab.h,v 1.1 2003/07/16 01:38:37 dawes Exp $ */
#ifndef _CFBTAB_H_
#define _CFBTAB_H_
/* prototypes */
extern int starttab[32], endtab[32];
extern unsigned int partmasks[32][32];
#endif /* _CFBTAB_H_ */

View File

@ -0,0 +1,50 @@
/*
* 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/darwinKeyboard.h,v 1.1 2003/11/01 08:13:08 torrey Exp $ */
#ifndef DARWIN_KEYBOARD_H
#define DARWIN_KEYBOARD_H 1
#define XK_TECHNICAL // needed to get XK_Escape
#define XK_PUBLISHING
#include "keysym.h"
#include "inputstr.h"
// Each key can generate 4 glyphs. They are, in order:
// unshifted, shifted, modeswitch unshifted, modeswitch shifted
#define GLYPHS_PER_KEY 4
#define NUM_KEYCODES 248 // NX_NUMKEYCODES might be better
#define MAX_KEYCODE NUM_KEYCODES + MIN_KEYCODE - 1
typedef struct darwinKeyboardInfo_struct {
CARD8 modMap[MAP_LENGTH];
KeySym keyMap[MAP_LENGTH * GLYPHS_PER_KEY];
unsigned char modifierKeycodes[32][2];
} darwinKeyboardInfo;
Bool DarwinModeReadSystemKeymap(darwinKeyboardInfo *info);
#endif /* DARWIN_KEYBOARD_H */

770
hw/darwin/iokit/xfIOKit.c Normal file
View File

@ -0,0 +1,770 @@
/**************************************************************
*
* IOKit support for the Darwin X Server
*
* HISTORY:
* Original port to Mac OS X Server by John Carmack
* Port to Darwin 1.0 by Dave Zarzycki
* Significantly rewritten for XFree86 4.0.1 by Torrey Lyons
*
**************************************************************/
/*
* Copyright (c) 2001-2002 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/iokit/xfIOKit.c,v 1.2 2003/10/16 23:50:09 torrey Exp $ */
#include "X.h"
#include "Xproto.h"
#include "os.h"
#include "servermd.h"
#include "inputstr.h"
#include "scrnintstr.h"
#include "mi.h"
#include "mibstore.h"
#include "mipointer.h"
#include "micmap.h"
#include "shadow.h"
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <mach/mach_interface.h>
#define NO_CFPLUGIN
#include <IOKit/IOKitLib.h>
#include <IOKit/hidsystem/IOHIDShared.h>
#include <IOKit/graphics/IOGraphicsLib.h>
#include <drivers/event_status_driver.h>
// Define this to work around bugs in the display drivers for
// older PowerBook G3's. If the X server starts without this
// #define, you don't need it.
#undef OLD_POWERBOOK_G3
#include "darwin.h"
#include "xfIOKit.h"
// Globals
int xfIOKitScreenIndex = 0;
io_connect_t xfIOKitInputConnect = 0;
static pthread_t inputThread;
static EvGlobals * evg;
static mach_port_t masterPort;
static mach_port_t notificationPort;
static IONotificationPortRef NotificationPortRef;
static mach_port_t pmNotificationPort;
static io_iterator_t fbIter;
/*
* XFIOKitStoreColors
* This is a callback from X to change the hardware colormap
* when using PsuedoColor.
*/
static void XFIOKitStoreColors(
ColormapPtr pmap,
int numEntries,
xColorItem *pdefs)
{
kern_return_t kr;
int i;
IOColorEntry *newColors;
ScreenPtr pScreen = pmap->pScreen;
XFIOKitScreenPtr iokitScreen = XFIOKIT_SCREEN_PRIV(pScreen);
assert( newColors = (IOColorEntry *)
xalloc( numEntries*sizeof(IOColorEntry) ));
// Convert xColorItem values to IOColorEntry
// assume the colormap is PsuedoColor
// as we do not support DirectColor
for (i = 0; i < numEntries; i++) {
newColors[i].index = pdefs[i].pixel;
newColors[i].red = pdefs[i].red;
newColors[i].green = pdefs[i].green;
newColors[i].blue = pdefs[i].blue;
}
kr = IOFBSetCLUT( iokitScreen->fbService, 0, numEntries,
kSetCLUTByValue, newColors );
kern_assert( kr );
xfree( newColors );
}
/*
* DarwinModeBell
* FIXME
*/
void DarwinModeBell(
int loud,
DeviceIntPtr pDevice,
pointer ctrl,
int fbclass)
{
}
/*
* DarwinModeGiveUp
* Closes the connections to IOKit services
*/
void DarwinModeGiveUp( void )
{
int i;
// we must close the HID System first
// because it is a client of the framebuffer
NXCloseEventStatus( darwinParamConnect );
IOServiceClose( xfIOKitInputConnect );
for (i = 0; i < screenInfo.numScreens; i++) {
XFIOKitScreenPtr iokitScreen =
XFIOKIT_SCREEN_PRIV(screenInfo.screens[i]);
IOServiceClose( iokitScreen->fbService );
}
}
/*
* ClearEvent
* Clear an event from the HID System event queue
*/
static void ClearEvent(NXEvent * ep)
{
static NXEvent nullEvent = {NX_NULLEVENT, {0, 0 }, 0, -1, 0 };
*ep = nullEvent;
ep->data.compound.subType = ep->data.compound.misc.L[0] =
ep->data.compound.misc.L[1] = 0;
}
/*
* XFIOKitHIDThread
* Read the HID System event queue, translate it to an X event,
* and queue it for processing.
*/
static void *XFIOKitHIDThread(void *unused)
{
for (;;) {
NXEQElement *oldHead;
mach_msg_return_t kr;
mach_msg_empty_rcv_t msg;
kr = mach_msg((mach_msg_header_t*) &msg, MACH_RCV_MSG, 0,
sizeof(msg), notificationPort, 0, MACH_PORT_NULL);
kern_assert(kr);
while (evg->LLEHead != evg->LLETail) {
NXEvent ev;
xEvent xe;
// Extract the next event from the kernel queue
oldHead = (NXEQElement*)&evg->lleq[evg->LLEHead];
ev_lock(&oldHead->sema);
ev = oldHead->event;
ClearEvent(&oldHead->event);
evg->LLEHead = oldHead->next;
ev_unlock(&oldHead->sema);
memset(&xe, 0, sizeof(xe));
// These fields should be filled in for every event
xe.u.keyButtonPointer.rootX = ev.location.x;
xe.u.keyButtonPointer.rootY = ev.location.y;
xe.u.keyButtonPointer.time = GetTimeInMillis();
switch( ev.type ) {
case NX_MOUSEMOVED:
xe.u.u.type = MotionNotify;
break;
case NX_LMOUSEDOWN:
xe.u.u.type = ButtonPress;
xe.u.u.detail = 1;
break;
case NX_LMOUSEUP:
xe.u.u.type = ButtonRelease;
xe.u.u.detail = 1;
break;
// A newer kernel generates multi-button events with
// NX_SYSDEFINED. Button 2 isn't handled correctly by
// older kernels anyway. Just let NX_SYSDEFINED events
// handle these.
#if 0
case NX_RMOUSEDOWN:
xe.u.u.type = ButtonPress;
xe.u.u.detail = 2;
break;
case NX_RMOUSEUP:
xe.u.u.type = ButtonRelease;
xe.u.u.detail = 2;
break;
#endif
case NX_KEYDOWN:
xe.u.u.type = KeyPress;
xe.u.u.detail = ev.data.key.keyCode;
break;
case NX_KEYUP:
xe.u.u.type = KeyRelease;
xe.u.u.detail = ev.data.key.keyCode;
break;
case NX_FLAGSCHANGED:
xe.u.u.type = kXDarwinUpdateModifiers;
xe.u.clientMessage.u.l.longs0 = ev.flags;
break;
case NX_SYSDEFINED:
if (ev.data.compound.subType == 7) {
xe.u.u.type = kXDarwinUpdateButtons;
xe.u.clientMessage.u.l.longs0 =
ev.data.compound.misc.L[0];
xe.u.clientMessage.u.l.longs1 =
ev.data.compound.misc.L[1];
} else {
continue;
}
break;
case NX_SCROLLWHEELMOVED:
xe.u.u.type = kXDarwinScrollWheel;
xe.u.clientMessage.u.s.shorts0 =
ev.data.scrollWheel.deltaAxis1;
break;
default:
continue;
}
DarwinEQEnqueue(&xe);
}
}
return NULL;
}
/*
* XFIOKitPMThread
* Handle power state notifications
*/
static void *XFIOKitPMThread(void *arg)
{
ScreenPtr pScreen = (ScreenPtr)arg;
XFIOKitScreenPtr iokitScreen = XFIOKIT_SCREEN_PRIV(pScreen);
for (;;) {
mach_msg_return_t kr;
mach_msg_empty_rcv_t msg;
kr = mach_msg((mach_msg_header_t*) &msg, MACH_RCV_MSG, 0,
sizeof(msg), pmNotificationPort, 0, MACH_PORT_NULL);
kern_assert(kr);
// display is powering down
if (msg.header.msgh_id == 0) {
IOFBAcknowledgePM( iokitScreen->fbService );
xf86SetRootClip(pScreen, FALSE);
}
// display just woke up
else if (msg.header.msgh_id == 1) {
xf86SetRootClip(pScreen, TRUE);
}
}
return NULL;
}
/*
* SetupFBandHID
* Setup an IOFramebuffer service and connect the HID system to it.
*/
static Bool SetupFBandHID(
int index,
DarwinFramebufferPtr dfb,
XFIOKitScreenPtr iokitScreen)
{
kern_return_t kr;
io_service_t service;
io_connect_t fbService;
vm_address_t vram;
vm_size_t shmemSize;
int i;
UInt32 numModes;
IODisplayModeInformation modeInfo;
IODisplayModeID displayMode, *allModes;
IOIndex displayDepth;
IOFramebufferInformation fbInfo;
IOPixelInformation pixelInfo;
StdFBShmem_t *cshmem;
// find and open the IOFrameBuffer service
service = IOIteratorNext(fbIter);
if (service == 0)
return FALSE;
kr = IOServiceOpen( service, mach_task_self(),
kIOFBServerConnectType, &iokitScreen->fbService );
IOObjectRelease( service );
if (kr != KERN_SUCCESS) {
ErrorF("Failed to connect as window server to screen %i.\n", index);
return FALSE;
}
fbService = iokitScreen->fbService;
// create the slice of shared memory containing cursor state data
kr = IOFBCreateSharedCursor( fbService,
kIOFBCurrentShmemVersion,
32, 32 );
if (kr != KERN_SUCCESS)
return FALSE;
// Register for power management events for the framebuffer's device
kr = IOCreateReceivePort(kOSNotificationMessageID, &pmNotificationPort);
kern_assert(kr);
kr = IOConnectSetNotificationPort( fbService, 0,
pmNotificationPort, 0 );
if (kr != KERN_SUCCESS) {
ErrorF("Power management registration failed.\n");
}
// SET THE SCREEN PARAMETERS
// get the current screen resolution, refresh rate and depth
kr = IOFBGetCurrentDisplayModeAndDepth( fbService,
&displayMode,
&displayDepth );
if (kr != KERN_SUCCESS)
return FALSE;
// use the current screen resolution if the user
// only wants to change the refresh rate
if (darwinDesiredRefresh != -1 && darwinDesiredWidth == 0) {
kr = IOFBGetDisplayModeInformation( fbService,
displayMode,
&modeInfo );
if (kr != KERN_SUCCESS)
return FALSE;
darwinDesiredWidth = modeInfo.nominalWidth;
darwinDesiredHeight = modeInfo.nominalHeight;
}
// use the current resolution and refresh rate
// if the user doesn't have a preference
if (darwinDesiredWidth == 0) {
// change the pixel depth if desired
if (darwinDesiredDepth != -1) {
kr = IOFBGetDisplayModeInformation( fbService,
displayMode,
&modeInfo );
if (kr != KERN_SUCCESS)
return FALSE;
if (modeInfo.maxDepthIndex < darwinDesiredDepth) {
ErrorF("Discarding screen %i:\n", index);
ErrorF("Current screen resolution does not support desired pixel depth.\n");
return FALSE;
}
displayDepth = darwinDesiredDepth;
kr = IOFBSetDisplayModeAndDepth( fbService, displayMode,
displayDepth );
if (kr != KERN_SUCCESS)
return FALSE;
}
// look for display mode with correct resolution and refresh rate
} else {
// get an array of all supported display modes
kr = IOFBGetDisplayModeCount( fbService, &numModes );
if (kr != KERN_SUCCESS)
return FALSE;
assert(allModes = (IODisplayModeID *)
xalloc( numModes * sizeof(IODisplayModeID) ));
kr = IOFBGetDisplayModes( fbService, numModes, allModes );
if (kr != KERN_SUCCESS)
return FALSE;
for (i = 0; i < numModes; i++) {
kr = IOFBGetDisplayModeInformation( fbService, allModes[i],
&modeInfo );
if (kr != KERN_SUCCESS)
return FALSE;
if (modeInfo.flags & kDisplayModeValidFlag &&
modeInfo.nominalWidth == darwinDesiredWidth &&
modeInfo.nominalHeight == darwinDesiredHeight) {
if (darwinDesiredDepth == -1)
darwinDesiredDepth = modeInfo.maxDepthIndex;
if (modeInfo.maxDepthIndex < darwinDesiredDepth) {
ErrorF("Discarding screen %i:\n", index);
ErrorF("Desired screen resolution does not support desired pixel depth.\n");
return FALSE;
}
if ((darwinDesiredRefresh == -1 ||
(darwinDesiredRefresh << 16) == modeInfo.refreshRate)) {
displayMode = allModes[i];
displayDepth = darwinDesiredDepth;
kr = IOFBSetDisplayModeAndDepth(fbService,
displayMode,
displayDepth);
if (kr != KERN_SUCCESS)
return FALSE;
break;
}
}
}
xfree( allModes );
if (i >= numModes) {
ErrorF("Discarding screen %i:\n", index);
ErrorF("Desired screen resolution or refresh rate is not supported.\n");
return FALSE;
}
}
kr = IOFBGetPixelInformation( fbService, displayMode, displayDepth,
kIOFBSystemAperture, &pixelInfo );
if (kr != KERN_SUCCESS)
return FALSE;
#ifdef __i386__
/* x86 in 8bit mode currently needs fixed color map... */
if( pixelInfo.bitsPerComponent == 8 ) {
pixelInfo.pixelType = kIOFixedCLUTPixels;
}
#endif
#ifdef OLD_POWERBOOK_G3
if (pixelInfo.pixelType == kIOCLUTPixels)
pixelInfo.pixelType = kIOFixedCLUTPixels;
#endif
kr = IOFBGetFramebufferInformationForAperture( fbService,
kIOFBSystemAperture,
&fbInfo );
if (kr != KERN_SUCCESS)
return FALSE;
// FIXME: 1x1 IOFramebuffers are sometimes used to indicate video
// outputs without a monitor connected to them. Since IOKit Xinerama
// does not really work, this often causes problems on PowerBooks.
// For now we explicitly check and ignore these screens.
if (fbInfo.activeWidth <= 1 || fbInfo.activeHeight <= 1) {
ErrorF("Discarding screen %i:\n", index);
ErrorF("Invalid width or height.\n");
return FALSE;
}
kr = IOConnectMapMemory( fbService, kIOFBCursorMemory,
mach_task_self(), (vm_address_t *) &cshmem,
&shmemSize, kIOMapAnywhere );
if (kr != KERN_SUCCESS)
return FALSE;
iokitScreen->cursorShmem = cshmem;
kr = IOConnectMapMemory( fbService, kIOFBSystemAperture,
mach_task_self(), &vram, &shmemSize,
kIOMapAnywhere );
if (kr != KERN_SUCCESS)
return FALSE;
iokitScreen->framebuffer = (void*)vram;
dfb->x = cshmem->screenBounds.minx;
dfb->y = cshmem->screenBounds.miny;
dfb->width = fbInfo.activeWidth;
dfb->height = fbInfo.activeHeight;
dfb->pitch = fbInfo.bytesPerRow;
dfb->bitsPerPixel = fbInfo.bitsPerPixel;
dfb->colorBitsPerPixel = pixelInfo.componentCount *
pixelInfo.bitsPerComponent;
dfb->bitsPerComponent = pixelInfo.bitsPerComponent;
// allocate shadow framebuffer
iokitScreen->shadowPtr = shadowAlloc(dfb->width, dfb->height,
dfb->bitsPerPixel);
dfb->framebuffer = iokitScreen->shadowPtr;
// Note: Darwin kIORGBDirectPixels = X TrueColor, not DirectColor
if (pixelInfo.pixelType == kIORGBDirectPixels) {
dfb->colorType = TrueColor;
} else if (pixelInfo.pixelType == kIOCLUTPixels) {
dfb->colorType = PseudoColor;
} else if (pixelInfo.pixelType == kIOFixedCLUTPixels) {
dfb->colorType = StaticColor;
}
// Inform the HID system that the framebuffer is also connected to it.
kr = IOConnectAddClient( xfIOKitInputConnect, fbService );
kern_assert( kr );
// We have to have added at least one screen
// before we can enable the cursor.
kr = IOHIDSetCursorEnable(xfIOKitInputConnect, TRUE);
kern_assert( kr );
return TRUE;
}
/*
* DarwinModeAddScreen
* IOKit specific initialization for each screen.
*/
Bool DarwinModeAddScreen(
int index,
ScreenPtr pScreen)
{
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
XFIOKitScreenPtr iokitScreen;
// allocate space for private per screen storage
iokitScreen = xalloc(sizeof(XFIOKitScreenRec));
XFIOKIT_SCREEN_PRIV(pScreen) = iokitScreen;
// setup hardware framebuffer
iokitScreen->fbService = 0;
if (! SetupFBandHID(index, dfb, iokitScreen)) {
if (iokitScreen->fbService) {
IOServiceClose(iokitScreen->fbService);
}
return FALSE;
}
return TRUE;
}
/*
* XFIOKitShadowUpdate
* Update the damaged regions of the shadow framebuffer on the screen.
*/
static void XFIOKitShadowUpdate(ScreenPtr pScreen,
shadowBufPtr pBuf)
{
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
XFIOKitScreenPtr iokitScreen = XFIOKIT_SCREEN_PRIV(pScreen);
RegionPtr damage = &pBuf->damage;
int numBox = REGION_NUM_RECTS(damage);
BoxPtr pBox = REGION_RECTS(damage);
int pitch = dfb->pitch;
int bpp = dfb->bitsPerPixel/8;
// Loop through all the damaged boxes
while (numBox--) {
int width, height, offset;
unsigned char *src, *dst;
width = (pBox->x2 - pBox->x1) * bpp;
height = pBox->y2 - pBox->y1;
offset = (pBox->y1 * pitch) + (pBox->x1 * bpp);
src = iokitScreen->shadowPtr + offset;
dst = iokitScreen->framebuffer + offset;
while (height--) {
memcpy(dst, src, width);
dst += pitch;
src += pitch;
}
// Get the next box
pBox++;
}
}
/*
* DarwinModeSetupScreen
* Finalize IOKit specific initialization of each screen.
*/
Bool DarwinModeSetupScreen(
int index,
ScreenPtr pScreen)
{
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
pthread_t pmThread;
// initalize cursor support
if (! XFIOKitInitCursor(pScreen)) {
return FALSE;
}
// initialize shadow framebuffer support
if (! shadowInit(pScreen, XFIOKitShadowUpdate, NULL)) {
ErrorF("Failed to initalize shadow framebuffer for screen %i.\n",
index);
return FALSE;
}
// initialize colormap handling as needed
if (dfb->colorType == PseudoColor) {
pScreen->StoreColors = XFIOKitStoreColors;
}
// initialize power manager handling
pthread_create( &pmThread, NULL, XFIOKitPMThread,
(void *) pScreen );
return TRUE;
}
/*
* DarwinModeInitOutput
* One-time initialization of IOKit output support.
*/
void DarwinModeInitOutput(
int argc,
char **argv)
{
static unsigned long generation = 0;
kern_return_t kr;
io_iterator_t iter;
io_service_t service;
vm_address_t shmem;
vm_size_t shmemSize;
ErrorF("Display mode: IOKit\n");
// Allocate private storage for each screen's IOKit specific info
if (generation != serverGeneration) {
xfIOKitScreenIndex = AllocateScreenPrivateIndex();
generation = serverGeneration;
}
kr = IOMasterPort(bootstrap_port, &masterPort);
kern_assert( kr );
// Find and open the HID System Service
// Do this now to be sure the Mac OS X window server is not running.
kr = IOServiceGetMatchingServices( masterPort,
IOServiceMatching( kIOHIDSystemClass ),
&iter );
kern_assert( kr );
assert( service = IOIteratorNext( iter ) );
kr = IOServiceOpen( service, mach_task_self(), kIOHIDServerConnectType,
&xfIOKitInputConnect );
if (kr != KERN_SUCCESS) {
ErrorF("Failed to connect to the HID System as the window server!\n");
#ifdef DARWIN_WITH_QUARTZ
FatalError("Quit the Mac OS X window server or use the -quartz option.\n");
#else
FatalError("Make sure you have quit the Mac OS X window server.\n");
#endif
}
IOObjectRelease( service );
IOObjectRelease( iter );
// Setup the event queue in memory shared by the kernel and X server
kr = IOHIDCreateSharedMemory( xfIOKitInputConnect,
kIOHIDCurrentShmemVersion );
kern_assert( kr );
kr = IOConnectMapMemory( xfIOKitInputConnect, kIOHIDGlobalMemory,
mach_task_self(), &shmem, &shmemSize,
kIOMapAnywhere );
kern_assert( kr );
evg = (EvGlobals *)(shmem + ((EvOffsets *)shmem)->evGlobalsOffset);
assert(sizeof(EvGlobals) == evg->structSize);
NotificationPortRef = IONotificationPortCreate( masterPort );
notificationPort = IONotificationPortGetMachPort(NotificationPortRef);
kr = IOConnectSetNotificationPort( xfIOKitInputConnect,
kIOHIDEventNotification,
notificationPort, 0 );
kern_assert( kr );
evg->movedMask |= NX_MOUSEMOVEDMASK;
// find number of framebuffers
kr = IOServiceGetMatchingServices( masterPort,
IOServiceMatching( IOFRAMEBUFFER_CONFORMSTO ),
&fbIter );
kern_assert( kr );
darwinScreensFound = 0;
while ((service = IOIteratorNext(fbIter))) {
IOObjectRelease( service );
darwinScreensFound++;
}
IOIteratorReset(fbIter);
}
/*
* DarwinModeInitInput
* One-time initialization of IOKit input support.
*/
void DarwinModeInitInput(
int argc,
char **argv)
{
kern_return_t kr;
int fd[2];
kr = IOHIDSetEventsEnable(xfIOKitInputConnect, TRUE);
kern_assert( kr );
// Start event passing thread
assert( pipe(fd) == 0 );
darwinEventReadFD = fd[0];
darwinEventWriteFD = fd[1];
fcntl(darwinEventReadFD, F_SETFL, O_NONBLOCK);
pthread_create(&inputThread, NULL,
XFIOKitHIDThread, NULL);
}
/*
* DarwinModeProcessEvent
* Process IOKit specific events.
*/
void DarwinModeProcessEvent(
xEvent *xe)
{
// No mode specific events
ErrorF("Unknown X event caught: %d\n", xe->u.u.type);
}

57
hw/darwin/iokit/xfIOKit.h Normal file
View File

@ -0,0 +1,57 @@
/*
xfIOKit.h
IOKit specific functions and definitions
*/
/*
* Copyright (c) 2001-2002 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/iokit/xfIOKit.h,v 1.1 2003/05/14 05:27:56 torrey Exp $ */
#ifndef _XFIOKIT_H
#define _XFIOKIT_H
#include <pthread.h>
#include <IOKit/graphics/IOFramebufferShared.h>
#include "X11/Xproto.h"
#include "screenint.h"
#include "darwin.h"
typedef struct {
io_connect_t fbService;
StdFBShmem_t *cursorShmem;
unsigned char *framebuffer;
unsigned char *shadowPtr;
} XFIOKitScreenRec, *XFIOKitScreenPtr;
#define XFIOKIT_SCREEN_PRIV(pScreen) \
((XFIOKitScreenPtr)pScreen->devPrivates[xfIOKitScreenIndex].ptr)
extern int xfIOKitScreenIndex; // index into pScreen.devPrivates
extern io_connect_t xfIOKitInputConnect;
Bool XFIOKitInitCursor(ScreenPtr pScreen);
#endif /* _XFIOKIT_H */

View File

@ -0,0 +1,735 @@
/**************************************************************
*
* Cursor support for Darwin X Server
*
* Three different cursor modes are possible:
* X (0) - tracking via Darwin kernel,
* display via X machine independent
* Kernel (1) - tracking and display via Darwin kernel
* (not currently supported)
* Hardware (2) - tracking and display via hardware
*
* The X software cursor uses the Darwin software cursor
* routines in IOFramebuffer.cpp to track the cursor, but
* displays the cursor image using the X machine
* independent display cursor routines in midispcur.c.
*
* The kernel cursor uses IOFramebuffer.cpp routines to
* track and display the cursor. This gives better
* performance as the display calls don't have to cross
* the kernel boundary. Unfortunately, this mode has
* synchronization issues with the user land X server
* and isn't currently used.
*
* Hardware cursor support lets the hardware handle these
* details.
*
* Kernel and hardware cursor mode only work for cursors
* up to a certain size, currently 16x16 pixels. If a
* bigger cursor is set, we fallback to X cursor mode.
*
* HISTORY:
* 1.0 by Torrey T. Lyons, October 30, 2000
*
**************************************************************/
/*
* Copyright (c) 2001-2002 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/iokit/xfIOKitCursor.c,v 1.1 2003/05/14 05:27:56 torrey Exp $ */
#include "scrnintstr.h"
#include "cursorstr.h"
#include "mipointrst.h"
#include "micmap.h"
#define NO_CFPLUGIN
#include <IOKit/graphics/IOGraphicsLib.h>
#include <IOKit/hidsystem/IOHIDLib.h>
#include "darwin.h"
#include "xfIOKit.h"
#define DUMP_DARWIN_CURSOR FALSE
#define CURSOR_PRIV(pScreen) \
((XFIOKitCursorScreenPtr)pScreen->devPrivates[darwinCursorScreenIndex].ptr)
// The cursors format are documented in IOFramebufferShared.h.
#define RGBto34WithGamma(red, green, blue) \
( 0x000F \
| (((red) & 0xF) << 12) \
| (((green) & 0xF) << 8) \
| (((blue) & 0xF) << 4) )
#define RGBto38WithGamma(red, green, blue) \
( 0xFF << 24 \
| (((red) & 0xFF) << 16) \
| (((green) & 0xFF) << 8) \
| (((blue) & 0xFF)) )
#define HighBitOf32 0x80000000
typedef struct {
Bool canHWCursor;
short cursorMode;
RecolorCursorProcPtr RecolorCursor;
InstallColormapProcPtr InstallColormap;
QueryBestSizeProcPtr QueryBestSize;
miPointerSpriteFuncPtr spriteFuncs;
ColormapPtr pInstalledMap;
} XFIOKitCursorScreenRec, *XFIOKitCursorScreenPtr;
static int darwinCursorScreenIndex = -1;
static unsigned long darwinCursorGeneration = 0;
/*
===========================================================================
Pointer sprite functions
===========================================================================
*/
/*
Realizing the Darwin hardware cursor (ie. converting from the
X representation to the IOKit representation) is complicated
by the fact that we have three different potential cursor
formats to go to, one for each bit depth (8, 15, or 24).
The IOKit formats are documented in IOFramebufferShared.h.
X cursors are represented as two pieces, a source and a mask.
The mask is a bitmap indicating which parts of the cursor are
transparent and which parts are drawn. The source is a bitmap
indicating which parts of the non-transparent portion of the the
cursor should be painted in the foreground color and which should
be painted in the background color. The bitmaps are given in
32-bit format with least significant byte and bit first.
(This is opposite PowerPC Darwin.)
*/
typedef struct {
unsigned char image[CURSORWIDTH*CURSORHEIGHT];
unsigned char mask[CURSORWIDTH*CURSORHEIGHT];
} cursorPrivRec, *cursorPrivPtr;
/*
* XFIOKitRealizeCursor8
* Convert the X cursor representation to an 8-bit depth
* format for Darwin. This function assumes the maximum cursor
* width is a multiple of 8.
*/
static Bool
XFIOKitRealizeCursor8(
ScreenPtr pScreen,
CursorPtr pCursor)
{
cursorPrivPtr newCursor;
unsigned char *newSourceP, *newMaskP;
CARD32 *oldSourceP, *oldMaskP;
xColorItem fgColor, bgColor;
int index, x, y, rowPad;
int cursorWidth, cursorHeight;
ColormapPtr pmap;
// check cursor size just to be sure
cursorWidth = pCursor->bits->width;
cursorHeight = pCursor->bits->height;
if (cursorHeight > CURSORHEIGHT || cursorWidth > CURSORWIDTH)
return FALSE;
// get cursor colors in colormap
index = pScreen->myNum;
pmap = miInstalledMaps[index];
if (!pmap) return FALSE;
fgColor.red = pCursor->foreRed;
fgColor.green = pCursor->foreGreen;
fgColor.blue = pCursor->foreBlue;
FakeAllocColor(pmap, &fgColor);
bgColor.red = pCursor->backRed;
bgColor.green = pCursor->backGreen;
bgColor.blue = pCursor->backBlue;
FakeAllocColor(pmap, &bgColor);
FakeFreeColor(pmap, fgColor.pixel);
FakeFreeColor(pmap, bgColor.pixel);
// allocate memory for new cursor image
newCursor = xalloc( sizeof(cursorPrivRec) );
if (!newCursor)
return FALSE;
memset( newCursor->image, pScreen->blackPixel, CURSORWIDTH*CURSORHEIGHT );
memset( newCursor->mask, 0, CURSORWIDTH*CURSORHEIGHT );
// convert to 8-bit Darwin cursor format
oldSourceP = (CARD32 *) pCursor->bits->source;
oldMaskP = (CARD32 *) pCursor->bits->mask;
newSourceP = newCursor->image;
newMaskP = newCursor->mask;
rowPad = CURSORWIDTH - cursorWidth;
for (y = 0; y < cursorHeight; y++) {
for (x = 0; x < cursorWidth; x++) {
if (*oldSourceP & (HighBitOf32 >> x))
*newSourceP = fgColor.pixel;
else
*newSourceP = bgColor.pixel;
if (*oldMaskP & (HighBitOf32 >> x))
*newMaskP = 255;
else
*newSourceP = pScreen->blackPixel;
newSourceP++; newMaskP++;
}
oldSourceP++; oldMaskP++;
newSourceP += rowPad; newMaskP += rowPad;
}
// save the result
pCursor->devPriv[pScreen->myNum] = (pointer) newCursor;
return TRUE;
}
/*
* XFIOKitRealizeCursor15
* Convert the X cursor representation to an 15-bit depth
* format for Darwin.
*/
static Bool
XFIOKitRealizeCursor15(
ScreenPtr pScreen,
CursorPtr pCursor)
{
unsigned short *newCursor;
unsigned short fgPixel, bgPixel;
unsigned short *newSourceP;
CARD32 *oldSourceP, *oldMaskP;
int x, y, rowPad;
int cursorWidth, cursorHeight;
// check cursor size just to be sure
cursorWidth = pCursor->bits->width;
cursorHeight = pCursor->bits->height;
if (cursorHeight > CURSORHEIGHT || cursorWidth > CURSORWIDTH)
return FALSE;
// allocate memory for new cursor image
newCursor = xalloc( CURSORWIDTH*CURSORHEIGHT*sizeof(short) );
if (!newCursor)
return FALSE;
memset( newCursor, 0, CURSORWIDTH*CURSORHEIGHT*sizeof(short) );
// calculate pixel values
fgPixel = RGBto34WithGamma( pCursor->foreRed, pCursor->foreGreen,
pCursor->foreBlue );
bgPixel = RGBto34WithGamma( pCursor->backRed, pCursor->backGreen,
pCursor->backBlue );
// convert to 15-bit Darwin cursor format
oldSourceP = (CARD32 *) pCursor->bits->source;
oldMaskP = (CARD32 *) pCursor->bits->mask;
newSourceP = newCursor;
rowPad = CURSORWIDTH - cursorWidth;
for (y = 0; y < cursorHeight; y++) {
for (x = 0; x < cursorWidth; x++) {
if (*oldMaskP & (HighBitOf32 >> x)) {
if (*oldSourceP & (HighBitOf32 >> x))
*newSourceP = fgPixel;
else
*newSourceP = bgPixel;
} else {
*newSourceP = 0;
}
newSourceP++;
}
oldSourceP++; oldMaskP++;
newSourceP += rowPad;
}
#if DUMP_DARWIN_CURSOR
// Write out the cursor
ErrorF("Cursor: 0x%x\n", pCursor);
ErrorF("Width = %i, Height = %i, RowPad = %i\n", cursorWidth,
cursorHeight, rowPad);
for (y = 0; y < cursorHeight; y++) {
newSourceP = newCursor + y*CURSORWIDTH;
for (x = 0; x < cursorWidth; x++) {
if (*newSourceP == fgPixel)
ErrorF("x");
else if (*newSourceP == bgPixel)
ErrorF("o");
else
ErrorF(" ");
newSourceP++;
}
ErrorF("\n");
}
#endif
// save the result
pCursor->devPriv[pScreen->myNum] = (pointer) newCursor;
return TRUE;
}
/*
* XFIOKitRealizeCursor24
* Convert the X cursor representation to an 24-bit depth
* format for Darwin. This function assumes the maximum cursor
* width is a multiple of 8.
*/
static Bool
XFIOKitRealizeCursor24(
ScreenPtr pScreen,
CursorPtr pCursor)
{
unsigned int *newCursor;
unsigned int fgPixel, bgPixel;
unsigned int *newSourceP;
CARD32 *oldSourceP, *oldMaskP;
int x, y, rowPad;
int cursorWidth, cursorHeight;
// check cursor size just to be sure
cursorWidth = pCursor->bits->width;
cursorHeight = pCursor->bits->height;
if (cursorHeight > CURSORHEIGHT || cursorWidth > CURSORWIDTH)
return FALSE;
// allocate memory for new cursor image
newCursor = xalloc( CURSORWIDTH*CURSORHEIGHT*sizeof(int) );
if (!newCursor)
return FALSE;
memset( newCursor, 0, CURSORWIDTH*CURSORHEIGHT*sizeof(int) );
// calculate pixel values
fgPixel = RGBto38WithGamma( pCursor->foreRed, pCursor->foreGreen,
pCursor->foreBlue );
bgPixel = RGBto38WithGamma( pCursor->backRed, pCursor->backGreen,
pCursor->backBlue );
// convert to 24-bit Darwin cursor format
oldSourceP = (CARD32 *) pCursor->bits->source;
oldMaskP = (CARD32 *) pCursor->bits->mask;
newSourceP = newCursor;
rowPad = CURSORWIDTH - cursorWidth;
for (y = 0; y < cursorHeight; y++) {
for (x = 0; x < cursorWidth; x++) {
if (*oldMaskP & (HighBitOf32 >> x)) {
if (*oldSourceP & (HighBitOf32 >> x))
*newSourceP = fgPixel;
else
*newSourceP = bgPixel;
} else {
*newSourceP = 0;
}
newSourceP++;
}
oldSourceP++; oldMaskP++;
newSourceP += rowPad;
}
#if DUMP_DARWIN_CURSOR
// Write out the cursor
ErrorF("Cursor: 0x%x\n", pCursor);
ErrorF("Width = %i, Height = %i, RowPad = %i\n", cursorWidth,
cursorHeight, rowPad);
for (y = 0; y < cursorHeight; y++) {
newSourceP = newCursor + y*CURSORWIDTH;
for (x = 0; x < cursorWidth; x++) {
if (*newSourceP == fgPixel)
ErrorF("x");
else if (*newSourceP == bgPixel)
ErrorF("o");
else
ErrorF(" ");
newSourceP++;
}
ErrorF("\n");
}
#endif
// save the result
pCursor->devPriv[pScreen->myNum] = (pointer) newCursor;
return TRUE;
}
/*
* XFIOKitRealizeCursor
*
*/
static Bool
XFIOKitRealizeCursor(
ScreenPtr pScreen,
CursorPtr pCursor)
{
Bool result;
XFIOKitCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
if ((pCursor->bits->height > CURSORHEIGHT) ||
(pCursor->bits->width > CURSORWIDTH) ||
// FIXME: this condition is not needed after kernel cursor works
!ScreenPriv->canHWCursor) {
result = (*ScreenPriv->spriteFuncs->RealizeCursor)(pScreen, pCursor);
} else if (dfb->bitsPerPixel == 8) {
result = XFIOKitRealizeCursor8(pScreen, pCursor);
} else if (dfb->bitsPerPixel == 16) {
result = XFIOKitRealizeCursor15(pScreen, pCursor);
} else {
result = XFIOKitRealizeCursor24(pScreen, pCursor);
}
return result;
}
/*
* XFIOKitUnrealizeCursor
*
*/
static Bool
XFIOKitUnrealizeCursor(
ScreenPtr pScreen,
CursorPtr pCursor)
{
Bool result;
XFIOKitCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
if ((pCursor->bits->height > CURSORHEIGHT) ||
(pCursor->bits->width > CURSORWIDTH) ||
// FIXME: this condition is not needed after kernel cursor works
!ScreenPriv->canHWCursor) {
result = (*ScreenPriv->spriteFuncs->UnrealizeCursor)(pScreen, pCursor);
} else {
xfree( pCursor->devPriv[pScreen->myNum] );
result = TRUE;
}
return result;
}
/*
* XFIOKitSetCursor
* Set the cursor sprite and position
* Use hardware cursor if possible
*/
static void
XFIOKitSetCursor(
ScreenPtr pScreen,
CursorPtr pCursor,
int x,
int y)
{
kern_return_t kr;
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
XFIOKitScreenPtr iokitScreen = XFIOKIT_SCREEN_PRIV(pScreen);
StdFBShmem_t *cshmem = iokitScreen->cursorShmem;
XFIOKitCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
// are we supposed to remove the cursor?
if (!pCursor) {
if (ScreenPriv->cursorMode == 0)
(*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
else {
if (!cshmem->cursorShow) {
cshmem->cursorShow++;
if (cshmem->hardwareCursorActive) {
kr = IOFBSetCursorVisible(iokitScreen->fbService, FALSE);
kern_assert( kr );
}
}
}
return;
}
// can we use the kernel or hardware cursor?
if ((pCursor->bits->height <= CURSORHEIGHT) &&
(pCursor->bits->width <= CURSORWIDTH) &&
// FIXME: condition not needed when kernel cursor works
ScreenPriv->canHWCursor) {
if (ScreenPriv->cursorMode == 0) // remove the X cursor
(*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
ScreenPriv->cursorMode = 1; // kernel cursor
// change the cursor image in shared memory
if (dfb->bitsPerPixel == 8) {
cursorPrivPtr newCursor =
(cursorPrivPtr) pCursor->devPriv[pScreen->myNum];
memcpy(cshmem->cursor.bw8.image[0], newCursor->image,
CURSORWIDTH*CURSORHEIGHT);
memcpy(cshmem->cursor.bw8.mask[0], newCursor->mask,
CURSORWIDTH*CURSORHEIGHT);
} else if (dfb->bitsPerPixel == 16) {
unsigned short *newCursor =
(unsigned short *) pCursor->devPriv[pScreen->myNum];
memcpy(cshmem->cursor.rgb.image[0], newCursor,
2*CURSORWIDTH*CURSORHEIGHT);
} else {
unsigned int *newCursor =
(unsigned int *) pCursor->devPriv[pScreen->myNum];
memcpy(cshmem->cursor.rgb24.image[0], newCursor,
4*CURSORWIDTH*CURSORHEIGHT);
}
// FIXME: We always use a full size cursor, even if the image
// is smaller because I couldn't get the padding to come out
// right otherwise.
cshmem->cursorSize[0].width = CURSORWIDTH;
cshmem->cursorSize[0].height = CURSORHEIGHT;
cshmem->hotSpot[0].x = pCursor->bits->xhot;
cshmem->hotSpot[0].y = pCursor->bits->yhot;
// try to use a hardware cursor
if (ScreenPriv->canHWCursor) {
kr = IOFBSetNewCursor(iokitScreen->fbService, 0, 0, 0);
// FIXME: this is a fatal error without the kernel cursor
kern_assert( kr );
#if 0
if (kr != KERN_SUCCESS) {
ErrorF("Could not set new cursor with kernel return 0x%x.\n", kr);
ScreenPriv->canHWCursor = FALSE;
}
#endif
}
// make the new cursor visible
if (cshmem->cursorShow)
cshmem->cursorShow--;
if (!cshmem->cursorShow && ScreenPriv->canHWCursor) {
kr = IOFBSetCursorVisible(iokitScreen->fbService, TRUE);
// FIXME: this is a fatal error without the kernel cursor
kern_assert( kr );
#if 0
if (kr != KERN_SUCCESS) {
ErrorF("Couldn't set hardware cursor visible with kernel return 0x%x.\n", kr);
ScreenPriv->canHWCursor = FALSE;
} else
#endif
ScreenPriv->cursorMode = 2; // hardware cursor
}
return;
}
// otherwise we use a software cursor
if (ScreenPriv->cursorMode) {
/* remove the kernel or hardware cursor */
XFIOKitSetCursor(pScreen, 0, x, y);
}
ScreenPriv->cursorMode = 0;
(*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCursor, x, y);
}
/*
* XFIOKitMoveCursor
* Move the cursor. This is a noop for a kernel or hardware cursor.
*/
static void
XFIOKitMoveCursor(
ScreenPtr pScreen,
int x,
int y)
{
XFIOKitCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
// only the X cursor needs to be explicitly moved
if (!ScreenPriv->cursorMode)
(*ScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, y);
}
static miPointerSpriteFuncRec darwinSpriteFuncsRec = {
XFIOKitRealizeCursor,
XFIOKitUnrealizeCursor,
XFIOKitSetCursor,
XFIOKitMoveCursor
};
/*
===========================================================================
Pointer screen functions
===========================================================================
*/
/*
* XFIOKitCursorOffScreen
*/
static Bool XFIOKitCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
{ return FALSE;
}
/*
* XFIOKitCrossScreen
*/
static void XFIOKitCrossScreen(ScreenPtr pScreen, Bool entering)
{ return;
}
/*
* XFIOKitWarpCursor
* Change the cursor position without generating an event or motion history
*/
static void
XFIOKitWarpCursor(
ScreenPtr pScreen,
int x,
int y)
{
kern_return_t kr;
kr = IOHIDSetMouseLocation( xfIOKitInputConnect, x, y );
if (kr != KERN_SUCCESS) {
ErrorF("Could not set cursor position with kernel return 0x%x.\n", kr);
}
miPointerWarpCursor(pScreen, x, y);
}
static miPointerScreenFuncRec darwinScreenFuncsRec = {
XFIOKitCursorOffScreen,
XFIOKitCrossScreen,
XFIOKitWarpCursor,
DarwinEQPointerPost,
DarwinEQSwitchScreen
};
/*
===========================================================================
Other screen functions
===========================================================================
*/
/*
* XFIOKitCursorQueryBestSize
* Handle queries for best cursor size
*/
static void
XFIOKitCursorQueryBestSize(
int class,
unsigned short *width,
unsigned short *height,
ScreenPtr pScreen)
{
XFIOKitCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
if (class == CursorShape) {
*width = CURSORWIDTH;
*height = CURSORHEIGHT;
} else
(*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
}
/*
* XFIOKitInitCursor
* Initialize cursor support
*/
Bool
XFIOKitInitCursor(
ScreenPtr pScreen)
{
XFIOKitScreenPtr iokitScreen = XFIOKIT_SCREEN_PRIV(pScreen);
XFIOKitCursorScreenPtr ScreenPriv;
miPointerScreenPtr PointPriv;
kern_return_t kr;
// start with no cursor displayed
if (!iokitScreen->cursorShmem->cursorShow++) {
if (iokitScreen->cursorShmem->hardwareCursorActive) {
kr = IOFBSetCursorVisible(iokitScreen->fbService, FALSE);
kern_assert( kr );
}
}
// initialize software cursor handling (always needed as backup)
if (!miDCInitialize(pScreen, &darwinScreenFuncsRec)) {
return FALSE;
}
// allocate private storage for this screen's hardware cursor info
if (darwinCursorGeneration != serverGeneration) {
if ((darwinCursorScreenIndex = AllocateScreenPrivateIndex()) < 0)
return FALSE;
darwinCursorGeneration = serverGeneration;
}
ScreenPriv = xcalloc( 1, sizeof(XFIOKitCursorScreenRec) );
if (!ScreenPriv) return FALSE;
pScreen->devPrivates[darwinCursorScreenIndex].ptr = (pointer) ScreenPriv;
// check if a hardware cursor is supported
if (!iokitScreen->cursorShmem->hardwareCursorCapable) {
ScreenPriv->canHWCursor = FALSE;
ErrorF("Hardware cursor not supported.\n");
} else {
// we need to make sure that the hardware cursor really works
ScreenPriv->canHWCursor = TRUE;
kr = IOFBSetNewCursor(iokitScreen->fbService, 0, 0, 0);
if (kr != KERN_SUCCESS) {
ErrorF("Could not set hardware cursor with kernel return 0x%x.\n", kr);
ScreenPriv->canHWCursor = FALSE;
}
kr = IOFBSetCursorVisible(iokitScreen->fbService, TRUE);
if (kr != KERN_SUCCESS) {
ErrorF("Couldn't set hardware cursor visible with kernel return 0x%x.\n", kr);
ScreenPriv->canHWCursor = FALSE;
}
IOFBSetCursorVisible(iokitScreen->fbService, FALSE);
}
ScreenPriv->cursorMode = 0;
ScreenPriv->pInstalledMap = NULL;
// override some screen procedures
ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
pScreen->QueryBestSize = XFIOKitCursorQueryBestSize;
// ScreenPriv->ConstrainCursor = pScreen->ConstrainCursor;
// pScreen->ConstrainCursor = XFIOKitConstrainCursor;
// initialize hardware cursor handling
PointPriv = (miPointerScreenPtr)
pScreen->devPrivates[miPointerScreenIndex].ptr;
ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
PointPriv->spriteFuncs = &darwinSpriteFuncsRec;
/* Other routines that might be overridden */
/*
CursorLimitsProcPtr CursorLimits;
RecolorCursorProcPtr RecolorCursor;
*/
return TRUE;
}

View File

@ -0,0 +1,115 @@
/**************************************************************
*
* Startup code for the IOKit Darwin X Server
*
**************************************************************/
/*
* Copyright (c) 2001-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/iokit/xfIOKitStartup.c,v 1.2 2003/11/01 08:13:08 torrey Exp $ */
#include "darwin.h"
#include "darwinKeyboard.h"
#include "micmap.h"
void GlxExtensionInit(void);
void GlxWrapInitVisuals(miInitVisualsProcPtr *procPtr);
/*
* DarwinHandleGUI
* This function is called first from main().
* It does nothing for the IOKit X server.
*/
void DarwinHandleGUI(
int argc,
char *argv[],
char *envp[] )
{
}
/*
* DarwinGlxExtensionInit
* Initialize the GLX extension.
* Mesa is linked into the IOKit mode X server so we just call directly.
*/
void DarwinGlxExtensionInit(void)
{
GlxExtensionInit();
}
/*
* DarwinGlxWrapInitVisuals
*/
void DarwinGlxWrapInitVisuals(
miInitVisualsProcPtr *procPtr)
{
GlxWrapInitVisuals(procPtr);
}
/*
* DarwinModeProcessArgument
* Process IOKit specific command line arguments.
*/
int DarwinModeProcessArgument(
int argc,
char *argv[],
int i)
{
#ifdef DARWIN_WITH_QUARTZ
// XDarwinStartup uses these arguments to indicate which X server
// should be started. Ignore them here.
if (!strcmp( argv[i], "-fullscreen" ) ||
!strcmp( argv[i], "-rootless" ) ||
!strcmp( argv[i], "-quartz" ))
{
return 1;
}
#else
if (!strcmp( argv[i], "-fullscreen" ) ||
!strcmp( argv[i], "-rootless" ) ||
!strcmp( argv[i], "-quartz" ))
{
FatalError("Command line option %s is not available without Quartz "
"support.\n", argv[i]);
}
#endif
return 0;
}
/*
* DarwinModeReadSystemKeymap
* IOKit has no alternative to NXKeyMapping API.
*/
Bool DarwinModeReadSystemKeymap(
darwinKeyboardInfo *info)
{
return FALSE;
}

697
hw/darwin/quartz/applewm.c Normal file
View File

@ -0,0 +1,697 @@
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/applewm.c,v 1.3 2003/11/11 23:48:41 torrey Exp $ */
/**************************************************************************
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, 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.
**************************************************************************/
#include "quartzCommon.h"
#define NEED_REPLIES
#define NEED_EVENTS
#include "misc.h"
#include "dixstruct.h"
#include "globals.h"
#include "extnsionst.h"
#include "colormapst.h"
#include "cursorstr.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "servermd.h"
#include "swaprep.h"
#include "Xatom.h"
#include "darwin.h"
#define _APPLEWM_SERVER_
#include "applewmstr.h"
#include "applewmExt.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_screen_origin, "_NATIVE_SCREEN_ORIGIN")
static AppleWMProcsPtr appleWMProcs;
static int WMErrorBase;
static DISPATCH_PROC(ProcAppleWMDispatch);
static DISPATCH_PROC(SProcAppleWMDispatch);
static void AppleWMResetProc(ExtensionEntry* extEntry);
static unsigned char WMReqCode = 0;
static int WMEventBase = 0;
static RESTYPE ClientType, EventType; /* resource types for event masks */
static XID eventResource;
/* Currently selected events */
static unsigned int eventMask = 0;
static int WMFreeClient (pointer data, XID id);
static int WMFreeEvents (pointer data, XID id);
static void SNotifyEvent(xAppleWMNotifyEvent *from, xAppleWMNotifyEvent *to);
typedef struct _WMEvent *WMEventPtr;
typedef struct _WMEvent {
WMEventPtr next;
ClientPtr client;
XID clientResource;
unsigned int mask;
} WMEventRec;
static inline BoxRec
make_box (int x, int y, int w, int h)
{
BoxRec r;
r.x1 = x;
r.y1 = y;
r.x2 = x + w;
r.y2 = y + h;
return r;
}
void
AppleWMExtensionInit(
AppleWMProcsPtr procsPtr)
{
ExtensionEntry* extEntry;
ClientType = CreateNewResourceType(WMFreeClient);
EventType = CreateNewResourceType(WMFreeEvents);
eventResource = FakeClientID(0);
if (ClientType && EventType &&
(extEntry = AddExtension(APPLEWMNAME,
AppleWMNumberEvents,
AppleWMNumberErrors,
ProcAppleWMDispatch,
SProcAppleWMDispatch,
AppleWMResetProc,
StandardMinorOpcode)))
{
WMReqCode = (unsigned char)extEntry->base;
WMErrorBase = extEntry->errorBase;
WMEventBase = extEntry->eventBase;
EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent;
appleWMProcs = procsPtr;
}
}
/*ARGSUSED*/
static void
AppleWMResetProc (
ExtensionEntry* extEntry
)
{
}
/* Updates the _NATIVE_SCREEN_ORIGIN property on the given root window. */
void
AppleWMSetScreenOrigin(
WindowPtr pWin
)
{
long data[2];
data[0] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].x
+ darwinMainScreenX);
data[1] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].y
+ darwinMainScreenY);
ChangeWindowProperty(pWin, xa_native_screen_origin(), XA_INTEGER,
32, PropModeReplace, 2, data, TRUE);
}
static int
ProcAppleWMQueryVersion(
register ClientPtr client
)
{
xAppleWMQueryVersionReply rep;
register int n;
REQUEST_SIZE_MATCH(xAppleWMQueryVersionReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.majorVersion = APPLE_WM_MAJOR_VERSION;
rep.minorVersion = APPLE_WM_MINOR_VERSION;
rep.patchVersion = APPLE_WM_PATCH_VERSION;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
}
WriteToClient(client, sizeof(xAppleWMQueryVersionReply), (char *)&rep);
return (client->noClientException);
}
/* events */
static inline void
updateEventMask (WMEventPtr *pHead)
{
WMEventPtr pCur;
eventMask = 0;
for (pCur = *pHead; pCur != NULL; pCur = pCur->next)
eventMask |= pCur->mask;
}
/*ARGSUSED*/
static int
WMFreeClient (data, id)
pointer data;
XID id;
{
WMEventPtr pEvent;
WMEventPtr *pHead, pCur, pPrev;
pEvent = (WMEventPtr) data;
pHead = (WMEventPtr *) LookupIDByType(eventResource, EventType);
if (pHead) {
pPrev = 0;
for (pCur = *pHead; pCur && pCur != pEvent; pCur=pCur->next)
pPrev = pCur;
if (pCur) {
if (pPrev)
pPrev->next = pEvent->next;
else
*pHead = pEvent->next;
}
updateEventMask (pHead);
}
xfree ((pointer) pEvent);
return 1;
}
/*ARGSUSED*/
static int
WMFreeEvents (data, id)
pointer data;
XID id;
{
WMEventPtr *pHead, pCur, pNext;
pHead = (WMEventPtr *) data;
for (pCur = *pHead; pCur; pCur = pNext) {
pNext = pCur->next;
FreeResource (pCur->clientResource, ClientType);
xfree ((pointer) pCur);
}
xfree ((pointer) pHead);
eventMask = 0;
return 1;
}
static int
ProcAppleWMSelectInput (client)
register ClientPtr client;
{
REQUEST(xAppleWMSelectInputReq);
WMEventPtr pEvent, pNewEvent, *pHead;
XID clientResource;
REQUEST_SIZE_MATCH (xAppleWMSelectInputReq);
pHead = (WMEventPtr *)SecurityLookupIDByType(client,
eventResource, EventType, SecurityWriteAccess);
if (stuff->mask != 0) {
if (pHead) {
/* check for existing entry. */
for (pEvent = *pHead; pEvent; pEvent = pEvent->next)
{
if (pEvent->client == client)
{
pEvent->mask = stuff->mask;
updateEventMask (pHead);
return Success;
}
}
}
/* build the entry */
pNewEvent = (WMEventPtr) xalloc (sizeof (WMEventRec));
if (!pNewEvent)
return BadAlloc;
pNewEvent->next = 0;
pNewEvent->client = client;
pNewEvent->mask = stuff->mask;
/*
* add a resource that will be deleted when
* the client goes away
*/
clientResource = FakeClientID (client->index);
pNewEvent->clientResource = clientResource;
if (!AddResource (clientResource, ClientType, (pointer)pNewEvent))
return BadAlloc;
/*
* create a resource to contain a pointer to the list
* of clients selecting input. This must be indirect as
* the list may be arbitrarily rearranged which cannot be
* done through the resource database.
*/
if (!pHead)
{
pHead = (WMEventPtr *) xalloc (sizeof (WMEventPtr));
if (!pHead ||
!AddResource (eventResource, EventType, (pointer)pHead))
{
FreeResource (clientResource, RT_NONE);
return BadAlloc;
}
*pHead = 0;
}
pNewEvent->next = *pHead;
*pHead = pNewEvent;
updateEventMask (pHead);
} else if (stuff->mask == 0) {
/* delete the interest */
if (pHead) {
pNewEvent = 0;
for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
if (pEvent->client == client)
break;
pNewEvent = pEvent;
}
if (pEvent) {
FreeResource (pEvent->clientResource, ClientType);
if (pNewEvent)
pNewEvent->next = pEvent->next;
else
*pHead = pEvent->next;
xfree (pEvent);
updateEventMask (pHead);
}
}
} else {
client->errorValue = stuff->mask;
return BadValue;
}
return Success;
}
/*
* deliver the event
*/
void
AppleWMSendEvent (type, mask, which, arg)
int type, which, arg;
unsigned int mask;
{
WMEventPtr *pHead, pEvent;
ClientPtr client;
xAppleWMNotifyEvent se;
pHead = (WMEventPtr *) LookupIDByType(eventResource, EventType);
if (!pHead)
return;
for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
client = pEvent->client;
if ((pEvent->mask & mask) == 0
|| client == serverClient || client->clientGone)
{
continue;
}
se.type = type + WMEventBase;
se.kind = which;
se.arg = arg;
se.sequenceNumber = client->sequence;
se.time = currentTime.milliseconds;
WriteEventsToClient (client, 1, (xEvent *) &se);
}
}
/* Safe to call from any thread. */
unsigned int
AppleWMSelectedEvents (void)
{
return eventMask;
}
/* general utility functions */
static int
ProcAppleWMDisableUpdate(
register ClientPtr client
)
{
REQUEST_SIZE_MATCH(xAppleWMDisableUpdateReq);
appleWMProcs->DisableUpdate();
return (client->noClientException);
}
static int
ProcAppleWMReenableUpdate(
register ClientPtr client
)
{
REQUEST_SIZE_MATCH(xAppleWMReenableUpdateReq);
appleWMProcs->EnableUpdate();
return (client->noClientException);
}
/* window functions */
static int
ProcAppleWMSetWindowMenu(
register ClientPtr client
)
{
const char *bytes, **items;
char *shortcuts;
int max_len, nitems, i, j;
REQUEST(xAppleWMSetWindowMenuReq);
REQUEST_AT_LEAST_SIZE(xAppleWMSetWindowMenuReq);
nitems = stuff->nitems;
items = xalloc (sizeof (char *) * nitems);
shortcuts = xalloc (sizeof (char) * nitems);
max_len = (stuff->length << 2) - sizeof(xAppleWMSetWindowMenuReq);
bytes = (char *) &stuff[1];
for (i = j = 0; i < max_len && j < nitems;)
{
shortcuts[j] = bytes[i++];
items[j++] = bytes + i;
while (i < max_len)
{
if (bytes[i++] == 0)
break;
}
}
QuartzSetWindowMenu (nitems, items, shortcuts);
free(items);
free(shortcuts);
return (client->noClientException);
}
static int
ProcAppleWMSetWindowMenuCheck(
register ClientPtr client
)
{
REQUEST(xAppleWMSetWindowMenuCheckReq);
REQUEST_SIZE_MATCH(xAppleWMSetWindowMenuCheckReq);
QuartzMessageMainThread(kQuartzSetWindowMenuCheck, &stuff->index,
sizeof(stuff->index));
return (client->noClientException);
}
static int
ProcAppleWMSetFrontProcess(
register ClientPtr client
)
{
REQUEST_SIZE_MATCH(xAppleWMSetFrontProcessReq);
QuartzMessageMainThread(kQuartzSetFrontProcess, NULL, 0);
return (client->noClientException);
}
static int
ProcAppleWMSetWindowLevel(
register ClientPtr client
)
{
REQUEST(xAppleWMSetWindowLevelReq);
WindowPtr pWin;
int errno;
REQUEST_SIZE_MATCH(xAppleWMSetWindowLevelReq);
if (!(pWin = SecurityLookupWindow((Drawable)stuff->window,
client, SecurityReadAccess)))
{
return BadValue;
}
if (stuff->level < 0 || stuff->level >= AppleWMNumWindowLevels) {
return BadValue;
}
errno = appleWMProcs->SetWindowLevel(pWin, stuff->level);
if (errno != Success) {
return errno;
}
return (client->noClientException);
}
static int
ProcAppleWMSetCanQuit(
register ClientPtr client
)
{
REQUEST(xAppleWMSetCanQuitReq);
REQUEST_SIZE_MATCH(xAppleWMSetCanQuitReq);
QuartzMessageMainThread(kQuartzSetCanQuit, &stuff->state,
sizeof(stuff->state));
return (client->noClientException);
}
/* frame functions */
static int
ProcAppleWMFrameGetRect(
register ClientPtr client
)
{
xAppleWMFrameGetRectReply rep;
BoxRec ir, or, rr;
REQUEST(xAppleWMFrameGetRectReq);
REQUEST_SIZE_MATCH(xAppleWMFrameGetRectReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh);
if (appleWMProcs->FrameGetRect(stuff->frame_rect,
stuff->frame_class,
&or, &ir, &rr) != Success)
{
return BadValue;
}
rep.x = rr.x1;
rep.y = rr.y1;
rep.w = rr.x2 - rr.x1;
rep.h = rr.y2 - rr.y1;
WriteToClient(client, sizeof(xAppleWMFrameGetRectReply), (char *)&rep);
return (client->noClientException);
}
static int
ProcAppleWMFrameHitTest(
register ClientPtr client
)
{
xAppleWMFrameHitTestReply rep;
BoxRec ir, or;
int ret;
REQUEST(xAppleWMFrameHitTestReq);
REQUEST_SIZE_MATCH(xAppleWMFrameHitTestReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh);
if (appleWMProcs->FrameHitTest(stuff->frame_class, stuff->px,
stuff->py, &or, &ir, &ret) != Success)
{
return BadValue;
}
rep.ret = ret;
WriteToClient(client, sizeof(xAppleWMFrameHitTestReply), (char *)&rep);
return (client->noClientException);
}
static int
ProcAppleWMFrameDraw(
register ClientPtr client
)
{
BoxRec ir, or;
unsigned int title_length, title_max;
unsigned char *title_bytes;
REQUEST(xAppleWMFrameDrawReq);
WindowPtr pWin;
REQUEST_AT_LEAST_SIZE(xAppleWMFrameDrawReq);
if (!(pWin = SecurityLookupWindow((Drawable)stuff->window,
client, SecurityReadAccess)))
{
return BadValue;
}
ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh);
title_length = stuff->title_length;
title_max = (stuff->length << 2) - sizeof(xAppleWMFrameDrawReq);
if (title_max < title_length)
return BadValue;
title_bytes = (unsigned char *) &stuff[1];
errno = appleWMProcs->FrameDraw(pWin, stuff->frame_class,
stuff->frame_attr, &or, &ir,
title_length, title_bytes);
if (errno != Success) {
return errno;
}
return (client->noClientException);
}
/* dispatch */
static int
ProcAppleWMDispatch (
register ClientPtr client
)
{
REQUEST(xReq);
switch (stuff->data)
{
case X_AppleWMQueryVersion:
return ProcAppleWMQueryVersion(client);
}
if (!LocalClient(client))
return WMErrorBase + AppleWMClientNotLocal;
switch (stuff->data)
{
case X_AppleWMSelectInput:
return ProcAppleWMSelectInput(client);
case X_AppleWMDisableUpdate:
return ProcAppleWMDisableUpdate(client);
case X_AppleWMReenableUpdate:
return ProcAppleWMReenableUpdate(client);
case X_AppleWMSetWindowMenu:
return ProcAppleWMSetWindowMenu(client);
case X_AppleWMSetWindowMenuCheck:
return ProcAppleWMSetWindowMenuCheck(client);
case X_AppleWMSetFrontProcess:
return ProcAppleWMSetFrontProcess(client);
case X_AppleWMSetWindowLevel:
return ProcAppleWMSetWindowLevel(client);
case X_AppleWMSetCanQuit:
return ProcAppleWMSetCanQuit(client);
case X_AppleWMFrameGetRect:
return ProcAppleWMFrameGetRect(client);
case X_AppleWMFrameHitTest:
return ProcAppleWMFrameHitTest(client);
case X_AppleWMFrameDraw:
return ProcAppleWMFrameDraw(client);
default:
return BadRequest;
}
}
static void
SNotifyEvent(from, to)
xAppleWMNotifyEvent *from, *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
SProcAppleWMQueryVersion(
register ClientPtr client
)
{
register int n;
REQUEST(xAppleWMQueryVersionReq);
swaps(&stuff->length, n);
return ProcAppleWMQueryVersion(client);
}
static int
SProcAppleWMDispatch (
register ClientPtr client
)
{
REQUEST(xReq);
/* It is bound to be non-local when there is byte swapping */
if (!LocalClient(client))
return WMErrorBase + AppleWMClientNotLocal;
/* only local clients are allowed WM access */
switch (stuff->data)
{
case X_AppleWMQueryVersion:
return SProcAppleWMQueryVersion(client);
default:
return BadRequest;
}
}

View File

@ -0,0 +1,83 @@
/*
* External interface for the server's AppleWM support
*/
/**************************************************************************
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, 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.
**************************************************************************/
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/applewmExt.h,v 1.3 2003/11/17 22:20:35 dawes Exp $ */
#ifndef _APPLEWMEXT_H_
#define _APPLEWMEXT_H_
#include "window.h"
typedef int (*DisableUpdateProc)(void);
typedef int (*EnableUpdateProc)(void);
typedef int (*SetWindowLevelProc)(WindowPtr pWin, int level);
typedef int (*FrameGetRectProc)(int type, int class, const BoxRec *outer,
const BoxRec *inner, BoxRec *ret);
typedef int (*FrameHitTestProc)(int class, int x, int y,
const BoxRec *outer,
const BoxRec *inner, int *ret);
typedef int (*FrameDrawProc)(WindowPtr pWin, int class, unsigned int attr,
const BoxRec *outer, const BoxRec *inner,
unsigned int title_len,
const unsigned char *title_bytes);
/*
* AppleWM implementation function list
*/
typedef struct _AppleWMProcs {
DisableUpdateProc DisableUpdate;
EnableUpdateProc EnableUpdate;
SetWindowLevelProc SetWindowLevel;
FrameGetRectProc FrameGetRect;
FrameHitTestProc FrameHitTest;
FrameDrawProc FrameDraw;
} AppleWMProcsRec, *AppleWMProcsPtr;
extern AppleWMProcsPtr appleWMProcs;
void AppleWMExtensionInit(
AppleWMProcsPtr procsPtr
);
void AppleWMSetScreenOrigin(
WindowPtr pWin
);
void AppleWMSendEvent(
int /* type */,
unsigned int /* mask */,
int /* which */,
int /* arg */
);
unsigned int AppleWMSelectedEvents(
void
);
#endif /* _APPLEWMEXT_H_ */

View File

@ -0,0 +1,42 @@
/*
* NSView subclass for Mac OS X rootless X server
*
* Copyright (c) 2001 Greg Parker. 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/cr/XView.h,v 1.1 2003/06/07 05:49:07 torrey Exp $ */
#import <Cocoa/Cocoa.h>
@interface XView : NSQuickDrawView
- (BOOL)isFlipped;
- (BOOL)isOpaque;
- (BOOL)acceptsFirstResponder;
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent;
- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent;
- (void)mouseDown:(NSEvent *)anEvent;
@end

View File

@ -0,0 +1,74 @@
/*
* NSView subclass for Mac OS X rootless X server
*
* Each rootless window contains an instance of this class.
* This class handles events while drawing is handled by Carbon
* code in the rootless Aqua implementation.
*
* Copyright (c) 2001 Greg Parker. 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/cr/XView.m,v 1.2 2003/10/16 23:50:16 torrey Exp $ */
#import "XView.h"
@implementation XView
- (BOOL)isFlipped
{
return NO;
}
- (BOOL)isOpaque
{
return YES;
}
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
return YES;
}
- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)theEvent
{
return YES;
}
- (void)mouseDown:(NSEvent *)anEvent
{
// Only X is allowed to restack windows.
[NSApp preventWindowOrdering];
if (! [NSApp isActive]) {
[NSApp activateIgnoringOtherApps:YES];
}
[[self nextResponder] mouseDown:anEvent];
}
@end

62
hw/darwin/quartz/cr/cr.h Normal file
View File

@ -0,0 +1,62 @@
/*
* Internal definitions of the Cocoa 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/cr/cr.h,v 1.3 2003/11/03 05:36:31 tsi Exp $ */
#ifndef _CR_H
#define _CR_H
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#import "XView.h"
#else
typedef struct OpaqueNSWindow NSWindow;
typedef struct OpaqueXView XView;
#endif
#undef BOOL
#define BOOL xBOOL
#include "screenint.h"
#include "window.h"
#undef BOOL
// Predefined style for the window which is about to be framed
extern WindowPtr nextWindowToFrame;
extern unsigned int nextWindowStyle;
typedef struct {
NSWindow *window;
XView *view;
GrafPtr port;
CGContextRef context;
} CRWindowRec, *CRWindowPtr;
Bool CRInit(ScreenPtr pScreen);
void CRAppleWMInit(void);
#endif /* _CR_H */

View File

@ -0,0 +1,157 @@
/*
* Cocoa rootless implementation functions for AppleWM extension
*/
/*
* 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/cr/crAppleWM.m,v 1.1 2003/09/16 00:36:14 torrey Exp $ */
#include "quartzCommon.h"
#include "cr.h"
#undef BOOL
#define BOOL xBOOL
#include "rootless.h"
#include "X.h"
#define _APPLEWM_SERVER_
#include "applewm.h"
#include "applewmExt.h"
#undef BOOL
#define StdDocumentStyleMask (NSTitledWindowMask | \
NSClosableWindowMask | \
NSMiniaturizableWindowMask | \
NSResizableWindowMask)
static int
CRDisableUpdate(void)
{
return Success;
}
static int
CREnableUpdate(void)
{
return Success;
}
static int CRSetWindowLevel(
WindowPtr pWin,
int level)
{
CRWindowPtr crWinPtr;
crWinPtr = (CRWindowPtr) RootlessFrameForWindow(pWin, TRUE);
if (crWinPtr == 0)
return BadWindow;
RootlessStopDrawing(pWin, FALSE);
[crWinPtr->window setLevel:level];
return Success;
}
static int CRFrameGetRect(
int type,
int class,
const BoxRec *outer,
const BoxRec *inner,
BoxRec *ret)
{
return Success;
}
static int CRFrameHitTest(
int class,
int x,
int y,
const BoxRec *outer,
const BoxRec *inner,
int *ret)
{
return 0;
}
static int CRFrameDraw(
WindowPtr pWin,
int class,
unsigned int attr,
const BoxRec *outer,
const BoxRec *inner,
unsigned int title_len,
const unsigned char *title_bytes)
{
CRWindowPtr crWinPtr;
NSWindow *window;
Bool hasResizeIndicator;
/* We assume the window has not yet been framed so
RootlessFrameForWindow() will cause it to be. Record the window
style so that the appropriate one will be used when it is framed.
If the window is already framed, we can't change the window
style and the following will have no effect. */
nextWindowToFrame = pWin;
if (class == AppleWMFrameClassDocument)
nextWindowStyle = StdDocumentStyleMask;
else
nextWindowStyle = NSBorderlessWindowMask;
crWinPtr = (CRWindowPtr) RootlessFrameForWindow(pWin, TRUE);
if (crWinPtr == 0)
return BadWindow;
window = crWinPtr->window;
[window setTitle:[NSString stringWithCString:title_bytes
length:title_len]];
hasResizeIndicator = (attr & AppleWMFrameGrowBox) ? YES : NO;
[window setShowsResizeIndicator:hasResizeIndicator];
return Success;
}
static AppleWMProcsRec crAppleWMProcs = {
CRDisableUpdate,
CREnableUpdate,
CRSetWindowLevel,
CRFrameGetRect,
CRFrameHitTest,
CRFrameDraw
};
void CRAppleWMInit(void)
{
AppleWMExtensionInit(&crAppleWMProcs);
}

View File

@ -0,0 +1,403 @@
/*
* Cocoa rootless implementation frame functions
*/
/*
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
* Copyright (c) 2002-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/cr/crFrame.m,v 1.5 2003/11/13 20:26:31 torrey Exp $ */
#include "quartzCommon.h"
#include "cr.h"
#undef BOOL
#define BOOL xBOOL
#include "rootless.h"
#undef BOOL
WindowPtr nextWindowToFrame = NULL;
unsigned int nextWindowStyle = 0;
static void CRReshapeFrame(RootlessFrameID wid, RegionPtr pShape);
/*
* CRCreateFrame
* Create a new physical window.
* Rootless windows must not autodisplay! Autodisplay can cause a deadlock.
* Event thread - autodisplay: locks view hierarchy, then window
* X Server thread - window resize: locks window, then view hierarchy
* Deadlock occurs if each thread gets one lock and waits for the other.
*/
static Bool
CRCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
int newX, int newY, RegionPtr pShape)
{
CRWindowPtr crWinPtr;
NSRect bounds;
NSWindow *theWindow;
XView *theView;
unsigned int theStyleMask = NSBorderlessWindowMask;
crWinPtr = (CRWindowPtr) xalloc(sizeof(CRWindowRec));
bounds = NSMakeRect(newX,
NSHeight([[NSScreen mainScreen] frame]) -
newY - pFrame->height,
pFrame->width, pFrame->height);
// Check if AppleWM has specified a style for this window
if (pFrame->win == nextWindowToFrame) {
theStyleMask = nextWindowStyle;
}
nextWindowToFrame = NULL;
// Create an NSWindow for the new X11 window
theWindow = [[NSWindow alloc] initWithContentRect:bounds
styleMask:theStyleMask
backing:NSBackingStoreBuffered
defer:NO];
if (!theWindow) return FALSE;
[theWindow setBackgroundColor:[NSColor clearColor]]; // erase transparent
[theWindow setAlphaValue:1.0]; // draw opaque
[theWindow setOpaque:YES]; // changed when window is shaped
[theWindow useOptimizedDrawing:YES]; // Has no overlapping sub-views
[theWindow setAutodisplay:NO]; // See comment above
[theWindow disableFlushWindow]; // We do all the flushing manually
[theWindow setHasShadow:YES]; // All windows have shadows
[theWindow setReleasedWhenClosed:YES]; // Default, but we want to be sure
theView = [[XView alloc] initWithFrame:bounds];
[theWindow setContentView:theView];
[theWindow setInitialFirstResponder:theView];
[theWindow setAcceptsMouseMovedEvents:YES];
crWinPtr->window = theWindow;
crWinPtr->view = theView;
[theView lockFocus];
// Fill the window with white to make sure alpha channel is set
NSEraseRect(bounds);
crWinPtr->port = [theView qdPort];
crWinPtr->context = [[NSGraphicsContext currentContext] graphicsPort];
// CreateCGContextForPort(crWinPtr->port, &crWinPtr->context);
[theView unlockFocus];
// Store the implementation private frame ID
pFrame->wid = (RootlessFrameID) crWinPtr;
// Reshape the frame if it was created shaped.
if (pShape != NULL)
CRReshapeFrame(pFrame->wid, pShape);
return TRUE;
}
/*
* CRDestroyFrame
* Destroy a frame.
*/
static void
CRDestroyFrame(RootlessFrameID wid)
{
CRWindowPtr crWinPtr = (CRWindowPtr) wid;
[crWinPtr->window orderOut:nil];
[crWinPtr->window close];
[crWinPtr->view release];
free(crWinPtr);
}
/*
* CRMoveFrame
* Move a frame on screen.
*/
static void
CRMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY)
{
CRWindowPtr crWinPtr = (CRWindowPtr) wid;
NSPoint topLeft;
topLeft = NSMakePoint(newX,
NSHeight([[NSScreen mainScreen] frame]) - newY);
[crWinPtr->window setFrameTopLeftPoint:topLeft];
}
/*
* CRResizeFrame
* Move and resize a frame.
*/
static void
CRResizeFrame(RootlessFrameID wid, ScreenPtr pScreen,
int newX, int newY, unsigned int newW, unsigned int newH,
unsigned int gravity)
{
CRWindowPtr crWinPtr = (CRWindowPtr) wid;
NSRect bounds = NSMakeRect(newX, NSHeight([[NSScreen mainScreen] frame]) -
newY - newH, newW, newH);
[crWinPtr->window setFrame:bounds display:NO];
}
/*
* CRRestackFrame
* Change the frame order. Put the frame behind nextWid or on top if
* it is NULL. Unmapped frames are mapped by restacking them.
*/
static void
CRRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
{
CRWindowPtr crWinPtr = (CRWindowPtr) wid;
CRWindowPtr crNextWinPtr = (CRWindowPtr) nextWid;
if (crNextWinPtr) {
int upperNum = [crNextWinPtr->window windowNumber];
[crWinPtr->window orderWindow:NSWindowBelow relativeTo:upperNum];
} else {
[crWinPtr->window makeKeyAndOrderFront:nil];
}
}
/*
* CRReshapeFrame
* Set the shape of a frame.
*/
static void
CRReshapeFrame(RootlessFrameID wid, RegionPtr pShape)
{
CRWindowPtr crWinPtr = (CRWindowPtr) wid;
NSRect bounds = [crWinPtr->view frame];
int winHeight = NSHeight(bounds);
BoxRec localBox = {0, 0, NSWidth(bounds), winHeight};
[crWinPtr->view lockFocus];
if (pShape != NULL) {
// Calculate the region outside the new shape.
REGION_INVERSE(NULL, pShape, pShape, &localBox);
}
// If window is currently shaped we need to undo the previous shape.
if (![crWinPtr->window isOpaque]) {
[[NSColor whiteColor] set];
NSRectFillUsingOperation(bounds, NSCompositeDestinationAtop);
}
if (pShape != NULL) {
int count = REGION_NUM_RECTS(pShape);
BoxRec *extRects = REGION_RECTS(pShape);
BoxRec *rects, *end;
// Make transparent if window is now shaped.
[crWinPtr->window setOpaque:NO];
// Clear the areas outside the window shape
[[NSColor clearColor] set];
for (rects = extRects, end = extRects+count; rects < end; rects++) {
int rectHeight = rects->y2 - rects->y1;
NSRectFill( NSMakeRect(rects->x1,
winHeight - rects->y1 - rectHeight,
rects->x2 - rects->x1, rectHeight) );
}
[[NSGraphicsContext currentContext] flushGraphics];
// force update of window shadow
[crWinPtr->window setHasShadow:NO];
[crWinPtr->window setHasShadow:YES];
} else {
[crWinPtr->window setOpaque:YES];
[[NSGraphicsContext currentContext] flushGraphics];
}
[crWinPtr->view unlockFocus];
}
/*
* CRUnmapFrame
* Unmap a frame.
*/
static void
CRUnmapFrame(RootlessFrameID wid)
{
CRWindowPtr crWinPtr = (CRWindowPtr) wid;
[crWinPtr->window orderOut:nil];
}
/*
* CRStartDrawing
* When a window's buffer is not being drawn to, the CoreGraphics
* window server may compress or move it. Call this routine
* to lock down the buffer during direct drawing. It returns
* a pointer to the backing buffer.
*/
static void
CRStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
{
CRWindowPtr crWinPtr = (CRWindowPtr) wid;
PixMapHandle pix;
[crWinPtr->view lockFocus];
crWinPtr->port = [crWinPtr->view qdPort];
LockPortBits(crWinPtr->port);
[crWinPtr->view unlockFocus];
pix = GetPortPixMap(crWinPtr->port);
*pixelData = GetPixBaseAddr(pix);
*bytesPerRow = GetPixRowBytes(pix) & 0x3fff; // fixme is mask needed?
}
/*
* CRStopDrawing
* When direct access to a window's buffer is no longer needed, this
* routine should be called to allow CoreGraphics to compress or
* move it.
*/
static void
CRStopDrawing(RootlessFrameID wid, Bool flush)
{
CRWindowPtr crWinPtr = (CRWindowPtr) wid;
UnlockPortBits(crWinPtr->port);
if (flush) {
QDFlushPortBuffer(crWinPtr->port, NULL);
}
}
/*
* CRUpdateRegion
* Flush a region from a window's backing buffer to the screen.
*/
static void
CRUpdateRegion(RootlessFrameID wid, RegionPtr pDamage)
{
CRWindowPtr crWinPtr = (CRWindowPtr) wid;
#ifdef ROOTLESS_TRACK_DAMAGE
int count = REGION_NUM_RECTS(pDamage);
BoxRec *rects = REGION_RECTS(pDamage);
BoxRec *end;
static RgnHandle rgn = NULL;
static RgnHandle box = NULL;
if (!rgn) rgn = NewRgn();
if (!box) box = NewRgn();
for (end = rects+count; rects < end; rects++) {
Rect qdRect;
qdRect.left = rects->x1;
qdRect.top = rects->y1;
qdRect.right = rects->x2;
qdRect.bottom = rects->y2;
RectRgn(box, &qdRect);
UnionRgn(rgn, box, rgn);
}
QDFlushPortBuffer(crWinPtr->port, rgn);
SetEmptyRgn(rgn);
SetEmptyRgn(box);
#else /* !ROOTLESS_TRACK_DAMAGE */
QDFlushPortBuffer(crWinPtr->port, NULL);
#endif
}
/*
* CRDamageRects
* Mark damaged rectangles as requiring redisplay to screen.
*/
static void
CRDamageRects(RootlessFrameID wid, int count, const BoxRec *rects,
int shift_x, int shift_y)
{
CRWindowPtr crWinPtr = (CRWindowPtr) wid;
const BoxRec *end;
for (end = rects + count; rects < end; rects++) {
Rect qdRect;
qdRect.left = rects->x1 + shift_x;
qdRect.top = rects->y1 + shift_y;
qdRect.right = rects->x2 + shift_x;
qdRect.bottom = rects->y2 + shift_y;
QDAddRectToDirtyRegion(crWinPtr->port, &qdRect);
}
}
static RootlessFrameProcsRec CRRootlessProcs = {
CRCreateFrame,
CRDestroyFrame,
CRMoveFrame,
CRResizeFrame,
CRRestackFrame,
CRReshapeFrame,
CRUnmapFrame,
CRStartDrawing,
CRStopDrawing,
CRUpdateRegion,
CRDamageRects,
NULL,
NULL,
NULL,
NULL
};
/*
* Initialize CR implementation
*/
Bool
CRInit(ScreenPtr pScreen)
{
RootlessInit(pScreen, &CRRootlessProcs);
rootless_CopyBytes_threshold = 0;
rootless_FillBytes_threshold = 0;
rootless_CompositePixels_threshold = 0;
rootless_CopyWindow_threshold = 0;
return TRUE;
}

View File

@ -0,0 +1,321 @@
/*
* Cocoa rootless implementation initialization
*/
/*
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
* Copyright (c) 2002-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/cr/crScreen.m,v 1.5 2003/11/12 20:21:52 torrey Exp $ */
#include "quartzCommon.h"
#include "cr.h"
#undef BOOL
#define BOOL xBOOL
#include "darwin.h"
#include "quartz.h"
#include "quartzCursor.h"
#include "rootless.h"
#include "safeAlpha.h"
#include "pseudoramiX.h"
#include "applewmExt.h"
#include "regionstr.h"
#include "scrnintstr.h"
#include "picturestr.h"
#include "globals.h"
#undef BOOL
// Name of GLX bundle using AGL framework
static const char *crOpenGLBundle = "glxAGL.bundle";
static Class classXView = nil;
/*
* CRDisplayInit
* Find all screens.
*
* Multihead note: When rootless mode uses PseudoramiX, the
* X server only sees one screen; only PseudoramiX itself knows
* about all of the screens.
*/
static void
CRDisplayInit(void)
{
ErrorF("Display mode: Rootless Quartz -- Cocoa implementation\n");
if (noPseudoramiXExtension) {
darwinScreensFound = [[NSScreen screens] count];
} else {
darwinScreensFound = 1; // only PseudoramiX knows about the rest
}
CRAppleWMInit();
}
/*
* CRScreenParams
* Set the basic screen parameters.
*/
static void
CRScreenParams(int index, DarwinFramebufferPtr dfb)
{
dfb->bitsPerComponent = CGDisplayBitsPerSample(kCGDirectMainDisplay);
dfb->bitsPerPixel = CGDisplayBitsPerPixel(kCGDirectMainDisplay);
dfb->colorBitsPerPixel = 3 * dfb->bitsPerComponent;
if (noPseudoramiXExtension) {
NSScreen *screen = [[NSScreen screens] objectAtIndex:index];
NSRect frame = [screen frame];
// set x, y so (0,0) is top left of main screen
dfb->x = NSMinX(frame);
dfb->y = NSHeight([[NSScreen mainScreen] frame]) -
NSHeight(frame) - NSMinY(frame);
dfb->width = NSWidth(frame);
dfb->height = NSHeight(frame);
dfb->pitch = (dfb->width) * (dfb->bitsPerPixel) / 8;
// Shift the usable part of main screen down to avoid the menu bar.
if (NSEqualRects(frame, [[NSScreen mainScreen] frame])) {
dfb->y += aquaMenuBarHeight;
dfb->height -= aquaMenuBarHeight;
}
} else {
int i;
NSRect unionRect = NSMakeRect(0, 0, 0, 0);
NSArray *screens = [NSScreen screens];
// Get the union of all screens (minus the menu bar on main screen)
for (i = 0; i < [screens count]; i++) {
NSScreen *screen = [screens objectAtIndex:i];
NSRect frame = [screen frame];
frame.origin.y = [[NSScreen mainScreen] frame].size.height -
frame.size.height - frame.origin.y;
if (NSEqualRects([screen frame], [[NSScreen mainScreen] frame])) {
frame.origin.y += aquaMenuBarHeight;
frame.size.height -= aquaMenuBarHeight;
}
unionRect = NSUnionRect(unionRect, frame);
}
// Use unionRect as the screen size for the X server.
dfb->x = unionRect.origin.x;
dfb->y = unionRect.origin.y;
dfb->width = unionRect.size.width;
dfb->height = unionRect.size.height;
dfb->pitch = (dfb->width) * (dfb->bitsPerPixel) / 8;
// Tell PseudoramiX about the real screens.
// InitOutput() will move the big screen to (0,0),
// so compensate for that here.
for (i = 0; i < [screens count]; i++) {
NSScreen *screen = [screens objectAtIndex:i];
NSRect frame = [screen frame];
int j;
// Skip this screen if it's a mirrored copy of an earlier screen.
for (j = 0; j < i; j++) {
if (NSEqualRects(frame, [[screens objectAtIndex:j] frame])) {
ErrorF("PseudoramiX screen %d is a mirror of screen %d.\n",
i, j);
break;
}
}
if (j < i) continue; // this screen is a mirrored copy
frame.origin.y = [[NSScreen mainScreen] frame].size.height -
frame.size.height - frame.origin.y;
if (NSEqualRects([screen frame], [[NSScreen mainScreen] frame])) {
frame.origin.y += aquaMenuBarHeight;
frame.size.height -= aquaMenuBarHeight;
}
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);
}
}
}
/*
* CRAddScreen
* Init the framebuffer and record pixmap parameters for the screen.
*/
static Bool
CRAddScreen(int index, ScreenPtr pScreen)
{
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
QuartzScreenPtr displayInfo = QUARTZ_PRIV(pScreen);
CGRect cgRect;
CGDisplayCount numDisplays;
CGDisplayCount allocatedDisplays = 0;
CGDirectDisplayID *displays = NULL;
CGDisplayErr cgErr;
CRScreenParams(index, dfb);
dfb->colorType = TrueColor;
// No frame buffer - it's all in window pixmaps.
dfb->framebuffer = NULL; // malloc(dfb.pitch * dfb.height);
// Get all CoreGraphics displays covered by this X11 display.
cgRect = CGRectMake(dfb->x, dfb->y, dfb->width, dfb->height);
do {
cgErr = CGGetDisplaysWithRect(cgRect, 0, NULL, &numDisplays);
if (cgErr) break;
allocatedDisplays = numDisplays;
displays = xrealloc(displays,
numDisplays * sizeof(CGDirectDisplayID));
cgErr = CGGetDisplaysWithRect(cgRect, allocatedDisplays, displays,
&numDisplays);
if (cgErr != CGDisplayNoErr) break;
} while (numDisplays > allocatedDisplays);
if (cgErr != CGDisplayNoErr || numDisplays == 0) {
ErrorF("Could not find CGDirectDisplayID(s) for X11 screen %d: %dx%d @ %d,%d.\n",
index, dfb->width, dfb->height, dfb->x, dfb->y);
return FALSE;
}
// This X11 screen covers all CoreGraphics displays we just found.
// If there's more than one CG display, then video mirroring is on
// or PseudoramiX is on.
displayInfo->displayCount = allocatedDisplays;
displayInfo->displayIDs = displays;
return TRUE;
}
/*
* CRSetupScreen
* Setup the screen for rootless access.
*/
static Bool
CRSetupScreen(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
return CRInit(pScreen);
}
/*
* CRInitInput
* Finalize CR specific setup.
*/
static void
CRInitInput(int argc, char **argv)
{
int i;
rootlessGlobalOffsetX = darwinMainScreenX;
rootlessGlobalOffsetY = darwinMainScreenY;
for (i = 0; i < screenInfo.numScreens; i++)
AppleWMSetScreenOrigin(WindowTable[i]);
}
/*
* CRIsX11Window
* Returns TRUE if cr is displaying this window.
*/
static Bool
CRIsX11Window(void *nsWindow, int windowNumber)
{
NSWindow *theWindow = nsWindow;
if (!theWindow)
return FALSE;
if ([[theWindow contentView] isKindOfClass:classXView])
return TRUE;
else
return FALSE;
}
/*
* Quartz display mode function list.
*/
static QuartzModeProcsRec crModeProcs = {
CRDisplayInit,
CRAddScreen,
CRSetupScreen,
CRInitInput,
QuartzInitCursor,
QuartzReallySetCursor,
QuartzSuspendXCursor,
QuartzResumeXCursor,
NULL, // No capture or release in rootless mode
NULL,
CRIsX11Window,
RootlessFrameForWindow,
TopLevelParent,
NULL, // No support for DRI surfaces
NULL
};
/*
* QuartzModeBundleInit
* Initialize the display mode bundle after loading.
*/
Bool
QuartzModeBundleInit(void)
{
quartzProcs = &crModeProcs;
quartzOpenGLBundle = crOpenGLBundle;
classXView = [XView class];
return TRUE;
}

View File

@ -0,0 +1,567 @@
/*
* Screen routines for full screen Quartz mode
*
* Copyright (c) 2002-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
* TORREY T. LYONS 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/fullscreen/fullscreen.c,v 1.2 2003/11/12 20:21:52 torrey Exp $ */
#include "quartzCommon.h"
#include "darwin.h"
#include "quartz.h"
#include "quartzCursor.h"
#include "colormapst.h"
#include "scrnintstr.h"
#include "micmap.h"
#include "shadow.h"
// Full screen specific per screen storage structure
typedef struct {
CGDirectDisplayID displayID;
CFDictionaryRef xDisplayMode;
CFDictionaryRef aquaDisplayMode;
CGDirectPaletteRef xPalette;
CGDirectPaletteRef aquaPalette;
unsigned char *framebuffer;
unsigned char *shadowPtr;
} FSScreenRec, *FSScreenPtr;
#define FULLSCREEN_PRIV(pScreen) \
((FSScreenPtr)pScreen->devPrivates[fsScreenIndex].ptr)
static int fsScreenIndex;
static CGDirectDisplayID *quartzDisplayList = NULL;
static int quartzNumScreens = 0;
static FSScreenPtr quartzScreens[MAXSCREENS];
static int darwinCmapPrivateIndex = -1;
static unsigned long darwinCmapGeneration = 0;
#define CMAP_PRIV(pCmap) \
((CGDirectPaletteRef) (pCmap)->devPrivates[darwinCmapPrivateIndex].ptr)
/*
=============================================================================
Colormap handling
=============================================================================
*/
/*
* FSInitCmapPrivates
* Colormap privates may be allocated after the default colormap has
* already been created for some screens. This initialization procedure
* is called for each default colormap that is found.
*/
static Bool
FSInitCmapPrivates(
ColormapPtr pCmap)
{
return TRUE;
}
/*
* FSCreateColormap
* This is a callback from X after a new colormap is created.
* We allocate a new CoreGraphics pallete for each colormap.
*/
static Bool
FSCreateColormap(
ColormapPtr pCmap)
{
CGDirectPaletteRef pallete;
// Allocate private storage for the hardware dependent colormap info.
if (darwinCmapGeneration != serverGeneration) {
if ((darwinCmapPrivateIndex =
AllocateColormapPrivateIndex(FSInitCmapPrivates)) < 0)
{
return FALSE;
}
darwinCmapGeneration = serverGeneration;
}
pallete = CGPaletteCreateDefaultColorPalette();
if (!pallete) return FALSE;
CMAP_PRIV(pCmap) = pallete;
return TRUE;
}
/*
* FSDestroyColormap
* This is called by DIX FreeColormap after it has uninstalled a colormap
* and notified all interested parties. We deallocated the corresponding
* CoreGraphics pallete.
*/
static void
FSDestroyColormap(
ColormapPtr pCmap)
{
CGPaletteRelease( CMAP_PRIV(pCmap) );
}
/*
* FSInstallColormap
* Set the current CoreGraphics pallete to the pallete corresponding
* to the provided colormap.
*/
static void
FSInstallColormap(
ColormapPtr pCmap)
{
CGDirectPaletteRef palette = CMAP_PRIV(pCmap);
ScreenPtr pScreen = pCmap->pScreen;
FSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen);
// Inform all interested parties that the map is being changed.
miInstallColormap(pCmap);
if (quartzServerVisible)
CGDisplaySetPalette(fsDisplayInfo->displayID, palette);
fsDisplayInfo->xPalette = palette;
}
/*
* FSStoreColors
* This is a callback from X to change the hardware colormap
* when using PsuedoColor in full screen mode.
*/
static void
FSStoreColors(
ColormapPtr pCmap,
int numEntries,
xColorItem *pdefs)
{
CGDirectPaletteRef palette = CMAP_PRIV(pCmap);
ScreenPtr pScreen = pCmap->pScreen;
FSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen);
CGDeviceColor color;
int i;
if (! palette)
return;
for (i = 0; i < numEntries; i++) {
color.red = pdefs[i].red / 65535.0;
color.green = pdefs[i].green / 65535.0;
color.blue = pdefs[i].blue / 65535.0;
CGPaletteSetColorAtIndex(palette, color, pdefs[i].pixel);
}
// Update hardware colormap
if (quartzServerVisible)
CGDisplaySetPalette(fsDisplayInfo->displayID, palette);
}
/*
=============================================================================
Switching between Aqua and X
=============================================================================
*/
/*
* FSCapture
* Capture the screen so we can draw. Called directly from the main thread
* to synchronize with hiding the menubar.
*/
static void FSCapture(void)
{
int i;
if (quartzRootless) return;
for (i = 0; i < quartzNumScreens; i++) {
FSScreenPtr fsDisplayInfo = quartzScreens[i];
CGDirectDisplayID cgID = fsDisplayInfo->displayID;
if (!CGDisplayIsCaptured(cgID)) {
CGDisplayCapture(cgID);
fsDisplayInfo->aquaDisplayMode = CGDisplayCurrentMode(cgID);
if (fsDisplayInfo->xDisplayMode != fsDisplayInfo->aquaDisplayMode)
CGDisplaySwitchToMode(cgID, fsDisplayInfo->xDisplayMode);
if (fsDisplayInfo->xPalette)
CGDisplaySetPalette(cgID, fsDisplayInfo->xPalette);
}
}
}
/*
* FSRelease
* Release the screen so others can draw.
*/
static void FSRelease(void)
{
int i;
if (quartzRootless) return;
for (i = 0; i < quartzNumScreens; i++) {
FSScreenPtr fsDisplayInfo = quartzScreens[i];
CGDirectDisplayID cgID = fsDisplayInfo->displayID;
if (CGDisplayIsCaptured(cgID)) {
if (fsDisplayInfo->xDisplayMode != fsDisplayInfo->aquaDisplayMode)
CGDisplaySwitchToMode(cgID, fsDisplayInfo->aquaDisplayMode);
if (fsDisplayInfo->aquaPalette)
CGDisplaySetPalette(cgID, fsDisplayInfo->aquaPalette);
CGDisplayRelease(cgID);
}
}
}
/*
* FSSuspendScreen
* Suspend X11 cursor and drawing to the screen.
*/
static void FSSuspendScreen(
ScreenPtr pScreen)
{
QuartzSuspendXCursor(pScreen);
xf86SetRootClip(pScreen, FALSE);
}
/*
* FSResumeScreen
* Resume X11 cursor and drawing to the screen.
*/
static void FSResumeScreen(
ScreenPtr pScreen,
int x, // cursor location
int y )
{
QuartzResumeXCursor(pScreen, x, y);
xf86SetRootClip(pScreen, TRUE);
}
/*
=============================================================================
Screen initialization
=============================================================================
*/
/*
* FSDisplayInit
* Full screen specific initialization called from InitOutput.
*/
static void FSDisplayInit(void)
{
static unsigned long generation = 0;
CGDisplayCount quartzDisplayCount = 0;
ErrorF("Display mode: Full screen Quartz -- Direct Display\n");
// Allocate private storage for each screen's mode specific info
if (generation != serverGeneration) {
fsScreenIndex = AllocateScreenPrivateIndex();
generation = serverGeneration;
}
// Find all the CoreGraphics displays
CGGetActiveDisplayList(0, NULL, &quartzDisplayCount);
quartzDisplayList = xalloc(quartzDisplayCount * sizeof(CGDirectDisplayID));
CGGetActiveDisplayList(quartzDisplayCount, quartzDisplayList,
&quartzDisplayCount);
darwinScreensFound = quartzDisplayCount;
atexit(FSRelease);
}
/*
* FSFindDisplayMode
* Find the appropriate display mode to use in full screen mode.
* If display mode is not the same as the current Aqua mode, switch
* to the new mode.
*/
static Bool FSFindDisplayMode(
FSScreenPtr fsDisplayInfo)
{
CGDirectDisplayID cgID = fsDisplayInfo->displayID;
size_t height, width, bpp;
boolean_t exactMatch;
fsDisplayInfo->aquaDisplayMode = CGDisplayCurrentMode(cgID);
// If no user options, use current display mode
if (darwinDesiredWidth == 0 && darwinDesiredDepth == -1 &&
darwinDesiredRefresh == -1)
{
fsDisplayInfo->xDisplayMode = fsDisplayInfo->aquaDisplayMode;
return TRUE;
}
// If the user has no choice for size, use current
if (darwinDesiredWidth == 0) {
width = CGDisplayPixelsWide(cgID);
height = CGDisplayPixelsHigh(cgID);
} else {
width = darwinDesiredWidth;
height = darwinDesiredHeight;
}
switch (darwinDesiredDepth) {
case 0:
bpp = 8;
break;
case 1:
bpp = 16;
break;
case 2:
bpp = 32;
break;
default:
bpp = CGDisplayBitsPerPixel(cgID);
}
if (darwinDesiredRefresh == -1) {
fsDisplayInfo->xDisplayMode =
CGDisplayBestModeForParameters(cgID, bpp, width, height,
&exactMatch);
} else {
fsDisplayInfo->xDisplayMode =
CGDisplayBestModeForParametersAndRefreshRate(cgID, bpp,
width, height, darwinDesiredRefresh, &exactMatch);
}
if (!exactMatch) {
fsDisplayInfo->xDisplayMode = fsDisplayInfo->aquaDisplayMode;
return FALSE;
}
// Switch to the new display mode
CGDisplaySwitchToMode(cgID, fsDisplayInfo->xDisplayMode);
return TRUE;
}
/*
* FSAddScreen
* Do initialization of each screen for Quartz in full screen mode.
*/
static Bool FSAddScreen(
int index,
ScreenPtr pScreen)
{
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
QuartzScreenPtr displayInfo = QUARTZ_PRIV(pScreen);
CGDirectDisplayID cgID = quartzDisplayList[index];
CGRect bounds;
FSScreenPtr fsDisplayInfo;
// Allocate space for private per screen fullscreen specific storage.
fsDisplayInfo = xalloc(sizeof(FSScreenRec));
FULLSCREEN_PRIV(pScreen) = fsDisplayInfo;
displayInfo->displayCount = 1;
displayInfo->displayIDs = xrealloc(displayInfo->displayIDs,
1 * sizeof(CGDirectDisplayID));
displayInfo->displayIDs[0] = cgID;
fsDisplayInfo->displayID = cgID;
fsDisplayInfo->xDisplayMode = 0;
fsDisplayInfo->aquaDisplayMode = 0;
fsDisplayInfo->xPalette = 0;
fsDisplayInfo->aquaPalette = 0;
// Capture full screen because X doesn't like read-only framebuffer.
// We need to do this before we (potentially) switch the display mode.
CGDisplayCapture(cgID);
if (! FSFindDisplayMode(fsDisplayInfo)) {
ErrorF("Could not support specified display mode on screen %i.\n",
index);
xfree(fsDisplayInfo);
return FALSE;
}
// Don't need to flip y-coordinate as CoreGraphics treats (0, 0)
// as the top left of main screen.
bounds = CGDisplayBounds(cgID);
dfb->x = bounds.origin.x;
dfb->y = bounds.origin.y;
dfb->width = bounds.size.width;
dfb->height = bounds.size.height;
dfb->pitch = CGDisplayBytesPerRow(cgID);
dfb->bitsPerPixel = CGDisplayBitsPerPixel(cgID);
if (dfb->bitsPerPixel == 8) {
if (CGDisplayCanSetPalette(cgID)) {
dfb->colorType = PseudoColor;
} else {
dfb->colorType = StaticColor;
}
dfb->bitsPerComponent = 8;
dfb->colorBitsPerPixel = 8;
} else {
dfb->colorType = TrueColor;
dfb->bitsPerComponent = CGDisplayBitsPerSample(cgID);
dfb->colorBitsPerPixel = CGDisplaySamplesPerPixel(cgID) *
dfb->bitsPerComponent;
}
fsDisplayInfo->framebuffer = CGDisplayBaseAddress(cgID);
// allocate shadow framebuffer
fsDisplayInfo->shadowPtr = xalloc(dfb->pitch * dfb->height);
dfb->framebuffer = fsDisplayInfo->shadowPtr;
return TRUE;
}
/*
* FSShadowUpdate
* Update the damaged regions of the shadow framebuffer on the display.
*/
static void FSShadowUpdate(
ScreenPtr pScreen,
shadowBufPtr pBuf)
{
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
FSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen);
RegionPtr damage = &pBuf->damage;
int numBox = REGION_NUM_RECTS(damage);
BoxPtr pBox = REGION_RECTS(damage);
int pitch = dfb->pitch;
int bpp = dfb->bitsPerPixel/8;
ErrorF("FSShadowUpdate: %i\n", quartzServerVisible);
// Don't update if the X server is not visible
if (!quartzServerVisible)
return;
// Loop through all the damaged boxes
while (numBox--) {
int width, height, offset;
unsigned char *src, *dst;
width = (pBox->x2 - pBox->x1) * bpp;
height = pBox->y2 - pBox->y1;
offset = (pBox->y1 * pitch) + (pBox->x1 * bpp);
src = fsDisplayInfo->shadowPtr + offset;
dst = fsDisplayInfo->framebuffer + offset;
while (height--) {
memcpy(dst, src, width);
dst += pitch;
src += pitch;
}
// Get the next box
pBox++;
}
}
/*
* FSSetupScreen
* Finalize full screen specific setup of each screen.
*/
static Bool FSSetupScreen(
int index,
ScreenPtr pScreen)
{
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
FSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen);
CGDirectDisplayID cgID = fsDisplayInfo->displayID;
ErrorF("FSSetupScreen\n");
// Initialize shadow framebuffer support
if (! shadowInit(pScreen, FSShadowUpdate, NULL)) {
ErrorF("Failed to initalize shadow framebuffer for screen %i.\n",
index);
return FALSE;
}
if (dfb->colorType == PseudoColor) {
// Initialize colormap handling
size_t aquaBpp;
// If Aqua is using 8 bits we need to keep track of its pallete.
CFNumberGetValue(CFDictionaryGetValue(fsDisplayInfo->aquaDisplayMode,
kCGDisplayBitsPerPixel), kCFNumberLongType, &aquaBpp);
if (aquaBpp <= 8)
fsDisplayInfo->aquaPalette = CGPaletteCreateWithDisplay(cgID);
pScreen->CreateColormap = FSCreateColormap;
pScreen->DestroyColormap = FSDestroyColormap;
pScreen->InstallColormap = FSInstallColormap;
pScreen->StoreColors = FSStoreColors;
}
quartzScreens[quartzNumScreens++] = fsDisplayInfo;
return TRUE;
}
/*
* Quartz display mode function list.
*/
static QuartzModeProcsRec fsModeProcs = {
FSDisplayInit,
FSAddScreen,
FSSetupScreen,
NULL, // Not needed
QuartzInitCursor,
QuartzReallySetCursor,
FSSuspendScreen,
FSResumeScreen,
FSCapture,
FSRelease,
NULL, // No rootless code in fullscreen
NULL,
NULL,
NULL, // No support for DRI surfaces
NULL
};
/*
* QuartzModeBundleInit
* Initialize the display mode bundle after loading.
*/
Bool
QuartzModeBundleInit(void)
{
quartzProcs = &fsModeProcs;
quartzOpenGLBundle = NULL; // Only Mesa support for now
return TRUE;
}

View File

@ -0,0 +1,653 @@
/**************************************************************
*
* Support for using the Quartz Window Manager cursor
*
**************************************************************/
/*
* Copyright (c) 2001-2003 Torrey T. Lyons and Greg Parker.
* 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/fullscreen/quartzCursor.c,v 1.1 2003/09/16 00:36:15 torrey Exp $ */
#include "quartzCommon.h"
#include "quartzCursor.h"
#include "darwin.h"
#include <pthread.h>
#include "mi.h"
#include "scrnintstr.h"
#include "cursorstr.h"
#include "mipointrst.h"
#include "globals.h"
// Size of the QuickDraw cursor
#define CURSORWIDTH 16
#define CURSORHEIGHT 16
typedef struct {
int qdCursorMode;
int qdCursorVisible;
int useQDCursor;
QueryBestSizeProcPtr QueryBestSize;
miPointerSpriteFuncPtr spriteFuncs;
} QuartzCursorScreenRec, *QuartzCursorScreenPtr;
static int darwinCursorScreenIndex = -1;
static unsigned long darwinCursorGeneration = 0;
static CursorPtr quartzLatentCursor = NULL;
static QD_Cursor gQDArrow; // QuickDraw arrow cursor
// Cursor for the main thread to set (NULL = arrow cursor).
static CCrsrHandle currentCursor = NULL;
static pthread_mutex_t cursorMutex;
static pthread_cond_t cursorCondition;
#define CURSOR_PRIV(pScreen) \
((QuartzCursorScreenPtr)pScreen->devPrivates[darwinCursorScreenIndex].ptr)
#define HIDE_QD_CURSOR(pScreen, visible) \
if (visible) { \
int ix; \
for (ix = 0; ix < QUARTZ_PRIV(pScreen)->displayCount; ix++) { \
CGDisplayHideCursor(QUARTZ_PRIV(pScreen)->displayIDs[ix]); \
} \
visible = FALSE; \
} ((void)0)
#define SHOW_QD_CURSOR(pScreen, visible) \
{ \
int ix; \
for (ix = 0; ix < QUARTZ_PRIV(pScreen)->displayCount; ix++) { \
CGDisplayShowCursor(QUARTZ_PRIV(pScreen)->displayIDs[ix]); \
} \
visible = TRUE; \
} ((void)0)
#define CHANGE_QD_CURSOR(cursorH) \
if (!quartzServerQuitting) { \
/* Acquire lock and tell the main thread to change cursor */ \
pthread_mutex_lock(&cursorMutex); \
currentCursor = (CCrsrHandle) (cursorH); \
QuartzMessageMainThread(kQuartzCursorUpdate, NULL, 0); \
\
/* Wait for the main thread to change the cursor */ \
pthread_cond_wait(&cursorCondition, &cursorMutex); \
pthread_mutex_unlock(&cursorMutex); \
} ((void)0)
/*
* MakeQDCursor helpers: CTAB_ENTER, interleave
*/
// Add a color entry to a ctab
#define CTAB_ENTER(ctab, index, r, g, b) \
ctab->ctTable[index].value = index; \
ctab->ctTable[index].rgb.red = r; \
ctab->ctTable[index].rgb.green = g; \
ctab->ctTable[index].rgb.blue = b
// Make an unsigned short by interleaving the bits of bytes c1 and c2.
// High bit of c1 is first; low bit of c2 is last.
// Interleave is a built-in INTERCAL operator.
static unsigned short
interleave(
unsigned char c1,
unsigned char c2 )
{
return
((c1 & 0x80) << 8) | ((c2 & 0x80) << 7) |
((c1 & 0x40) << 7) | ((c2 & 0x40) << 6) |
((c1 & 0x20) << 6) | ((c2 & 0x20) << 5) |
((c1 & 0x10) << 5) | ((c2 & 0x10) << 4) |
((c1 & 0x08) << 4) | ((c2 & 0x08) << 3) |
((c1 & 0x04) << 3) | ((c2 & 0x04) << 2) |
((c1 & 0x02) << 2) | ((c2 & 0x02) << 1) |
((c1 & 0x01) << 1) | ((c2 & 0x01) << 0) ;
}
/*
* MakeQDCursor
* Make a QuickDraw color cursor from the given X11 cursor.
* Warning: This code is nasty. Color cursors were meant to be read
* from resources; constructing the structures programmatically is messy.
*/
/*
QuickDraw cursor representation:
Our color cursor is a 2 bit per pixel pixmap.
Each pixel's bits are (source<<1 | mask) from the original X cursor pixel.
The cursor's color table maps the colors like this:
(2-bit value | X result | colortable | Mac result)
00 | transparent | white | transparent (white outside mask)
01 | back color | back color | back color
10 | undefined | black | invert background (just for fun)
11 | fore color | fore color | fore color
*/
static CCrsrHandle
MakeQDCursor(
CursorPtr pCursor )
{
CCrsrHandle result;
CCrsrPtr curs;
int i, w, h;
unsigned short rowMask;
PixMap *pix;
ColorTable *ctab;
unsigned short *image;
result = (CCrsrHandle) NewHandleClear(sizeof(CCrsr));
if (!result) return NULL;
HLock((Handle)result);
curs = *result;
// Initialize CCrsr
curs->crsrType = 0x8001; // 0x8000 = b&w, 0x8001 = color
curs->crsrMap = (PixMapHandle) NewHandleClear(sizeof(PixMap));
if (!curs->crsrMap) goto pixAllocFailed;
HLock((Handle)curs->crsrMap);
pix = *curs->crsrMap;
curs->crsrData = NULL; // raw cursor image data (set below)
curs->crsrXData = NULL; // QD's processed data
curs->crsrXValid = 0; // zero means QD must re-process cursor data
curs->crsrXHandle = NULL; // reserved
memset(curs->crsr1Data, 0, CURSORWIDTH*CURSORHEIGHT/8); // b&w data
memset(curs->crsrMask, 0, CURSORWIDTH*CURSORHEIGHT/8); // b&w & color mask
curs->crsrHotSpot.h = min(CURSORWIDTH, pCursor->bits->xhot); // hot spot
curs->crsrHotSpot.v = min(CURSORHEIGHT, pCursor->bits->yhot); // hot spot
curs->crsrXTable = 0; // reserved
curs->crsrID = GetCTSeed(); // unique ID from Color Manager
// Set the b&w data and mask
w = min(pCursor->bits->width, CURSORWIDTH);
h = min(pCursor->bits->height, CURSORHEIGHT);
rowMask = ~((1 << (CURSORWIDTH - w)) - 1);
for (i = 0; i < h; i++) {
curs->crsr1Data[i] = rowMask &
((pCursor->bits->source[i*4]<<8) | pCursor->bits->source[i*4+1]);
curs->crsrMask[i] = rowMask &
((pCursor->bits->mask[i*4]<<8) | pCursor->bits->mask[i*4+1]);
}
// Set the color data and mask
// crsrMap: defines bit depth and size and colortable only
pix->rowBytes = (CURSORWIDTH * 2 / 8) | 0x8000; // last bit on means PixMap
SetRect(&pix->bounds, 0, 0, CURSORWIDTH, CURSORHEIGHT); // see TN 1020
pix->pixelSize = 2;
pix->cmpCount = 1;
pix->cmpSize = 2;
// pix->pmTable set below
// crsrData is the pixel data. crsrMap's baseAddr is not used.
curs->crsrData = NewHandleClear(CURSORWIDTH*CURSORHEIGHT * 2 / 8);
if (!curs->crsrData) goto imageAllocFailed;
HLock((Handle)curs->crsrData);
image = (unsigned short *) *curs->crsrData;
// Pixel data is just 1-bit data and mask interleaved (see above)
for (i = 0; i < h; i++) {
unsigned char s, m;
s = pCursor->bits->source[i*4] & (rowMask >> 8);
m = pCursor->bits->mask[i*4] & (rowMask >> 8);
image[2*i] = interleave(s, m);
s = pCursor->bits->source[i*4+1] & (rowMask & 0x00ff);
m = pCursor->bits->mask[i*4+1] & (rowMask & 0x00ff);
image[2*i+1] = interleave(s, m);
}
// Build the color table (entries described above)
// NewPixMap allocates a color table handle.
pix->pmTable = (CTabHandle) NewHandleClear(sizeof(ColorTable) + 3
* sizeof(ColorSpec));
if (!pix->pmTable) goto ctabAllocFailed;
HLock((Handle)pix->pmTable);
ctab = *pix->pmTable;
ctab->ctSeed = GetCTSeed();
ctab->ctFlags = 0;
ctab->ctSize = 3; // color count - 1
CTAB_ENTER(ctab, 0, 0xffff, 0xffff, 0xffff);
CTAB_ENTER(ctab, 1, pCursor->backRed, pCursor->backGreen,
pCursor->backBlue);
CTAB_ENTER(ctab, 2, 0x0000, 0x0000, 0x0000);
CTAB_ENTER(ctab, 3, pCursor->foreRed, pCursor->foreGreen,
pCursor->foreBlue);
HUnlock((Handle)pix->pmTable); // ctab
HUnlock((Handle)curs->crsrData); // image data
HUnlock((Handle)curs->crsrMap); // pix
HUnlock((Handle)result); // cursor
return result;
// "What we have here is a failure to allocate"
ctabAllocFailed:
HUnlock((Handle)curs->crsrData);
DisposeHandle((Handle)curs->crsrData);
imageAllocFailed:
HUnlock((Handle)curs->crsrMap);
DisposeHandle((Handle)curs->crsrMap);
pixAllocFailed:
HUnlock((Handle)result);
DisposeHandle((Handle)result);
return NULL;
}
/*
* FreeQDCursor
* Destroy a QuickDraw color cursor created with MakeQDCursor().
* The cursor must not currently be on screen.
*/
static void FreeQDCursor(CCrsrHandle cursHandle)
{
CCrsrPtr curs;
PixMap *pix;
HLock((Handle)cursHandle);
curs = *cursHandle;
HLock((Handle)curs->crsrMap);
pix = *curs->crsrMap;
DisposeHandle((Handle)pix->pmTable);
HUnlock((Handle)curs->crsrMap);
DisposeHandle((Handle)curs->crsrMap);
DisposeHandle((Handle)curs->crsrData);
HUnlock((Handle)cursHandle);
DisposeHandle((Handle)cursHandle);
}
/*
===========================================================================
Pointer sprite functions
===========================================================================
*/
/*
* QuartzRealizeCursor
* Convert the X cursor representation to QuickDraw format if possible.
*/
Bool
QuartzRealizeCursor(
ScreenPtr pScreen,
CursorPtr pCursor )
{
CCrsrHandle qdCursor;
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
if(!pCursor || !pCursor->bits)
return FALSE;
// if the cursor is too big we use a software cursor
if ((pCursor->bits->height > CURSORHEIGHT) ||
(pCursor->bits->width > CURSORWIDTH) || !ScreenPriv->useQDCursor)
{
if (quartzRootless) {
// rootless can't use a software cursor
return TRUE;
} else {
return (*ScreenPriv->spriteFuncs->RealizeCursor)
(pScreen, pCursor);
}
}
// make new cursor image
qdCursor = MakeQDCursor(pCursor);
if (!qdCursor) return FALSE;
// save the result
pCursor->devPriv[pScreen->myNum] = (pointer) qdCursor;
return TRUE;
}
/*
* QuartzUnrealizeCursor
* Free the storage space associated with a realized cursor.
*/
Bool
QuartzUnrealizeCursor(
ScreenPtr pScreen,
CursorPtr pCursor )
{
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
if ((pCursor->bits->height > CURSORHEIGHT) ||
(pCursor->bits->width > CURSORWIDTH) || !ScreenPriv->useQDCursor)
{
if (quartzRootless) {
return TRUE;
} else {
return (*ScreenPriv->spriteFuncs->UnrealizeCursor)
(pScreen, pCursor);
}
} else {
CCrsrHandle oldCursor = (CCrsrHandle) pCursor->devPriv[pScreen->myNum];
if (currentCursor != oldCursor) {
// This should only fail when quitting, in which case we just leak.
FreeQDCursor(oldCursor);
}
pCursor->devPriv[pScreen->myNum] = NULL;
return TRUE;
}
}
/*
* QuartzSetCursor
* Set the cursor sprite and position.
* Use QuickDraw cursor if possible.
*/
static void
QuartzSetCursor(
ScreenPtr pScreen,
CursorPtr pCursor,
int x,
int y)
{
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
quartzLatentCursor = pCursor;
// Don't touch Mac OS cursor if X is hidden!
if (!quartzServerVisible)
return;
if (!pCursor) {
// Remove the cursor completely.
HIDE_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
if (! ScreenPriv->qdCursorMode)
(*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
}
else if ((pCursor->bits->height <= CURSORHEIGHT) &&
(pCursor->bits->width <= CURSORWIDTH) && ScreenPriv->useQDCursor)
{
// Cursor is small enough to use QuickDraw directly.
if (! ScreenPriv->qdCursorMode) // remove the X cursor
(*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
ScreenPriv->qdCursorMode = TRUE;
CHANGE_QD_CURSOR(pCursor->devPriv[pScreen->myNum]);
SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
}
else if (quartzRootless) {
// Rootless can't use a software cursor, so we just use Mac OS arrow.
CHANGE_QD_CURSOR(NULL);
SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
}
else {
// Cursor is too big for QuickDraw. Use X software cursor.
HIDE_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
ScreenPriv->qdCursorMode = FALSE;
(*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCursor, x, y);
}
}
/*
* QuartzReallySetCursor
* Set the QuickDraw cursor. Called from the main thread since changing the
* cursor with QuickDraw is not thread safe on dual processor machines.
*/
void
QuartzReallySetCursor()
{
pthread_mutex_lock(&cursorMutex);
if (currentCursor) {
SetCCursor(currentCursor);
} else {
SetCursor(&gQDArrow);
}
pthread_cond_signal(&cursorCondition);
pthread_mutex_unlock(&cursorMutex);
}
/*
* QuartzMoveCursor
* Move the cursor. This is a noop for QuickDraw.
*/
static void
QuartzMoveCursor(
ScreenPtr pScreen,
int x,
int y)
{
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
// only the X cursor needs to be explicitly moved
if (!ScreenPriv->qdCursorMode)
(*ScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, 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 int neverMoved = TRUE;
if (neverMoved) {
// Don't move the cursor the first time. This is the jump-to-center
// initialization, and it's annoying because we may still be in MacOS.
neverMoved = FALSE;
return;
}
if (quartzServerVisible) {
CGDisplayErr cgErr;
CGPoint cgPoint;
// Only need to do this for one display. Any display will do.
CGDirectDisplayID cgID = QUARTZ_PRIV(pScreen)->displayIDs[0];
CGRect cgRect = CGDisplayBounds(cgID);
// Convert (x,y) to CoreGraphics screen-local CG coordinates.
// This is necessary because the X11 screen and CG screen may not
// coincide. (e.g. X11 screen may be moved to dodge the menu bar)
// Make point in X11 global coordinates
cgPoint = CGPointMake(x + dixScreenOrigins[pScreen->myNum].x,
y + dixScreenOrigins[pScreen->myNum].y);
// Shift to CoreGraphics global screen coordinates
cgPoint.x += darwinMainScreenX;
cgPoint.y += darwinMainScreenY;
// Shift to CoreGraphics screen-local coordinates
cgPoint.x -= cgRect.origin.x;
cgPoint.y -= cgRect.origin.y;
cgErr = CGDisplayMoveCursorToPoint(cgID, cgPoint);
if (cgErr != CGDisplayNoErr) {
ErrorF("Could not set cursor position with error code 0x%x.\n",
cgErr);
}
}
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) {
*width = CURSORWIDTH;
*height = CURSORHEIGHT;
} else {
(*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
}
}
/*
* QuartzInitCursor
* Initialize cursor support
*/
Bool
QuartzInitCursor(
ScreenPtr pScreen )
{
QuartzCursorScreenPtr ScreenPriv;
miPointerScreenPtr PointPriv;
DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
// 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) return FALSE;
CURSOR_PRIV(pScreen) = ScreenPriv;
// override some screen procedures
ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
pScreen->QueryBestSize = QuartzCursorQueryBestSize;
// initialize QuickDraw cursor handling
GetQDGlobalsArrow(&gQDArrow);
PointPriv = (miPointerScreenPtr)
pScreen->devPrivates[miPointerScreenIndex].ptr;
ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
PointPriv->spriteFuncs = &quartzSpriteFuncsRec;
if (!quartzRootless)
ScreenPriv->useQDCursor = QuartzFSUseQDCursor(dfb->colorBitsPerPixel);
else
ScreenPriv->useQDCursor = TRUE;
ScreenPriv->qdCursorMode = TRUE;
ScreenPriv->qdCursorVisible = TRUE;
// initialize cursor mutex lock
pthread_mutex_init(&cursorMutex, NULL);
// initialize condition for waiting
pthread_cond_init(&cursorCondition, NULL);
return TRUE;
}
// X server is hiding. Restore the Aqua cursor.
void QuartzSuspendXCursor(
ScreenPtr pScreen )
{
QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
CHANGE_QD_CURSOR(NULL);
SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
}
// X server is showing. Restore the X cursor.
void QuartzResumeXCursor(
ScreenPtr pScreen,
int x,
int y )
{
QuartzSetCursor(pScreen, quartzLatentCursor, x, y);
}

View File

@ -0,0 +1,44 @@
/*
* quartzCursor.h
*
* External interface for Quartz hardware cursor
*/
/*
* Copyright (c) 2001 Torrey T. Lyons and Greg Parker.
* 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/fullscreen/quartzCursor.h,v 1.1 2003/09/16 00:36:15 torrey Exp $ */
#ifndef QUARTZCURSOR_H
#define QUARTZCURSOR_H
#include "screenint.h"
Bool QuartzInitCursor(ScreenPtr pScreen);
void QuartzReallySetCursor(void);
void QuartzSuspendXCursor(ScreenPtr pScreen);
void QuartzResumeXCursor(ScreenPtr pScreen, int x, int y);
#endif

View File

@ -0,0 +1,909 @@
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/keysym2ucs.c,v 1.1 2003/11/01 08:13:08 torrey Exp $
*
* This module converts keysym values into the corresponding ISO 10646
* (UCS, Unicode) values.
*
* The array keysymtab[] contains pairs of X11 keysym values for graphical
* characters and the corresponding Unicode value. The function
* keysym2ucs() maps a keysym onto a Unicode value using a binary search,
* therefore keysymtab[] must remain SORTED by keysym value.
*
* The keysym -> UTF-8 conversion will hopefully one day be provided
* by Xlib via XmbLookupString() and should ideally not have to be
* done in X applications. But we are not there yet.
*
* We allow to represent any UCS character in the range U-00000000 to
* U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.
* This admittedly does not cover the entire 31-bit space of UCS, but
* it does cover all of the characters up to U-10FFFF, which can be
* represented by UTF-16, and more, and it is very unlikely that higher
* UCS codes will ever be assigned by ISO. So to get Unicode character
* U+ABCD you can directly use keysym 0x0100abcd.
*
* NOTE: The comments in the table below contain the actual character
* encoded in UTF-8, so for viewing and editing best use an editor in
* UTF-8 mode.
*
* Author: Markus G. Kuhn <mkuhn@acm.org>, University of Cambridge, April 2001
*
* Special thanks to Richard Verhoeven <river@win.tue.nl> for preparing
* an initial draft of the mapping table.
*
* This software is in the public domain. Share and enjoy!
*
* AUTOMATICALLY GENERATED FILE, DO NOT EDIT !!! (unicode/convmap.pl)
*/
#include "keysym2ucs.h"
#include <stdlib.h>
#include <string.h>
struct codepair {
unsigned short keysym;
unsigned short ucs;
};
const static struct codepair keysymtab[] = {
{ 0x01a1, 0x0104 },
{ 0x01a2, 0x02d8 },
{ 0x01a3, 0x0141 },
{ 0x01a5, 0x013d },
{ 0x01a6, 0x015a },
{ 0x01a9, 0x0160 },
{ 0x01aa, 0x015e },
{ 0x01ab, 0x0164 },
{ 0x01ac, 0x0179 },
{ 0x01ae, 0x017d },
{ 0x01af, 0x017b },
{ 0x01b1, 0x0105 },
{ 0x01b2, 0x02db },
{ 0x01b3, 0x0142 },
{ 0x01b5, 0x013e },
{ 0x01b6, 0x015b },
{ 0x01b7, 0x02c7 },
{ 0x01b9, 0x0161 },
{ 0x01ba, 0x015f },
{ 0x01bb, 0x0165 },
{ 0x01bc, 0x017a },
{ 0x01bd, 0x02dd },
{ 0x01be, 0x017e },
{ 0x01bf, 0x017c },
{ 0x01c0, 0x0154 },
{ 0x01c3, 0x0102 },
{ 0x01c5, 0x0139 },
{ 0x01c6, 0x0106 },
{ 0x01c8, 0x010c },
{ 0x01ca, 0x0118 },
{ 0x01cc, 0x011a },
{ 0x01cf, 0x010e },
{ 0x01d0, 0x0110 },
{ 0x01d1, 0x0143 },
{ 0x01d2, 0x0147 },
{ 0x01d5, 0x0150 },
{ 0x01d8, 0x0158 },
{ 0x01d9, 0x016e },
{ 0x01db, 0x0170 },
{ 0x01de, 0x0162 },
{ 0x01e0, 0x0155 },
{ 0x01e3, 0x0103 },
{ 0x01e5, 0x013a },
{ 0x01e6, 0x0107 },
{ 0x01e8, 0x010d },
{ 0x01ea, 0x0119 },
{ 0x01ec, 0x011b },
{ 0x01ef, 0x010f },
{ 0x01f0, 0x0111 },
{ 0x01f1, 0x0144 },
{ 0x01f2, 0x0148 },
{ 0x01f5, 0x0151 },
{ 0x01f8, 0x0159 },
{ 0x01f9, 0x016f },
{ 0x01fb, 0x0171 },
{ 0x01fe, 0x0163 },
{ 0x01ff, 0x02d9 },
{ 0x02a1, 0x0126 },
{ 0x02a6, 0x0124 },
{ 0x02a9, 0x0130 },
{ 0x02ab, 0x011e },
{ 0x02ac, 0x0134 },
{ 0x02b1, 0x0127 },
{ 0x02b6, 0x0125 },
{ 0x02b9, 0x0131 },
{ 0x02bb, 0x011f },
{ 0x02bc, 0x0135 },
{ 0x02c5, 0x010a },
{ 0x02c6, 0x0108 },
{ 0x02d5, 0x0120 },
{ 0x02d8, 0x011c },
{ 0x02dd, 0x016c },
{ 0x02de, 0x015c },
{ 0x02e5, 0x010b },
{ 0x02e6, 0x0109 },
{ 0x02f5, 0x0121 },
{ 0x02f8, 0x011d },
{ 0x02fd, 0x016d },
{ 0x02fe, 0x015d },
{ 0x03a2, 0x0138 },
{ 0x03a3, 0x0156 },
{ 0x03a5, 0x0128 },
{ 0x03a6, 0x013b },
{ 0x03aa, 0x0112 },
{ 0x03ab, 0x0122 },
{ 0x03ac, 0x0166 },
{ 0x03b3, 0x0157 },
{ 0x03b5, 0x0129 },
{ 0x03b6, 0x013c },
{ 0x03ba, 0x0113 },
{ 0x03bb, 0x0123 },
{ 0x03bc, 0x0167 },
{ 0x03bd, 0x014a },
{ 0x03bf, 0x014b },
{ 0x03c0, 0x0100 },
{ 0x03c7, 0x012e },
{ 0x03cc, 0x0116 },
{ 0x03cf, 0x012a },
{ 0x03d1, 0x0145 },
{ 0x03d2, 0x014c },
{ 0x03d3, 0x0136 },
{ 0x03d9, 0x0172 },
{ 0x03dd, 0x0168 },
{ 0x03de, 0x016a },
{ 0x03e0, 0x0101 },
{ 0x03e7, 0x012f },
{ 0x03ec, 0x0117 },
{ 0x03ef, 0x012b },
{ 0x03f1, 0x0146 },
{ 0x03f2, 0x014d },
{ 0x03f3, 0x0137 },
{ 0x03f9, 0x0173 },
{ 0x03fd, 0x0169 },
{ 0x03fe, 0x016b },
{ 0x047e, 0x203e },
{ 0x04a1, 0x3002 },
{ 0x04a2, 0x300c },
{ 0x04a3, 0x300d },
{ 0x04a4, 0x3001 },
{ 0x04a5, 0x30fb },
{ 0x04a6, 0x30f2 },
{ 0x04a7, 0x30a1 },
{ 0x04a8, 0x30a3 },
{ 0x04a9, 0x30a5 },
{ 0x04aa, 0x30a7 },
{ 0x04ab, 0x30a9 },
{ 0x04ac, 0x30e3 },
{ 0x04ad, 0x30e5 },
{ 0x04ae, 0x30e7 },
{ 0x04af, 0x30c3 },
{ 0x04b0, 0x30fc },
{ 0x04b1, 0x30a2 },
{ 0x04b2, 0x30a4 },
{ 0x04b3, 0x30a6 },
{ 0x04b4, 0x30a8 },
{ 0x04b5, 0x30aa },
{ 0x04b6, 0x30ab },
{ 0x04b7, 0x30ad },
{ 0x04b8, 0x30af },
{ 0x04b9, 0x30b1 },
{ 0x04ba, 0x30b3 },
{ 0x04bb, 0x30b5 },
{ 0x04bc, 0x30b7 },
{ 0x04bd, 0x30b9 },
{ 0x04be, 0x30bb },
{ 0x04bf, 0x30bd },
{ 0x04c0, 0x30bf },
{ 0x04c1, 0x30c1 },
{ 0x04c2, 0x30c4 },
{ 0x04c3, 0x30c6 },
{ 0x04c4, 0x30c8 },
{ 0x04c5, 0x30ca },
{ 0x04c6, 0x30cb },
{ 0x04c7, 0x30cc },
{ 0x04c8, 0x30cd },
{ 0x04c9, 0x30ce },
{ 0x04ca, 0x30cf },
{ 0x04cb, 0x30d2 },
{ 0x04cc, 0x30d5 },
{ 0x04cd, 0x30d8 },
{ 0x04ce, 0x30db },
{ 0x04cf, 0x30de },
{ 0x04d0, 0x30df },
{ 0x04d1, 0x30e0 },
{ 0x04d2, 0x30e1 },
{ 0x04d3, 0x30e2 },
{ 0x04d4, 0x30e4 },
{ 0x04d5, 0x30e6 },
{ 0x04d6, 0x30e8 },
{ 0x04d7, 0x30e9 },
{ 0x04d8, 0x30ea },
{ 0x04d9, 0x30eb },
{ 0x04da, 0x30ec },
{ 0x04db, 0x30ed },
{ 0x04dc, 0x30ef },
{ 0x04dd, 0x30f3 },
{ 0x04de, 0x309b },
{ 0x04df, 0x309c },
{ 0x05ac, 0x060c },
{ 0x05bb, 0x061b },
{ 0x05bf, 0x061f },
{ 0x05c1, 0x0621 },
{ 0x05c2, 0x0622 },
{ 0x05c3, 0x0623 },
{ 0x05c4, 0x0624 },
{ 0x05c5, 0x0625 },
{ 0x05c6, 0x0626 },
{ 0x05c7, 0x0627 },
{ 0x05c8, 0x0628 },
{ 0x05c9, 0x0629 },
{ 0x05ca, 0x062a },
{ 0x05cb, 0x062b },
{ 0x05cc, 0x062c },
{ 0x05cd, 0x062d },
{ 0x05ce, 0x062e },
{ 0x05cf, 0x062f },
{ 0x05d0, 0x0630 },
{ 0x05d1, 0x0631 },
{ 0x05d2, 0x0632 },
{ 0x05d3, 0x0633 },
{ 0x05d4, 0x0634 },
{ 0x05d5, 0x0635 },
{ 0x05d6, 0x0636 },
{ 0x05d7, 0x0637 },
{ 0x05d8, 0x0638 },
{ 0x05d9, 0x0639 },
{ 0x05da, 0x063a },
{ 0x05e0, 0x0640 },
{ 0x05e1, 0x0641 },
{ 0x05e2, 0x0642 },
{ 0x05e3, 0x0643 },
{ 0x05e4, 0x0644 },
{ 0x05e5, 0x0645 },
{ 0x05e6, 0x0646 },
{ 0x05e7, 0x0647 },
{ 0x05e8, 0x0648 },
{ 0x05e9, 0x0649 },
{ 0x05ea, 0x064a },
{ 0x05eb, 0x064b },
{ 0x05ec, 0x064c },
{ 0x05ed, 0x064d },
{ 0x05ee, 0x064e },
{ 0x05ef, 0x064f },
{ 0x05f0, 0x0650 },
{ 0x05f1, 0x0651 },
{ 0x05f2, 0x0652 },
{ 0x06a1, 0x0452 },
{ 0x06a2, 0x0453 },
{ 0x06a3, 0x0451 },
{ 0x06a4, 0x0454 },
{ 0x06a5, 0x0455 },
{ 0x06a6, 0x0456 },
{ 0x06a7, 0x0457 },
{ 0x06a8, 0x0458 },
{ 0x06a9, 0x0459 },
{ 0x06aa, 0x045a },
{ 0x06ab, 0x045b },
{ 0x06ac, 0x045c },
{ 0x06ae, 0x045e },
{ 0x06af, 0x045f },
{ 0x06b0, 0x2116 },
{ 0x06b1, 0x0402 },
{ 0x06b2, 0x0403 },
{ 0x06b3, 0x0401 },
{ 0x06b4, 0x0404 },
{ 0x06b5, 0x0405 },
{ 0x06b6, 0x0406 },
{ 0x06b7, 0x0407 },
{ 0x06b8, 0x0408 },
{ 0x06b9, 0x0409 },
{ 0x06ba, 0x040a },
{ 0x06bb, 0x040b },
{ 0x06bc, 0x040c },
{ 0x06be, 0x040e },
{ 0x06bf, 0x040f },
{ 0x06c0, 0x044e },
{ 0x06c1, 0x0430 },
{ 0x06c2, 0x0431 },
{ 0x06c3, 0x0446 },
{ 0x06c4, 0x0434 },
{ 0x06c5, 0x0435 },
{ 0x06c6, 0x0444 },
{ 0x06c7, 0x0433 },
{ 0x06c8, 0x0445 },
{ 0x06c9, 0x0438 },
{ 0x06ca, 0x0439 },
{ 0x06cb, 0x043a },
{ 0x06cc, 0x043b },
{ 0x06cd, 0x043c },
{ 0x06ce, 0x043d },
{ 0x06cf, 0x043e },
{ 0x06d0, 0x043f },
{ 0x06d1, 0x044f },
{ 0x06d2, 0x0440 },
{ 0x06d3, 0x0441 },
{ 0x06d4, 0x0442 },
{ 0x06d5, 0x0443 },
{ 0x06d6, 0x0436 },
{ 0x06d7, 0x0432 },
{ 0x06d8, 0x044c },
{ 0x06d9, 0x044b },
{ 0x06da, 0x0437 },
{ 0x06db, 0x0448 },
{ 0x06dc, 0x044d },
{ 0x06dd, 0x0449 },
{ 0x06de, 0x0447 },
{ 0x06df, 0x044a },
{ 0x06e0, 0x042e },
{ 0x06e1, 0x0410 },
{ 0x06e2, 0x0411 },
{ 0x06e3, 0x0426 },
{ 0x06e4, 0x0414 },
{ 0x06e5, 0x0415 },
{ 0x06e6, 0x0424 },
{ 0x06e7, 0x0413 },
{ 0x06e8, 0x0425 },
{ 0x06e9, 0x0418 },
{ 0x06ea, 0x0419 },
{ 0x06eb, 0x041a },
{ 0x06ec, 0x041b },
{ 0x06ed, 0x041c },
{ 0x06ee, 0x041d },
{ 0x06ef, 0x041e },
{ 0x06f0, 0x041f },
{ 0x06f1, 0x042f },
{ 0x06f2, 0x0420 },
{ 0x06f3, 0x0421 },
{ 0x06f4, 0x0422 },
{ 0x06f5, 0x0423 },
{ 0x06f6, 0x0416 },
{ 0x06f7, 0x0412 },
{ 0x06f8, 0x042c },
{ 0x06f9, 0x042b },
{ 0x06fa, 0x0417 },
{ 0x06fb, 0x0428 },
{ 0x06fc, 0x042d },
{ 0x06fd, 0x0429 },
{ 0x06fe, 0x0427 },
{ 0x06ff, 0x042a },
{ 0x07a1, 0x0386 },
{ 0x07a2, 0x0388 },
{ 0x07a3, 0x0389 },
{ 0x07a4, 0x038a },
{ 0x07a5, 0x03aa },
{ 0x07a7, 0x038c },
{ 0x07a8, 0x038e },
{ 0x07a9, 0x03ab },
{ 0x07ab, 0x038f },
{ 0x07ae, 0x0385 },
{ 0x07af, 0x2015 },
{ 0x07b1, 0x03ac },
{ 0x07b2, 0x03ad },
{ 0x07b3, 0x03ae },
{ 0x07b4, 0x03af },
{ 0x07b5, 0x03ca },
{ 0x07b6, 0x0390 },
{ 0x07b7, 0x03cc },
{ 0x07b8, 0x03cd },
{ 0x07b9, 0x03cb },
{ 0x07ba, 0x03b0 },
{ 0x07bb, 0x03ce },
{ 0x07c1, 0x0391 },
{ 0x07c2, 0x0392 },
{ 0x07c3, 0x0393 },
{ 0x07c4, 0x0394 },
{ 0x07c5, 0x0395 },
{ 0x07c6, 0x0396 },
{ 0x07c7, 0x0397 },
{ 0x07c8, 0x0398 },
{ 0x07c9, 0x0399 },
{ 0x07ca, 0x039a },
{ 0x07cb, 0x039b },
{ 0x07cc, 0x039c },
{ 0x07cd, 0x039d },
{ 0x07ce, 0x039e },
{ 0x07cf, 0x039f },
{ 0x07d0, 0x03a0 },
{ 0x07d1, 0x03a1 },
{ 0x07d2, 0x03a3 },
{ 0x07d4, 0x03a4 },
{ 0x07d5, 0x03a5 },
{ 0x07d6, 0x03a6 },
{ 0x07d7, 0x03a7 },
{ 0x07d8, 0x03a8 },
{ 0x07d9, 0x03a9 },
{ 0x07e1, 0x03b1 },
{ 0x07e2, 0x03b2 },
{ 0x07e3, 0x03b3 },
{ 0x07e4, 0x03b4 },
{ 0x07e5, 0x03b5 },
{ 0x07e6, 0x03b6 },
{ 0x07e7, 0x03b7 },
{ 0x07e8, 0x03b8 },
{ 0x07e9, 0x03b9 },
{ 0x07ea, 0x03ba },
{ 0x07eb, 0x03bb },
{ 0x07ec, 0x03bc },
{ 0x07ed, 0x03bd },
{ 0x07ee, 0x03be },
{ 0x07ef, 0x03bf },
{ 0x07f0, 0x03c0 },
{ 0x07f1, 0x03c1 },
{ 0x07f2, 0x03c3 },
{ 0x07f3, 0x03c2 },
{ 0x07f4, 0x03c4 },
{ 0x07f5, 0x03c5 },
{ 0x07f6, 0x03c6 },
{ 0x07f7, 0x03c7 },
{ 0x07f8, 0x03c8 },
{ 0x07f9, 0x03c9 },
{ 0x08a1, 0x23b7 },
{ 0x08a2, 0x250c },
{ 0x08a3, 0x2500 },
{ 0x08a4, 0x2320 },
{ 0x08a5, 0x2321 },
{ 0x08a6, 0x2502 },
{ 0x08a7, 0x23a1 },
{ 0x08a8, 0x23a3 },
{ 0x08a9, 0x23a4 },
{ 0x08aa, 0x23a6 },
{ 0x08ab, 0x239b },
{ 0x08ac, 0x239d },
{ 0x08ad, 0x239e },
{ 0x08ae, 0x23a0 },
{ 0x08af, 0x23a8 },
{ 0x08b0, 0x23ac },
{ 0x08bc, 0x2264 },
{ 0x08bd, 0x2260 },
{ 0x08be, 0x2265 },
{ 0x08bf, 0x222b },
{ 0x08c0, 0x2234 },
{ 0x08c1, 0x221d },
{ 0x08c2, 0x221e },
{ 0x08c5, 0x2207 },
{ 0x08c8, 0x223c },
{ 0x08c9, 0x2243 },
{ 0x08cd, 0x21d4 },
{ 0x08ce, 0x21d2 },
{ 0x08cf, 0x2261 },
{ 0x08d6, 0x221a },
{ 0x08da, 0x2282 },
{ 0x08db, 0x2283 },
{ 0x08dc, 0x2229 },
{ 0x08dd, 0x222a },
{ 0x08de, 0x2227 },
{ 0x08df, 0x2228 },
{ 0x08ef, 0x2202 },
{ 0x08f6, 0x0192 },
{ 0x08fb, 0x2190 },
{ 0x08fc, 0x2191 },
{ 0x08fd, 0x2192 },
{ 0x08fe, 0x2193 },
{ 0x09e0, 0x25c6 },
{ 0x09e1, 0x2592 },
{ 0x09e2, 0x2409 },
{ 0x09e3, 0x240c },
{ 0x09e4, 0x240d },
{ 0x09e5, 0x240a },
{ 0x09e8, 0x2424 },
{ 0x09e9, 0x240b },
{ 0x09ea, 0x2518 },
{ 0x09eb, 0x2510 },
{ 0x09ec, 0x250c },
{ 0x09ed, 0x2514 },
{ 0x09ee, 0x253c },
{ 0x09ef, 0x23ba },
{ 0x09f0, 0x23bb },
{ 0x09f1, 0x2500 },
{ 0x09f2, 0x23bc },
{ 0x09f3, 0x23bd },
{ 0x09f4, 0x251c },
{ 0x09f5, 0x2524 },
{ 0x09f6, 0x2534 },
{ 0x09f7, 0x252c },
{ 0x09f8, 0x2502 },
{ 0x0aa1, 0x2003 },
{ 0x0aa2, 0x2002 },
{ 0x0aa3, 0x2004 },
{ 0x0aa4, 0x2005 },
{ 0x0aa5, 0x2007 },
{ 0x0aa6, 0x2008 },
{ 0x0aa7, 0x2009 },
{ 0x0aa8, 0x200a },
{ 0x0aa9, 0x2014 },
{ 0x0aaa, 0x2013 },
{ 0x0aae, 0x2026 },
{ 0x0aaf, 0x2025 },
{ 0x0ab0, 0x2153 },
{ 0x0ab1, 0x2154 },
{ 0x0ab2, 0x2155 },
{ 0x0ab3, 0x2156 },
{ 0x0ab4, 0x2157 },
{ 0x0ab5, 0x2158 },
{ 0x0ab6, 0x2159 },
{ 0x0ab7, 0x215a },
{ 0x0ab8, 0x2105 },
{ 0x0abb, 0x2012 },
{ 0x0abc, 0x2329 },
{ 0x0abe, 0x232a },
{ 0x0ac3, 0x215b },
{ 0x0ac4, 0x215c },
{ 0x0ac5, 0x215d },
{ 0x0ac6, 0x215e },
{ 0x0ac9, 0x2122 },
{ 0x0aca, 0x2613 },
{ 0x0acc, 0x25c1 },
{ 0x0acd, 0x25b7 },
{ 0x0ace, 0x25cb },
{ 0x0acf, 0x25af },
{ 0x0ad0, 0x2018 },
{ 0x0ad1, 0x2019 },
{ 0x0ad2, 0x201c },
{ 0x0ad3, 0x201d },
{ 0x0ad4, 0x211e },
{ 0x0ad6, 0x2032 },
{ 0x0ad7, 0x2033 },
{ 0x0ad9, 0x271d },
{ 0x0adb, 0x25ac },
{ 0x0adc, 0x25c0 },
{ 0x0add, 0x25b6 },
{ 0x0ade, 0x25cf },
{ 0x0adf, 0x25ae },
{ 0x0ae0, 0x25e6 },
{ 0x0ae1, 0x25ab },
{ 0x0ae2, 0x25ad },
{ 0x0ae3, 0x25b3 },
{ 0x0ae4, 0x25bd },
{ 0x0ae5, 0x2606 },
{ 0x0ae6, 0x2022 },
{ 0x0ae7, 0x25aa },
{ 0x0ae8, 0x25b2 },
{ 0x0ae9, 0x25bc },
{ 0x0aea, 0x261c },
{ 0x0aeb, 0x261e },
{ 0x0aec, 0x2663 },
{ 0x0aed, 0x2666 },
{ 0x0aee, 0x2665 },
{ 0x0af0, 0x2720 },
{ 0x0af1, 0x2020 },
{ 0x0af2, 0x2021 },
{ 0x0af3, 0x2713 },
{ 0x0af4, 0x2717 },
{ 0x0af5, 0x266f },
{ 0x0af6, 0x266d },
{ 0x0af7, 0x2642 },
{ 0x0af8, 0x2640 },
{ 0x0af9, 0x260e },
{ 0x0afa, 0x2315 },
{ 0x0afb, 0x2117 },
{ 0x0afc, 0x2038 },
{ 0x0afd, 0x201a },
{ 0x0afe, 0x201e },
{ 0x0ba3, 0x003c },
{ 0x0ba6, 0x003e },
{ 0x0ba8, 0x2228 },
{ 0x0ba9, 0x2227 },
{ 0x0bc0, 0x00af },
{ 0x0bc2, 0x22a5 },
{ 0x0bc3, 0x2229 },
{ 0x0bc4, 0x230a },
{ 0x0bc6, 0x005f },
{ 0x0bca, 0x2218 },
{ 0x0bcc, 0x2395 },
{ 0x0bce, 0x22a4 },
{ 0x0bcf, 0x25cb },
{ 0x0bd3, 0x2308 },
{ 0x0bd6, 0x222a },
{ 0x0bd8, 0x2283 },
{ 0x0bda, 0x2282 },
{ 0x0bdc, 0x22a2 },
{ 0x0bfc, 0x22a3 },
{ 0x0cdf, 0x2017 },
{ 0x0ce0, 0x05d0 },
{ 0x0ce1, 0x05d1 },
{ 0x0ce2, 0x05d2 },
{ 0x0ce3, 0x05d3 },
{ 0x0ce4, 0x05d4 },
{ 0x0ce5, 0x05d5 },
{ 0x0ce6, 0x05d6 },
{ 0x0ce7, 0x05d7 },
{ 0x0ce8, 0x05d8 },
{ 0x0ce9, 0x05d9 },
{ 0x0cea, 0x05da },
{ 0x0ceb, 0x05db },
{ 0x0cec, 0x05dc },
{ 0x0ced, 0x05dd },
{ 0x0cee, 0x05de },
{ 0x0cef, 0x05df },
{ 0x0cf0, 0x05e0 },
{ 0x0cf1, 0x05e1 },
{ 0x0cf2, 0x05e2 },
{ 0x0cf3, 0x05e3 },
{ 0x0cf4, 0x05e4 },
{ 0x0cf5, 0x05e5 },
{ 0x0cf6, 0x05e6 },
{ 0x0cf7, 0x05e7 },
{ 0x0cf8, 0x05e8 },
{ 0x0cf9, 0x05e9 },
{ 0x0cfa, 0x05ea },
{ 0x0da1, 0x0e01 },
{ 0x0da2, 0x0e02 },
{ 0x0da3, 0x0e03 },
{ 0x0da4, 0x0e04 },
{ 0x0da5, 0x0e05 },
{ 0x0da6, 0x0e06 },
{ 0x0da7, 0x0e07 },
{ 0x0da8, 0x0e08 },
{ 0x0da9, 0x0e09 },
{ 0x0daa, 0x0e0a },
{ 0x0dab, 0x0e0b },
{ 0x0dac, 0x0e0c },
{ 0x0dad, 0x0e0d },
{ 0x0dae, 0x0e0e },
{ 0x0daf, 0x0e0f },
{ 0x0db0, 0x0e10 },
{ 0x0db1, 0x0e11 },
{ 0x0db2, 0x0e12 },
{ 0x0db3, 0x0e13 },
{ 0x0db4, 0x0e14 },
{ 0x0db5, 0x0e15 },
{ 0x0db6, 0x0e16 },
{ 0x0db7, 0x0e17 },
{ 0x0db8, 0x0e18 },
{ 0x0db9, 0x0e19 },
{ 0x0dba, 0x0e1a },
{ 0x0dbb, 0x0e1b },
{ 0x0dbc, 0x0e1c },
{ 0x0dbd, 0x0e1d },
{ 0x0dbe, 0x0e1e },
{ 0x0dbf, 0x0e1f },
{ 0x0dc0, 0x0e20 },
{ 0x0dc1, 0x0e21 },
{ 0x0dc2, 0x0e22 },
{ 0x0dc3, 0x0e23 },
{ 0x0dc4, 0x0e24 },
{ 0x0dc5, 0x0e25 },
{ 0x0dc6, 0x0e26 },
{ 0x0dc7, 0x0e27 },
{ 0x0dc8, 0x0e28 },
{ 0x0dc9, 0x0e29 },
{ 0x0dca, 0x0e2a },
{ 0x0dcb, 0x0e2b },
{ 0x0dcc, 0x0e2c },
{ 0x0dcd, 0x0e2d },
{ 0x0dce, 0x0e2e },
{ 0x0dcf, 0x0e2f },
{ 0x0dd0, 0x0e30 },
{ 0x0dd1, 0x0e31 },
{ 0x0dd2, 0x0e32 },
{ 0x0dd3, 0x0e33 },
{ 0x0dd4, 0x0e34 },
{ 0x0dd5, 0x0e35 },
{ 0x0dd6, 0x0e36 },
{ 0x0dd7, 0x0e37 },
{ 0x0dd8, 0x0e38 },
{ 0x0dd9, 0x0e39 },
{ 0x0dda, 0x0e3a },
{ 0x0ddf, 0x0e3f },
{ 0x0de0, 0x0e40 },
{ 0x0de1, 0x0e41 },
{ 0x0de2, 0x0e42 },
{ 0x0de3, 0x0e43 },
{ 0x0de4, 0x0e44 },
{ 0x0de5, 0x0e45 },
{ 0x0de6, 0x0e46 },
{ 0x0de7, 0x0e47 },
{ 0x0de8, 0x0e48 },
{ 0x0de9, 0x0e49 },
{ 0x0dea, 0x0e4a },
{ 0x0deb, 0x0e4b },
{ 0x0dec, 0x0e4c },
{ 0x0ded, 0x0e4d },
{ 0x0df0, 0x0e50 },
{ 0x0df1, 0x0e51 },
{ 0x0df2, 0x0e52 },
{ 0x0df3, 0x0e53 },
{ 0x0df4, 0x0e54 },
{ 0x0df5, 0x0e55 },
{ 0x0df6, 0x0e56 },
{ 0x0df7, 0x0e57 },
{ 0x0df8, 0x0e58 },
{ 0x0df9, 0x0e59 },
{ 0x0ea1, 0x3131 },
{ 0x0ea2, 0x3132 },
{ 0x0ea3, 0x3133 },
{ 0x0ea4, 0x3134 },
{ 0x0ea5, 0x3135 },
{ 0x0ea6, 0x3136 },
{ 0x0ea7, 0x3137 },
{ 0x0ea8, 0x3138 },
{ 0x0ea9, 0x3139 },
{ 0x0eaa, 0x313a },
{ 0x0eab, 0x313b },
{ 0x0eac, 0x313c },
{ 0x0ead, 0x313d },
{ 0x0eae, 0x313e },
{ 0x0eaf, 0x313f },
{ 0x0eb0, 0x3140 },
{ 0x0eb1, 0x3141 },
{ 0x0eb2, 0x3142 },
{ 0x0eb3, 0x3143 },
{ 0x0eb4, 0x3144 },
{ 0x0eb5, 0x3145 },
{ 0x0eb6, 0x3146 },
{ 0x0eb7, 0x3147 },
{ 0x0eb8, 0x3148 },
{ 0x0eb9, 0x3149 },
{ 0x0eba, 0x314a },
{ 0x0ebb, 0x314b },
{ 0x0ebc, 0x314c },
{ 0x0ebd, 0x314d },
{ 0x0ebe, 0x314e },
{ 0x0ebf, 0x314f },
{ 0x0ec0, 0x3150 },
{ 0x0ec1, 0x3151 },
{ 0x0ec2, 0x3152 },
{ 0x0ec3, 0x3153 },
{ 0x0ec4, 0x3154 },
{ 0x0ec5, 0x3155 },
{ 0x0ec6, 0x3156 },
{ 0x0ec7, 0x3157 },
{ 0x0ec8, 0x3158 },
{ 0x0ec9, 0x3159 },
{ 0x0eca, 0x315a },
{ 0x0ecb, 0x315b },
{ 0x0ecc, 0x315c },
{ 0x0ecd, 0x315d },
{ 0x0ece, 0x315e },
{ 0x0ecf, 0x315f },
{ 0x0ed0, 0x3160 },
{ 0x0ed1, 0x3161 },
{ 0x0ed2, 0x3162 },
{ 0x0ed3, 0x3163 },
{ 0x0ed4, 0x11a8 },
{ 0x0ed5, 0x11a9 },
{ 0x0ed6, 0x11aa },
{ 0x0ed7, 0x11ab },
{ 0x0ed8, 0x11ac },
{ 0x0ed9, 0x11ad },
{ 0x0eda, 0x11ae },
{ 0x0edb, 0x11af },
{ 0x0edc, 0x11b0 },
{ 0x0edd, 0x11b1 },
{ 0x0ede, 0x11b2 },
{ 0x0edf, 0x11b3 },
{ 0x0ee0, 0x11b4 },
{ 0x0ee1, 0x11b5 },
{ 0x0ee2, 0x11b6 },
{ 0x0ee3, 0x11b7 },
{ 0x0ee4, 0x11b8 },
{ 0x0ee5, 0x11b9 },
{ 0x0ee6, 0x11ba },
{ 0x0ee7, 0x11bb },
{ 0x0ee8, 0x11bc },
{ 0x0ee9, 0x11bd },
{ 0x0eea, 0x11be },
{ 0x0eeb, 0x11bf },
{ 0x0eec, 0x11c0 },
{ 0x0eed, 0x11c1 },
{ 0x0eee, 0x11c2 },
{ 0x0eef, 0x316d },
{ 0x0ef0, 0x3171 },
{ 0x0ef1, 0x3178 },
{ 0x0ef2, 0x317f },
{ 0x0ef3, 0x3181 },
{ 0x0ef4, 0x3184 },
{ 0x0ef5, 0x3186 },
{ 0x0ef6, 0x318d },
{ 0x0ef7, 0x318e },
{ 0x0ef8, 0x11eb },
{ 0x0ef9, 0x11f0 },
{ 0x0efa, 0x11f9 },
{ 0x0eff, 0x20a9 },
#if 0
/* FIXME: there is no keysym 0x13a4? But 0x20ac is EuroSign in both
keysym and Unicode */
{ 0x13a4, 0x20ac },
#endif
{ 0x13bc, 0x0152 },
{ 0x13bd, 0x0153 },
{ 0x13be, 0x0178 },
{ 0x20ac, 0x20ac },
/* Special function keys. */
{ 0xff08, 0x0008 }, /* XK_BackSpace */
{ 0xff09, 0x0009 }, /* XK_Tab */
{ 0xff0a, 0x000a }, /* XK_Linefeed */
{ 0xff0d, 0x000d }, /* XK_Return */
{ 0xff13, 0x0013 }, /* XK_Pause */
{ 0xff1b, 0x001b }, /* XK_Escape */
{ 0xff50, 0x0001 }, /* XK_Home */
{ 0xff51, 0x001c }, /* XK_Left */
{ 0xff52, 0x001e }, /* XK_Up */
{ 0xff53, 0x001d }, /* XK_Right */
{ 0xff54, 0x001f }, /* XK_Down */
{ 0xff55, 0x000b }, /* XK_Prior */
{ 0xff56, 0x000c }, /* XK_Next */
{ 0xff57, 0x0004 }, /* XK_End */
{ 0xff6a, 0x0005 }, /* XK_Help */
{ 0xffff, 0x007f }, /* XK_Delete */
};
long keysym2ucs(int keysym)
{
int min = 0;
int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
int mid;
/* first check for Latin-1 characters (1:1 mapping) */
if ((keysym >= 0x0020 && keysym <= 0x007e) ||
(keysym >= 0x00a0 && keysym <= 0x00ff))
return keysym;
/* also check for directly encoded 24-bit UCS characters */
if ((keysym & 0xff000000) == 0x01000000)
return keysym & 0x00ffffff;
/* binary search in table */
while (max >= min) {
mid = (min + max) / 2;
if (keysymtab[mid].keysym < keysym)
min = mid + 1;
else if (keysymtab[mid].keysym > keysym)
max = mid - 1;
else {
/* found it */
return keysymtab[mid].ucs;
}
}
/* no matching Unicode value found */
return -1;
}
static int reverse_compare (const void *a, const void *b)
{
const struct codepair *ca = a, *cb = b;
return ca->ucs - cb->ucs;
}
int ucs2keysym(long ucs)
{
static struct codepair *reverse_keysymtab;
int min = 0;
int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
int mid;
if (reverse_keysymtab == NULL)
{
reverse_keysymtab = malloc (sizeof (keysymtab));
memcpy (reverse_keysymtab, keysymtab, sizeof (keysymtab));
qsort (reverse_keysymtab,
sizeof (keysymtab) / sizeof (struct codepair),
sizeof (struct codepair),
reverse_compare);
}
/* first check for Latin-1 characters (1:1 mapping) */
if ((ucs >= 0x0020 && ucs <= 0x007e) ||
(ucs >= 0x00a0 && ucs <= 0x00ff))
return ucs;
/* binary search in table */
while (max >= min) {
mid = (min + max) / 2;
if (reverse_keysymtab[mid].ucs < ucs)
min = mid + 1;
else if (reverse_keysymtab[mid].ucs > ucs)
max = mid - 1;
else {
/* found it */
return reverse_keysymtab[mid].keysym;
}
}
/* finally, assume a directly encoded 24-bit UCS character */
return ucs | 0x01000000;
}

View File

@ -0,0 +1,37 @@
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/keysym2ucs.h,v 1.1 2003/11/01 08:13:08 torrey Exp $
*
* This module converts keysym values into the corresponding ISO 10646
* (UCS, Unicode) values.
*
* The array keysymtab[] contains pairs of X11 keysym values for graphical
* characters and the corresponding Unicode value. The function
* keysym2ucs() maps a keysym onto a Unicode value using a binary search,
* therefore keysymtab[] must remain SORTED by keysym value.
*
* The keysym -> UTF-8 conversion will hopefully one day be provided
* by Xlib via XmbLookupString() and should ideally not have to be
* done in X applications. But we are not there yet.
*
* We allow to represent any UCS character in the range U-00000000 to
* U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.
* This admittedly does not cover the entire 31-bit space of UCS, but
* it does cover all of the characters up to U-10FFFF, which can be
* represented by UTF-16, and more, and it is very unlikely that higher
* UCS codes will ever be assigned by ISO. So to get Unicode character
* U+ABCD you can directly use keysym 0x0100abcd.
*
* Author: Markus G. Kuhn <mkuhn@acm.org>, University of Cambridge, April 2001
*
* Special thanks to Richard Verhoeven <river@win.tue.nl> for preparing
* an initial draft of the mapping table.
*
* This software is in the public domain. Share and enjoy!
*/
#ifndef KEYSYM2UCS_H
#define KEYSYM2UCS_H 1
extern long keysym2ucs(int keysym);
extern int ucs2keysym(long ucs);
#endif /* KEYSYM2UCS_H */

View File

@ -0,0 +1,380 @@
/*
quartzKeyboard.c
$Id$
Code to build a keymap using the Carbon Keyboard Layout API,
which is supported on Mac OS X 10.2 and newer.
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/quartzKeyboard.c,v 1.1 2003/11/01 08:13:08 torrey Exp $ */
#ifdef HAS_KL_API
#include "quartzCommon.h"
#include <CoreServices/CoreServices.h>
#include <Carbon/Carbon.h>
#include "darwinKeyboard.h"
#include "keysym.h"
#include "keysym2ucs.h"
#define HACK_MISSING 1
#define HACK_KEYPAD 1
enum {
MOD_COMMAND = 256,
MOD_SHIFT = 512,
MOD_OPTION = 2048,
MOD_CONTROL = 4096,
};
#define UKEYSYM(u) ((u) | 0x01000000)
/* Table of keycode->keysym mappings we use to fallback on for important
keys that are often not in the Unicode mapping. */
const static struct {
unsigned short keycode;
KeySym keysym;
} known_keys[] = {
{55, XK_Meta_L},
{56, XK_Shift_L},
{57, XK_Caps_Lock},
{58, XK_Alt_L},
{59, XK_Control_L},
{60, XK_Shift_R},
{61, XK_Alt_R},
{62, XK_Control_R},
{122, XK_F1},
{120, XK_F2},
{99, XK_F3},
{118, XK_F4},
{96, XK_F5},
{97, XK_F6},
{98, XK_F7},
{100, XK_F8},
{101, XK_F9},
{109, XK_F10},
{103, XK_F11},
{111, XK_F12},
{105, XK_F13},
{107, XK_F14},
{113, XK_F15},
};
/* Table of keycode->old,new-keysym mappings we use to fixup the numeric
keypad entries. */
const static struct {
unsigned short keycode;
KeySym normal, keypad;
} known_numeric_keys[] = {
{65, XK_period, XK_KP_Decimal},
{67, XK_asterisk, XK_KP_Multiply},
{69, XK_plus, XK_KP_Add},
{75, XK_slash, XK_KP_Divide},
{76, 0x01000003, XK_KP_Enter},
{78, XK_minus, XK_KP_Subtract},
{81, XK_equal, XK_KP_Equal},
{82, XK_0, XK_KP_0},
{83, XK_1, XK_KP_1},
{84, XK_2, XK_KP_2},
{85, XK_3, XK_KP_3},
{86, XK_4, XK_KP_4},
{87, XK_5, XK_KP_5},
{88, XK_6, XK_KP_6},
{89, XK_7, XK_KP_7},
{91, XK_8, XK_KP_8},
{92, XK_9, XK_KP_9},
};
/* Table mapping normal keysyms to their dead equivalents.
FIXME: all the unicode keysyms (apart from circumflex) were guessed. */
const static struct {
KeySym normal, dead;
} dead_keys[] = {
{XK_grave, XK_dead_grave},
{XK_acute, XK_dead_acute},
{XK_asciicircum, XK_dead_circumflex},
{UKEYSYM (0x2c6), XK_dead_circumflex}, /* MODIFIER LETTER CIRCUMFLEX ACCENT */
{XK_asciitilde, XK_dead_tilde},
{UKEYSYM (0x2dc), XK_dead_tilde}, /* SMALL TILDE */
{XK_macron, XK_dead_macron},
{XK_breve, XK_dead_breve},
{XK_abovedot, XK_dead_abovedot},
{XK_diaeresis, XK_dead_diaeresis},
{UKEYSYM (0x2da), XK_dead_abovering}, /* DOT ABOVE */
{XK_doubleacute, XK_dead_doubleacute},
{XK_caron, XK_dead_caron},
{XK_cedilla, XK_dead_cedilla},
{XK_ogonek, XK_dead_ogonek},
{UKEYSYM (0x269), XK_dead_iota}, /* LATIN SMALL LETTER IOTA */
{UKEYSYM (0x2ec), XK_dead_voiced_sound}, /* MODIFIER LETTER VOICING */
/* {XK_semivoiced_sound, XK_dead_semivoiced_sound}, */
{UKEYSYM (0x323), XK_dead_belowdot}, /* COMBINING DOT BELOW */
{UKEYSYM (0x309), XK_dead_hook}, /* COMBINING HOOK ABOVE */
{UKEYSYM (0x31b), XK_dead_horn}, /* COMBINING HORN */
};
unsigned int
DarwinSystemKeymapSeed (void)
{
static unsigned int seed;
static KeyboardLayoutRef last_key_layout;
KeyboardLayoutRef key_layout;
KLGetCurrentKeyboardLayout (&key_layout);
if (key_layout != last_key_layout)
seed++;
last_key_layout = key_layout;
return seed;
}
static inline UniChar
macroman2ucs (unsigned char c)
{
/* Precalculated table mapping MacRoman-128 to Unicode. Generated
by creating single element CFStringRefs then extracting the
first character. */
static const unsigned short table[128] = {
0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1,
0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8,
0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3,
0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc,
0x2020, 0xb0, 0xa2, 0xa3, 0xa7, 0x2022, 0xb6, 0xdf,
0xae, 0xa9, 0x2122, 0xb4, 0xa8, 0x2260, 0xc6, 0xd8,
0x221e, 0xb1, 0x2264, 0x2265, 0xa5, 0xb5, 0x2202, 0x2211,
0x220f, 0x3c0, 0x222b, 0xaa, 0xba, 0x3a9, 0xe6, 0xf8,
0xbf, 0xa1, 0xac, 0x221a, 0x192, 0x2248, 0x2206, 0xab,
0xbb, 0x2026, 0xa0, 0xc0, 0xc3, 0xd5, 0x152, 0x153,
0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0xf7, 0x25ca,
0xff, 0x178, 0x2044, 0x20ac, 0x2039, 0x203a, 0xfb01, 0xfb02,
0x2021, 0xb7, 0x201a, 0x201e, 0x2030, 0xc2, 0xca, 0xc1,
0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4,
0xf8ff, 0xd2, 0xda, 0xdb, 0xd9, 0x131, 0x2c6, 0x2dc,
0xaf, 0x2d8, 0x2d9, 0x2da, 0xb8, 0x2dd, 0x2db, 0x2c7,
};
if (c < 128)
return c;
else
return table[c - 128];
}
static KeySym
make_dead_key (KeySym in)
{
int i;
for (i = 0; i < sizeof (dead_keys) / sizeof (dead_keys[0]); i++)
{
if (dead_keys[i].normal == in)
return dead_keys[i].dead;
}
return in;
}
Bool
DarwinModeReadSystemKeymap (darwinKeyboardInfo *info)
{
KeyboardLayoutRef key_layout;
const void *chr_data;
int num_keycodes = NUM_KEYCODES;
UInt32 keyboard_type = 0;
int is_uchr, i, j;
OSStatus err;
KeySym *k;
KLGetCurrentKeyboardLayout (&key_layout);
KLGetKeyboardLayoutProperty (key_layout, kKLuchrData, &chr_data);
if (chr_data != NULL)
{
is_uchr = 1;
keyboard_type = LMGetKbdType ();
}
else
{
KLGetKeyboardLayoutProperty (key_layout, kKLKCHRData, &chr_data);
if (chr_data == NULL)
{
ErrorF ( "Couldn't get uchr or kchr resource\n");
return FALSE;
}
is_uchr = 0;
num_keycodes = 128;
}
/* Scan the keycode range for the Unicode character that each
key produces in the four shift states. Then convert that to
an X11 keysym (which may just the bit that says "this is
Unicode" if it can't find the real symbol.) */
for (i = 0; i < num_keycodes; i++)
{
static const int mods[4] = {0, MOD_SHIFT, MOD_OPTION,
MOD_OPTION | MOD_SHIFT};
k = info->keyMap + i * GLYPHS_PER_KEY;
for (j = 0; j < 4; j++)
{
if (is_uchr)
{
UniChar s[8];
UniCharCount len;
UInt32 dead_key_state, extra_dead;
dead_key_state = 0;
err = UCKeyTranslate (chr_data, i, kUCKeyActionDown,
mods[j] >> 8, keyboard_type, 0,
&dead_key_state, 8, &len, s);
if (err != noErr)
continue;
if (len == 0 && dead_key_state != 0)
{
/* Found a dead key. Work out which one it is, but
remembering that it's dead. */
extra_dead = 0;
err = UCKeyTranslate (chr_data, i, kUCKeyActionDown,
mods[j] >> 8, keyboard_type,
kUCKeyTranslateNoDeadKeysMask,
&extra_dead, 8, &len, s);
if (err != noErr)
continue;
}
if (len > 0 && s[0] != 0x0010)
{
k[j] = ucs2keysym (s[0]);
if (dead_key_state != 0)
k[j] = make_dead_key (k[j]);
}
}
else
{
UInt32 c, state = 0;
UInt16 code;
code = i | mods[j];
c = KeyTranslate (chr_data, code, &state);
/* Dead keys are only processed on key-down, so ask
to translate those events. When we find a dead key,
translating the matching key up event will give
us the actual dead character. */
if (state != 0)
{
UInt32 state2 = 0;
c = KeyTranslate (chr_data, code | 128, &state2);
}
/* Characters seem to be in MacRoman encoding. */
if (c != 0 && c != 0x0010)
{
k[j] = ucs2keysym (macroman2ucs (c & 255));
if (state != 0)
k[j] = make_dead_key (k[j]);
}
}
}
if (k[3] == k[2])
k[3] = NoSymbol;
if (k[2] == k[1])
k[2] = NoSymbol;
if (k[1] == k[0])
k[1] = NoSymbol;
if (k[0] == k[2] && k[1] == k[3])
k[2] = k[3] = NoSymbol;
}
/* Fix up some things that are normally missing.. */
if (HACK_MISSING)
{
for (i = 0; i < sizeof (known_keys) / sizeof (known_keys[0]); i++)
{
k = info->keyMap + known_keys[i].keycode * GLYPHS_PER_KEY;
if (k[0] == NoSymbol && k[1] == NoSymbol
&& k[2] == NoSymbol && k[3] == NoSymbol)
{
k[0] = known_keys[i].keysym;
}
}
}
/* And some more things. We find the right symbols for the numeric
keypad, but not the KP_ keysyms. So try to convert known keycodes. */
if (HACK_KEYPAD)
{
for (i = 0; i < sizeof (known_numeric_keys)
/ sizeof (known_numeric_keys[0]); i++)
{
k = info->keyMap + known_numeric_keys[i].keycode * GLYPHS_PER_KEY;
if (k[0] == known_numeric_keys[i].normal)
{
k[0] = known_numeric_keys[i].keypad;
}
}
}
return TRUE;
}
#else /* !HAS_KL_API */
Bool
DarwinModeReadSystemKeymap (darwinKeyboardInfo *info)
{
return FALSE;
}
#endif /* HAS_KL_API */

View File

@ -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 */

View File

@ -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;
}
}

690
hw/darwin/quartz/xpr/dri.c Normal file
View File

@ -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);
}
}

130
hw/darwin/quartz/xpr/dri.h Normal file
View File

@ -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

View File

@ -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 */

View File

@ -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);
}
}
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -0,0 +1,354 @@
/* $DHD: xc/programs/Xserver/hw/xfree86/common/xf86AutoConfig.c,v 1.15 2003/09/24 19:39:36 dawes Exp $ */
/*
* Copyright 2003 by David H. Dawes.
* Copyright 2003 by X-Oz Technologies.
* 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 COPYRIGHT HOLDER(S) OR AUTHOR(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 of the copyright holder(s)
* and author(s) shall not be used in advertising or otherwise to promote
* the sale, use or other dealings in this Software without prior written
* authorization from the copyright holder(s) and author(s).
*
* Author: David Dawes <dawes@XFree86.Org>.
*/
/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86AutoConfig.c,v 1.2 2003/11/03 05:11:01 tsi Exp $ */
#include "xf86.h"
#include "xf86Parser.h"
#include "xf86tokens.h"
#include "xf86Config.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
/*
* Sections for the default built-in configuration.
*/
#define BUILTIN_MODULE_SECTION \
"Section \"Module\"\n" \
"\tLoad\t\"extmod\"\n" \
"\tLoad\t\"dbe\"\n" \
"\tLoad\t\"glx\"\n" \
"\tLoad\t\"freetype\"\n" \
"EndSection\n\n"
#define BUILTIN_DEVICE_NAME \
"\"Builtin Default %s Device %d\""
#define BUILTIN_DEVICE_SECTION_PRE \
"Section \"Device\"\n" \
"\tIdentifier\t" BUILTIN_DEVICE_NAME "\n" \
"\tDriver\t\"%s\"\n"
#define BUILTIN_DEVICE_SECTION_POST \
"EndSection\n\n"
#define BUILTIN_DEVICE_SECTION \
BUILTIN_DEVICE_SECTION_PRE \
BUILTIN_DEVICE_SECTION_POST
#define BUILTIN_MONITOR_NAME \
"\"Builtin Default Monitor\""
#define BUILTIN_MONITOR_SECTION \
"Section \"Monitor\"\n" \
"\tIdentifier\t" BUILTIN_MONITOR_NAME "\n" \
"\tOption\t\"TargetRefresh\"\t\"75.0\"\n" \
"EndSection\n\n"
#define BUILTIN_SCREEN_NAME \
"\"Builtin Default %s Screen %d\""
#define BUILTIN_SCREEN_SECTION \
"Section \"Screen\"\n" \
"\tIdentifier\t" BUILTIN_SCREEN_NAME "\n" \
"\tDevice\t" BUILTIN_DEVICE_NAME "\n" \
"\tMonitor\t" BUILTIN_MONITOR_NAME "\n" \
"EndSection\n\n"
#define BUILTIN_LAYOUT_SECTION_PRE \
"Section \"ServerLayout\"\n" \
"\tIdentifier\t\"Builtin Default Layout\"\n"
#define BUILTIN_LAYOUT_SCREEN_LINE \
"\tScreen\t" BUILTIN_SCREEN_NAME "\n"
#define BUILTIN_LAYOUT_SECTION_POST \
"EndSection\n\n"
#ifndef GET_CONFIG_CMD
#define GET_CONFIG_CMD "getconfig"
#endif
#ifndef GETCONFIG_DIR
#define GETCONFIG_DIR PROJECTROOT "/lib/X11/getconfig"
#endif
#define GETCONFIG_WHITESPACE " \t\n"
static const char **builtinConfig = NULL;
static int builtinLines = 0;
static const char *deviceList[] = {
"fbdev",
"vesa",
"vga",
NULL
};
/*
* A built-in config file is stored as an array of strings, with each string
* representing a single line. AppendToConfig() breaks up the string "s"
* into lines, and appends those lines it to builtinConfig.
*/
static void
AppendToList(const char *s, const char ***list, int *lines)
{
char *str, *newstr, *p;
str = xnfstrdup(s);
for (p = strtok(str, "\n"); p; p = strtok(NULL, "\n")) {
(*lines)++;
*list = xnfrealloc(*list, (*lines + 1) * sizeof(**list));
newstr = xnfalloc(strlen(p) + 2);
strcpy(newstr, p);
strcat(newstr, "\n");
(*list)[*lines - 1] = newstr;
(*list)[*lines] = NULL;
}
xfree(str);
}
static void
FreeList(const char ***list, int *lines)
{
int i;
for (i = 0; i < *lines; i++) {
if ((*list)[i])
xfree((*list)[i]);
}
xfree(*list);
*list = NULL;
*lines = 0;
}
static void
FreeConfig(void)
{
FreeList(&builtinConfig, &builtinLines);
}
static void
AppendToConfig(const char *s)
{
AppendToList(s, &builtinConfig, &builtinLines);
}
Bool
xf86AutoConfig(void)
{
const char **p;
char buf[1024];
pciVideoPtr *pciptr, info = NULL;
char *driver = NULL;
FILE *gp = NULL;
ConfigStatus ret;
/* Find the primary device, and get some information about it. */
if (xf86PciVideoInfo) {
for (pciptr = xf86PciVideoInfo; (info = *pciptr); pciptr++) {
if (xf86IsPrimaryPci(info)) {
break;
}
}
if (!info) {
ErrorF("Primary device is not PCI\n");
}
} else {
ErrorF("xf86PciVideoInfo is not set\n");
}
if (info) {
char *tmp;
char *path = NULL, *a, *b;
char *searchPath = NULL;
/*
* Look for the getconfig program first in the xf86ModulePath
* directories, then in BINDIR. If it isn't found in any of those
* locations, just use the normal search path.
*/
if (xf86ModulePath) {
a = xnfstrdup(xf86ModulePath);
b = strtok(a, ",");
while (b) {
path = xnfrealloc(path,
strlen(b) + 1 + strlen(GET_CONFIG_CMD) + 1);
sprintf(path, "%s/%s", b, GET_CONFIG_CMD);
if (access(path, X_OK) == 0)
break;
b = strtok(NULL, ",");
}
if (!b) {
xfree(path);
path = NULL;
}
xfree(a);
}
#ifdef BINDIR
if (!path) {
path = xnfstrdup(BINDIR "/" GET_CONFIG_CMD);
if (access(path, X_OK) != 0) {
xfree(path);
path = NULL;
}
}
#endif
if (!path)
path = xnfstrdup(GET_CONFIG_CMD);
/*
* Build up the config file directory search path:
*
* /etc/X11
* PROJECTROOT/etc/X11
* xf86ModulePath
* PROJECTROOT/lib/X11/getconfig (GETCONFIG_DIR)
*/
searchPath = xnfalloc(strlen("/etc/X11") + 1 +
strlen(PROJECTROOT "/etc/X11") + 1 +
(xf86ModulePath ? strlen(xf86ModulePath) : 0)
+ 1 +
strlen(GETCONFIG_DIR) + 1);
strcpy(searchPath, "/etc/X11," PROJECTROOT "/etc/X11,");
if (xf86ModulePath && *xf86ModulePath) {
strcat(searchPath, xf86ModulePath);
strcat(searchPath, ",");
}
strcat(searchPath, GETCONFIG_DIR);
ErrorF("xf86AutoConfig: Primary PCI is %d:%d:%d\n",
info->bus, info->device, info->func);
snprintf(buf, sizeof(buf), "%s"
#ifdef DEBUG
" -D"
#endif
" -X %d"
" -I %s"
" -v 0x%04x -d 0x%04x -r 0x%02x -s 0x%04x"
" -b 0x%04x -c 0x%04x",
path,
(unsigned int)xf86GetVersion(),
searchPath,
info->vendor, info->chipType, info->chipRev,
info->subsysVendor, info->subsysCard,
info->class << 8 | info->subclass);
ErrorF("Running \"%s\"\n", buf);
gp = Popen(buf, "r");
if (gp) {
if (fgets(buf, sizeof(buf) - 1, gp)) {
buf[strlen(buf) - 1] = '\0';
tmp = strtok(buf, GETCONFIG_WHITESPACE);
if (tmp)
driver = xnfstrdup(tmp);
}
}
xfree(path);
xfree(searchPath);
}
AppendToConfig(BUILTIN_MODULE_SECTION);
AppendToConfig(BUILTIN_MONITOR_SECTION);
if (driver) {
snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION_PRE,
driver, 0, driver);
AppendToConfig(buf);
ErrorF("New driver is \"%s\"\n", driver);
buf[0] = '\t';
while (fgets(buf + 1, sizeof(buf) - 2, gp)) {
AppendToConfig(buf);
ErrorF("Extra line: %s", buf);
}
AppendToConfig(BUILTIN_DEVICE_SECTION_POST);
snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION,
driver, 0, driver, 0);
AppendToConfig(buf);
}
if (gp)
Pclose(gp);
for (p = deviceList; *p; p++) {
snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION, *p, 0, *p);
AppendToConfig(buf);
snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION, *p, 0, *p, 0);
AppendToConfig(buf);
}
AppendToConfig(BUILTIN_LAYOUT_SECTION_PRE);
if (driver) {
snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE, driver, 0);
AppendToConfig(buf);
}
for (p = deviceList; *p; p++) {
snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE, *p, 0);
AppendToConfig(buf);
}
AppendToConfig(BUILTIN_LAYOUT_SECTION_POST);
#ifdef BUILTIN_EXTRA
AppendToConfig(BUILTIN_EXTRA);
#endif
if (driver)
xfree(driver);
xf86MsgVerb(X_DEFAULT, 0,
"Using default built-in configuration (%d lines)\n",
builtinLines);
xf86MsgVerb(X_DEFAULT, 3, "--- Start of built-in configuration ---\n");
for (p = builtinConfig; *p; p++)
xf86ErrorFVerb(3, "\t%s", *p);
xf86MsgVerb(X_DEFAULT, 3, "--- End of built-in configuration ---\n");
xf86setBuiltinConfig(builtinConfig);
ret = xf86HandleConfigFile(TRUE);
FreeConfig();
switch(ret) {
case CONFIG_OK:
return TRUE;
default:
xf86Msg(X_ERROR, "Error parsing the built-in default configuration.\n");
return FALSE;
}
}

View File

@ -0,0 +1,77 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Versions.c,v 1.2 2003/08/24 20:01:19 dawes Exp $ */
/*
* Copyright (c) 2003 by The XFree86 Project, Inc.
*
* 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 COPYRIGHT HOLDER(S) OR AUTHOR(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 of the copyright holder(s)
* and author(s) shall not be used in advertising or otherwise to promote
* the sale, use or other dealings in this Software without prior written
* authorization from the copyright holder(s) and author(s).
*/
#include "xf86.h"
#include "xf86OSmouse.h"
#include "xf86OSKbd.h"
static CARD32 registeredVersions[NUM_BUILTIN_IFS];
CARD32
xf86GetBuiltinInterfaceVersion(BuiltinInterface iface, int flags)
{
if (iface < 0 || iface >= NUM_BUILTIN_IFS) {
xf86Msg(X_ERROR, "xf86GetBuiltinInterfaceVersion: Unexpected interface"
"query: %d\n", iface);
return 0;
}
if (registeredVersions[iface])
return registeredVersions[iface];
/* Most built-in interfaces are handled this way. */
switch (iface) {
case BUILTIN_IF_OSMOUSE:
return OS_MOUSE_VERSION_CURRENT;
case BUILTIN_IF_OSKBD:
return OS_KBD_VERSION_CURRENT;
default:
xf86Msg(X_ERROR, "xf86GetBuiltinInterfaceVersion: internal error: "
"interface %d not handled\n", iface);
return 0;
}
}
Bool
xf86RegisterBuiltinInterfaceVersion(BuiltinInterface iface, CARD32 version,
int flags)
{
if (iface < 0 || iface >= NUM_BUILTIN_IFS) {
xf86Msg(X_ERROR, "xf86RegisterBuiltinInterfaceVersion: "
"unexpected interface number: %d\n", iface);
return FALSE;
}
if (version == 0) {
xf86Msg(X_ERROR, "xf86RegisterBuiltinInterfaceVersion: "
"versions must be greater than zero\n");
return FALSE;
}
registeredVersions[iface] = version;
return TRUE;
}

View File

@ -0,0 +1,86 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86xvpriv.h,v 1.2 2003/08/24 17:36:56 dawes Exp $ */
/*
* Copyright (c) 2003 by The XFree86 Project, Inc.
*
* 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 COPYRIGHT HOLDER(S) OR AUTHOR(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 of the copyright holder(s)
* and author(s) shall not be used in advertising or otherwise to promote
* the sale, use or other dealings in this Software without prior written
* authorization from the copyright holder(s) and author(s).
*/
#ifndef _XF86XVPRIV_H_
#define _XF86XVPRIV_H_
#include "xf86xv.h"
/*** These are DDX layer privates ***/
extern int XF86XvScreenIndex;
typedef struct {
DestroyWindowProcPtr DestroyWindow;
ClipNotifyProcPtr ClipNotify;
WindowExposuresProcPtr WindowExposures;
void (*AdjustFrame)(int, int, int, int);
Bool (*EnterVT)(int, int);
void (*LeaveVT)(int, int);
GCPtr videoGC;
} XF86XVScreenRec, *XF86XVScreenPtr;
typedef struct {
int flags;
PutVideoFuncPtr PutVideo;
PutStillFuncPtr PutStill;
GetVideoFuncPtr GetVideo;
GetStillFuncPtr GetStill;
StopVideoFuncPtr StopVideo;
SetPortAttributeFuncPtr SetPortAttribute;
GetPortAttributeFuncPtr GetPortAttribute;
QueryBestSizeFuncPtr QueryBestSize;
PutImageFuncPtr PutImage;
ReputImageFuncPtr ReputImage;
QueryImageAttributesFuncPtr QueryImageAttributes;
} XvAdaptorRecPrivate, *XvAdaptorRecPrivatePtr;
typedef struct {
ScrnInfoPtr pScrn;
DrawablePtr pDraw;
unsigned char type;
unsigned int subWindowMode;
DDXPointRec clipOrg;
RegionPtr clientClip;
RegionPtr pCompositeClip;
Bool FreeCompositeClip;
XvAdaptorRecPrivatePtr AdaptorRec;
XvStatus isOn;
Bool moved;
int vid_x, vid_y, vid_w, vid_h;
int drw_x, drw_y, drw_w, drw_h;
DevUnion DevPriv;
} XvPortRecPrivate, *XvPortRecPrivatePtr;
typedef struct _XF86XVWindowRec{
XvPortRecPrivatePtr PortRec;
struct _XF86XVWindowRec *next;
} XF86XVWindowRec, *XF86XVWindowPtr;
#endif /* _XF86XVPRIV_H_ */

View File

@ -0,0 +1,144 @@
/* $XFree86: xc/programs/Xserver/Xext/extmod/modinit.h,v 1.2 2003/09/13 21:33:04 dawes Exp $ */
#ifndef INITARGS
#define INITARGS void
#endif
#ifdef SHAPE
extern void ShapeExtensionInit(INITARGS);
#define _SHAPE_SERVER_ /* don't want Xlib structures */
#include "shapestr.h"
#endif
#ifdef MULTIBUFFER
extern void MultibufferExtensionInit(INITARGS);
#define _MULTIBUF_SERVER_ /* don't want Xlib structures */
#include "multibufst.h"
#endif
#ifdef MITMISC
extern void MITMiscExtensionInit(INITARGS);
#define _MITMISC_SERVER_
#include "mitmiscstr.h"
#endif
#ifdef XTEST
extern void XTestExtensionInit(INITARGS);
#define _XTEST_SERVER_
#include "XTest.h"
#include "xteststr.h"
#endif
#if 1
extern void XTestExtension1Init(INITARGS);
#endif
#ifdef BIGREQS
extern void BigReqExtensionInit(INITARGS);
#include "bigreqstr.h"
#endif
#ifdef XSYNC
extern void SyncExtensionInit(INITARGS);
#define _SYNC_SERVER
#include "sync.h"
#include "syncstr.h"
#endif
#ifdef SCREENSAVER
extern void ScreenSaverExtensionInit (INITARGS);
#include "saver.h"
#endif
#ifdef XCMISC
extern void XCMiscExtensionInit(INITARGS);
#include "xcmiscstr.h"
#endif
#ifdef XF86VIDMODE
extern void XFree86VidModeExtensionInit(INITARGS);
#define _XF86VIDMODE_SERVER_
#include "xf86vmstr.h"
#endif
#ifdef XF86MISC
extern void XFree86MiscExtensionInit(INITARGS);
#define _XF86MISC_SERVER_
#define _XF86MISC_SAVER_COMPAT_
#include "xf86mscstr.h"
#endif
#ifdef XFreeXDGA
extern void XFree86DGAExtensionInit(INITARGS);
extern void XFree86DGARegister(INITARGS);
#define _XF86DGA_SERVER_
#include "xf86dgastr.h"
#endif
#ifdef DPMSExtension
extern void DPMSExtensionInit(INITARGS);
#include "dpmsstr.h"
#endif
#ifdef FONTCACHE
extern void FontCacheExtensionInit(INITARGS);
#define _FONTCACHE_SERVER_
#include "fontcacheP.h"
#include "fontcachstr.h"
#endif
#ifdef TOGCUP
extern void XcupExtensionInit(INITARGS);
#define _XCUP_SERVER_
#include "Xcupstr.h"
#endif
#ifdef EVI
extern void EVIExtensionInit(INITARGS);
#define _XEVI_SERVER_
#include "XEVIstr.h"
#endif
#ifdef XV
extern void XvExtensionInit(INITARGS);
extern void XvMCExtensionInit(INITARGS);
extern void XvRegister(INITARGS);
#include "Xv.h"
#include "XvMC.h"
#endif
#ifdef RES
extern void ResExtensionInit(INITARGS);
#include "XResproto.h"
#endif
#ifdef SHM
extern void ShmExtensionInit(INITARGS);
#include "shmstr.h"
extern void ShmSetPixmapFormat(
ScreenPtr pScreen,
int format);
extern void ShmRegisterFuncs(
ScreenPtr pScreen,
ShmFuncsPtr funcs);
#endif
#if 1
extern void SecurityExtensionInit(INITARGS);
#endif
#if 1
extern void XagExtensionInit(INITARGS);
#endif
#if 1
extern void XpExtensionInit(INITARGS);
#endif
#if 1
extern void PanoramiXExtensionInit(int argc, char *argv[]);
#endif
#if 1
extern void XkbExtensionInit(INITARGS);
#endif

View File

@ -0,0 +1,8 @@
/* $XFree86: xc/programs/Xserver/Xext/xf86dgaext.h,v 1.1 2003/07/16 01:38:30 dawes Exp $ */
#ifndef _XF86DGAEXT_H_
#define _XF86DGAEXT_H_
extern DISPATCH_PROC(ProcXF86DGADispatch);
#endif /* _XF86DGAEXT_H_ */

View File

@ -0,0 +1,18 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/dummylib/logvwrite.c,v 1.1 2003/09/09 03:20:38 dawes Exp $ */
#include "X.h"
#include "os.h"
#include "xf86.h"
#include "xf86Priv.h"
/*
* Utility functions required by libxf86_os.
*/
void
LogVWrite(int verb, const char *format, va_list ap)
{
if (xf86Verbose >= verb)
vfprintf(stderr, format, ap);
}

View File

@ -0,0 +1,138 @@
.\" $XFree86: xc/programs/Xserver/hw/xfree86/getconfig/cfg.man,v 1.1 2003/11/12 04:52:15 dawes Exp $
.TH getconfig __filemansuffix__ __vendorversion__
.SH NAME
getconfig - meta configuration files for getconfig(1)
.SH SYNOPSIS
.B \(**.cfg
.SH DESCRIPTION
.B getconfig
is a programatic interface that is used by the
.B XFree86
server to get configuration information about video hardware when
operating without an
.B XF86Config
file.
.PP
This implementation of
.B getconfig
is written in perl. It processes rules from meta-configuration files.
All meta-configuration files have a
.I .cfg
suffix.
.PP
Lines starting with a pound-sign (#) are comments, and are ignored.
Blank lines that consist only of white space are also treated as comments
and ignored.
.PP
The first non-comment line must be a signature string followed by
the file format version number. The signature string is
.PP
.RS 4
.nf
"XFree86 Project getconfig rules file.\ \ Version: "
.fi
.RE
.PP
The currently defined version is "1.0". Files that do not have the
correct signature string are ignored.
.PP
The remaining non-comment lines define rules. The start of a new rule
is indicated by a line with no leading white space. Subsequent lines
making up a rule must be indented with white space. Logical lines within
a rule may be split over multiple physical lines by using the usual
continuation convention ('\e' at the end of the line). The first logical
line of each rule is a perl expression. It may be any valid perl
expression whose evaluated (with 'eval') result may be used as the
argument to a perl 'if' statement. The second logical line should be
the name of the XFree86 video driver to use when the rule is true, and
subsequent logical lines of each rule, if present, are additional
configuration output for the video device's
.B XF86Config
.B Device
section. The driver name and additional lines of configuration information
are written to standard output when the rule is chosen as the successful
rule.
.PP
Pseudo rules consisting of perl expressions may be present in the file
for the purpose of defining custom perl variables or setting the weight
to use for the following rules. Pseudo rules are rules that consist of
a single logical line only, and the are never candidates themselves for the
successful rule.
.PP
Several perl variables are pre-defined, and may be used within rules.
They include:
.PP
.RS 4
.nf
.BR "$vendor " "PCI vendor ID"
.BR "$device " "PCI device ID"
.BR "$revision " "PCI revision ID"
.BR "$subsys " "PCI subsystem ID"
.BR "$subsysVendor " "PCI subsystem vendor ID"
.BR "$class " "PCI class"
.BR "$XFree86Version " "XFree86 version, as a 'v' string"
.BR "$XFree86VersionNumeric " "XFree86 numeric version"
.BR "$XFree86VersionMajor " "XFree86 major version"
.BR "$XFree86VersionMinor " "XFree86 minor version"
.BR "$XFree86VersionPatch " "XFree86 patch version"
.BR "$XFree86VersionSnap " "XFree86 snap version"
.BR "$weight " "current rule weight"
.fi
.RE
.PP
The
.B $weight
variable deterines the weight of the rules as they are processed. The
weight for subsequent rules may be set with a pseudo rule that sets or
changes the value of
.BR $weight .
The default weight, and the weight used for built-in rules is 500. The
meta-configuration files are processed in an unpredictable order. The
weighting of the rules is used to determine their relative priority
.PP
After processing all of the rules, both built-in and those read from
the meta-configration files, the
.B getconfig
program chooses as the successful rule the last and highest weighted
rule that evaluates to true.
.SH FILES
.I .cfg
files located in the search path. The search path typically specified
by the
.B XFree86
server is:
.PP
.RS 4
.nf
.I /etc/X11
.I __projectroot__/etc/X11
.I <modulepath>
.I __projectroot__/lib/X11/getconfig
.fi
.RE
.PP
where
.I <modulepath>
is the
.B XFree86
server's module search path.
.PP
.TP 30
.I __projectroot__/lib/X11/getconfig/xfree86.cfg
Default rules file that gets installed. This file doesn't contain any
rules by default.
.TP 30
.I __projectroot__/lib/X11/getconfig/cfg.sample
A sample rules file that gives some examples of what types of rules can
appear in rules files.
.SH "SEE ALSO"
getconfig(1),
XFree86(1),
XF86Config(__filemansuffix__).
.SH AUTHORS
The XFree86 automatic configuration support and the
.B getconfig
interface was written by David H. Dawes, with the support of X-Oz
Technologies.

View File

@ -0,0 +1,111 @@
# $DHD: xc/programs/Xserver/hw/xfree86/getconfig/cfg.sample,v 1.2 2003/09/23 05:12:07 dawes Exp $
# $XFree86: xc/programs/Xserver/hw/xfree86/getconfig/cfg.sample,v 1.2 2003/11/12 04:52:15 dawes Exp $
# Some sample XFree86 getconfig rules file.
#
# The line below is the getconfig rules file signature, and must be the
# first non-blank, non-comment line.
#
XFree86 Project getconfig rules file. Version: 1.0
#
# Set the weight for the following rules. This should be set, otherwise
# the previously set weight will get used, and you have no idea of knowing
# what that might be.
#
$weight = 1000
#
# Rules. Rules consist of a condition (in perl code) followed by
# a driver name and optionally some additional strings. The start of a
# rule is indicated by a line with no leading white space. Subsequent
# lines making up a rule must be indented. Logical lines may be split
# over multiple physical lines by using the usual continuation '\'.
#
# Rules that are not followed by a driver name may be used to do other
# things, like setting the weight as above.
#
#
# Pre-defined variables include:
#
# $vendor PCI vendor ID
# $device PCI device ID
# $revision PCI revision ID
# $subsys PCI subsystem ID
# $subsysVendor PCI subsystem vendor ID
# $class PCI class
# $XFree86Version XFree86 version, as a 'v' string.
#
# The XFree86 version information is also available as the following:
#
# $XFree86VersionNumeric
# $XFree86VersionMajor
# $XFree86VersionMinor
# $XFree86VersionPatch
# $XFree86VersionSnap
#
# Define a fake vendor ID for some sample rules.
$novendor = 0x10000
$nodevice = 0x10000
$vendor == $novendor
nodriver
Option "xx"
Videoram 1000
# A rule with continued lines.
$vendor == $novendor && \
$device == $nodevice
nodriver2
Option \
"yy"
# Increase the weight of the following rules if the XFree86 version is 4.3 or
# higher.
$weight++ if ($XFree86Version ge v4.3)
$vendor == $novendor
nodriver
Option "yy"
#
# The weight can be changed at any times, and applies to rules that follow
# until changed again.
#
$weight = 100
$vendor == $novendor && $XFree86Version eq v4.3.2.1
nodriver3
$weight = 600
#
# The following two examples use some real values.
#
# Example: make the default depth 24 for Radeon R200 and RV200 cards.
$vendor == 0x1002 && \
($device >= 0x5148 && $device <= 0x514F || \
$device >= 0x5168 && $device <= 0x516C || \
$device == 0x4242 || \
$device >= 0x5157 && device <= 0x5158)
ati
Option "DefaultDepth" "24"
# Example: enable DRI for MGA G400
$vendor == 0x102b && $device == 0x0525
mga
Option "dri"

View File

@ -0,0 +1,45 @@
#!/bin/sh
# $DHD: xc/programs/Xserver/hw/xfree86/getconfig/getconfig.sh,v 1.2 2003/09/20 01:45:57 dawes Exp $
#
# Copyright 2003 by David H. Dawes.
# Copyright 2003 by X-Oz Technologies.
# 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 COPYRIGHT HOLDER(S) OR AUTHOR(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 of the copyright holder(s)
# and author(s) shall not be used in advertising or otherwise to promote
# the sale, use or other dealings in this Software without prior written
# authorization from the copyright holder(s) and author(s).
#
# Author: David Dawes <dawes@XFree86.Org>.
#
# $XFree86: xc/programs/Xserver/hw/xfree86/getconfig/getconfig.sh,v 1.1 2003/10/08 14:58:29 dawes Exp $
# A simple wrapper to execute the real getconfig program. So long as perl
# is in $PATH, we don't need to know where it is this way.
if echo $0 | grep / >/dev/null 2>&1; then
DIR=`dirname $0`/
fi
exec perl ${DIR}getconfig.pl "$@"

View File

@ -0,0 +1,98 @@
.\" $XFree86: xc/programs/Xserver/hw/xfree86/getconfig/getconfig.man,v 1.1 2003/11/12 04:52:15 dawes Exp $
.TH getconfig 1 __vendorversion__
.SH NAME
getconfig - get configuration information for the XFree86 server
.SH SYNOPSIS
.B getconfig
.RI [ option
.IR ... ]
.SH DESCRIPTION
.B getconfig
is a programatic interface that is used by the
.B XFree86
server to get configuration information about video hardware when
operating without an
.B XF86Config
file.
.PP
This implementation of
.B getconfig
is written in perl. It processes a prioritized and ordered list of
rules supplied internally and from meta-configuration files. The rules
are in the form of perl expressions.
.B getconfig
writes to standard output the XF86Config-style configuration data
specified by the last highest priority rule that evaluates to true.
Information about the format of the meta-configuration files can be
found in the getconfig(__filemansuffix__) manual page.
.SH OPTIONS
.TP 8
.BI \-I " search-path"
Specify the search path to use for meta-config files.
.I search-path
is a comma-separated list of directories to search. Each directory in
the search path is searched for files with a
.I .cfg
suffix. Each such file is opened and checked for a valid signature
string. Rules are read from files with a valid signature string and
appended to the list of rules to evaluate. If no search path is specified,
only the internally supplied configuration rules will be used.
.TP 8
.B \-D
Enable debugging output.
.TP 8
.B \-V
Print out the version information and exit.
.TP 8
.BI \-X " XFree86-version"
Specify the XFree86 version in numeric (integer) form.
.TP 8
.BI \-b " subsys-id"
Specify the PCI subsystem ID of the video device.
.TP 8
.BI \-c " class"
Specify the PCI class of the video device.
.TP 8
.BI \-d " device-id"
Specify the PCI devide ID of the video device.
.TP 8
.BI \-r " revision"
Specify the PCI revision of the video device.
.TP 8
.BI \-s " subsysvendor-id"
Specify the PCI subsystem vendor ID of the video device.
.TP 8
.BI \-v " vendor-id"
Specify the PCI vendor ID of the video device.
.SH FILES
.I .cfg
files located in the search path. The search path typically specified
by the
.B XFree86
server is:
.PP
.RS 4
.nf
.I /etc/X11
.I __projectroot__/etc/X11
.I <modulepath>
.I __projectroot__/lib/X11/getconfig
.fi
.RE
.PP
where
.I <modulepath>
is the
.B XFree86
server's module search path.
.SH "SEE ALSO"
getconfig(__filemansuffix__),
XFree86(1),
XF86Config(__filemansuffix__).
.SH AUTHORS
The XFree86 automatic configuration support and the
.B getconfig
interface was written by David H. Dawes, with the support of X-Oz
Technologies.

View File

@ -0,0 +1,429 @@
#!/usr/bin/perl
# $DHD: xc/programs/Xserver/hw/xfree86/getconfig/getconfig.pl,v 1.13 2003/09/23 05:12:07 dawes Exp $
#
# Copyright 2003 by David H. Dawes.
# Copyright 2003 by X-Oz Technologies.
# 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 COPYRIGHT HOLDER(S) OR AUTHOR(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 of the copyright holder(s)
# and author(s) shall not be used in advertising or otherwise to promote
# the sale, use or other dealings in this Software without prior written
# authorization from the copyright holder(s) and author(s).
#
# Author: David Dawes <dawes@XFree86.Org>.
#
# $XFree86: xc/programs/Xserver/hw/xfree86/getconfig/getconfig.pl,v 1.1 2003/10/08 14:58:29 dawes Exp $
#
# This script takes PCI id information, compares it against an ordered list
# of rules, and prints out the configuration information specified by the
# last matching rule.
#
# This script is called by xf86AutoConfig().
#
# Command line processing.
$GetconfigVersion = v1.0;
$debug = 0;
$myname = $0;
$myname =~ s/.*\///;
$signature = "XFree86 Project getconfig rules file. Version: ";
while (@ARGV[0] =~ /^-[A-Za-z]$/) {
$f = shift;
SWITCH: {
if ($f eq "-D") {
$debug = 1;
last SWITCH;
}
if ($f eq "-I") {
push(@searchPaths, split(/,/, shift));
last SWITCH;
}
if ($f eq "-V") {
printf STDERR "$myname: Version %vd.\n", $GetconfigVersion;
exit 0;
}
if ($f eq "-X") {
$XFree86VersionNumeric = shift;
if (!defined($XFree86VersionNumeric)) {
print STDERR "$myname: -X requires the XFree86 version.\n";
exit 1;
}
}
if ($f eq "-b") {
$subsys = oct(shift);
if (!defined($subsys)) {
print STDERR "$myname: -b requires the subsys id.\n";
exit 1;
}
last SWITCH;
}
if ($f eq "-c") {
$class = oct(shift);
if (!defined($class)) {
print STDERR "$myname: -c requires the class value.\n";
exit 1;
}
last SWITCH;
}
if ($f eq "-d") {
$device = oct(shift);
if (!defined($device)) {
print STDERR "$myname: -d requires the device id.\n";
exit 1;
}
last SWITCH;
}
if ($f eq "-r") {
$revision = oct(shift);
if (!defined($revision)) {
print STDERR "$myname: -r requires the device revision.\n";
exit 1;
}
last SWITCH;
}
if ($f eq "-s") {
$subsysVendor = oct(shift);
if (!defined($subsysVendor)) {
print STDERR "$myname: -s requires the subsysVendor id.\n";
exit 1;
}
last SWITCH;
}
if ($f eq "-v") {
$vendor = oct(shift);
if (!defined($vendor)) {
print STDERR "$myname: -v requires the vendor id.\n";
exit 1;
}
last SWITCH;
}
}
}
printf STDERR "$myname: Version %vd.\n", $GetconfigVersion;
if (defined($XFree86VersionNumeric)) {
$XFree86VersionMajor = $XFree86VersionNumeric / 10000000;
$XFree86VersionMinor = ($XFree86VersionNumeric % 10000000) / 100000;
$XFree86VersionPatch = ($XFree86VersionNumeric % 100000) / 1000;
$XFree86VersionSnapshot = $XFree86VersionNumeric % 1000;
$XFree86Version = chr($XFree86VersionMajor) . chr($XFree86VersionMinor) .
chr($XFree86VersionPatch) . chr($XFree86VersionSnapshot);
}
if ($debug) {
printf STDERR "$myname: XFree86 Version: %d, %d.%d.%d.%d, %vd.\n",
$XFree86VersionNumeric, $XFree86VersionMajor, $XFree86VersionMinor,
$XFree86VersionPatch, $XFree86VersionSnapshot, $XFree86Version;
} else {
printf STDERR "$myname: XFree86 Version: %vd.\n", $XFree86Version;
}
# The rules here are just basic vendor ID to driver mappings.
# Ideally this is all that would be required. More complicated configuration
# rules will be provided in external files.
# XXX This set of basic rules isn't complete yet.
@rules = (
# Set the weight for the built-in rules.
['$weight = 500'],
# APM
['$vendor == 0x1142',
'apm'],
# ARK
['$vendor == 0xedd8',
'apm'],
# ATI
['$vendor == 0x1002',
'ati'],
# Chips & Technologies
['$vendor == 0x102c',
'chips'],
# Cirrus
['$vendor == 0x1013',
'cirrus'],
# Intel
['$vendor == 0x8086',
'i810'],
['$vendor == 0x8086 && ($chipType == 0x00d1 || $chipType == 0x7800)',
'i740'],
# Matrox
['$vendor == 0x102b',
'mga'],
# Neomagic
['$vendor == 0x10c8',
'neomagic'],
# Number Nine
['$vendor == 0x105d',
'i128'],
# NVIDIA
['$vendor == 0x10de || $vendor == 0x12d2',
'nv'],
# S3
['$vendor == 0x5333 && ($device == 0x88d0 ||' .
'$device == 0x88d1 ||' .
'$device == 0x88f0 ||' .
'$device == 0x8811 ||' .
'$device == 0x8812 ||' .
'$device == 0x8814 ||' .
'$device == 0x8901)',
's3'],
# S3 virge
['$vendor == 0x5333 && ($device == 0x5631 ||' .
'$device == 0x883d ||' .
'$device == 0x8a01 ||' .
'$device == 0x8a10 ||' .
'$device == 0x8c01 ||' .
'$device == 0x8c03 ||' .
'$device == 0x8904 ||' .
'$device == 0x8a13)',
's3virge'],
# S3 Savage
['$vendor == 0x5333 && ($device >= 0x8a20 && $device <= 0x8a22 ||' .
'$device == 0x9102 ||' .
'$device >= 0x8c10 && $device <= 0x8c13 ||' .
'$device == 0x8a25 ||' .
'$device == 0x8a26 ||' .
'$device >= 0x8d01 && $device <= 0x8d04 ||' .
'$device >= 0x8c2a && $device <= 0x8c2f ||' .
'$device == 0x8c22 ||' .
'$device == 0x8c24 ||' .
'$device == 0x8c26)',
'savage'],
# SIS
['$vendor == 0x1039',
'sis'],
# SMI
['$vendor == 0x126f',
'siliconmotion'],
# 3Dfx
['$vendor == 0x121a',
'tdfx'],
# 3Dlabs
['$vendor == 0x3d3d',
'glint'],
# Trident
['$vendor == 0x1023',
'trident'],
# Tseng Labs
['$vendor == 0x100c',
'tseng'],
# VIA
['$vendor == 0x1106',
'via'],
# VMware
['$vendor == 0x15ad',
'vmware'],
);
# Reverse the search path list, since the later rules have higher priority
# than earlier ones (weighting being equal).
@searchPaths = reverse(@searchPaths);
if ($debug) {
$i = 0;
for $path (@searchPaths) {
print STDERR "$myname: Search path $i is: \"$path\".\n";
$i++;
}
}
print STDERR "$myname: ", $#rules + 1, " built-in rule", plural($#rules + 1),
".\n";
for $path (@searchPaths) {
while (<$path/*.cfg>) {
@tmp = readRulesFile($_);
if (defined(@tmp[0])) {
push @rules, @tmp;
}
}
}
if ($debug) {
$i = 0;
for $r (@rules) {
print STDERR "$myname: rule $i is: \'@$r\'.\n";
$i++
}
}
$i = 0;
$e = 0;
$weight = 0;
$w = 0;
for $r (@rules) {
($cond, $d, @o) = @$r;
$result = eval $cond;
if ($@) {
print STDERR "$myname: Error evaluating rule $i \'$cond\': $@";
$e++;
}
if ($debug) {
print STDERR "$myname: rule $i \'$cond\' evaluates to \'$result\'.\n";
}
if ($result && defined($d) && $weight >= $w) {
$driver = $d;
@opts = @o;
$w = $weight;
}
$i++;
}
print STDERR "$myname: Evaluated $i rule", plural($i),
" with $e error", plural($e), ".\n";
print STDERR "$myname: Weight of result is $w.\n";
if ($debug) {
if (defined($driver)) {
print STDERR "$myname: Driver is \'$driver\'.\n";
} else {
print STDERR "$myname: No driver.\n";
}
if (defined(@opts)) {
print STDERR "$myname: options are:\n";
for $opt (@opts) {
print STDERR "\t$opt\n";
}
} else {
print STDERR "$myname: No options.\n";
}
}
print "$driver\n";
for $opt (@opts) {
print "$opt\n";
}
exit 0;
# Subroutines.
sub readRulesFile {
my ($file) = @_;
my $signatureOK = 0;
my @r, @tmp;
my $line, $cont, $prevcont, $fileversion;
undef @tmp;
undef @r;
if (open(RF, "<$file")) {
$prevcont = 0;
while (<RF>) {
chop;
$line = $_;
next if ($line =~ /^#/);
next if ($line =~ /^\s*$/);
if (!$signatureOK) {
if ($line =~ /^$signature(.*)$/) {
$fileversion = $1;
$signatureOK = 1;
print STDERR
"$myname: rules file \'$file\' has version $fileversion.\n";
next;
}
}
if (!$signatureOK) {
print STDERR "$myname: file \'$file\' has bad signature.\n";
close(RF);
last;
}
$cont = 0;
if ($line =~ s/\\\s*$//) {
$cont = 1;
}
if (!$prevcont && $line =~ /^\S+/) {
if (defined(@tmp[0])) {
push(@r,[@tmp]);
}
undef @tmp;
}
if ($prevcont) {
push(@tmp, pop(@tmp) . $line);
} else {
push(@tmp, $line);
}
$prevcont = $cont;
}
if (defined(@tmp[0])) {
push(@r,[@tmp]);
}
if (!defined(@r[0])) {
print STDERR "$myname: no rules in file \'$file\'.\n";
} else {
print STDERR "$myname: ", $#r + 1,
" rule", plural($#r + 1),
" added from file \'$file\'.\n";
}
} else {
print STDERR "$myname: cannot open file \'$file\'.\n";
}
return @r;
}
sub plural {
my ($count) = @_;
if ($count != 1) {
return "s";
} else {
return "";
}
}

View File

@ -0,0 +1,105 @@
# XWin Server Resource File - EXAMPLE
# Earle F. Philhower, III
# Place in ~/.XWinrc or in /usr/X11R6/lib/X11/system.XWinrc
# Keywords are case insensitive, comments legal pretty much anywhere
# you can have an end-of-line
# Comments begin with "#" or "//" and go to the end-of-line
# Paths to commands are **cygwin** based (i.e. /usr/local/bin/xcalc)
# Paths to icons are **WINDOWS** based (i.e. c:\windows\icons)
# Menus are defined as...
# MENU <name> {
# <Menu Text> EXEC <command>
# ^^ This command will have any "%display%"
# string replaced with the proper display
# variable (i.e. 127.0.0.1:<display>.0)
# or <Menu Text> MENU <name-of-some-prior-defined-menu>
# or <Menu Text> ALWAYSONTOP
# ^^ Sets the window to display above all others
# or <Menu Text> RELOAD
# ^^ Causes ~/.XWinrc or the system.XWinrc file
# to be reloaded and icons and menus regenerated
# or SEPARATOR
# ...
# }
# Set the taskmar menu with
# ROOTMENU <name-of-some-prior-defined-menu>
# If you want a menu to be applied to all popup window's system menu
# DEFAULTSYSMENU <name-of-some-prior-defined-menu> <atstart|atend>
# To choose a specific menu for a specific WM_CLASS or WM_NAME use ...
# SYSMENU {
# <class-or-name-of-window> <name-of-prior-defined-menu> <atstart|atend>
# ...
# }
# To define where ICO files live (** Windows path**)
# ICONDIRECTORY <windows-path i.e. c:\cygwin\usr\icons>
# To define a replacement for the standard X icon for apps w/o specified icons
# DEFAULTICON <name-of-windows-ico-file-in-icondirectory>
# To define substitute icons on a per-window basis use...
# ICONS {
# <class-or-name-of-window> <icon-file-name.ico>
# ...
# }
# In the case where multiple matches occur, the first listed in the ICONS
# section will be chosen.
# DEBUG <string> prints out the string to the XWin.log file
// Below are just some silly menus to demonstrate writing your
// own configuration file.
// Make some menus...
menu apps {
xterm exec "xterm"
"Emacs" exec "emacs"
notepad exec notepad
xload exec "xload -display %display%" # Comment
}
menu root {
// Comments fit here, too...
"Reload .XWinrc" RELOAD
"Applications" menu apps
SEParATOR
}
menu aot {
Separator
"Always on Top" alwaysontop
}
menu xtermspecial {
"Emacs" exec "emacs"
"Always on Top" alwaysontop
SepArAtor
}
RootMenu root
DefaultSysMenu aot atend
SysMenu {
"xterm" xtermspecial atstart
}
# IconDirectory "c:\winnt\"
# DefaultIcon "reinstall.ico"
# Icons {
# "xterm" "uninstall.ico"
# }
DEBUG "Done parsing the configuration file..."

320
hw/xwin/windialogs.c Executable file
View File

@ -0,0 +1,320 @@
/*
*Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
*shall not be used in advertising or otherwise to promote the sale, use
*or other dealings in this Software without prior written authorization
*from the XFree86 Project.
*
* Authors: Harold L Hunt II
*/
/* $XFree86: xc/programs/Xserver/hw/xwin/windialogs.c,v 1.1 2003/07/29 21:25:17 dawes Exp $ */
#include "win.h"
extern Bool g_fCursor;
BOOL CALLBACK
winExitDlgProc (HWND hDialog, UINT message,
WPARAM wParam, LPARAM lParam);
BOOL CALLBACK
winChangeDepthDlgProc (HWND hDialog, UINT message,
WPARAM wParam, LPARAM lParam);
/*
* Display the Exit dialog box
*/
void
winDisplayExitDialog (winPrivScreenPtr pScreenPriv)
{
/* Check if dialog already exists */
if (g_hDlgExit != NULL)
{
/* Dialog box already exists, display it */
ShowWindow (g_hDlgExit, SW_SHOWDEFAULT);
/* User has lost the dialog. Show them where it is. */
SetForegroundWindow (g_hDlgExit);
return;
}
/* Create dialog box */
g_hDlgExit = CreateDialogParam (g_hInstance,
"EXIT_DIALOG",
pScreenPriv->hwndScreen,
winExitDlgProc,
(int) pScreenPriv);
/* Drop minimize and maximize buttons */
SetWindowLong (g_hDlgExit, GWL_STYLE,
GetWindowLong (g_hDlgExit, GWL_STYLE)
& ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX));
SetWindowLong (g_hDlgExit, GWL_EXSTYLE,
GetWindowLong (g_hDlgExit, GWL_EXSTYLE) & ~WS_EX_APPWINDOW );
SetWindowPos (g_hDlgExit, 0, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE);
/* Show the dialog box */
ShowWindow (g_hDlgExit, SW_SHOW);
/* Needed to get keyboard controls (tab, arrows, enter, esc) to work */
SetForegroundWindow (g_hDlgExit);
/* Set focus to the Cancel buton */
PostMessage (g_hDlgExit, WM_NEXTDLGCTL,
(int) GetDlgItem (g_hDlgExit, IDCANCEL), TRUE);
}
/*
* Exit dialog window procedure
*/
BOOL CALLBACK
winExitDlgProc (HWND hDialog, UINT message,
WPARAM wParam, LPARAM lParam)
{
static winPrivScreenPtr s_pScreenPriv = NULL;
static winScreenInfo *s_pScreenInfo = NULL;
static ScreenPtr s_pScreen = NULL;
/* Branch on message type */
switch (message)
{
case WM_INITDIALOG:
/* Store pointers to private structures for future use */
s_pScreenPriv = (winPrivScreenPtr) lParam;
s_pScreenInfo = s_pScreenPriv->pScreenInfo;
s_pScreen = s_pScreenInfo->pScreen;
/* Set icon to standard app icon */
PostMessage (hDialog,
WM_SETICON,
ICON_SMALL,
(LPARAM) LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)));
return TRUE;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK:
/* Send message to call the GiveUp function */
PostMessage (s_pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0);
DestroyWindow (g_hDlgExit);
g_hDlgExit = NULL;
/* Fix to make sure keyboard focus isn't trapped */
PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
return TRUE;
case IDCANCEL:
DestroyWindow (g_hDlgExit);
g_hDlgExit = NULL;
/* Fix to make sure keyboard focus isn't trapped */
PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
return TRUE;
}
break;
case WM_MOUSEMOVE:
case WM_NCMOUSEMOVE:
/* Show the cursor if it is hidden */
if (!g_fCursor)
{
g_fCursor = TRUE;
ShowCursor (TRUE);
}
return TRUE;
case WM_CLOSE:
DestroyWindow (g_hDlgExit);
g_hDlgExit = NULL;
/* Fix to make sure keyboard focus isn't trapped */
PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
return TRUE;
}
return FALSE;
}
/*
* Display the Depth Change dialog box
*/
void
winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv)
{
/* Check if dialog already exists */
if (g_hDlgDepthChange != NULL)
{
/* Dialog box already exists, display it */
ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT);
/* User has lost the dialog. Show them where it is. */
SetForegroundWindow (g_hDlgDepthChange);
return;
}
/*
* Display a notification to the user that the visual
* will not be displayed until the Windows display depth
* is restored to the original value.
*/
g_hDlgDepthChange = CreateDialogParam (g_hInstance,
"DEPTH_CHANGE_BOX",
pScreenPriv->hwndScreen,
winChangeDepthDlgProc,
(int) pScreenPriv);
/* Drop minimize and maximize buttons */
SetWindowLong (g_hDlgDepthChange, GWL_STYLE,
GetWindowLong (g_hDlgDepthChange, GWL_STYLE)
& ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX));
SetWindowLong (g_hDlgDepthChange, GWL_EXSTYLE,
GetWindowLong (g_hDlgDepthChange, GWL_EXSTYLE)
& ~WS_EX_APPWINDOW );
SetWindowPos (g_hDlgDepthChange, 0, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE);
/* Show the dialog box */
ShowWindow (g_hDlgDepthChange, SW_SHOW);
ErrorF ("winDisplayDepthChangeDialog - DialogBox returned: %d\n",
g_hDlgDepthChange);
ErrorF ("winDisplayDepthChangeDialog - GetLastError: %d\n", GetLastError ());
/* Minimize the display window */
ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE);
}
/*
* Process messages for the dialog that is displayed for
* disruptive screen depth changes.
*/
BOOL CALLBACK
winChangeDepthDlgProc (HWND hwndDialog, UINT message,
WPARAM wParam, LPARAM lParam)
{
static winPrivScreenPtr s_pScreenPriv = NULL;
static winScreenInfo *s_pScreenInfo = NULL;
static ScreenPtr s_pScreen = NULL;
#if CYGDEBUG
ErrorF ("winChangeDepthDlgProc\n");
#endif
/* Branch on message type */
switch (message)
{
case WM_INITDIALOG:
#if CYGDEBUG
ErrorF ("winChangeDepthDlgProc - WM_INITDIALOG\n");
#endif
/* Store pointers to private structures for future use */
s_pScreenPriv = (winPrivScreenPtr) lParam;
s_pScreenInfo = s_pScreenPriv->pScreenInfo;
s_pScreen = s_pScreenInfo->pScreen;
#if CYGDEBUG
ErrorF ("winChangeDepthDlgProc - WM_INITDIALG - s_pScreenPriv: %08x, "
"s_pScreenInfo: %08x, s_pScreen: %08x\n",
s_pScreenPriv, s_pScreenInfo, s_pScreen);
#endif
#if CYGDEBUG
ErrorF ("winChangeDepthDlgProc - WM_INITDIALOG - orig bpp: %d, "
"last bpp: %d\n",
s_pScreenInfo->dwBPP,
s_pScreenPriv->dwLastWindowsBitsPixel);
#endif
/* Set icon to standard app icon */
PostMessage (hwndDialog,
WM_SETICON,
ICON_SMALL,
(LPARAM) LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)));
return TRUE;
case WM_DISPLAYCHANGE:
#if CYGDEBUG
ErrorF ("winChangeDepthDlgProc - WM_DISPLAYCHANGE - orig bpp: %d, "
"last bpp: %d, new bpp: %d\n",
s_pScreenInfo->dwBPP,
s_pScreenPriv->dwLastWindowsBitsPixel,
wParam);
#endif
/* Dismiss the dialog if the display returns to the original depth */
if (wParam == s_pScreenInfo->dwBPP)
{
ErrorF ("winChangeDelthDlgProc - wParam == s_pScreenInfo->dwBPP\n");
/* Depth has been restored, dismiss dialog */
DestroyWindow (g_hDlgDepthChange);
g_hDlgDepthChange = NULL;
/* Flag that we have a valid screen depth */
s_pScreenPriv->fBadDepth = FALSE;
}
return TRUE;
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK:
case IDCANCEL:
ErrorF ("winChangeDepthDlgProc - WM_COMMAND - IDOK or IDCANCEL\n");
/*
* User dismissed the dialog, hide it until the
* display mode is restored.
*/
ShowWindow (g_hDlgDepthChange, SW_HIDE);
return TRUE;
}
break;
case WM_CLOSE:
ErrorF ("winChangeDepthDlgProc - WM_CLOSE\n");
/*
* User dismissed the dialog, hide it until the
* display mode is restored.
*/
ShowWindow (g_hDlgDepthChange, SW_HIDE);
return TRUE;
}
return FALSE;
}

284
hw/xwin/winmultiwindowclass.c Executable file
View File

@ -0,0 +1,284 @@
/*
*Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
*shall not be used in advertising or otherwise to promote the sale, use
*or other dealings in this Software without prior written authorization
*from the XFree86 Project.
*
* Authors: Earle F. Philhower, III
*/
/* $XFree86: xc/programs/Xserver/hw/xwin/winmultiwindowclass.c,v 1.2 2003/10/02 13:30:10 eich Exp $ */
#include <Xatom.h>
#include "propertyst.h"
#include "windowstr.h"
#include "winmultiwindowclass.h"
int
winMultiWindowGetClassHint (WindowPtr pWin, char **res_name, char **res_class)
{
struct _Window *pwin;
struct _Property *prop;
int len_name, len_class;
if (!pWin || !res_name || !res_class)
{
ErrorF ("winMultiWindowGetClassHint - pWin, res_name, or res_class was "
"NULL\n");
return 0;
}
pwin = (struct _Window*) pWin;
if (pwin->optional)
prop = (struct _Property *) pwin->optional->userProps;
else
prop = NULL;
*res_name = *res_class = NULL;
while (prop)
{
if (prop->propertyName == XA_WM_CLASS
&& prop->type == XA_STRING
&& prop->format == 8
&& prop->data)
{
len_name = strlen ((char *) prop->data);
(*res_name) = malloc (len_name + 1);
if (!*res_name)
{
ErrorF ("winMultiWindowGetClassHint - *res_name was NULL\n");
return 0;
}
/* Add one to len_name to allow copying of trailing 0 */
strncpy ((*res_name), prop->data, len_name + 1);
if (len_name == prop->size)
len_name--;
len_class = strlen (((char *)prop->data) + 1 + len_name);
(*res_class) = malloc (len_class + 1);
if (!*res_class)
{
ErrorF ("winMultiWindowGetClassHint - *res_class was NULL\n");
/* Free the previously allocated res_name */
free (*res_name);
return 0;
}
strcpy ((*res_class), ((char *)prop->data) + 1 + len_name);
return 1;
}
else
prop = prop->next;
}
return 0;
}
int
winMultiWindowGetWMHints (WindowPtr pWin, WinXWMHints *hints)
{
struct _Window *pwin;
struct _Property *prop;
if (!pWin || !hints)
{
ErrorF ("winMultiWindowGetWMHints - pWin or hints was NULL\n");
return 0;
}
pwin = (struct _Window*) pWin;
if (pwin->optional)
prop = (struct _Property *) pwin->optional->userProps;
else
prop = NULL;
memset (hints, 0, sizeof (WinXWMHints));
while (prop)
{
if (prop->propertyName == XA_WM_HINTS
&& prop->data)
{
memcpy (hints, prop->data, sizeof (WinXWMHints));
return 1;
}
else
prop = prop->next;
}
return 0;
}
int
winMultiWindowGetWindowRole (WindowPtr pWin, char **res_role)
{
struct _Window *pwin;
struct _Property *prop;
int len_role;
static Atom atmWmWindowRole = 0;
if (!pWin || !res_role)
return 0;
/* Initialize the window role atom, not in XAtom.h */
if (!atmWmWindowRole)
atmWmWindowRole = MakeAtom ("WM_WINDOW_ROLE", 14, 1);
pwin = (struct _Window*) pWin;
if (pwin->optional)
prop = (struct _Property *) pwin->optional->userProps;
else
prop = NULL;
*res_role = NULL;
while (prop)
{
if (prop->propertyName == atmWmWindowRole
&& prop->type == XA_STRING
&& prop->format == 8
&& prop->data)
{
len_role= strlen ((char *) prop->data);
(*res_role) = malloc (len_role + 1);
if (!*res_role)
{
ErrorF ("winMultiWindowGetWindowRole - *res_role was NULL\n");
return 0;
}
strcpy ((*res_role), prop->data);
return 1;
}
else
prop = prop->next;
}
return 0;
}
int
winMultiWindowGetWMNormalHints (WindowPtr pWin, WinXSizeHints *hints)
{
struct _Window *pwin;
struct _Property *prop;
if (!pWin || !hints)
{
ErrorF ("winMultiWindowGetWMNormalHints - pWin or hints was NULL\n");
return 0;
}
pwin = (struct _Window*) pWin;
if (pwin->optional)
prop = (struct _Property *) pwin->optional->userProps;
else
prop = NULL;
memset (hints, 0, sizeof (WinXSizeHints));
while (prop)
{
if (prop->propertyName == XA_WM_NORMAL_HINTS
&& prop->data)
{
memcpy (hints, prop->data, sizeof (WinXSizeHints));
return 1;
}
else
prop = prop->next;
}
return 0;
}
int
winMultiWindowGetWMName (WindowPtr pWin, char **wmName)
{
struct _Window *pwin;
struct _Property *prop;
int len_name;
if (!pWin || !wmName)
{
ErrorF ("winMultiWindowGetClassHint - pWin, res_name, or res_class was "
"NULL\n");
return 0;
}
pwin = (struct _Window*) pWin;
if (pwin->optional)
prop = (struct _Property *) pwin->optional->userProps;
else
prop = NULL;
*wmName = NULL;
while (prop)
{
if (prop->propertyName == XA_WM_NAME
&& prop->type == XA_STRING
&& prop->data)
{
len_name = strlen ((char *) prop->data);
(*wmName) = malloc (len_name + 1);
if (!*wmName)
{
ErrorF ("winMultiWindowGetWMName - *wmName was NULL\n");
return 0;
}
/* Add one to len_name to allow copying of trailing 0 */
strncpy ((*wmName), prop->data, len_name+1);
return 1;
}
else
prop = prop->next;
}
return 0;
}

110
hw/xwin/winmultiwindowclass.h Executable file
View File

@ -0,0 +1,110 @@
/*
*Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
*shall not be used in advertising or otherwise to promote the sale, use
*or other dealings in this Software without prior written authorization
*from the XFree86 Project.
*
* Authors: Earle F. Philhower, III
*/
/* $XFree86: xc/programs/Xserver/hw/xwin/winmultiwindowclass.h,v 1.2 2003/10/02 13:30:10 eich Exp $ */
/*
* Structures
*/
typedef struct {
long flags; /* marks which fields in this structure are defined */
Bool input; /* does this application rely on the window manager to
get keyboard input? */
int initial_state; /* see below */
Pixmap icon_pixmap; /* pixmap to be used as icon */
Window icon_window; /* window to be used as icon */
int icon_x, icon_y; /* initial position of icon */
Pixmap icon_mask; /* icon mask bitmap */
XID window_group; /* id of related window group */
/* this structure may be extended in the future */
} WinXWMHints;
/*
* new version containing base_width, base_height, and win_gravity fields;
* used with WM_NORMAL_HINTS.
*/
typedef struct {
long flags; /* marks which fields in this structure are defined */
int x, y; /* obsolete for new window mgrs, but clients */
int width, height; /* should set so old wm's don't mess up */
int min_width, min_height;
int max_width, max_height;
int width_inc, height_inc;
struct {
int x; /* numerator */
int y; /* denominator */
} min_aspect, max_aspect;
int base_width, base_height; /* added by ICCCM version 1 */
int win_gravity; /* added by ICCCM version 1 */
} WinXSizeHints;
/*
* The next block of definitions are for window manager properties that
* clients and applications use for communication.
*/
/* flags argument in size hints */
#define USPosition (1L << 0) /* user specified x, y */
#define USSize (1L << 1) /* user specified width, height */
#define PPosition (1L << 2) /* program specified position */
#define PSize (1L << 3) /* program specified size */
#define PMinSize (1L << 4) /* program specified minimum size */
#define PMaxSize (1L << 5) /* program specified maximum size */
#define PResizeInc (1L << 6) /* program specified resize increments */
#define PAspect (1L << 7) /* program specified min and max aspect ratios */
#define PBaseSize (1L << 8) /* program specified base for incrementing */
#define PWinGravity (1L << 9) /* program specified window gravity */
/* obsolete */
#define PAllHints (PPosition|PSize|PMinSize|PMaxSize|PResizeInc|PAspect)
/*
* Function prototypes
*/
int
winMultiWindowGetWMHints (WindowPtr pWin, WinXWMHints *hints);
int
winMultiWindowGetClassHint (WindowPtr pWin, char **res_name, char **res_class);
int
winMultiWindowGetWindowRole (WindowPtr pWin, char **res_role);
int
winMultiWindowGetWMNormalHints (WindowPtr pWin, WinXSizeHints *hints);
int
winMultiWindowGetWMName (WindowPtr pWin, char **wmName);

378
hw/xwin/winmultiwindowicons.c Executable file
View File

@ -0,0 +1,378 @@
/*
*Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
*shall not be used in advertising or otherwise to promote the sale, use
*or other dealings in this Software without prior written authorization
*from the XFree86 Project.
*
* Authors: Earle F. Philhower, III
*/
/* $XFree86: xc/programs/Xserver/hw/xwin/winmultiwindowicons.c,v 1.2 2003/10/02 13:30:10 eich Exp $ */
#include "win.h"
#include "dixevents.h"
#include "winmultiwindowclass.h"
#include "winprefs.h"
/*
* External global variables
*/
extern HICON g_hiconX;
/*
* Prototypes for local functions
*/
static void
winScaleXBitmapToWindows (int iconSize, int effBPP,
PixmapPtr pixmap, unsigned char *image);
/*
* Scale an X icon bitmap into a Windoze icon bitmap
*/
static void
winScaleXBitmapToWindows (int iconSize,
int effBPP,
PixmapPtr pixmap,
unsigned char *image)
{
int row, column, effXBPP, effXDepth;
unsigned char *outPtr;
unsigned char *iconData = 0;
int stride, xStride;
float factX, factY;
int posX, posY;
unsigned char *ptr;
unsigned int zero;
unsigned int color;
if (pixmap->drawable.bitsPerPixel == 15)
effXBPP = 16;
else
effXBPP = pixmap->drawable.bitsPerPixel;
if (pixmap->drawable.depth == 15)
effXDepth = 16;
else
effXDepth = pixmap->drawable.depth;
/* Need 32-bit aligned rows */
stride = ((iconSize * effBPP + 31) & (~31)) / 8;
xStride = ((pixmap->drawable.width * effXBPP + 31) & (~31)) / 8;
iconData = malloc (xStride * pixmap->drawable.height);
miGetImage ((DrawablePtr) &(pixmap->drawable), 0, 0,
pixmap->drawable.width, pixmap->drawable.height,
ZPixmap, 0xffffffff, iconData);
/* Keep aspect ratio */
factX = ((float)pixmap->drawable.width) / ((float)iconSize);
factY = ((float)pixmap->drawable.height) / ((float)iconSize);
if (factX > factY)
factY = factX;
else
factX = factY;
/* Out-of-bounds, fill icon with zero */
zero = 0;
for (row = 0; row < iconSize; row++)
{
outPtr = image + stride * row;
for (column = 0; column < iconSize; column++)
{
posX = factX * column;
posY = factY * row;
ptr = iconData + posY*xStride;
if (effXBPP == 1)
{
ptr += posX / 8;
/* Out of X icon bounds, leave space blank */
if (posX >= pixmap->drawable.width
|| posY >= pixmap->drawable.height)
ptr = (unsigned char *) &zero;
if ((*ptr) & (1 << (posX & 7)))
switch (effBPP)
{
case 32:
*(outPtr++) = 0;
case 24:
*(outPtr++) = 0;
case 16:
*(outPtr++) = 0;
case 8:
*(outPtr++) = 0;
break;
case 1:
outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
break;
}
else
switch (effBPP)
{
case 32:
*(outPtr++) = 255;
*(outPtr++) = 255;
*(outPtr++) = 255;
*(outPtr++) = 0;
break;
case 24:
*(outPtr++) = 255;
case 16:
*(outPtr++) = 255;
case 8:
*(outPtr++) = 255;
break;
case 1:
outPtr[column / 8] |= (1 << (7 - (column & 7)));
break;
}
}
else if (effXDepth == 24 || effXDepth == 32)
{
ptr += posX * (effXBPP / 8);
/* Out of X icon bounds, leave space blank */
if (posX >= pixmap->drawable.width
|| posY >= pixmap->drawable.height)
ptr = (unsigned char *) &zero;
color = (((*ptr) << 16)
+ ((*(ptr + 1)) << 8)
+ ((*(ptr + 2)) << 0));
switch (effBPP)
{
case 32:
*(outPtr++) = *(ptr++); // b
*(outPtr++) = *(ptr++); // g
*(outPtr++) = *(ptr++); // r
*(outPtr++) = 0; // resvd
break;
case 24:
*(outPtr++) = *(ptr++);
*(outPtr++) = *(ptr++);
*(outPtr++) = *(ptr++);
break;
case 16:
color = ((((*ptr) >> 2) << 10)
+ (((*(ptr + 1)) >> 2) << 5)
+ (((*(ptr + 2)) >> 2)));
*(outPtr++) = (color >> 8);
*(outPtr++) = (color & 255);
break;
case 8:
color = (((*ptr))) + (((*(ptr + 1)))) + (((*(ptr + 2))));
color /= 3;
*(outPtr++) = color;
break;
case 1:
if (color)
outPtr[column / 8] |= (1 << (7 - (column & 7)));
else
outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
}
}
else if (effXDepth == 16)
{
ptr += posX * (effXBPP / 8);
/* Out of X icon bounds, leave space blank */
if (posX >= pixmap->drawable.width
|| posY >= pixmap->drawable.height)
ptr = (unsigned char *) &zero;
color = ((*ptr) << 8) + (*(ptr + 1));
switch (effBPP)
{
case 32:
*(outPtr++) = (color & 31) << 2;
*(outPtr++) = ((color >> 5) & 31) << 2;
*(outPtr++) = ((color >> 10) & 31) << 2;
*(outPtr++) = 0; // resvd
break;
case 24:
*(outPtr++) = (color & 31) << 2;
*(outPtr++) = ((color >> 5) & 31) << 2;
*(outPtr++) = ((color >> 10) & 31) << 2;
break;
case 16:
*(outPtr++) = *(ptr++);
*(outPtr++) = *(ptr++);
break;
case 8:
*(outPtr++) = (((color & 31)
+ ((color >> 5) & 31)
+ ((color >> 10) & 31)) / 3) << 2;
break;
case 1:
if (color)
outPtr[column / 8] |= (1 << (7 - (column & 7)));
else
outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
break;
} /* end switch(effbpp) */
} /* end if effxbpp==16) */
} /* end for column */
} /* end for row */
free (iconData);
}
/*
* Attempt to create a custom icon from the WM_HINTS bitmaps
*/
HICON
winXIconToHICON (WindowPtr pWin)
{
unsigned char *mask, *image, *imageMask;
unsigned char *dst, *src;
PixmapPtr iconPtr;
PixmapPtr maskPtr;
int iconSize, planes, bpp, effBPP, stride, maskStride, i;
HDC hDC;
ICONINFO ii;
WinXWMHints hints;
HICON hIcon;
winMultiWindowGetWMHints (pWin, &hints);
if (!hints.icon_pixmap) return NULL;
iconPtr = LookupIDByType (hints.icon_pixmap, RT_PIXMAP);
if (!iconPtr) return NULL;
iconSize = 32;
hDC = GetDC (GetDesktopWindow ());
planes = GetDeviceCaps (hDC, PLANES);
bpp = GetDeviceCaps (hDC, BITSPIXEL);
ReleaseDC (GetDesktopWindow (), hDC);
/* 15 BPP is really 16BPP as far as we care */
if (bpp == 15)
effBPP = 16;
else
effBPP = bpp;
/* Need 32-bit aligned rows */
stride = ((iconSize * effBPP + 31) & (~31)) / 8;
/* Mask is 1-bit deep */
maskStride = ((iconSize * 1 + 31) & (~31)) / 8;
image = (unsigned char * ) malloc (stride * iconSize);
imageMask = (unsigned char *) malloc (stride * iconSize);
mask = (unsigned char *) malloc (maskStride * iconSize);
/* Default to a completely black mask */
memset (mask, 0, maskStride * iconSize);
winScaleXBitmapToWindows (iconSize, effBPP, iconPtr, image);
maskPtr = LookupIDByType (hints.icon_mask, RT_PIXMAP);
if (maskPtr)
{
winScaleXBitmapToWindows (iconSize, 1, maskPtr, mask);
winScaleXBitmapToWindows (iconSize, effBPP, maskPtr, imageMask);
/* Now we need to set all bits of the icon which are not masked */
/* on to 0 because Color is really an XOR, not an OR function */
dst = image;
src = imageMask;
for (i = 0; i < (stride * iconSize); i++)
if ((*(src++)))
*(dst++) = 0;
else
dst++;
}
ii.fIcon = TRUE;
ii.xHotspot = 0; /* ignored */
ii.yHotspot = 0; /* ignored */
/* Create Win32 mask from pixmap shape */
ii.hbmMask = CreateBitmap (iconSize, iconSize, planes, 1, mask);
/* Create Win32 bitmap from pixmap */
ii.hbmColor = CreateBitmap (iconSize, iconSize, planes, bpp, image);
/* Merge Win32 mask and bitmap into icon */
hIcon = CreateIconIndirect (&ii);
/* Release Win32 mask and bitmap */
DeleteObject (ii.hbmMask);
DeleteObject (ii.hbmColor);
/* Free X mask and bitmap */
free (mask);
free (image);
free (imageMask);
return hIcon;
}
/*
* Change the Windows window icon
*/
void
winUpdateIcon (Window id)
{
WindowPtr pWin;
HICON hIcon, hiconOld;
pWin = LookupIDByType (id, RT_WINDOW);
hIcon = (HICON)winOverrideIcon ((unsigned long)pWin);
if (!hIcon)
hIcon = winXIconToHICON (pWin);
if (hIcon)
{
winWindowPriv(pWin);
if (pWinPriv->hWnd)
{
hiconOld = (HICON) SetClassLong (pWinPriv->hWnd,
GCL_HICON,
(int) hIcon);
/* Delete the icon if its not the default */
if (hiconOld != g_hiconX &&
!winIconIsOverride((unsigned long)hiconOld))
DeleteObject (hiconOld);
}
}
}

212
hw/xwin/winmultiwindowshape.c Executable file
View File

@ -0,0 +1,212 @@
/*
*Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
*shall not be used in advertising or otherwise to promote the sale, use
*or other dealings in this Software without prior written authorization
*from the XFree86 Project.
*
* Authors: Kensuke Matsuzaki
* Harold L Hunt II
*/
/* $XFree86: xc/programs/Xserver/hw/xwin/winmultiwindowshape.c,v 1.2 2003/11/10 18:22:44 tsi Exp $ */
#ifdef SHAPE
#include "win.h"
/*
* External global variables
*/
extern HICON g_hiconX;
/*
* winSetShapeMultiWindow - See Porting Layer Definition - p. 42
*/
void
winSetShapeMultiWindow (WindowPtr pWin)
{
#if CYGMULTIWINDOW_DEBUG
ErrorF ("winSetShapeMultiWindow - pWin: %08x\n", pWin);
#endif
/* Call any wrapped SetShape function */
if (winGetScreenPriv(pWin->drawable.pScreen)->SetShape)
winGetScreenPriv(pWin->drawable.pScreen)->SetShape (pWin);
/* Update the Windows window's shape */
winReshapeMultiWindow (pWin);
winUpdateRgnMultiWindow (pWin);
return;
}
/*
* winUpdateRgnMultiWindow - Local function to update a Windows window region
*/
void
winUpdateRgnMultiWindow (WindowPtr pWin)
{
SetWindowRgn (winGetWindowPriv(pWin)->hWnd,
winGetWindowPriv(pWin)->hRgn, TRUE);
}
/*
* winReshapeMultiWindow - Computes the composite clipping region for a window
*/
void
winReshapeMultiWindow (WindowPtr pWin)
{
int nRects;
RegionRec rrNewShape;
BoxPtr pShape, pRects, pEnd;
HRGN hRgn, hRgnRect;
winWindowPriv(pWin);
#if CYGDEBUG
ErrorF ("winReshape ()\n");
#endif
/* Bail if the window is the root window */
if (pWin->parent == NULL)
return;
/* Bail if the window is not top level */
if (pWin->parent->parent != NULL)
return;
/* Bail if Windows window handle is invalid */
if (pWinPriv->hWnd == NULL)
return;
/* Free any existing window region stored in the window privates */
if (pWinPriv->hRgn != NULL)
{
DeleteObject (pWinPriv->hRgn);
pWinPriv->hRgn = NULL;
}
/* Bail if the window has no bounding region defined */
if (!wBoundingShape (pWin))
return;
REGION_NULL(pScreen, &rrNewShape);
REGION_COPY(pScreen, &rrNewShape, wBoundingShape(pWin));
REGION_TRANSLATE(pScreen,
&rrNewShape,
pWin->borderWidth,
pWin->borderWidth);
nRects = REGION_NUM_RECTS(&rrNewShape);
pShape = REGION_RECTS(&rrNewShape);
/* Don't do anything if there are no rectangles in the region */
if (nRects > 0)
{
RECT rcClient;
RECT rcWindow;
int iOffsetX, iOffsetY;
/* Get client rectangle */
if (!GetClientRect (pWinPriv->hWnd, &rcClient))
{
ErrorF ("winReshape - GetClientRect failed, bailing: %d\n",
GetLastError ());
return;
}
/* Translate client rectangle coords to screen coords */
/* NOTE: Only transforms top and left members */
ClientToScreen (pWinPriv->hWnd, (LPPOINT) &rcClient);
/* Get window rectangle */
if (!GetWindowRect (pWinPriv->hWnd, &rcWindow))
{
ErrorF ("winReshape - GetWindowRect failed, bailing: %d\n",
GetLastError ());
return;
}
/* Calculate offset from window upper-left to client upper-left */
iOffsetX = rcClient.left - rcWindow.left;
iOffsetY = rcClient.top - rcWindow.top;
/* Create initial Windows region for title bar */
/* FIXME: Mean, nasty, ugly hack!!! */
hRgn = CreateRectRgn (0, 0, rcWindow.right, iOffsetY);
if (hRgn == NULL)
{
ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) "
"failed: %d\n",
0, 0, rcWindow.right, iOffsetY, GetLastError ());
}
/* Loop through all rectangles in the X region */
for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++)
{
/* Create a Windows region for the X rectangle */
hRgnRect = CreateRectRgn (pRects->x1 + iOffsetX - 1,
pRects->y1 + iOffsetY - 1,
pRects->x2 + iOffsetX - 1,
pRects->y2 + iOffsetY - 1);
if (hRgnRect == NULL)
{
ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) "
"failed: %d\n"
"\tx1: %d x2: %d xOff: %d y1: %d y2: %d yOff: %d\n",
pRects->x1 + iOffsetX - 1,
pRects->y1 + iOffsetY - 1,
pRects->x2 + iOffsetX - 1,
pRects->y2 + iOffsetY - 1,
GetLastError (),
pRects->x1, pRects->x2, iOffsetX,
pRects->y1, pRects->y2, iOffsetY);
}
/* Merge the Windows region with the accumulated region */
if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR)
{
ErrorF ("winReshape - CombineRgn () failed: %d\n",
GetLastError ());
}
/* Delete the temporary Windows region */
DeleteObject (hRgnRect);
}
/* Save a handle to the composite region in the window privates */
pWinPriv->hRgn = hRgn;
}
REGION_UNINIT(pScreen, &rrNewShape);
return;
}
#endif

1005
hw/xwin/winmultiwindowwndproc.c Executable file

File diff suppressed because it is too large Load Diff

661
hw/xwin/winprefs.c Normal file
View File

@ -0,0 +1,661 @@
/*
* Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
* shall not be used in advertising or otherwise to promote the sale, use
* or other dealings in this Software without prior written authorization
* from the XFree86 Project.
*
* Authors: Earle F. Philhower, III
*/
/* $XFree86: xc/programs/Xserver/hw/xwin/winprefs.c,v 1.1 2003/10/02 13:30:11 eich Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include "win.h"
/* Fixups to prevent collisions between Windows and X headers */
#define ATOM DWORD
#include <windows.h>
#include "winprefs.h"
#include "winmultiwindowclass.h"
/* Where will the custom menu commands start counting from? */
#define STARTMENUID WM_USER
/* From winmultiwindowflex.l, the real parser */
extern void parse_file (FILE *fp);
/* From winmultiwindowyacc.y, the pref structure loaded by the parser */
extern WINMULTIWINDOWPREFS pref;
/* The global X default icon */
extern HICON g_hiconX;
/* Currently in use command ID, incremented each new menu item created */
static int g_cmdid = STARTMENUID;
/* Defined in DIX */
extern char *display;
/*
* Creates or appends a menu from a MENUPARSED structure
*/
static HMENU
MakeMenu (char *name,
HMENU editMenu,
int editItem)
{
int i;
int item;
MENUPARSED *m;
HMENU hmenu;
for (i=0; i<pref.menuItems; i++)
{
if (!strcmp(name, pref.menu[i].menuName))
break;
}
/* Didn't find a match, bummer */
if (i==pref.menuItems)
{
ErrorF("MakeMenu: Can't find menu %s\n", name);
return NULL;
}
m = &(pref.menu[i]);
if (editMenu)
{
hmenu = editMenu;
item = editItem;
}
else
{
hmenu = CreatePopupMenu();
item = 0;
}
/* Add the menu items */
for (i=0; i<m->menuItems; i++)
{
/* Only assign IDs one time... */
if ( m->menuItem[i].commandID == 0 )
m->menuItem[i].commandID = g_cmdid++;
switch (m->menuItem[i].cmd)
{
case CMD_EXEC:
case CMD_ALWAYSONTOP:
case CMD_RELOAD:
InsertMenu (hmenu,
item,
MF_BYPOSITION|MF_ENABLED|MF_STRING,
m->menuItem[i].commandID,
m->menuItem[i].text);
break;
case CMD_SEPARATOR:
InsertMenu (hmenu,
item,
MF_BYPOSITION|MF_SEPARATOR,
0,
NULL);
break;
case CMD_MENU:
/* Recursive! */
InsertMenu (hmenu,
item,
MF_BYPOSITION|MF_POPUP|MF_ENABLED|MF_STRING,
(UINT_PTR)MakeMenu (m->menuItem[i].param, 0, 0),
m->menuItem[i].text);
break;
}
/* If item==-1 (means to add at end of menu) don't increment) */
if (item>=0)
item++;
}
return hmenu;
}
/*
* Callback routine that is executed once per window class.
* Removes or creates custom window settings depending on LPARAM
*/
static BOOL CALLBACK
ReloadEnumWindowsProc (HWND hwnd, LPARAM lParam)
{
char szClassName[1024];
HICON hicon;
if (!GetClassName (hwnd, szClassName, 1024))
return TRUE;
if (strncmp (szClassName, WINDOW_CLASS_X, strlen (WINDOW_CLASS_X)))
/* Not one of our windows... */
return TRUE;
/* It's our baby, either clean or dirty it */
if (lParam==FALSE)
{
hicon = (HICON)GetClassLong(hwnd, GCL_HICON);
/* Unselect any icon in the class structure */
SetClassLong (hwnd, GCL_HICON, (LONG)LoadIcon (NULL, IDI_APPLICATION));
/* If it's generated on-the-fly, get rid of it, will regen */
if (!winIconIsOverride((unsigned long)hicon) && hicon!=g_hiconX)
DestroyIcon (hicon);
/* Remove any menu additions, use bRevert flag */
GetSystemMenu (hwnd, TRUE);
/* This window is now clean of our taint */
}
else
{
/* Make the icon default, dynamic, of from xwinrc */
SetClassLong (hwnd, GCL_HICON, (LONG)g_hiconX);
winUpdateIcon ((Window)GetProp (hwnd, WIN_WID_PROP));
/* Update the system menu for this window */
SetupSysMenu ((unsigned long)hwnd);
/* That was easy... */
}
return TRUE;
}
/*
* Removes any custom icons in classes, custom menus, etc.
* Frees all members in pref structure.
* Reloads the preferences file.
* Set custom icons and menus again.
*/
static void
ReloadPrefs ()
{
int i;
/* First, iterate over all windows replacing their icon with system */
/* default one and deleting any custom system menus */
EnumWindows (ReloadEnumWindowsProc, FALSE);
/* Now, free/clear all info from our prefs structure */
for (i=0; i<pref.menuItems; i++)
free (pref.menu[i].menuItem);
free (pref.menu);
pref.menu = NULL;
pref.menuItems = 0;
pref.rootMenuName[0] = 0;
free (pref.sysMenu);
pref.sysMenuItems = 0;
pref.defaultSysMenuName[0] = 0;
pref.defaultSysMenuPos = 0;
pref.iconDirectory[0] = 0;
pref.defaultIconName[0] = 0;
for (i=0; i<pref.iconItems; i++)
if (pref.icon[i].hicon)
DestroyIcon ((HICON)pref.icon[i].hicon);
free (pref.icon);
pref.icon = NULL;
pref.iconItems = 0;
/* Free global default X icon */
DestroyIcon (g_hiconX);
/* Reset the custom command IDs */
g_cmdid = STARTMENUID;
/* Load the updated resource file */
LoadPreferences();
/* Define global icon, load it */
g_hiconX = (HICON)winOverrideDefaultIcon();
if (!g_hiconX)
g_hiconX = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN));
/* Rebuild the icons and menus */
EnumWindows (ReloadEnumWindowsProc, TRUE);
/* Whew, done */
}
/*
* Check/uncheck the ALWAYSONTOP items in this menu
*/
void
HandleCustomWM_INITMENU(unsigned long hwndIn,
unsigned long hmenuIn)
{
HWND hwnd;
HMENU hmenu;
DWORD dwExStyle;
int i, j;
hwnd = (HWND)hwndIn;
hmenu = (HMENU)hmenuIn;
if (!hwnd || !hmenu)
return;
if (GetWindowLong (hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)
dwExStyle = MF_BYCOMMAND | MF_CHECKED;
else
dwExStyle = MF_BYCOMMAND | MF_UNCHECKED;
for (i=0; i<pref.menuItems; i++)
for (j=0; j<pref.menu[i].menuItems; j++)
if (pref.menu[i].menuItem[j].cmd==CMD_ALWAYSONTOP)
CheckMenuItem (hmenu, pref.menu[i].menuItem[j].commandID, dwExStyle );
}
/*
* Searches for the custom WM_COMMAND command ID and performs action
*/
int
HandleCustomWM_COMMAND (unsigned long hwndIn,
int command)
{
HWND hwnd;
int i, j;
MENUPARSED *m;
DWORD dwExStyle;
hwnd = (HWND)hwndIn;
if (!command)
return 0;
for (i=0; i<pref.menuItems; i++)
{
m = &(pref.menu[i]);
for (j=0; j<m->menuItems; j++)
{
if (command==m->menuItem[j].commandID)
{
/* Match! */
switch(m->menuItem[j].cmd)
{
case CMD_EXEC:
if (fork()==0)
{
struct rlimit rl;
unsigned long i;
/* Close any open descriptors except for STD* */
getrlimit (RLIMIT_NOFILE, &rl);
for (i = STDERR_FILENO+1; i < rl.rlim_cur; i++)
close(i);
/* Disassociate any TTYs */
setsid();
execl ("/bin/sh",
"/bin/sh",
"-c",
m->menuItem[j].param,
NULL);
exit (0);
}
else
return 0;
break;
case CMD_ALWAYSONTOP:
if (!hwnd)
return 0;
/* Get extended window style */
dwExStyle = GetWindowLong (hwnd, GWL_EXSTYLE);
/* Handle topmost windows */
if (dwExStyle & WS_EX_TOPMOST)
SetWindowPos (hwnd,
HWND_NOTOPMOST,
0, 0,
0, 0,
SWP_NOSIZE | SWP_NOMOVE);
else
SetWindowPos (hwnd,
HWND_TOPMOST,
0, 0,
0, 0,
SWP_NOSIZE | SWP_NOMOVE);
return 0;
case CMD_RELOAD:
ReloadPrefs();
return 0;
default:
return 0;
}
} /* match */
} /* for j */
} /* for i */
return 0;
}
/*
* Add the default or a custom menu depending on the class match
*/
void
SetupSysMenu (unsigned long hwndIn)
{
HWND hwnd;
HMENU sys;
int i;
WindowPtr pWin;
char *res_name, *res_class;
hwnd = (HWND)hwndIn;
if (!hwnd)
return;
pWin = GetProp (hwnd, WIN_WINDOW_PROP);
sys = GetSystemMenu (hwnd, FALSE);
if (!sys)
return;
if (pWin)
{
/* First see if there's a class match... */
if (winMultiWindowGetClassHint (pWin, &res_name, &res_class))
{
for (i=0; i<pref.sysMenuItems; i++)
{
if (!strcmp(pref.sysMenu[i].match, res_name) ||
!strcmp(pref.sysMenu[i].match, res_class) )
{
free(res_name);
free(res_class);
MakeMenu (pref.sysMenu[i].menuName, sys,
pref.sysMenu[i].menuPos==AT_START?0:-1);
return;
}
}
/* No match, just free alloc'd strings */
free(res_name);
free(res_class);
} /* Found wm_class */
} /* if pwin */
/* Fallback to system default */
if (pref.defaultSysMenuName[0])
{
if (pref.defaultSysMenuPos==AT_START)
MakeMenu (pref.defaultSysMenuName, sys, 0);
else
MakeMenu (pref.defaultSysMenuName, sys, -1);
}
}
/*
* Possibly add a menu to the toolbar icon
*/
void
SetupRootMenu (unsigned long hmenuRoot)
{
HMENU root;
root = (HMENU)hmenuRoot;
if (!root)
return;
if (pref.rootMenuName[0])
{
MakeMenu(pref.rootMenuName, root, 0);
}
}
/*
* Check for and return an overridden default ICON specified in the prefs
*/
unsigned long
winOverrideDefaultIcon()
{
HICON hicon;
char fname[PATH_MAX+NAME_MAX+2];
if (pref.defaultIconName[0])
{
/* Make sure we have a dir with trailing backslash */
/* Note we are using _Windows_ paths here, not cygwin */
strcpy (fname, pref.iconDirectory);
if (pref.iconDirectory[0])
if (fname[strlen(fname)-1]!='\\')
strcat (fname, "\\");
strcat (fname, pref.defaultIconName);
hicon = (HICON)LoadImage(NULL,
fname,
IMAGE_ICON,
0, 0,
LR_DEFAULTSIZE|LR_LOADFROMFILE);
if (hicon==NULL)
ErrorF ("winOverrideDefaultIcon: LoadIcon(%s) failed\n", fname);
return (unsigned long)hicon;
}
return 0;
}
/*
* Check for a match of the window class to one specified in the
* ICONS{} section in the prefs file, and load the icon from a file
*/
unsigned long
winOverrideIcon (unsigned long longWin)
{
WindowPtr pWin = (WindowPtr) longWin;
char *res_name, *res_class;
int i;
HICON hicon;
char fname[PATH_MAX+NAME_MAX+2];
char *wmName;
if (pWin==NULL)
return 0;
/* If we can't find the class, we can't override from default! */
if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class))
return 0;
winMultiWindowGetWMName (pWin, &wmName);
for (i=0; i<pref.iconItems; i++) {
if (!strcmp(pref.icon[i].match, res_name) ||
!strcmp(pref.icon[i].match, res_class) ||
(wmName && strstr(wmName, pref.icon[i].match)))
{
free (res_name);
free (res_class);
if (wmName)
free (wmName);
if (pref.icon[i].hicon)
return pref.icon[i].hicon;
/* Make sure we have a dir with trailing backslash */
/* Note we are using _Windows_ paths here, not cygwin */
strcpy (fname, pref.iconDirectory);
if (pref.iconDirectory[0])
if (fname[strlen(fname)-1]!='\\')
strcat (fname, "\\");
strcat (fname, pref.icon[i].iconFile);
hicon = (HICON)LoadImage(NULL,
fname,
IMAGE_ICON,
0, 0,
LR_DEFAULTSIZE|LR_LOADFROMFILE);
if (hicon==NULL)
ErrorF ("winOverrideIcon: LoadIcon(%s) failed\n", fname);
pref.icon[i].hicon = (unsigned long)hicon;
return (unsigned long)hicon;
}
}
/* Didn't find the icon, fail gracefully */
free (res_name);
free (res_class);
if (wmName)
free (wmName);
return 0;
}
/*
* Should we free this icon or leave it in memory (is it part of our
* ICONS{} overrides)?
*/
int
winIconIsOverride(unsigned hiconIn)
{
HICON hicon;
int i;
hicon = (HICON)hiconIn;
if (!hicon)
return 0;
for (i=0; i<pref.iconItems; i++)
if ((HICON)pref.icon[i].hicon == hicon)
return 1;
return 0;
}
/*
* Try and open ~/.XWinrc and /usr/X11R6/lib/X11/system.XWinrc
* Load it into prefs structure for use by other functions
*/
void
LoadPreferences ()
{
char *home;
char fname[PATH_MAX+NAME_MAX+2];
FILE *prefFile;
char szDisplay[512];
char *szEnvDisplay;
int i, j;
char param[PARAM_MAX+1];
char *srcParam, *dstParam;
/* First, clear all preference settings */
memset (&pref, 0, sizeof(pref));
prefFile = NULL;
/* Now try and find a ~/.xwinrc file */
home = getenv ("HOME");
if (home)
{
strcpy (fname, home);
if (fname[strlen(fname)-1]!='/')
strcat (fname, "/");
strcat (fname, ".XWinrc");
prefFile = fopen (fname, "r");
}
/* No home file found, check system default */
if (!prefFile)
prefFile = fopen (PROJECTROOT"/lib/X11/system.XWinrc", "r");
/* If we could open it, then read the settings and close it */
if (prefFile)
{
parse_file (prefFile);
fclose (prefFile);
}
/* Setup a DISPLAY environment variable, need to allocate on heap */
/* because putenv doesn't copy the argument... */
snprintf (szDisplay, 512, "DISPLAY=127.0.0.1:%s.0", display);
szEnvDisplay = (char *)(malloc (strlen(szDisplay)+1));
if (szEnvDisplay)
{
strcpy (szEnvDisplay, szDisplay);
putenv (szEnvDisplay);
}
/* Replace any "%display%" in menu commands with display string */
snprintf (szDisplay, 512, "127.0.0.1:%s.0", display);
for (i=0; i<pref.menuItems; i++)
{
for (j=0; j<pref.menu[i].menuItems; j++)
{
if (pref.menu[i].menuItem[j].cmd==CMD_EXEC)
{
srcParam = pref.menu[i].menuItem[j].param;
dstParam = param;
while (*srcParam) {
if (!strncmp(srcParam, "%display%", 9))
{
memcpy (dstParam, szDisplay, strlen(szDisplay));
dstParam += strlen(szDisplay);
srcParam += 9;
}
else
{
*dstParam = *srcParam;
dstParam++;
srcParam++;
}
}
*dstParam = 0;
strcpy (pref.menu[i].menuItem[j].param, param);
} /* cmd==cmd_exec */
} /* for all menuitems */
} /* for all menus */
}

147
hw/xwin/winprefs.h Normal file
View File

@ -0,0 +1,147 @@
/*
* Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
* shall not be used in advertising or otherwise to promote the sale, use
* or other dealings in this Software without prior written authorization
* from the XFree86 Project.
*
* Authors: Earle F. Philhower, III
*/
/* $XFree86: xc/programs/Xserver/hw/xwin/winprefs.h,v 1.1 2003/10/02 13:30:11 eich Exp $ */
/* Need to know how long paths can be... */
#include <limits.h>
#ifndef NAME_MAX
#define NAME_MAX PATH_MAX
#endif
#define MENU_MAX 128 /* Maximum string length of a menu name or item */
#define PARAM_MAX (4*PATH_MAX) /* Maximim length of a parameter to a MENU */
/* Supported commands in a MENU {} statement */
typedef enum MENUCOMMANDTYPE
{
CMD_EXEC, /* /bin/sh -c the parameter */
CMD_MENU, /* Display a popup menu named param */
CMD_SEPARATOR, /* Menu separator */
CMD_ALWAYSONTOP, /* Toggle always-on-top mode */
CMD_RELOAD /* Reparse the .XWINRC file */
} MENUCOMMANDTYPE;
/* Where to place a system menu */
typedef enum MENUPOSITION
{
AT_START, /* Place menu at the top of the system menu */
AT_END /* Put it at the bottom of the menu (default) */
} MENUPOSITION;
/* Menu item definitions */
typedef struct MENUITEM
{
char text[MENU_MAX+1]; /* To be displayed in menu */
MENUCOMMANDTYPE cmd; /* What should it do? */
char param[PARAM_MAX+1]; /* Any parameters? */
unsigned long commandID; /* Windows WM_COMMAND ID assigned at runtime */
} MENUITEM;
/* A completely read in menu... */
typedef struct MENUPARSED
{
char menuName[MENU_MAX+1]; /* What's it called in the text? */
MENUITEM *menuItem; /* Array of items */
int menuItems; /* How big's the array? */
} MENUPARSED;
/* To map between a window and a system menu to add for it */
typedef struct SYSMENUITEM
{
char match[MENU_MAX+1]; /* String to look for to apply this sysmenu */
char menuName[MENU_MAX+1]; /* Which menu to show? Used to set *menu */
MENUPOSITION menuPos; /* Where to place it (ignored in root) */
} SYSMENUITEM;
/* To redefine icons for certain window types */
typedef struct ICONITEM
{
char match[MENU_MAX+1]; /* What string to search for? */
char iconFile[PATH_MAX+NAME_MAX+2]; /* Icon location, WIN32 path */
unsigned long hicon; /* LoadImage() result */
} ICONITEM;
typedef struct WINMULTIWINDOWPREFS
{
/* Menu information */
MENUPARSED *menu; /* Array of created menus */
int menuItems; /* How big? */
/* Taskbar menu settings */
char rootMenuName[MENU_MAX+1]; /* Menu for taskbar icon */
/* System menu addition menus */
SYSMENUITEM *sysMenu;
int sysMenuItems;
/* Which menu to add to unmatched windows? */
char defaultSysMenuName[MENU_MAX+1];
MENUPOSITION defaultSysMenuPos; /* Where to place it */
/* Icon information */
char iconDirectory[PATH_MAX+1]; /* Where do the .icos lie? (Win32 path) */
char defaultIconName[NAME_MAX+1]; /* Replacement for x.ico */
ICONITEM *icon;
int iconItems;
} WINMULTIWINDOWPREFS;
/* Functions */
void
LoadPreferences();
void
SetupRootMenu (unsigned long hmenuRoot);
void
SetupSysMenu (unsigned long hwndIn);
void
HandleCustomWM_INITMENU(unsigned long hwndIn,
unsigned long hmenuIn);
int
HandleCustomWM_COMMAND (unsigned long hwndIn,
int command);
int
winIconIsOverride (unsigned hiconIn);
unsigned long
winOverrideIcon (unsigned long longpWin);
unsigned long
winOverrideDefaultIcon();

113
hw/xwin/winprefslex.l Normal file
View File

@ -0,0 +1,113 @@
%{ # -*- C -*-
/*
* Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
* shall not be used in advertising or otherwise to promote the sale, use
* or other dealings in this Software without prior written authorization
* from the XFree86 Project.
*
* Authors: Earle F. Philhower, III
*/
/* $XFree86: xc/programs/Xserver/hw/xwin/winprefslex.l,v 1.1 2003/10/02 13:30:11 eich Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "winprefsyacc.h"
extern YYSTYPE yylval;
extern char *yytext;
extern int yyparse();
extern void ErrorF (const char* /*f*/, ...);
int yylineno;
/* Copy the parsed string, must be free()d in yacc parser */
static char *makestr(char *str)
{
char *ptr;
ptr = (char*)malloc (strlen(str)+1);
if (!ptr)
{
ErrorF ("winMultiWindowLex:makestr() out of memory\n");
exit (-1);
}
strcpy(ptr, str);
return ptr;
}
%}
%option yylineno
%%
\#.*[\r\n] { /* comment */ return NEWLINE; }
\/\/.*[\r\n] { /* comment */ return NEWLINE; }
[\r\n] { return NEWLINE; }
[ \t]+ { /* ignore whitespace */ }
[mM][eE][nN][uU] { return MENU; }
[iI][cC][oO][nN][dD][iI][rR][eE][cC][tT][oO][rR][yY] { return ICONDIRECTORY; }
[dD][eE][fF][aA][uU][lL][tT][iI][cC][oO][nN] { return DEFAULTICON; }
[iI][cC][oO][nN][sS] { return ICONS; }
[rR][oO][oO][tT][mM][eE][nN][uU] { return ROOTMENU; }
[dD][eE][fF][aA][uU][lL][tT][sS][yY][sS][mM][eE][nN][uU] { return DEFAULTSYSMENU; }
[sS][yY][sS][mM][eE][nN][uU] { return SYSMENU; }
[sS][eE][pP][aA][rR][aA][tT][oO][rR] { return SEPARATOR; }
[aA][tT][sS][tT][aA][rR][tT] { return ATSTART; }
[aA][tT][eE][nN][dD] { return ATEND; }
[eE][xX][eE][cC] { return EXEC; }
[aA][lL][wW][aA][yY][sS][oO][nN][tT][oO][pP] { return ALWAYSONTOP; }
[dD][eE][bB][uU][gG] { return DEBUG; }
[rR][eE][lL][oO][aA][dD] { return RELOAD; }
"{" { return LB; }
"}" { return RB; }
"\""[^\"\r\n]+"\"" { yylval.sVal = makestr(yytext+1); \
yylval.sVal[strlen(yylval.sVal)-1] = 0; \
return STRING; }
[^ \t\r\n]+ { yylval.sVal = makestr(yytext); \
return STRING; }
%%
/*
* Run-of-the mill requirement for yacc
*/
int
yywrap ()
{
return 1;
}
/*
* Run a file through the yacc parser
*/
void
parse_file (FILE *file)
{
if (!file)
return;
yylineno = 1;
yyin = file;
yyparse ();
}

334
hw/xwin/winprefsyacc.y Normal file
View File

@ -0,0 +1,334 @@
%{
/*
* Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
* shall not be used in advertising or otherwise to promote the sale, use
* or other dealings in this Software without prior written authorization
* from the XFree86 Project.
*
* Authors: Earle F. Philhower, III
*/
/* $XFree86: xc/programs/Xserver/hw/xwin/winprefsyacc.y,v 1.1 2003/10/02 13:30:11 eich Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "winprefs.h"
/* The following give better error messages in bison at the cost of a few KB */
#define YYERROR_VERBOSE 1
/* The global pref settings */
WINMULTIWINDOWPREFS pref;
/* The working menu */
static MENUPARSED menu;
/* Functions for parsing the tokens into out structure */
/* Defined at the end section of this file */
static void SetIconDirectory (char *path);
static void SetDefaultIcon (char *fname);
static void SetRootMenu (char *menu);
static void SetDefaultSysMenu (char *menu, int pos);
static void OpenMenu(char *menuname);
static void AddMenuLine(char *name, MENUCOMMANDTYPE cmd, char *param);
static void CloseMenu();
static void OpenIcons();
static void AddIconLine(char *matchstr, char *iconfile);
static void CloseIcons();
static void OpenSysMenu();
static void AddSysMenuLine(char *matchstr, char *menuname, int pos);
static void CloseSysMenu();
static int yyerror (char *s);
extern void ErrorF (const char* /*f*/, ...);
extern char *yytext;
extern int yylex();
%}
%union {
char *sVal;
int iVal;
}
%token NEWLINE MENU LB RB ICONDIRECTORY DEFAULTICON ICONS DEFAULTSYSMENU
%token SYSMENU ROOTMENU SEPARATOR ATSTART ATEND EXEC ALWAYSONTOP DEBUG
%token RELOAD
%token <sVal> STRING
%type <iVal> atspot
%%
input: /* empty */
| input line
;
line: NEWLINE
| command
;
newline_or_nada:
| NEWLINE newline_or_nada
;
command: defaulticon
| icondirectory
| menu
| icons
| sysmenu
| rootmenu
| defaultsysmenu
| debug
;
rootmenu: ROOTMENU STRING NEWLINE { SetRootMenu($2); free($2); }
;
defaultsysmenu: DEFAULTSYSMENU STRING atspot NEWLINE { SetDefaultSysMenu($2, $3); free($2); }
;
defaulticon: DEFAULTICON STRING NEWLINE { SetDefaultIcon($2); free($2); }
;
icondirectory: ICONDIRECTORY STRING NEWLINE { SetIconDirectory($2); free($2); }
;
menuline: SEPARATOR NEWLINE newline_or_nada { AddMenuLine("-", CMD_SEPARATOR, ""); }
| STRING ALWAYSONTOP NEWLINE newline_or_nada { AddMenuLine($1, CMD_ALWAYSONTOP, ""); free($1); }
| STRING EXEC STRING NEWLINE newline_or_nada { AddMenuLine($1, CMD_EXEC, $3); free($1); free($3); }
| STRING MENU STRING NEWLINE newline_or_nada { AddMenuLine($1, CMD_MENU, $3); free($1); free($3); }
| STRING RELOAD NEWLINE newline_or_nada { AddMenuLine($1, CMD_RELOAD, ""); free($1); }
;
menulist: menuline
| menuline menulist
;
menu: MENU STRING LB { OpenMenu($2); free($2); } newline_or_nada menulist RB {CloseMenu();}
;
iconline: STRING STRING NEWLINE newline_or_nada { AddIconLine($1, $2); free($1); free($2); }
;
iconlist: iconline
| iconline iconlist
;
icons: ICONS LB {OpenIcons();} newline_or_nada iconlist RB {CloseIcons();}
;
atspot: { $$=AT_END; }
| ATSTART { $$=AT_START; }
| ATEND { $$=AT_END; }
;
sysmenuline: STRING STRING atspot NEWLINE newline_or_nada { AddSysMenuLine($1, $2, $3); free($1); free($2); }
;
sysmenulist: sysmenuline
| sysmenuline sysmenulist
;
sysmenu: SYSMENU LB NEWLINE {OpenSysMenu();} newline_or_nada sysmenulist RB {CloseSysMenu();}
;
debug: DEBUG STRING NEWLINE { ErrorF("LoadPreferences: %s\n", $2); free($2); }
;
%%
/*
* Errors in parsing abort and print log messages
*/
static int
yyerror (char *s)
{
extern int yylineno; /* Handled by flex internally */
ErrorF("LoadPreferences: %s line %d\n", s, yylineno);
return 1;
}
/* Miscellaneous functions to store TOKENs into the structure */
static void
SetIconDirectory (char *path)
{
strncpy (pref.iconDirectory, path, PATH_MAX);
pref.iconDirectory[PATH_MAX] = 0;
}
static void
SetDefaultIcon (char *fname)
{
strncpy (pref.defaultIconName, fname, NAME_MAX);
pref.defaultIconName[NAME_MAX] = 0;
}
static void
SetRootMenu (char *menu)
{
strncpy (pref.rootMenuName, menu, MENU_MAX);
pref.rootMenuName[MENU_MAX] = 0;
}
static void
SetDefaultSysMenu (char *menu, int pos)
{
strncpy (pref.defaultSysMenuName, menu, MENU_MAX);
pref.defaultSysMenuName[MENU_MAX] = 0;
pref.defaultSysMenuPos = pos;
}
static void
OpenMenu (char *menuname)
{
if (menu.menuItem) free(menu.menuItem);
menu.menuItem = NULL;
strncpy(menu.menuName, menuname, MENU_MAX);
menu.menuName[MENU_MAX] = 0;
menu.menuItems = 0;
}
static void
AddMenuLine (char *text, MENUCOMMANDTYPE cmd, char *param)
{
if (menu.menuItem==NULL)
menu.menuItem = (MENUITEM*)malloc(sizeof(MENUITEM));
else
menu.menuItem = (MENUITEM*)
realloc(menu.menuItem, sizeof(MENUITEM)*(menu.menuItems+1));
strncpy (menu.menuItem[menu.menuItems].text, text, MENU_MAX);
menu.menuItem[menu.menuItems].text[MENU_MAX] = 0;
menu.menuItem[menu.menuItems].cmd = cmd;
strncpy(menu.menuItem[menu.menuItems].param, param, PARAM_MAX);
menu.menuItem[menu.menuItems].param[PARAM_MAX] = 0;
menu.menuItem[menu.menuItems].commandID = 0;
menu.menuItems++;
}
static void
CloseMenu ()
{
if (menu.menuItem==NULL || menu.menuItems==0)
{
ErrorF("LoadPreferences: Empty menu detected\n");
return;
}
if (pref.menuItems)
pref.menu = (MENUPARSED*)
realloc (pref.menu, (pref.menuItems+1)*sizeof(MENUPARSED));
else
pref.menu = (MENUPARSED*)malloc (sizeof(MENUPARSED));
memcpy (pref.menu+pref.menuItems, &menu, sizeof(MENUPARSED));
pref.menuItems++;
memset (&menu, 0, sizeof(MENUPARSED));
}
static void
OpenIcons ()
{
if (pref.icon != NULL) {
ErrorF("LoadPreferences: Redefining icon mappings\n");
free(pref.icon);
pref.icon = NULL;
}
pref.iconItems = 0;
}
static void
AddIconLine (char *matchstr, char *iconfile)
{
if (pref.icon==NULL)
pref.icon = (ICONITEM*)malloc(sizeof(ICONITEM));
else
pref.icon = (ICONITEM*)
realloc(pref.icon, sizeof(ICONITEM)*(pref.iconItems+1));
strncpy(pref.icon[pref.iconItems].match, matchstr, MENU_MAX);
pref.icon[pref.iconItems].match[MENU_MAX] = 0;
strncpy(pref.icon[pref.iconItems].iconFile, iconfile, PATH_MAX+NAME_MAX+1);
pref.icon[pref.iconItems].iconFile[PATH_MAX+NAME_MAX+1] = 0;
pref.icon[pref.iconItems].hicon = 0;
pref.iconItems++;
}
static void
CloseIcons ()
{
}
static void
OpenSysMenu ()
{
if (pref.sysMenu != NULL) {
ErrorF("LoadPreferences: Redefining system menu\n");
free(pref.sysMenu);
pref.sysMenu = NULL;
}
pref.sysMenuItems = 0;
}
static void
AddSysMenuLine (char *matchstr, char *menuname, int pos)
{
if (pref.sysMenu==NULL)
pref.sysMenu = (SYSMENUITEM*)malloc(sizeof(SYSMENUITEM));
else
pref.sysMenu = (SYSMENUITEM*)
realloc(pref.sysMenu, sizeof(SYSMENUITEM)*(pref.sysMenuItems+1));
strncpy (pref.sysMenu[pref.sysMenuItems].match, matchstr, MENU_MAX);
pref.sysMenu[pref.sysMenuItems].match[MENU_MAX] = 0;
strncpy (pref.sysMenu[pref.sysMenuItems].menuName, menuname, MENU_MAX);
pref.sysMenu[pref.sysMenuItems].menuName[MENU_MAX] = 0;
pref.sysMenu[pref.sysMenuItems].menuPos = pos;
pref.sysMenuItems++;
}
static void
CloseSysMenu ()
{
}

226
hw/xwin/winpushpxl.c Normal file
View File

@ -0,0 +1,226 @@
/* $XFree86: xc/programs/Xserver/hw/xwin/winpushpxl.c,v 1.1 2003/08/07 23:47:58 alanh Exp $ */
/***********************************************************
Copyright 1987, 1998 The Open Group
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
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
OPEN GROUP 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 of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Digital not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
******************************************************************/
#include "X.h"
#include "gcstruct.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "miscstruct.h"
#include "../mfb/maskbits.h"
#include "mi.h"
#define NPT 128
/* winPushPixels -- squeegees the fill style of pGC through pBitMap
* into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may
* be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit
* is set in the bitmap, the fill style is put onto the drawable using
* the GC's logical function. The drawable is not changed where the bitmap
* has a zero bit or outside the area covered by the stencil.
WARNING:
this code works if the 1-bit deep pixmap format returned by GetSpans
is the same as the format defined by the mfb code (i.e. 32-bit padding
per scanline, scanline unit = 32 bits; later, this might mean
bitsizeof(int) padding and sacnline unit == bitsizeof(int).)
*/
/*
* in order to have both (MSB_FIRST and LSB_FIRST) versions of this
* in the server, we need to rename one of them
*/
void
winPushPixels(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
GCPtr pGC;
PixmapPtr pBitMap;
DrawablePtr pDrawable;
int dx, dy, xOrg, yOrg;
{
int h, dxDivPPW, ibEnd;
MiBits *pwLineStart;
register MiBits *pw, *pwEnd;
register MiBits msk;
register int ib, w;
register int ipt; /* index into above arrays */
Bool fInBox;
DDXPointRec pt[NPT], ptThisLine;
int width[NPT];
PixelType startmask;
startmask = (MiBits)(-1) ^
LONG2CHARSDIFFORDER((MiBits)(-1) >> 1);
pwLineStart = (MiBits *)xalloc(BitmapBytePad(dx));
if (!pwLineStart)
return;
ipt = 0;
dxDivPPW = dx/PPW;
for(h = 0, ptThisLine.x = 0, ptThisLine.y = 0;
h < dy;
h++, ptThisLine.y++)
{
(*pBitMap->drawable.pScreen->GetSpans)((DrawablePtr)pBitMap, dx,
&ptThisLine, &dx, 1, (char *)pwLineStart);
pw = pwLineStart;
/* Process all words which are fully in the pixmap */
fInBox = FALSE;
pwEnd = pwLineStart + dxDivPPW;
while(pw < pwEnd)
{
w = *pw;
#ifdef XFree86Server
msk = startmask;
#else
msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1);
#endif
for(ib = 0; ib < PPW; ib++)
{
if(w & msk)
{
if(!fInBox)
{
pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
pt[ipt].y = h + yOrg;
/* start new box */
fInBox = TRUE;
}
}
else
{
if(fInBox)
{
width[ipt] = ((pw - pwLineStart) << PWSH) +
ib + xOrg - pt[ipt].x;
if (++ipt >= NPT)
{
(*pGC->ops->FillSpans)(pDrawable, pGC,
NPT, pt, width, TRUE);
ipt = 0;
}
/* end box */
fInBox = FALSE;
}
}
#ifdef XFree86Server
/* This is not quite right, but it'll do for now */
msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
#else
msk = SCRRIGHT(msk, 1);
#endif
}
pw++;
}
ibEnd = dx & PIM;
if(ibEnd)
{
/* Process final partial word on line */
w = *pw;
#ifdef XFree86Server
msk = startmask;
#else
msk = (MiBits)(-1) ^ SCRRIGHT((MiBits)(-1), 1);
#endif
for(ib = 0; ib < ibEnd; ib++)
{
if(w & msk)
{
if(!fInBox)
{
/* start new box */
pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
pt[ipt].y = h + yOrg;
fInBox = TRUE;
}
}
else
{
if(fInBox)
{
/* end box */
width[ipt] = ((pw - pwLineStart) << PWSH) +
ib + xOrg - pt[ipt].x;
if (++ipt >= NPT)
{
(*pGC->ops->FillSpans)(pDrawable,
pGC, NPT, pt, width, TRUE);
ipt = 0;
}
fInBox = FALSE;
}
}
#ifdef XFree86Server
/* This is not quite right, but it'll do for now */
msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
#else
msk = SCRRIGHT(msk, 1);
#endif
}
}
/* If scanline ended with last bit set, end the box */
if(fInBox)
{
width[ipt] = dx + xOrg - pt[ipt].x;
if (++ipt >= NPT)
{
(*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt, width, TRUE);
ipt = 0;
}
}
}
xfree(pwLineStart);
/* Flush any remaining spans */
if (ipt)
{
(*pGC->ops->FillSpans)(pDrawable, pGC, ipt, pt, width, TRUE);
}
}

139
hw/xwin/winrop.c Normal file
View File

@ -0,0 +1,139 @@
/*
*Copyright (C) 1994-2002 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
*shall not be used in advertising or otherwise to promote the sale, use
*or other dealings in this Software without prior written authorization
*from the XFree86 Project.
*
* Authors: Alan Hourihane <alanh@fairlite.demon.co.uk>
*/
/* $XFree86: xc/programs/Xserver/hw/xwin/winrop.c,v 1.1 2003/08/07 23:47:58 alanh Exp $ */
/*
* Raster operations used by Windows translated to X's 16 rop codes...
*/
#include "win.h"
int g_copyROP[16] = { 0xFF0062, /* GXclear - 0 */
0x8800C6, /* GXand - S & D */
0x440328, /* GXandReverse - S & !D */
0xCC0020, /* GXcopy - S */
0x220326, /* GXandInverted - !S & D */
0xAA0029, /* GXnoop - D */
0x660046, /* GXxor - S ^ D */
0xEE0086, /* GXor - S | D */
0x1100A6, /* GXnor - !S & !D */
0x990126, /* GXequiv - !S ^ D */
0x550009, /* GXinvert - !D */
0xDD0228, /* GXorReverse - S | !D */
0x330008, /* GXcopyInverted - !S */
0xBB0226, /* GXorInverted - !S | D */
0x7700C6, /* GXnand - !S | !D */
0x000042 /* GXset - 1 */
};
int g_patternROP[16] = {0xFF0062, /* GXclear - 0 */
0xA000C9, /* GXand - P & D */
0xF50225, /* GXandReverse - P & !D */
0xF00021, /* GXcopy - P */
0x5F00E9, /* GXandInverted - !P & D */
0xAA0029, /* GXnoop - D */
0xA50065, /* GXxor - P ^ D */
0xA000C9, /* GXor - P | D */
0x5F00E9, /* GXnor - !P & !D */
0x5A0049, /* GXequiv - !P ^ D */
0x550009, /* GXinvert - !D */
0x500325, /* GXorReverse - P | !D */
0x0F0001, /* GXcopyInverted - !P */
0x0A0329, /* GXorInverted - !P | D */
0x0500A9, /* GXnand - !P | !D */
0x000042 /* GXset - 1 */
};
void
ROP16 (HDC hdc, int rop)
{
switch (rop)
{
case GXclear:
SetROP2 (hdc, R2_BLACK);
break;
case GXand:
SetROP2 (hdc, R2_MASKPEN);
break;
case GXandReverse:
SetROP2 (hdc, R2_MASKPENNOT);
break;
case GXcopy:
SetROP2 (hdc, R2_COPYPEN);
break;
case GXnoop:
SetROP2 (hdc, R2_NOP);
break;
case GXxor:
SetROP2 (hdc, R2_XORPEN);
break;
case GXor:
SetROP2 (hdc, R2_MERGEPEN);
break;
case GXnor:
SetROP2 (hdc, R2_NOTMERGEPEN);
break;
case GXequiv:
SetROP2 (hdc, R2_NOTXORPEN);
break;
case GXinvert:
SetROP2 (hdc, R2_NOT);
break;
case GXorReverse:
SetROP2 (hdc, R2_MERGEPENNOT);
break;
case GXcopyInverted:
SetROP2 (hdc, R2_NOTCOPYPEN);
break;
case GXorInverted:
SetROP2 (hdc, R2_MERGENOTPEN);
break;
case GXnand:
SetROP2 (hdc, R2_NOTMASKPEN);
break;
case GXset:
SetROP2 (hdc, R2_WHITE);
break;
}
}

209
hw/xwin/wintrayicon.c Executable file
View File

@ -0,0 +1,209 @@
/*
*Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
*shall not be used in advertising or otherwise to promote the sale, use
*or other dealings in this Software without prior written authorization
*from the XFree86 Project.
*
* Authors: Early Ehlinger
* Harold L Hunt II
*/
/* $XFree86: xc/programs/Xserver/hw/xwin/wintrayicon.c,v 1.2 2003/10/02 13:30:11 eich Exp $ */
#include "win.h"
#include <shellapi.h>
#include "winprefs.h"
/*
* Initialize the tray icon
*/
void
winInitNotifyIcon (winPrivScreenPtr pScreenPriv)
{
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
NOTIFYICONDATA nid = {0};
nid.cbSize = sizeof (NOTIFYICONDATA);
nid.hWnd = pScreenPriv->hwndScreen;
nid.uID = pScreenInfo->dwScreen;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.uCallbackMessage = WM_TRAYICON;
nid.hIcon = LoadImage (g_hInstance,
MAKEINTRESOURCE(IDI_XWIN),
IMAGE_ICON,
GetSystemMetrics (SM_CXSMICON),
GetSystemMetrics (SM_CYSMICON),
0);
/* Save handle to the icon so it can be freed later */
pScreenPriv->hiconNotifyIcon = nid.hIcon;
/* Set display and screen-specific tooltip text */
snprintf (nid.szTip,
sizeof (nid.szTip),
"Cygwin/XFree86 Server - %s:%d",
display,
(int) pScreenInfo->dwScreen);
/* Add the tray icon */
if (!Shell_NotifyIcon (NIM_ADD, &nid))
ErrorF ("winInitNotifyIcon - Shell_NotifyIcon Failed\n");
}
/*
* Delete the tray icon
*/
void
winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv)
{
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
NOTIFYICONDATA nid = {0};
#if 0
ErrorF ("winDeleteNotifyIcon\n");
#endif
nid.cbSize = sizeof (NOTIFYICONDATA);
nid.hWnd = pScreenPriv->hwndScreen;
nid.uID = pScreenInfo->dwScreen;
/* Delete the tray icon */
if (!Shell_NotifyIcon (NIM_DELETE, &nid))
{
ErrorF ("winDeleteNotifyIcon - Shell_NotifyIcon failed\n");
return;
}
/* Free the icon that was loaded */
if (pScreenPriv->hiconNotifyIcon != NULL
&& DestroyIcon (pScreenPriv->hiconNotifyIcon) == 0)
{
ErrorF ("winDeleteNotifyIcon - DestroyIcon failed\n");
}
pScreenPriv->hiconNotifyIcon = NULL;
}
/*
* Process messages intended for the tray icon
*/
LRESULT
winHandleIconMessage (HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam,
winPrivScreenPtr pScreenPriv)
{
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
switch (lParam)
{
case WM_LBUTTONDBLCLK:
/* Display Exit dialog box */
winDisplayExitDialog (pScreenPriv);
break;
case WM_RBUTTONUP:
{
POINT ptCursor;
HMENU hmenuPopup;
HMENU hmenuTray;
/* Get cursor position */
GetCursorPos (&ptCursor);
/* Load tray icon menu resource */
hmenuPopup = LoadMenu (g_hInstance,
MAKEINTRESOURCE(IDM_TRAYICON_MENU));
if (!hmenuPopup)
ErrorF ("winHandleIconMessage - LoadMenu failed\n");
/* Get actual tray icon menu */
hmenuTray = GetSubMenu (hmenuPopup, 0);
/* Check for MultiWindow mode */
if (pScreenInfo->fMultiWindow)
{
/* Check if root window is shown or hidden */
if (pScreenPriv->fRootWindowShown)
{
/* Remove Show Root Window button */
RemoveMenu (hmenuTray,
ID_APP_SHOW_ROOT,
MF_BYCOMMAND);
}
else
{
/* Remove Hide Root Window button */
RemoveMenu (hmenuTray,
ID_APP_HIDE_ROOT,
MF_BYCOMMAND);
}
}
else
{
/* Remove Show Root Window button */
RemoveMenu (hmenuTray,
ID_APP_SHOW_ROOT,
MF_BYCOMMAND);
/* Remove Hide Root Window button */
RemoveMenu (hmenuTray,
ID_APP_HIDE_ROOT,
MF_BYCOMMAND);
/* Remove separator */
RemoveMenu (hmenuTray,
0,
MF_BYPOSITION);
}
SetupRootMenu ((unsigned long)hmenuTray);
/*
* NOTE: This three-step procedure is required for
* proper popup menu operation. Without the
* call to SetForegroundWindow the
* popup menu will often not disappear when you click
* outside of it. Without the PostMessage the second
* time you display the popup menu it might immediately
* disappear.
*/
SetForegroundWindow (hwnd);
TrackPopupMenuEx (hmenuTray,
TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_RIGHTBUTTON,
ptCursor.x, ptCursor.y,
hwnd,
NULL);
PostMessage (hwnd, WM_NULL, 0, 0);
/* Free menu */
DestroyMenu (hmenuPopup);
}
break;
}
return 0;
}

206
hw/xwin/winvideo.c Executable file
View File

@ -0,0 +1,206 @@
/*
*Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
*shall not be used in advertising or otherwise to promote the sale, use
*or other dealings in this Software without prior written authorization
*from the XFree86 Project.
*
* Authors: Harold L Hunt II
*/
/* $XFree86: xc/programs/Xserver/hw/xwin/winvideo.c,v 1.2 2003/11/10 18:22:44 tsi Exp $ */
#include "win.h"
#include "Xv.h"
#include "Xvproto.h"
/*
* winInitVideo - Initialize support for the X Video (Xv) Extension.
*/
void
winInitVideo (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
if (pScreenInfo->dwBPP > 8)
{
}
}
#if 0
#include "../xfree86/common/xf86.h"
#include "../Xext/xvdix.h"
#include "../xfree86/common/xf86xv.h"
#include "Xv.h"
#endif
#include "win.h"
#if 0
/* client libraries expect an encoding */
static XF86VideoEncodingRec DummyEncoding[1] =
{
{
0,
"XV_IMAGE",
IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
{1, 1}
}
};
#define NUM_FORMATS 3
static XF86VideoFormatRec Formats[NUM_FORMATS] =
{
{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
};
#define NUM_ATTRIBUTES 3
static XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
{
{XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
{XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
{XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
};
#define NUM_IMAGES 4
static XF86ImageRec Images[NUM_IMAGES] =
{
XVIMAGE_YUY2,
XVIMAGE_YV12,
XVIMAGE_I420,
XVIMAGE_UYVY
};
/*
* winInitVideo - Initialize support for the X Video (Xv) Extension.
*/
void
winInitVideo (ScreenPtr pScreen)
{
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
XF86VideoAdaptorPtr newAdaptor = NULL;
if (pScreenInfo->dwBPP > 8)
{
newAdaptor = I810SetupImageVideo (pScreen);
I810InitOffscreenImages (pScreen);
}
xf86XVScreenInit (pScreen, adaptors, 1);
}
static XF86VideoAdaptorPtr
winSetupImageVideo (ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
#if 0
I810Ptr pI810 = I810PTR(pScrn);
#endif
XF86VideoAdaptorPtr adapt;
if (!(adapt = xcalloc (1, sizeof(XF86VideoAdaptorRec))))
return NULL;
adapt->type = XvWindowMask | XvInputMask | XvImageMask;
adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
adapt->name = "Cygwin/XFree86 Video Overlay";
adapt->nEncodings = 1;
adapt->pEncodings = DummyEncoding;
adapt->nFormats = NUM_FORMATS;
adapt->pFormats = Formats;
adapt->nPorts = 1;
adapt->pPortPrivates = NULL;
adapt->pPortPrivates[0].ptr = NULL;
adapt->pAttributes = Attributes;
adapt->nImages = NUM_IMAGES;
adapt->nAttributes = NUM_ATTRIBUTES;
adapt->pImages = Images;
adapt->PutVideo = NULL;
adapt->PutStill = NULL;
adapt->GetVideo = NULL;
adapt->GetStill = NULL;
#if 0
adapt->StopVideo = I810StopVideo;
adapt->SetPortAttribute = I810SetPortAttribute;
adapt->GetPortAttribute = I810GetPortAttribute;
adapt->QueryBestSize = I810QueryBestSize;
adapt->PutImage = I810PutImage;
adapt->QueryImageAttributes = I810QueryImageAttributes;
#endif
#if 0
pPriv->colorKey = pI810->colorKey & ((1 << pScrn->depth) - 1);
#endif
pPriv->videoStatus = 0;
pPriv->brightness = 0;
pPriv->contrast = 64;
pPriv->linear = NULL;
pPriv->currentBuf = 0;
#if 0
/* gotta uninit this someplace */
REGION_NULL(pScreen, &pPriv->clip);
#endif
#if 0
pI810->adaptor = adapt;
pI810->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = I810BlockHandler;
#endif
#if 0
xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
xvContrast = MAKE_ATOM("XV_CONTRAST");
xvColorKey = MAKE_ATOM("XV_COLORKEY");
#endif
#if 0
I810ResetVideo(pScrn);
#endif
return adapt;
}
#endif

View File

@ -0,0 +1,135 @@
/*
* Rootless Acceleration Code
*/
/*
* 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/miext/rootless/accel/rlAccel.h,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
/*
* rlBlt.c
*/
void
rlBlt (FbBits *srcLine,
FbStride srcStride,
int srcX,
ScreenPtr pDstScreen,
FbBits *dstLine,
FbStride dstStride,
int dstX,
int width,
int height,
int alu,
FbBits pm,
int bpp,
Bool reverse,
Bool upsidedown);
/*
* rlCopy.c
*/
RegionPtr
rlCopyArea (DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable,
GCPtr pGC,
int xIn,
int yIn,
int widthSrc,
int heightSrc,
int xOut,
int yOut);
/*
* rlFill.c
*/
void
rlFill (DrawablePtr pDrawable,
GCPtr pGC,
int x,
int y,
int width,
int height);
void
rlSolidBoxClipped (DrawablePtr pDrawable,
RegionPtr pClip,
int x1,
int y1,
int x2,
int y2,
FbBits and,
FbBits xor);
/*
* rlFillRect.c
*/
void
rlPolyFillRect(DrawablePtr pDrawable,
GCPtr pGC,
int nrect,
xRectangle *prect);
/*
* rlFillSpans.c
*/
void
rlFillSpans (DrawablePtr pDrawable,
GCPtr pGC,
int n,
DDXPointPtr ppt,
int *pwidth,
int fSorted);
/*
* rlGlyph.c
*/
void
rlImageGlyphBlt (DrawablePtr pDrawable,
GCPtr pGC,
int x,
int y,
unsigned int nglyph,
CharInfoPtr *ppciInit,
pointer pglyphBase);
/*
* rlSolid.c
*/
void
rlSolid (ScreenPtr pScreen,
FbBits *dst,
FbStride dstStride,
int dstX,
int bpp,
int width,
int height,
FbBits and,
FbBits xor);

View File

@ -0,0 +1,366 @@
/*
* Accelerated rootless blit
*/
/*
* This code is largely copied from fbBlt.c.
*
* Copyright © 1998 Keith Packard
* Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
* Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlBlt.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
#include "fb.h"
#include "rootlessCommon.h"
#include "rlAccel.h"
void
rlBlt (FbBits *srcLine,
FbStride srcStride,
int srcX,
ScreenPtr pDstScreen,
FbBits *dstLine,
FbStride dstStride,
int dstX,
int width,
int height,
int alu,
FbBits pm,
int bpp,
Bool reverse,
Bool upsidedown)
{
FbBits *src, *dst;
int leftShift, rightShift;
FbBits startmask, endmask;
FbBits bits, bits1;
int n, nmiddle;
Bool destInvarient;
int startbyte, endbyte;
FbDeclareMergeRop ();
#ifdef FB_24BIT
if (bpp == 24 && !FbCheck24Pix (pm))
{
fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX,
width, height, alu, pm, reverse, upsidedown);
return;
}
#endif
FbInitializeMergeRop(alu, pm);
destInvarient = FbDestInvarientMergeRop();
if (upsidedown)
{
srcLine += (height - 1) * (srcStride);
dstLine += (height - 1) * (dstStride);
srcStride = -srcStride;
dstStride = -dstStride;
}
FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte,
nmiddle, endmask, endbyte);
/*
* Beginning of the rootless acceleration code
*/
if (!startmask && !endmask && alu == GXcopy &&
height * nmiddle * sizeof(*dst) > rootless_CopyBytes_threshold)
{
if (pm == FB_ALLONES && SCREENREC(pDstScreen)->imp->CopyBytes)
{
SCREENREC(pDstScreen)->imp->CopyBytes(
nmiddle * sizeof(*dst), height,
(char *) srcLine + (srcX >> 3),
srcStride * sizeof (*src),
(char *) dstLine + (dstX >> 3),
dstStride * sizeof (*dst));
return;
}
/* FIXME: the pm test here isn't super-wonderful - just because
we don't care about the top eight bits doesn't necessarily
mean we want them set to 255. But doing this does give a
factor of two performance improvement when copying from a
pixmap to a window, which is pretty common.. */
else if (bpp == 32 && sizeof(FbBits) == 4 &&
pm == 0x00FFFFFFUL && !reverse &&
SCREENREC(pDstScreen)->imp->CompositePixels)
{
/* need to copy XRGB to ARGB. */
void *src[2], *dest[2];
unsigned int src_rowbytes[2], dest_rowbytes[2];
unsigned int fn;
src[0] = (char *) srcLine + (srcX >> 3);
src[1] = NULL;
src_rowbytes[0] = srcStride * sizeof(*src);
src_rowbytes[1] = 0;
dest[0] = (char *) dstLine + (dstX >> 3);
dest[1] = dest[0];
dest_rowbytes[0] = dstStride * sizeof(*dst);
dest_rowbytes[1] = dest_rowbytes[0];
fn = RL_COMPOSITE_FUNCTION(RL_COMPOSITE_SRC, RL_DEPTH_ARGB8888,
RL_DEPTH_NIL, RL_DEPTH_ARGB8888);
if (SCREENREC(pDstScreen)->imp->CompositePixels(
nmiddle, height,
fn, src, src_rowbytes,
NULL, 0, dest, dest_rowbytes) == Success)
{
return;
}
}
}
/* End of the rootless acceleration code */
if (reverse)
{
srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
srcX = (srcX + width - 1) & FB_MASK;
dstX = (dstX + width - 1) & FB_MASK;
}
else
{
srcLine += srcX >> FB_SHIFT;
dstLine += dstX >> FB_SHIFT;
srcX &= FB_MASK;
dstX &= FB_MASK;
}
if (srcX == dstX)
{
while (height--)
{
src = srcLine;
srcLine += srcStride;
dst = dstLine;
dstLine += dstStride;
if (reverse)
{
if (endmask)
{
bits = *--src;
--dst;
FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
}
n = nmiddle;
if (destInvarient)
{
while (n--)
*--dst = FbDoDestInvarientMergeRop(*--src);
}
else
{
while (n--)
{
bits = *--src;
--dst;
*dst = FbDoMergeRop (bits, *dst);
}
}
if (startmask)
{
bits = *--src;
--dst;
FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
}
}
else
{
if (startmask)
{
bits = *src++;
FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
dst++;
}
n = nmiddle;
if (destInvarient)
{
#if 0
/*
* This provides some speedup on screen->screen blts
* over the PCI bus, usually about 10%. But fb
* isn't usually used for this operation...
*/
if (_ca2 + 1 == 0 && _cx2 == 0)
{
FbBits t1, t2, t3, t4;
while (n >= 4)
{
t1 = *src++;
t2 = *src++;
t3 = *src++;
t4 = *src++;
*dst++ = t1;
*dst++ = t2;
*dst++ = t3;
*dst++ = t4;
n -= 4;
}
}
#endif
while (n--)
*dst++ = FbDoDestInvarientMergeRop(*src++);
}
else
{
while (n--)
{
bits = *src++;
*dst = FbDoMergeRop (bits, *dst);
dst++;
}
}
if (endmask)
{
bits = *src;
FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
}
}
}
}
else
{
if (srcX > dstX)
{
leftShift = srcX - dstX;
rightShift = FB_UNIT - leftShift;
}
else
{
rightShift = dstX - srcX;
leftShift = FB_UNIT - rightShift;
}
while (height--)
{
src = srcLine;
srcLine += srcStride;
dst = dstLine;
dstLine += dstStride;
bits1 = 0;
if (reverse)
{
if (srcX < dstX)
bits1 = *--src;
if (endmask)
{
bits = FbScrRight(bits1, rightShift);
if (FbScrRight(endmask, leftShift))
{
bits1 = *--src;
bits |= FbScrLeft(bits1, leftShift);
}
--dst;
FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
}
n = nmiddle;
if (destInvarient)
{
while (n--)
{
bits = FbScrRight(bits1, rightShift);
bits1 = *--src;
bits |= FbScrLeft(bits1, leftShift);
--dst;
*dst = FbDoDestInvarientMergeRop(bits);
}
}
else
{
while (n--)
{
bits = FbScrRight(bits1, rightShift);
bits1 = *--src;
bits |= FbScrLeft(bits1, leftShift);
--dst;
*dst = FbDoMergeRop(bits, *dst);
}
}
if (startmask)
{
bits = FbScrRight(bits1, rightShift);
if (FbScrRight(startmask, leftShift))
{
bits1 = *--src;
bits |= FbScrLeft(bits1, leftShift);
}
--dst;
FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
}
}
else
{
if (srcX > dstX)
bits1 = *src++;
if (startmask)
{
bits = FbScrLeft(bits1, leftShift);
bits1 = *src++;
bits |= FbScrRight(bits1, rightShift);
FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
dst++;
}
n = nmiddle;
if (destInvarient)
{
while (n--)
{
bits = FbScrLeft(bits1, leftShift);
bits1 = *src++;
bits |= FbScrRight(bits1, rightShift);
*dst = FbDoDestInvarientMergeRop(bits);
dst++;
}
}
else
{
while (n--)
{
bits = FbScrLeft(bits1, leftShift);
bits1 = *src++;
bits |= FbScrRight(bits1, rightShift);
*dst = FbDoMergeRop(bits, *dst);
dst++;
}
}
if (endmask)
{
bits = FbScrLeft(bits1, leftShift);
if (FbScrLeft(endmask, rightShift))
{
bits1 = *src;
bits |= FbScrRight(bits1, rightShift);
}
FbDoRightMaskByteMergeRop (dst, bits, endbyte, endmask);
}
}
}
}
}

View File

@ -0,0 +1,103 @@
/*
* This code is largely copied from fbcopy.c.
*
* Copyright © 1998 Keith Packard
* Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlCopy.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
#include "fb.h"
#include "rlAccel.h"
void
rlCopyNtoN (DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable,
GCPtr pGC,
BoxPtr pbox,
int nbox,
int dx,
int dy,
Bool reverse,
Bool upsidedown,
Pixel bitplane,
void *closure)
{
CARD8 alu = pGC ? pGC->alu : GXcopy;
FbBits pm = pGC ? fbGetGCPrivate(pGC)->pm : FB_ALLONES;
FbBits *src;
FbStride srcStride;
int srcBpp;
int srcXoff, srcYoff;
FbBits *dst;
FbStride dstStride;
int dstBpp;
int dstXoff, dstYoff;
fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
while (nbox--)
{
rlBlt (src + (pbox->y1 + dy + srcYoff) * srcStride,
srcStride,
(pbox->x1 + dx + srcXoff) * srcBpp,
pDstDrawable->pScreen,
dst + (pbox->y1 + dstYoff) * dstStride,
dstStride,
(pbox->x1 + dstXoff) * dstBpp,
(pbox->x2 - pbox->x1) * dstBpp,
(pbox->y2 - pbox->y1),
alu,
pm,
dstBpp,
reverse,
upsidedown);
pbox++;
}
}
RegionPtr
rlCopyArea (DrawablePtr pSrcDrawable,
DrawablePtr pDstDrawable,
GCPtr pGC,
int xIn,
int yIn,
int widthSrc,
int heightSrc,
int xOut,
int yOut)
{
fbCopyProc copy;
#ifdef FB_24_32BIT
if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
copy = fb24_32CopyMtoN;
else
#endif
copy = rlCopyNtoN;
return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
widthSrc, heightSrc, xOut, yOut, copy, 0, 0);
}

View File

@ -0,0 +1,217 @@
/*
* This code is largely copied from fbfill.c.
*
* Copyright © 1998 Keith Packard
* Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlFill.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
#include "fb.h"
#include "rlAccel.h"
void
rlFill (DrawablePtr pDrawable,
GCPtr pGC,
int x,
int y,
int width,
int height)
{
FbBits *dst;
FbStride dstStride;
int dstBpp;
int dstXoff, dstYoff;
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
switch (pGC->fillStyle) {
case FillSolid:
rlSolid (pDrawable->pScreen,
dst + (y + dstYoff) * dstStride,
dstStride,
(x + dstXoff) * dstBpp,
dstBpp,
width * dstBpp, height,
pPriv->and, pPriv->xor);
break;
case FillStippled:
case FillOpaqueStippled: {
PixmapPtr pStip = pGC->stipple;
int stipWidth = pStip->drawable.width;
int stipHeight = pStip->drawable.height;
if (dstBpp == 1)
{
int alu;
FbBits *stip;
FbStride stipStride;
int stipBpp;
int stipXoff, stipYoff; /* XXX assumed to be zero */
if (pGC->fillStyle == FillStippled)
alu = FbStipple1Rop(pGC->alu,pGC->fgPixel);
else
alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel);
fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
fbTile (dst + (y + dstYoff) * dstStride,
dstStride,
x + dstXoff,
width, height,
stip,
stipStride,
stipWidth,
stipHeight,
alu,
pPriv->pm,
dstBpp,
(pGC->patOrg.x + pDrawable->x + dstXoff),
pGC->patOrg.y + pDrawable->y + dstYoff - y);
}
else
{
FbStip *stip;
FbStride stipStride;
int stipBpp;
int stipXoff, stipYoff; /* XXX assumed to be zero */
FbBits fgand, fgxor, bgand, bgxor;
fgand = pPriv->and;
fgxor = pPriv->xor;
if (pGC->fillStyle == FillStippled)
{
bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES);
bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES);
}
else
{
bgand = pPriv->bgand;
bgxor = pPriv->bgxor;
}
fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
fbStipple (dst + (y + dstYoff) * dstStride,
dstStride,
(x + dstXoff) * dstBpp,
dstBpp,
width * dstBpp, height,
stip,
stipStride,
stipWidth,
stipHeight,
pPriv->evenStipple,
fgand, fgxor,
bgand, bgxor,
pGC->patOrg.x + pDrawable->x + dstXoff,
pGC->patOrg.y + pDrawable->y + dstYoff - y);
}
break;
}
case FillTiled: {
PixmapPtr pTile = pGC->tile.pixmap;
FbBits *tile;
FbStride tileStride;
int tileBpp;
int tileWidth;
int tileHeight;
int tileXoff, tileYoff; /* XXX assumed to be zero */
fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff);
tileWidth = pTile->drawable.width;
tileHeight = pTile->drawable.height;
fbTile (dst + (y + dstYoff) * dstStride,
dstStride,
(x + dstXoff) * dstBpp,
width * dstBpp, height,
tile,
tileStride,
tileWidth * tileBpp,
tileHeight,
pGC->alu,
pPriv->pm,
dstBpp,
(pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp,
pGC->patOrg.y + pDrawable->y + dstYoff - y);
break;
}
}
fbValidateDrawable (pDrawable);
}
void
rlSolidBoxClipped (DrawablePtr pDrawable,
RegionPtr pClip,
int x1,
int y1,
int x2,
int y2,
FbBits and,
FbBits xor)
{
FbBits *dst;
FbStride dstStride;
int dstBpp;
int dstXoff, dstYoff;
BoxPtr pbox;
int nbox;
int partX1, partX2, partY1, partY2;
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
nbox--;
pbox++)
{
partX1 = pbox->x1;
if (partX1 < x1)
partX1 = x1;
partX2 = pbox->x2;
if (partX2 > x2)
partX2 = x2;
if (partX2 <= partX1)
continue;
partY1 = pbox->y1;
if (partY1 < y1)
partY1 = y1;
partY2 = pbox->y2;
if (partY2 > y2)
partY2 = y2;
if (partY2 <= partY1)
continue;
rlSolid (pDrawable->pScreen,
dst + (partY1 + dstYoff) * dstStride,
dstStride,
(partX1 + dstXoff) * dstBpp,
dstBpp,
(partX2 - partX1) * dstBpp,
(partY2 - partY1),
and, xor);
}
}

View File

@ -0,0 +1,114 @@
/*
* This code is largely copied from fbfillrect.c.
*
* Copyright © 1998 Keith Packard
* Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlFillRect.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
#include "fb.h"
#include "rlAccel.h"
void
rlPolyFillRect(DrawablePtr pDrawable,
GCPtr pGC,
int nrect,
xRectangle *prect)
{
RegionPtr pClip = fbGetCompositeClip(pGC);
register BoxPtr pbox;
BoxPtr pextent;
int extentX1, extentX2, extentY1, extentY2;
int fullX1, fullX2, fullY1, fullY2;
int partX1, partX2, partY1, partY2;
int xorg, yorg;
int n;
xorg = pDrawable->x;
yorg = pDrawable->y;
pextent = REGION_EXTENTS(pGC->pScreen, pClip);
extentX1 = pextent->x1;
extentY1 = pextent->y1;
extentX2 = pextent->x2;
extentY2 = pextent->y2;
while (nrect--)
{
fullX1 = prect->x + xorg;
fullY1 = prect->y + yorg;
fullX2 = fullX1 + (int) prect->width;
fullY2 = fullY1 + (int) prect->height;
prect++;
if (fullX1 < extentX1)
fullX1 = extentX1;
if (fullY1 < extentY1)
fullY1 = extentY1;
if (fullX2 > extentX2)
fullX2 = extentX2;
if (fullY2 > extentY2)
fullY2 = extentY2;
if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
continue;
n = REGION_NUM_RECTS (pClip);
if (n == 1)
{
rlFill (pDrawable,
pGC,
fullX1, fullY1, fullX2-fullX1, fullY2-fullY1);
}
else
{
pbox = REGION_RECTS(pClip);
/*
* clip the rectangle to each box in the clip region
* this is logically equivalent to calling Intersect()
*/
while(n--)
{
partX1 = pbox->x1;
if (partX1 < fullX1)
partX1 = fullX1;
partY1 = pbox->y1;
if (partY1 < fullY1)
partY1 = fullY1;
partX2 = pbox->x2;
if (partX2 > fullX2)
partX2 = fullX2;
partY2 = pbox->y2;
if (partY2 > fullY2)
partY2 = fullY2;
pbox++;
if (partX1 < partX2 && partY1 < partY2)
rlFill (pDrawable, pGC,
partX1, partY1,
partX2 - partX1, partY2 - partY1);
}
}
}
}

View File

@ -0,0 +1,102 @@
/*
* This code is largely copied from fbfillsp.c.
*
* Copyright © 1998 Keith Packard
* Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlFillSpans.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
#include "fb.h"
#include "rlAccel.h"
void
rlFillSpans (DrawablePtr pDrawable,
GCPtr pGC,
int n,
DDXPointPtr ppt,
int *pwidth,
int fSorted)
{
RegionPtr pClip = fbGetCompositeClip(pGC);
BoxPtr pextent, pbox;
int nbox;
int extentX1, extentX2, extentY1, extentY2;
int fullX1, fullX2, fullY1;
int partX1, partX2;
pextent = REGION_EXTENTS(pGC->pScreen, pClip);
extentX1 = pextent->x1;
extentY1 = pextent->y1;
extentX2 = pextent->x2;
extentY2 = pextent->y2;
while (n--)
{
fullX1 = ppt->x;
fullY1 = ppt->y;
fullX2 = fullX1 + (int) *pwidth;
ppt++;
pwidth++;
if (fullY1 < extentY1 || extentY2 <= fullY1)
continue;
if (fullX1 < extentX1)
fullX1 = extentX1;
if (fullX2 > extentX2)
fullX2 = extentX2;
if (fullX1 >= fullX2)
continue;
nbox = REGION_NUM_RECTS (pClip);
if (nbox == 1)
{
rlFill (pDrawable,
pGC,
fullX1, fullY1, fullX2-fullX1, 1);
}
else
{
pbox = REGION_RECTS(pClip);
while(nbox--)
{
if (pbox->y1 <= fullY1 && fullY1 < pbox->y2)
{
partX1 = pbox->x1;
if (partX1 < fullX1)
partX1 = fullX1;
partX2 = pbox->x2;
if (partX2 > fullX2)
partX2 = fullX2;
if (partX2 > partX1)
{
rlFill (pDrawable, pGC,
partX1, fullY1,
partX2 - partX1, 1);
}
}
pbox++;
}
}
}
}

View File

@ -0,0 +1,166 @@
/*
* This code is largely copied from fbglyph.c.
*
* Copyright © 1998 Keith Packard
* Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlGlyph.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
#include "fb.h"
#include "fontstruct.h"
#include "dixfontstr.h"
#include "rlAccel.h"
void
rlImageGlyphBlt (DrawablePtr pDrawable,
GCPtr pGC,
int x,
int y,
unsigned int nglyph,
CharInfoPtr *ppciInit,
pointer pglyphBase)
{
FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
CharInfoPtr *ppci;
CharInfoPtr pci;
unsigned char *pglyph; /* pointer bits in glyph */
int gWidth, gHeight; /* width and height of glyph */
FbStride gStride; /* stride of glyph */
Bool opaque;
int n;
int gx, gy;
#ifndef FBNOPIXADDR
void (*glyph) (FbBits *,
FbStride,
int,
FbStip *,
FbBits,
int,
int);
FbBits *dst = 0;
FbStride dstStride = 0;
int dstBpp = 0;
int dstXoff = 0, dstYoff = 0;
glyph = 0;
if (pPriv->and == 0)
{
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
switch (dstBpp) {
case 8: glyph = fbGlyph8; break;
case 16: glyph = fbGlyph16; break;
#ifdef FB_24BIT
case 24: glyph = fbGlyph24; break;
#endif
case 32: glyph = fbGlyph32; break;
}
}
#endif
x += pDrawable->x;
y += pDrawable->y;
if (TERMINALFONT (pGC->font)
#ifndef FBNOPIXADDR
&& !glyph
#endif
)
{
opaque = TRUE;
}
else
{
int xBack, widthBack;
int yBack, heightBack;
ppci = ppciInit;
n = nglyph;
widthBack = 0;
while (n--)
widthBack += (*ppci++)->metrics.characterWidth;
xBack = x;
if (widthBack < 0)
{
xBack += widthBack;
widthBack = -widthBack;
}
yBack = y - FONTASCENT(pGC->font);
heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
rlSolidBoxClipped (pDrawable,
fbGetCompositeClip(pGC),
xBack,
yBack,
xBack + widthBack,
yBack + heightBack,
fbAnd(GXcopy,pPriv->bg,pPriv->pm),
fbXor(GXcopy,pPriv->bg,pPriv->pm));
opaque = FALSE;
}
ppci = ppciInit;
while (nglyph--)
{
pci = *ppci++;
pglyph = FONTGLYPHBITS(pglyphBase, pci);
gWidth = GLYPHWIDTHPIXELS(pci);
gHeight = GLYPHHEIGHTPIXELS(pci);
if (gWidth && gHeight)
{
gx = x + pci->metrics.leftSideBearing;
gy = y - pci->metrics.ascent;
#ifndef FBNOPIXADDR
if (glyph && gWidth <= sizeof (FbStip) * 8 &&
fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
{
(*glyph) (dst + (gy + dstYoff) * dstStride,
dstStride,
dstBpp,
(FbStip *) pglyph,
pPriv->fg,
gx + dstXoff,
gHeight);
}
else
#endif
{
gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
fbPutXYImage (pDrawable,
fbGetCompositeClip(pGC),
pPriv->fg,
pPriv->bg,
pPriv->pm,
GXcopy,
opaque,
gx,
gy,
gWidth, gHeight,
(FbStip *) pglyph,
gStride,
0);
}
}
x += pci->metrics.characterWidth;
}
}

View File

@ -0,0 +1,108 @@
/*
* Accelerated rootless fill
*/
/*
* This code is largely copied from fbsolid.c.
*
* Copyright © 1998 Keith Packard
* Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
* Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/miext/rootless/accel/rlSolid.c,v 1.1 2003/10/24 00:33:15 torrey Exp $ */
#include "fb.h"
#include "rootlessCommon.h"
void
rlSolid (ScreenPtr pScreen,
FbBits *dst,
FbStride dstStride,
int dstX,
int bpp,
int width,
int height,
FbBits and,
FbBits xor)
{
FbBits startmask, endmask;
int n, nmiddle;
int startbyte, endbyte;
#ifdef FB_24BIT
if (bpp == 24 && (!FbCheck24Pix(and) || !FbCheck24Pix(xor)))
{
fbSolid24 (dst, dstStride, dstX, width, height, and, xor);
return;
}
#endif
dst += dstX >> FB_SHIFT;
dstX &= FB_MASK;
FbMaskBitsBytes(dstX, width, and == 0, startmask, startbyte,
nmiddle, endmask, endbyte);
/*
* Beginning of the rootless acceleration code
*/
if (!startmask && !endmask && !and &&
height * nmiddle * sizeof (*dst) > rootless_FillBytes_threshold &&
SCREENREC(pScreen)->imp->FillBytes)
{
if (bpp <= 8)
xor |= xor << 8;
if (bpp <= 16)
xor |= xor << 16;
SCREENREC(pScreen)->imp->FillBytes(nmiddle * sizeof (*dst), height,
xor, (char *) dst + (dstX >> 3),
dstStride * sizeof (*dst));
return;
}
/* End of the rootless acceleration code */
if (startmask)
dstStride--;
dstStride -= nmiddle;
while (height--)
{
if (startmask)
{
FbDoLeftMaskByteRRop(dst,startbyte,startmask,and,xor);
dst++;
}
n = nmiddle;
if (!and)
while (n--)
*dst++ = xor;
else
while (n--)
{
*dst = FbDoRRop (*dst, and, xor);
dst++;
}
if (endmask)
FbDoRightMaskByteRRop(dst,endbyte,endmask,and,xor);
dst += dstStride;
}
}

399
miext/rootless/rootless.h Normal file
View File

@ -0,0 +1,399 @@
/*
* External interface to generic rootless mode
*/
/*
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
* Copyright (c) 2002-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/miext/rootless/rootless.h,v 1.6 2003/10/24 00:33:14 torrey Exp $ */
#ifndef _ROOTLESS_H
#define _ROOTLESS_H
#include "rootlessConfig.h"
#include "mi.h"
#include "gcstruct.h"
/*
Each top-level rootless window has a one-to-one correspondence to a physical
on-screen window. The physical window is refered to as a "frame".
*/
typedef void * RootlessFrameID;
/*
* RootlessWindowRec
* This structure stores the per-frame data used by the rootless code.
* Each top-level X window has one RootlessWindowRec associated with it.
*/
typedef struct _RootlessWindowRec {
// Position and size includes the window border
// Position is in per-screen coordinates
int x, y;
unsigned int width, height;
unsigned int borderWidth;
RootlessFrameID wid; // implementation specific frame id
WindowPtr win; // underlying X window
// Valid only when drawing (ie. is_drawing is set)
char *pixelData;
int bytesPerRow;
PixmapPtr pixmap;
PixmapPtr oldPixmap;
#ifdef ROOTLESS_TRACK_DAMAGE
RegionRec damage;
#endif
unsigned int is_drawing :1; // Currently drawing?
unsigned int is_reorder_pending :1;
} RootlessWindowRec, *RootlessWindowPtr;
/* Offset for screen-local to global coordinate transforms */
#ifdef ROOTLESS_GLOBAL_COORDS
extern int rootlessGlobalOffsetX;
extern int rootlessGlobalOffsetY;
#endif
/* The minimum number of bytes or pixels for which to use the
implementation's accelerated functions. */
extern unsigned int rootless_CopyBytes_threshold;
extern unsigned int rootless_FillBytes_threshold;
extern unsigned int rootless_CompositePixels_threshold;
extern unsigned int rootless_CopyWindow_threshold;
/* Operations used by CompositePixels */
enum rl_composite_op_enum {
RL_COMPOSITE_SRC = 0,
RL_COMPOSITE_OVER,
};
/* Data formats for depth field and composite functions */
enum rl_depth_enum {
RL_DEPTH_NIL = 0, /* null source when compositing */
RL_DEPTH_ARGB8888,
RL_DEPTH_RGB555,
RL_DEPTH_A8, /* for masks when compositing */
RL_DEPTH_INDEX8,
};
/* Macro to form the composite function for CompositePixels */
#define RL_COMPOSITE_FUNCTION(op, src_depth, mask_depth, dest_depth) \
(((op) << 24) | ((src_depth) << 16) \
| ((mask_depth) << 8) | ((dest_depth) << 0))
/* Gravity for window contents during resizing */
enum rl_gravity_enum {
RL_GRAVITY_NONE = 0, /* no gravity, fill everything */
RL_GRAVITY_NORTH_WEST = 1, /* anchor to top-left corner */
RL_GRAVITY_NORTH_EAST = 2, /* anchor to top-right corner */
RL_GRAVITY_SOUTH_EAST = 3, /* anchor to bottom-right corner */
RL_GRAVITY_SOUTH_WEST = 4, /* anchor to bottom-left corner */
};
/*------------------------------------------
Rootless Implementation Functions
------------------------------------------*/
/*
* Create a new frame.
* The frame is created unmapped.
*
* pFrame RootlessWindowPtr for this frame should be completely
* initialized before calling except for pFrame->wid, which
* is set by this function.
* pScreen Screen on which to place the new frame
* newX, newY Position of the frame. These will be identical to pFrame-x,
* pFrame->y unless ROOTLESS_GLOBAL_COORDS is set.
* pNewShape Shape for the frame (in frame-local coordinates). NULL for
* unshaped frames.
*/
typedef Bool (*RootlessCreateFrameProc)
(RootlessWindowPtr pFrame, ScreenPtr pScreen, int newX, int newY,
RegionPtr pNewShape);
/*
* Destroy a frame.
* Drawing is stopped and all updates are flushed before this is called.
*
* wid Frame id
*/
typedef void (*RootlessDestroyFrameProc)
(RootlessFrameID wid);
/*
* Move a frame on screen.
* Drawing is stopped and all updates are flushed before this is called.
*
* wid Frame id
* pScreen Screen to move the new frame to
* newX, newY New position of the frame
*/
typedef void (*RootlessMoveFrameProc)
(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);
/*
* Resize and move a frame.
* Drawing is stopped and all updates are flushed before this is called.
*
* wid Frame id
* pScreen Screen to move the new frame to
* newX, newY New position of the frame
* newW, newH New size of the frame
* gravity Gravity for window contents (rl_gravity_enum). This is always
* RL_GRAVITY_NONE unless ROOTLESS_RESIZE_GRAVITY is set.
*/
typedef void (*RootlessResizeFrameProc)
(RootlessFrameID wid, ScreenPtr pScreen,
int newX, int newY, unsigned int newW, unsigned int newH,
unsigned int gravity);
/*
* Change frame ordering (AKA stacking, layering).
* Drawing is stopped before this is called. Unmapped frames are mapped by
* setting their ordering.
*
* wid Frame id
* nextWid Frame id of frame that is now above this one or NULL if this
* frame is at the top.
*/
typedef void (*RootlessRestackFrameProc)
(RootlessFrameID wid, RootlessFrameID nextWid);
/*
* Change frame's shape.
* Drawing is stopped before this is called.
*
* wid Frame id
* pNewShape New shape for the frame (in frame-local coordinates)
* or NULL if now unshaped.
*/
typedef void (*RootlessReshapeFrameProc)
(RootlessFrameID wid, RegionPtr pNewShape);
/*
* Unmap a frame.
*
* wid Frame id
*/
typedef void (*RootlessUnmapFrameProc)
(RootlessFrameID wid);
/*
* Start drawing to a frame.
* Prepare a frame for direct access to its backing buffer.
*
* wid Frame id
* pixelData Address of the backing buffer (returned)
* bytesPerRow Width in bytes of the backing buffer (returned)
*/
typedef void (*RootlessStartDrawingProc)
(RootlessFrameID wid, char **pixelData, int *bytesPerRow);
/*
* Stop drawing to a frame.
* No drawing to the frame's backing buffer will occur until drawing
* is started again.
*
* wid Frame id
* flush Flush drawing updates for this frame to the screen. This
* will always be FALSE if ROOTLESS_TRACK_DAMAGE is set.
*/
typedef void (*RootlessStopDrawingProc)
(RootlessFrameID wid, Bool flush);
/*
* Flush drawing updates to the screen.
* Drawing is stopped before this is called.
*
* wid Frame id
* pDamage Region containing all the changed pixels in frame-lcoal
* coordinates. This is clipped to the window's clip. This
* will be NULL if ROOTLESS_TRACK_DAMAGE is not set.
*/
typedef void (*RootlessUpdateRegionProc)
(RootlessFrameID wid, RegionPtr pDamage);
/*
* Mark damaged rectangles as requiring redisplay to screen.
* This will only be called if ROOTLESS_TRACK_DAMAGE is not set.
*
* wid Frame id
* nrects Number of damaged rectangles
* rects Array of damaged rectangles in frame-local coordinates
* shift_x, Vector to shift rectangles by
* shift_y
*/
typedef void (*RootlessDamageRectsProc)
(RootlessFrameID wid, int nrects, const BoxRec *rects,
int shift_x, int shift_y);
/*
* Switch the window associated with a frame. (Optional)
* When a framed window is reparented, the frame is resized and set to
* use the new top-level parent. If defined this function will be called
* afterwards for implementation specific bookkeeping.
*
* pFrame Frame whose window has switched
* oldWin Previous window wrapped by this frame
*/
typedef void (*RootlessSwitchWindowProc)
(RootlessWindowPtr pFrame, WindowPtr oldWin);
/*
* Copy bytes. (Optional)
* Source and destinate may overlap and the right thing should happen.
*
* width Bytes to copy per row
* height Number of rows
* src Source data
* srcRowBytes Width of source in bytes
* dst Destination data
* dstRowBytes Width of destination in bytes
*/
typedef void (*RootlessCopyBytesProc)
(unsigned int width, unsigned int height,
const void *src, unsigned int srcRowBytes,
void *dst, unsigned int dstRowBytes);
/*
* Fill memory with 32-bit pattern. (Optional)
*
* width Bytes to fill per row
* height Number of rows
* value 32-bit pattern to fill with
* dst Destination data
* dstRowBytes Width of destination in bytes
*/
typedef void (*RootlessFillBytesProc)
(unsigned int width, unsigned int height, unsigned int value,
void *dst, unsigned int dstRowBytes);
/*
* Composite pixels from source and mask to destination. (Optional)
*
* width, height Size of area to composite to in pizels
* function Composite function built with RL_COMPOSITE_FUNCTION
* src Source data
* srcRowBytes Width of source in bytes (Passing NULL means source
* is a single pixel.
* mask Mask data
* maskRowBytes Width of mask in bytes
* dst Destination data
* dstRowBytes Width of destination in bytes
*
* For src and dst, the first element of the array is the color data. If
* the second element is non-null it implies there is alpha data (which
* may be meshed or planar). Data without alpha is assumed to be opaque.
*
* An X11 error code is returned.
*/
typedef int (*RootlessCompositePixelsProc)
(unsigned int width, unsigned int height, unsigned int function,
void *src[2], unsigned int srcRowBytes[2],
void *mask, unsigned int maskRowBytes,
void *dst[2], unsigned int dstRowBytes[2]);
/*
* Copy area in frame to another part of frame. (Optional)
*
* wid Frame id
* dstNrects Number of rectangles to copy
* dstRects Array of rectangles to copy
* dx, dy Number of pixels away to copy area
*/
typedef void (*RootlessCopyWindowProc)
(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
int dx, int dy);
/*
* Rootless implementation function list
*/
typedef struct _RootlessFrameProcs {
RootlessCreateFrameProc CreateFrame;
RootlessDestroyFrameProc DestroyFrame;
RootlessMoveFrameProc MoveFrame;
RootlessResizeFrameProc ResizeFrame;
RootlessRestackFrameProc RestackFrame;
RootlessReshapeFrameProc ReshapeFrame;
RootlessUnmapFrameProc UnmapFrame;
RootlessStartDrawingProc StartDrawing;
RootlessStopDrawingProc StopDrawing;
RootlessUpdateRegionProc UpdateRegion;
#ifndef ROOTLESS_TRACK_DAMAGE
RootlessDamageRectsProc DamageRects;
#endif
/* Optional frame functions */
RootlessSwitchWindowProc SwitchWindow;
/* Optional acceleration functions */
RootlessCopyBytesProc CopyBytes;
RootlessFillBytesProc FillBytes;
RootlessCompositePixelsProc CompositePixels;
RootlessCopyWindowProc CopyWindow;
} RootlessFrameProcsRec, *RootlessFrameProcsPtr;
/*
* Initialize rootless mode on the given screen.
*/
Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs);
/*
* Return the frame ID for the physical window displaying the given window.
*
* create If true and the window has no frame, attempt to create one
*/
RootlessFrameID RootlessFrameForWindow(WindowPtr pWin, Bool create);
/*
* Return the top-level parent of a window.
* The root is the top-level parent of itself, even though the root is
* not otherwise considered to be a top-level window.
*/
WindowPtr TopLevelParent(WindowPtr pWindow);
/*
* Prepare a window for direct access to its backing buffer.
*/
void RootlessStartDrawing(WindowPtr pWindow);
/*
* Finish drawing to a window's backing buffer.
*
* flush If true and ROOTLESS_TRACK_DAMAGE is set, damaged areas
* are flushed to the screen.
*/
void RootlessStopDrawing(WindowPtr pWindow, Bool flush);
#endif /* _ROOTLESS_H */

View File

@ -0,0 +1,380 @@
/*
* Common rootless definitions and code
*/
/*
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
* Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
* 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/miext/rootless/rootlessCommon.c,v 1.5 2003/11/10 18:22:50 tsi Exp $ */
#include "rootlessCommon.h"
unsigned int rootless_CopyBytes_threshold = 0;
unsigned int rootless_FillBytes_threshold = 0;
unsigned int rootless_CompositePixels_threshold = 0;
unsigned int rootless_CopyWindow_threshold = 0;
#ifdef ROOTLESS_GLOBAL_COORDS
int rootlessGlobalOffsetX = 0;
int rootlessGlobalOffsetY = 0;
#endif
RegionRec rootlessHugeRoot = {{-32767, -32767, 32767, 32767}, NULL};
/* Following macro from miregion.c */
/* true iff two Boxes overlap */
#define EXTENTCHECK(r1,r2) \
(!( ((r1)->x2 <= (r2)->x1) || \
((r1)->x1 >= (r2)->x2) || \
((r1)->y2 <= (r2)->y1) || \
((r1)->y1 >= (r2)->y2) ) )
/*
* TopLevelParent
* Returns the top-level parent of pWindow.
* The root is the top-level parent of itself, even though the root is
* not otherwise considered to be a top-level window.
*/
WindowPtr
TopLevelParent(WindowPtr pWindow)
{
WindowPtr top;
if (IsRoot(pWindow))
return pWindow;
top = pWindow;
while (top && ! IsTopLevel(top))
top = top->parent;
return top;
}
/*
* IsFramedWindow
* Returns TRUE if this window is visible inside a frame
* (e.g. it is visible and has a top-level or root parent)
*/
Bool
IsFramedWindow(WindowPtr pWin)
{
WindowPtr top;
if (!pWin->realized)
return FALSE;
top = TopLevelParent(pWin);
return (top && WINREC(top));
}
/*
* RootlessStartDrawing
* Prepare a window for direct access to its backing buffer.
* Each top-level parent has a Pixmap representing its backing buffer,
* which all of its children inherit.
*/
void RootlessStartDrawing(WindowPtr pWindow)
{
ScreenPtr pScreen = pWindow->drawable.pScreen;
WindowPtr top = TopLevelParent(pWindow);
RootlessWindowRec *winRec;
if (top == NULL)
return;
winRec = WINREC(top);
if (winRec == NULL)
return;
// Make sure the window's top-level parent is prepared for drawing.
if (!winRec->is_drawing) {
int bw = wBorderWidth(top);
SCREENREC(pScreen)->imp->StartDrawing(winRec->wid, &winRec->pixelData,
&winRec->bytesPerRow);
winRec->pixmap =
GetScratchPixmapHeader(pScreen, winRec->width, winRec->height,
top->drawable.depth,
top->drawable.bitsPerPixel,
winRec->bytesPerRow,
winRec->pixelData);
SetPixmapBaseToScreen(winRec->pixmap,
top->drawable.x - bw, top->drawable.y - bw);
winRec->is_drawing = TRUE;
}
winRec->oldPixmap = pScreen->GetWindowPixmap(pWindow);
pScreen->SetWindowPixmap(pWindow, winRec->pixmap);
}
/*
* RootlessStopDrawing
* Stop drawing to a window's backing buffer. If flush is true,
* damaged regions are flushed to the screen.
*/
void RootlessStopDrawing(WindowPtr pWindow, Bool flush)
{
ScreenPtr pScreen = pWindow->drawable.pScreen;
WindowPtr top = TopLevelParent(pWindow);
RootlessWindowRec *winRec;
if (top == NULL)
return;
winRec = WINREC(top);
if (winRec == NULL)
return;
if (winRec->is_drawing) {
SCREENREC(pScreen)->imp->StopDrawing(winRec->wid, flush);
FreeScratchPixmapHeader(winRec->pixmap);
pScreen->SetWindowPixmap(pWindow, winRec->oldPixmap);
winRec->pixmap = NULL;
winRec->is_drawing = FALSE;
}
else if (flush) {
SCREENREC(pScreen)->imp->UpdateRegion(winRec->wid, NULL);
}
if (flush && winRec->is_reorder_pending) {
winRec->is_reorder_pending = FALSE;
RootlessReorderWindow(pWindow);
}
}
/*
* RootlessDamageRegion
* Mark a damaged region as requiring redisplay to screen.
* pRegion is in GLOBAL coordinates.
*/
void
RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion)
{
ScreenPtr pScreen = pWindow->drawable.pScreen;
RootlessWindowRec *winRec;
RegionRec clipped;
WindowPtr pTop;
BoxPtr b1, b2;
RL_DEBUG_MSG("Damaged win 0x%x ", pWindow);
pTop = TopLevelParent(pWindow);
if (pTop == NULL)
return;
winRec = WINREC(pTop);
if (winRec == NULL)
return;
/* We need to intersect the drawn region with the clip of the window
to avoid marking places we didn't actually draw (which can cause
problems when the window has an extra client-side backing store)
But this is a costly operation and since we'll normally just be
drawing inside the clip, go to some lengths to avoid the general
case intersection. */
b1 = REGION_EXTENTS(pScreen, &pWindow->borderClip);
b2 = REGION_EXTENTS(pScreen, pRegion);
if (EXTENTCHECK(b1, b2)) {
/* Regions may overlap. */
if (REGION_NUM_RECTS(pRegion) == 1) {
int in;
/* Damaged region only has a single rect, so we can
just compare that against the region */
in = RECT_IN_REGION(pScreen, &pWindow->borderClip,
REGION_RECTS (pRegion));
if (in == rgnIN) {
/* clip totally contains pRegion */
#ifdef ROOTLESS_TRACK_DAMAGE
REGION_UNION(pScreen, &winRec->damage,
&winRec->damage, (pRegion));
#else
SCREENREC(pScreen)->imp->DamageRects(winRec->wid,
REGION_NUM_RECTS(pRegion),
REGION_RECTS(pRegion),
-winRec->x, -winRec->y);
#endif
RootlessQueueRedisplay(pTop->drawable.pScreen);
goto out;
}
else if (in == rgnOUT) {
/* clip doesn't contain pRegion */
goto out;
}
}
/* clip overlaps pRegion, need to intersect */
REGION_NULL(pScreen, &clipped);
REGION_INTERSECT(pScreen, &clipped, &pWindow->borderClip, pRegion);
#ifdef ROOTLESS_TRACK_DAMAGE
REGION_UNION(pScreen, &winRec->damage,
&winRec->damage, (pRegion));
#else
SCREENREC(pScreen)->imp->DamageRects(winRec->wid,
REGION_NUM_RECTS(&clipped),
REGION_RECTS(&clipped),
-winRec->x, -winRec->y);
#endif
REGION_UNINIT(pScreen, &clipped);
RootlessQueueRedisplay(pTop->drawable.pScreen);
}
out:
#ifdef ROOTLESSDEBUG
{
BoxRec *box = REGION_RECTS(pRegion), *end;
int numBox = REGION_NUM_RECTS(pRegion);
for (end = box+numBox; box < end; box++) {
RL_DEBUG_MSG("Damage rect: %i, %i, %i, %i\n",
box->x1, box->x2, box->y1, box->y2);
}
}
#endif
return;
}
/*
* RootlessDamageBox
* Mark a damaged box as requiring redisplay to screen.
* pRegion is in GLOBAL coordinates.
*/
void
RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox)
{
RegionRec region;
REGION_INIT(pWindow->drawable.pScreen, &region, pBox, 1);
RootlessDamageRegion(pWindow, &region);
REGION_UNINIT(pWindow->drawable.pScreen, &region); /* no-op */
}
/*
* RootlessDamageRect
* Mark a damaged rectangle as requiring redisplay to screen.
* (x, y, w, h) is in window-local coordinates.
*/
void
RootlessDamageRect(WindowPtr pWindow, int x, int y, int w, int h)
{
BoxRec box;
RegionRec region;
x += pWindow->drawable.x;
y += pWindow->drawable.y;
box.x1 = x;
box.x2 = x + w;
box.y1 = y;
box.y2 = y + h;
REGION_INIT(pWindow->drawable.pScreen, &region, &box, 1);
RootlessDamageRegion(pWindow, &region);
REGION_UNINIT(pWindow->drawable.pScreen, &region); /* no-op */
}
/*
* RootlessRedisplay
* Stop drawing and redisplay the damaged region of a window.
*/
void
RootlessRedisplay(WindowPtr pWindow)
{
#ifdef ROOTLESS_TRACK_DAMAGE
RootlessWindowRec *winRec = WINREC(pWindow);
ScreenPtr pScreen = pWindow->drawable.pScreen;
RootlessStopDrawing(pWindow, FALSE);
if (REGION_NOTEMPTY(pScreen, &winRec->damage)) {
RL_DEBUG_MSG("Redisplay Win 0x%x, %i x %i @ (%i, %i)\n",
pWindow, winRec->width, winRec->height,
winRec->x, winRec->y);
// move region to window local coords
REGION_TRANSLATE(pScreen, &winRec->damage,
-winRec->x, -winRec->y);
SCREENREC(pScreen)->imp->UpdateRegion(winRec->wid, &winRec->damage);
REGION_EMPTY(pScreen, &winRec->damage);
}
#else /* !ROOTLESS_TRACK_DAMAGE */
RootlessStopDrawing(pWindow, TRUE);
#endif
}
/*
* RootlessRedisplayScreen
* Walk every window on a screen and redisplay the damaged regions.
*/
void
RootlessRedisplayScreen(ScreenPtr pScreen)
{
WindowPtr root = WindowTable[pScreen->myNum];
if (root != NULL) {
WindowPtr win;
RootlessRedisplay(root);
for (win = root->firstChild; win; win = win->nextSib) {
if (WINREC(win) != NULL) {
RootlessRedisplay(win);
}
}
}
}

View File

@ -0,0 +1,254 @@
/*
* Common internal rootless definitions and code
*/
/*
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
* Copyright (c) 2002-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/miext/rootless/rootlessCommon.h,v 1.4 2003/09/16 00:36:20 torrey Exp $ */
#ifndef _ROOTLESSCOMMON_H
#define _ROOTLESSCOMMON_H
#include "rootless.h"
#include "fb.h"
#ifdef RENDER
#include "picturestr.h"
#endif
// Debug output, or not.
#ifdef ROOTLESSDEBUG
#define RL_DEBUG_MSG ErrorF
#else
#define RL_DEBUG_MSG(a, ...)
#endif
// Global variables
extern int rootlessGCPrivateIndex;
extern int rootlessScreenPrivateIndex;
extern int rootlessWindowPrivateIndex;
// RootlessGCRec: private per-gc data
typedef struct {
GCFuncs *originalFuncs;
GCOps *originalOps;
} RootlessGCRec;
// RootlessScreenRec: per-screen private data
typedef struct _RootlessScreenRec {
// Rootless implementation functions
RootlessFrameProcsPtr imp;
// Wrapped screen functions
CreateScreenResourcesProcPtr CreateScreenResources;
CloseScreenProcPtr CloseScreen;
CreateWindowProcPtr CreateWindow;
DestroyWindowProcPtr DestroyWindow;
RealizeWindowProcPtr RealizeWindow;
UnrealizeWindowProcPtr UnrealizeWindow;
MoveWindowProcPtr MoveWindow;
ResizeWindowProcPtr ResizeWindow;
RestackWindowProcPtr RestackWindow;
ReparentWindowProcPtr ReparentWindow;
ChangeBorderWidthProcPtr ChangeBorderWidth;
PositionWindowProcPtr PositionWindow;
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
CreateGCProcPtr CreateGC;
PaintWindowBackgroundProcPtr PaintWindowBackground;
PaintWindowBorderProcPtr PaintWindowBorder;
CopyWindowProcPtr CopyWindow;
GetImageProcPtr GetImage;
SourceValidateProcPtr SourceValidate;
MarkOverlappedWindowsProcPtr MarkOverlappedWindows;
ValidateTreeProcPtr ValidateTree;
#ifdef SHAPE
SetShapeProcPtr SetShape;
#endif
#ifdef RENDER
CompositeProcPtr Composite;
GlyphsProcPtr Glyphs;
#endif
void *pixmap_data;
unsigned int pixmap_data_size;
void *redisplay_timer;
unsigned int redisplay_timer_set :1;
unsigned int redisplay_queued :1;
unsigned int redisplay_expired :1;
} RootlessScreenRec, *RootlessScreenPtr;
#undef MIN
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#undef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
// "Definition of the Porting Layer for the X11 Sample Server" says
// unwrap and rewrap of screen functions is unnecessary, but
// screen->CreateGC changes after a call to cfbCreateGC.
#define SCREEN_UNWRAP(screen, fn) \
screen->fn = SCREENREC(screen)->fn;
#define SCREEN_WRAP(screen, fn) \
SCREENREC(screen)->fn = screen->fn; \
screen->fn = Rootless##fn
// Accessors for screen and window privates
#define SCREENREC(pScreen) \
((RootlessScreenRec *)(pScreen)->devPrivates[rootlessScreenPrivateIndex].ptr)
#define WINREC(pWin) \
((RootlessWindowRec *)(pWin)->devPrivates[rootlessWindowPrivateIndex].ptr)
// Call a rootless implementation function.
// Many rootless implementation functions are allowed to be NULL.
#define CallFrameProc(pScreen, proc, params) \
if (SCREENREC(pScreen)->frameProcs.proc) { \
RL_DEBUG_MSG("calling frame proc " #proc " "); \
SCREENREC(pScreen)->frameProcs.proc params; \
}
// BoxRec manipulators
// Copied from shadowfb
#define TRIM_BOX(box, pGC) { \
BoxPtr extents = &pGC->pCompositeClip->extents;\
if(box.x1 < extents->x1) box.x1 = extents->x1; \
if(box.x2 > extents->x2) box.x2 = extents->x2; \
if(box.y1 < extents->y1) box.y1 = extents->y1; \
if(box.y2 > extents->y2) box.y2 = extents->y2; \
}
#define TRANSLATE_BOX(box, pDraw) { \
box.x1 += pDraw->x; \
box.x2 += pDraw->x; \
box.y1 += pDraw->y; \
box.y2 += pDraw->y; \
}
#define TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC) { \
TRANSLATE_BOX(box, pDraw); \
TRIM_BOX(box, pGC); \
}
#define BOX_NOT_EMPTY(box) \
(((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
// HUGE_ROOT and NORMAL_ROOT
// We don't want to clip windows to the edge of the screen.
// HUGE_ROOT temporarily makes the root window really big.
// This is needed as a wrapper around any function that calls
// SetWinSize or SetBorderSize which clip a window against its
// parents, including the root.
extern RegionRec rootlessHugeRoot;
#define HUGE_ROOT(pWin) \
do { \
WindowPtr w = pWin; \
while (w->parent) \
w = w->parent; \
saveRoot = w->winSize; \
w->winSize = rootlessHugeRoot; \
} while (0)
#define NORMAL_ROOT(pWin) \
do { \
WindowPtr w = pWin; \
while (w->parent) \
w = w->parent; \
w->winSize = saveRoot; \
} while (0)
// Returns TRUE if this window is a top-level window (i.e. child of the root)
// The root is not a top-level window.
#define IsTopLevel(pWin) \
((pWin) && (pWin)->parent && !(pWin)->parent->parent)
// Returns TRUE if this window is a root window
#define IsRoot(pWin) \
((pWin) == WindowTable[(pWin)->drawable.pScreen->myNum])
/*
* SetPixmapBaseToScreen
* Move the given pixmap's base address to where pixel (0, 0)
* would be if the pixmap's actual data started at (x, y).
* Can't access the bits before the first word of the drawable's data in
* rootless mode, so make sure our base address is always 32-bit aligned.
*/
#define SetPixmapBaseToScreen(pix, _x, _y) { \
PixmapPtr _pPix = (PixmapPtr) (pix); \
_pPix->devPrivate.ptr = (char *) (_pPix->devPrivate.ptr) - \
((int)(_x) * _pPix->drawable.bitsPerPixel/8 + \
(int)(_y) * _pPix->devKind); \
if (_pPix->drawable.bitsPerPixel != FB_UNIT) { \
unsigned _diff = ((unsigned) _pPix->devPrivate.ptr) & \
(FB_UNIT / CHAR_BIT - 1); \
_pPix->devPrivate.ptr = (char *) (_pPix->devPrivate.ptr) - \
_diff; \
_pPix->drawable.x = _diff / \
(_pPix->drawable.bitsPerPixel / CHAR_BIT); \
} \
}
// Returns TRUE if this window is visible inside a frame
// (e.g. it is visible and has a top-level or root parent)
Bool IsFramedWindow(WindowPtr pWin);
// Routines that cause regions to get redrawn.
// DamageRegion and DamageRect are in global coordinates.
// DamageBox is in window-local coordinates.
void RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion);
void RootlessDamageRect(WindowPtr pWindow, int x, int y, int w, int h);
void RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox);
void RootlessRedisplay(WindowPtr pWindow);
void RootlessRedisplayScreen(ScreenPtr pScreen);
void RootlessQueueRedisplay (ScreenPtr pScreen);
// Move the window to it's correct place in the physical stacking order.
void RootlessReorderWindow (WindowPtr pWin);
#endif /* _ROOTLESSCOMMON_H */

View File

@ -0,0 +1,50 @@
/*
* Platform specific rootless configuration
*/
/*
* 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/miext/rootless/rootlessConfig.h,v 1.2 2003/10/24 00:33:14 torrey Exp $ */
#ifndef _ROOTLESSCONFIG_H
#define _ROOTLESSCONFIG_H
#ifdef __DARWIN__
# define ROOTLESS_ACCEL TRUE
# define ROOTLESS_GLOBAL_COORDS TRUE
# define ROOTLESS_PROTECT_ALPHA TRUE
# define ROOTLESS_REDISPLAY_DELAY 10
# define ROOTLESS_RESIZE_GRAVITY TRUE
# undef ROOTLESS_TRACK_DAMAGE
/* Bit mask for alpha channel with a particular number of bits per
pixel. Note that we only care for 32bpp data. Mac OS X uses planar
alpha for 16bpp. */
# define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0)
#endif /* __DARWIN__ */
#endif /* _ROOTLESSCONFIG_H */

1515
miext/rootless/rootlessGC.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,666 @@
/*
* Screen routines for generic rootless X server
*/
/*
* Copyright (c) 2001 Greg Parker. All Rights Reserved.
* Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
* 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/miext/rootless/rootlessScreen.c,v 1.3 2003/06/30 01:45:13 torrey Exp $ */
#include "mi.h"
#include "scrnintstr.h"
#include "gcstruct.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "propertyst.h"
#include "mivalidate.h"
#include "picturestr.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "rootlessCommon.h"
#include "rootlessWindow.h"
/* In milliseconds */
#ifndef ROOTLESS_REDISPLAY_DELAY
#define ROOTLESS_REDISPLAY_DELAY 10
#endif
extern int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild,
VTKind kind);
extern Bool RootlessCreateGC(GCPtr pGC);
// Initialize globals
int rootlessGCPrivateIndex = -1;
int rootlessScreenPrivateIndex = -1;
int rootlessWindowPrivateIndex = -1;
/*
* RootlessUpdateScreenPixmap
* miCreateScreenResources does not like a null framebuffer pointer,
* it leaves the screen pixmap with an uninitialized data pointer.
* Thus, rootless implementations typically set the framebuffer width
* to zero so that miCreateScreenResources does not allocate a screen
* pixmap for us. We allocate our own screen pixmap here since we need
* the screen pixmap to be valid (e.g. CopyArea from the root window).
*/
void
RootlessUpdateScreenPixmap(ScreenPtr pScreen)
{
RootlessScreenRec *s = SCREENREC(pScreen);
PixmapPtr pPix;
unsigned int rowbytes;
pPix = (*pScreen->GetScreenPixmap)(pScreen);
if (pPix == NULL) {
pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth);
(*pScreen->SetScreenPixmap)(pPix);
}
rowbytes = PixmapBytePad(pScreen->width, pScreen->rootDepth);
if (s->pixmap_data_size < rowbytes) {
if (s->pixmap_data != NULL)
xfree(s->pixmap_data);
s->pixmap_data_size = rowbytes;
s->pixmap_data = xalloc(s->pixmap_data_size);
if (s->pixmap_data == NULL)
return;
memset(s->pixmap_data, 0xFF, s->pixmap_data_size);
pScreen->ModifyPixmapHeader(pPix, pScreen->width, pScreen->height,
pScreen->rootDepth,
BitsPerPixel(pScreen->rootDepth),
0, s->pixmap_data);
/* ModifyPixmapHeader ignores zero arguments, so install rowbytes
by hand. */
pPix->devKind = 0;
}
}
/*
* RootlessCreateScreenResources
* Rootless implementations typically set a null framebuffer pointer, which
* causes problems with miCreateScreenResources. We fix things up here.
*/
static Bool
RootlessCreateScreenResources(ScreenPtr pScreen)
{
Bool ret = TRUE;
SCREEN_UNWRAP(pScreen, CreateScreenResources);
if (pScreen->CreateScreenResources != NULL)
ret = (*pScreen->CreateScreenResources)(pScreen);
SCREEN_WRAP(pScreen, CreateScreenResources);
if (!ret)
return ret;
/* Make sure we have a valid screen pixmap. */
RootlessUpdateScreenPixmap(pScreen);
return ret;
}
static Bool
RootlessCloseScreen(int i, ScreenPtr pScreen)
{
RootlessScreenRec *s;
s = SCREENREC(pScreen);
// fixme unwrap everything that was wrapped?
pScreen->CloseScreen = s->CloseScreen;
if (s->pixmap_data != NULL) {
xfree (s->pixmap_data);
s->pixmap_data = NULL;
s->pixmap_data_size = 0;
}
xfree(s);
return pScreen->CloseScreen(i, pScreen);
}
static void
RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
unsigned int format, unsigned long planeMask, char *pdstLine)
{
ScreenPtr pScreen = pDrawable->pScreen;
SCREEN_UNWRAP(pScreen, GetImage);
if (pDrawable->type == DRAWABLE_WINDOW) {
int x0, y0, x1, y1;
RootlessWindowRec *winRec;
// Many apps use GetImage to sync with the visible frame buffer
// FIXME: entire screen or just window or all screens?
RootlessRedisplayScreen(pScreen);
// RedisplayScreen stops drawing, so we need to start it again
RootlessStartDrawing((WindowPtr)pDrawable);
/* Check that we have some place to read from. */
winRec = WINREC(TopLevelParent((WindowPtr) pDrawable));
if (winRec == NULL)
goto out;
/* Clip to top-level window bounds. */
/* FIXME: fbGetImage uses the width parameter to calculate the
stride of the destination pixmap. If w is clipped, the data
returned will be garbage, although we will not crash. */
x0 = pDrawable->x + sx;
y0 = pDrawable->y + sy;
x1 = x0 + w;
y1 = y0 + h;
x0 = MAX (x0, winRec->x);
y0 = MAX (y0, winRec->y);
x1 = MIN (x1, winRec->x + winRec->width);
y1 = MIN (y1, winRec->y + winRec->height);
sx = x0 - pDrawable->x;
sy = y0 - pDrawable->y;
w = x1 - x0;
h = y1 - y0;
if (w <= 0 || h <= 0)
goto out;
}
pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
out:
SCREEN_WRAP(pScreen, GetImage);
}
/*
* RootlessSourceValidate
* CopyArea and CopyPlane use a GC tied to the destination drawable.
* StartDrawing/StopDrawing wrappers won't be called if source is
* a visible window but the destination isn't. So, we call StartDrawing
* here and leave StopDrawing for the block handler.
*/
static void
RootlessSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h)
{
SCREEN_UNWRAP(pDrawable->pScreen, SourceValidate);
if (pDrawable->type == DRAWABLE_WINDOW) {
WindowPtr pWin = (WindowPtr)pDrawable;
RootlessStartDrawing(pWin);
}
if (pDrawable->pScreen->SourceValidate) {
pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h);
}
SCREEN_WRAP(pDrawable->pScreen, SourceValidate);
}
#ifdef RENDER
static void
RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
WindowPtr srcWin, dstWin, maskWin = NULL;
if (pMask) { // pMask can be NULL
maskWin = (pMask->pDrawable->type == DRAWABLE_WINDOW) ?
(WindowPtr)pMask->pDrawable : NULL;
}
srcWin = (pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
(WindowPtr)pSrc->pDrawable : NULL;
dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
(WindowPtr)pDst->pDrawable : NULL;
// SCREEN_UNWRAP(ps, Composite);
ps->Composite = SCREENREC(pScreen)->Composite;
if (srcWin && IsFramedWindow(srcWin))
RootlessStartDrawing(srcWin);
if (maskWin && IsFramedWindow(maskWin))
RootlessStartDrawing(maskWin);
if (dstWin && IsFramedWindow(dstWin))
RootlessStartDrawing(dstWin);
ps->Composite(op, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask,
xDst, yDst, width, height);
if (dstWin && IsFramedWindow(dstWin)) {
RootlessDamageRect(dstWin, xDst, yDst, width, height);
}
ps->Composite = RootlessComposite;
// SCREEN_WRAP(ps, Composite);
}
static void
RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
int nlist, GlyphListPtr list, GlyphPtr *glyphs)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
int x, y;
int n;
GlyphPtr glyph;
WindowPtr srcWin, dstWin;
srcWin = (pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
(WindowPtr)pSrc->pDrawable : NULL;
dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
(WindowPtr)pDst->pDrawable : NULL;
if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin);
if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin);
//SCREEN_UNWRAP(ps, Glyphs);
ps->Glyphs = SCREENREC(pScreen)->Glyphs;
ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
ps->Glyphs = RootlessGlyphs;
//SCREEN_WRAP(ps, Glyphs);
if (dstWin && IsFramedWindow(dstWin)) {
x = xSrc;
y = ySrc;
while (nlist--) {
x += list->xOff;
y += list->yOff;
n = list->len;
/* Calling DamageRect for the bounding box of each glyph is
inefficient. So compute the union of all glyphs in a list
and damage that. */
if (n > 0) {
BoxRec box;
glyph = *glyphs++;
box.x1 = x - glyph->info.x;
box.y1 = y - glyph->info.y;
box.x2 = box.x1 + glyph->info.width;
box.y2 = box.y2 + glyph->info.height;
x += glyph->info.xOff;
y += glyph->info.yOff;
while (--n > 0) {
short x1, y1, x2, y2;
glyph = *glyphs++;
x1 = x - glyph->info.x;
y1 = y - glyph->info.y;
x2 = x1 + glyph->info.width;
y2 = y1 + glyph->info.height;
box.x1 = MAX (box.x1, x1);
box.y1 = MAX (box.y1, y1);
box.x2 = MAX (box.x2, x2);
box.y2 = MAX (box.y2, y2);
x += glyph->info.xOff;
y += glyph->info.yOff;
}
RootlessDamageBox(dstWin, &box);
}
list++;
}
}
}
#endif // RENDER
/*
* RootlessValidateTree
* ValidateTree is modified in two ways:
* - top-level windows don't clip each other
* - windows aren't clipped against root.
* These only matter when validating from the root.
*/
static int
RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
{
int result;
RegionRec saveRoot;
ScreenPtr pScreen = pParent->drawable.pScreen;
SCREEN_UNWRAP(pScreen, ValidateTree);
RL_DEBUG_MSG("VALIDATETREE start ");
// Use our custom version to validate from root
if (IsRoot(pParent)) {
RL_DEBUG_MSG("custom ");
result = RootlessMiValidateTree(pParent, pChild, kind);
} else {
HUGE_ROOT(pParent);
result = pScreen->ValidateTree(pParent, pChild, kind);
NORMAL_ROOT(pParent);
}
SCREEN_WRAP(pScreen, ValidateTree);
RL_DEBUG_MSG("VALIDATETREE end\n");
return result;
}
/*
* RootlessMarkOverlappedWindows
* MarkOverlappedWindows is modified to ignore overlapping
* top-level windows.
*/
static Bool
RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst,
WindowPtr *ppLayerWin)
{
RegionRec saveRoot;
Bool result;
ScreenPtr pScreen = pWin->drawable.pScreen;
SCREEN_UNWRAP(pScreen, MarkOverlappedWindows);
RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start ");
HUGE_ROOT(pWin);
if (IsRoot(pWin)) {
// root - mark nothing
RL_DEBUG_MSG("is root not marking ");
result = FALSE;
}
else if (! IsTopLevel(pWin)) {
// not top-level window - mark normally
result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin);
}
else {
//top-level window - mark children ONLY - NO overlaps with sibs (?)
// This code copied from miMarkOverlappedWindows()
register WindowPtr pChild;
Bool anyMarked = FALSE;
void (* MarkWindow)() = pScreen->MarkWindow;
RL_DEBUG_MSG("is top level! ");
/* single layered systems are easy */
if (ppLayerWin) *ppLayerWin = pWin;
if (pWin == pFirst) {
/* Blindly mark pWin and all of its inferiors. This is a slight
* overkill if there are mapped windows that outside pWin's border,
* but it's better than wasting time on RectIn checks.
*/
pChild = pWin;
while (1) {
if (pChild->viewable) {
if (REGION_BROKEN (pScreen, &pChild->winSize))
SetWinSize (pChild);
if (REGION_BROKEN (pScreen, &pChild->borderSize))
SetBorderSize (pChild);
(* MarkWindow)(pChild);
if (pChild->firstChild) {
pChild = pChild->firstChild;
continue;
}
}
while (!pChild->nextSib && (pChild != pWin))
pChild = pChild->parent;
if (pChild == pWin)
break;
pChild = pChild->nextSib;
}
anyMarked = TRUE;
pFirst = pFirst->nextSib;
}
if (anyMarked)
(* MarkWindow)(pWin->parent);
result = anyMarked;
}
NORMAL_ROOT(pWin);
SCREEN_WRAP(pScreen, MarkOverlappedWindows);
RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n");
return result;
}
static CARD32
RootlessRedisplayCallback(OsTimerPtr timer, CARD32 time, void *arg)
{
RootlessScreenRec *screenRec = arg;
if (!screenRec->redisplay_queued) {
/* No update needed. Stop the timer. */
screenRec->redisplay_timer_set = FALSE;
return 0;
}
screenRec->redisplay_queued = FALSE;
/* Mark that we should redisplay before waiting for I/O next time */
screenRec->redisplay_expired = TRUE;
/* Reinstall the timer immediately, so we get as close to our
redisplay interval as possible. */
return ROOTLESS_REDISPLAY_DELAY;
}
/*
* RootlessQueueRedisplay
* Queue a redisplay after a timer delay to ensure we do not redisplay
* too frequently.
*/
void
RootlessQueueRedisplay(ScreenPtr pScreen)
{
RootlessScreenRec *screenRec = SCREENREC(pScreen);
screenRec->redisplay_queued = TRUE;
if (screenRec->redisplay_timer_set)
return;
screenRec->redisplay_timer = TimerSet(screenRec->redisplay_timer,
0, ROOTLESS_REDISPLAY_DELAY,
RootlessRedisplayCallback,
screenRec);
screenRec->redisplay_timer_set = TRUE;
}
/*
* RootlessBlockHandler
* If the redisplay timer has expired, flush drawing before blocking
* on select().
*/
static void
RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask)
{
ScreenPtr pScreen = pbdata;
RootlessScreenRec *screenRec = SCREENREC(pScreen);
if (screenRec->redisplay_expired) {
screenRec->redisplay_expired = FALSE;
RootlessRedisplayScreen(pScreen);
}
}
static void
RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask)
{
// nothing here
}
static Bool
RootlessAllocatePrivates(ScreenPtr pScreen)
{
RootlessScreenRec *s;
static unsigned long rootlessGeneration = 0;
if (rootlessGeneration != serverGeneration) {
rootlessScreenPrivateIndex = AllocateScreenPrivateIndex();
if (rootlessScreenPrivateIndex == -1) return FALSE;
rootlessGCPrivateIndex = AllocateGCPrivateIndex();
if (rootlessGCPrivateIndex == -1) return FALSE;
rootlessWindowPrivateIndex = AllocateWindowPrivateIndex();
if (rootlessWindowPrivateIndex == -1) return FALSE;
rootlessGeneration = serverGeneration;
}
// no allocation needed for screen privates
if (!AllocateGCPrivate(pScreen, rootlessGCPrivateIndex,
sizeof(RootlessGCRec)))
return FALSE;
if (!AllocateWindowPrivate(pScreen, rootlessWindowPrivateIndex, 0))
return FALSE;
s = xalloc(sizeof(RootlessScreenRec));
if (! s) return FALSE;
SCREENREC(pScreen) = s;
s->pixmap_data = NULL;
s->pixmap_data_size = 0;
s->redisplay_timer = NULL;
s->redisplay_timer_set = FALSE;
return TRUE;
}
static void
RootlessWrap(ScreenPtr pScreen)
{
RootlessScreenRec *s = (RootlessScreenRec*)
pScreen->devPrivates[rootlessScreenPrivateIndex].ptr;
#define WRAP(a) \
if (pScreen->a) { \
s->a = pScreen->a; \
} else { \
RL_DEBUG_MSG("null screen fn " #a "\n"); \
s->a = NULL; \
} \
pScreen->a = Rootless##a
WRAP(CreateScreenResources);
WRAP(CloseScreen);
WRAP(CreateGC);
WRAP(PaintWindowBackground);
WRAP(PaintWindowBorder);
WRAP(CopyWindow);
WRAP(GetImage);
WRAP(SourceValidate);
WRAP(CreateWindow);
WRAP(DestroyWindow);
WRAP(RealizeWindow);
WRAP(UnrealizeWindow);
WRAP(MoveWindow);
WRAP(PositionWindow);
WRAP(ResizeWindow);
WRAP(RestackWindow);
WRAP(ReparentWindow);
WRAP(ChangeBorderWidth);
WRAP(MarkOverlappedWindows);
WRAP(ValidateTree);
WRAP(ChangeWindowAttributes);
#ifdef SHAPE
WRAP(SetShape);
#endif
#ifdef RENDER
{
// Composite and Glyphs don't use normal screen wrapping
PictureScreenPtr ps = GetPictureScreen(pScreen);
s->Composite = ps->Composite;
ps->Composite = RootlessComposite;
s->Glyphs = ps->Glyphs;
ps->Glyphs = RootlessGlyphs;
}
#endif
// WRAP(ClearToBackground); fixme put this back? useful for shaped wins?
// WRAP(RestoreAreas); fixme put this back?
#undef WRAP
}
/*
* RootlessInit
* Called by the rootless implementation to initialize the rootless layer.
* Rootless wraps lots of stuff and needs a bunch of devPrivates.
*/
Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs)
{
RootlessScreenRec *s;
if (!RootlessAllocatePrivates(pScreen))
return FALSE;
s = (RootlessScreenRec*)
pScreen->devPrivates[rootlessScreenPrivateIndex].ptr;
s->imp = procs;
RootlessWrap(pScreen);
if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler,
RootlessWakeupHandler,
(pointer) pScreen))
{
return FALSE;
}
return TRUE;
}

View File

@ -0,0 +1,638 @@
/*
* Calculate window clip lists for rootless mode
*
* This file is very closely based on mivaltree.c.
*/
/* $XFree86: xc/programs/Xserver/miext/rootless/rootlessValTree.c,v 1.2 2003/11/10 18:22:50 tsi Exp $ */
/*
* mivaltree.c --
* Functions for recalculating window clip lists. Main function
* is miValidateTree.
*
Copyright 1987, 1988, 1989, 1998 The Open Group
All Rights Reserved.
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
OPEN GROUP 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 of The Open Group shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
*
* Copyright 1987, 1988, 1989 by
* Digital Equipment Corporation, Maynard, Massachusetts,
*
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of Digital not be
* used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
*
* DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
* DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
******************************************************************/
/* The panoramix components contained the following notice */
/****************************************************************
* *
* Copyright (c) Digital Equipment Corporation, 1991, 1997 *
* *
* All Rights Reserved. Unpublished rights reserved under *
* the copyright laws of the United States. *
* *
* The software contained on this media is proprietary to *
* and embodies the confidential technology of Digital *
* Equipment Corporation. Possession, use, duplication or *
* dissemination of the software and media is authorized only *
* pursuant to a valid written license from Digital Equipment *
* Corporation. *
* *
* RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure *
* by the U.S. Government is subject to restrictions as set *
* forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, *
* or in FAR 52.227-19, as applicable. *
* *
*****************************************************************/
/*
* Aug '86: Susan Angebranndt -- original code
* July '87: Adam de Boor -- substantially modified and commented
* Summer '89: Joel McCormack -- so fast you wouldn't believe it possible.
* In particular, much improved code for window mapping and
* circulating.
* Bob Scheifler -- avoid miComputeClips for unmapped windows,
* valdata changes
*/
#include "X.h"
#include "scrnintstr.h"
#include "validate.h"
#include "windowstr.h"
#include "mi.h"
#include "regionstr.h"
#include "mivalidate.h"
#include "globals.h"
#ifdef SHAPE
/*
* Compute the visibility of a shaped window
*/
int
RootlessShapedWindowIn (pScreen, universe, bounding, rect, x, y)
ScreenPtr pScreen;
RegionPtr universe, bounding;
BoxPtr rect;
register int x, y;
{
BoxRec box;
register BoxPtr boundBox;
int nbox;
Bool someIn, someOut;
register int t, x1, y1, x2, y2;
nbox = REGION_NUM_RECTS (bounding);
boundBox = REGION_RECTS (bounding);
someIn = someOut = FALSE;
x1 = rect->x1;
y1 = rect->y1;
x2 = rect->x2;
y2 = rect->y2;
while (nbox--)
{
if ((t = boundBox->x1 + x) < x1)
t = x1;
box.x1 = t;
if ((t = boundBox->y1 + y) < y1)
t = y1;
box.y1 = t;
if ((t = boundBox->x2 + x) > x2)
t = x2;
box.x2 = t;
if ((t = boundBox->y2 + y) > y2)
t = y2;
box.y2 = t;
if (box.x1 > box.x2)
box.x2 = box.x1;
if (box.y1 > box.y2)
box.y2 = box.y1;
switch (RECT_IN_REGION(pScreen, universe, &box))
{
case rgnIN:
if (someOut)
return rgnPART;
someIn = TRUE;
break;
case rgnOUT:
if (someIn)
return rgnPART;
someOut = TRUE;
break;
default:
return rgnPART;
}
boundBox++;
}
if (someIn)
return rgnIN;
return rgnOUT;
}
#endif
#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
HasBorder(w) && \
(w)->backgroundState == ParentRelative)
/*
*-----------------------------------------------------------------------
* RootlessComputeClips --
* Recompute the clipList, borderClip, exposed and borderExposed
* regions for pParent and its children. Only viewable windows are
* taken into account.
*
* Results:
* None.
*
* Side Effects:
* clipList, borderClip, exposed and borderExposed are altered.
* A VisibilityNotify event may be generated on the parent window.
*
*-----------------------------------------------------------------------
*/
static void
RootlessComputeClips (pParent, pScreen, universe, kind, exposed)
register WindowPtr pParent;
register ScreenPtr pScreen;
register RegionPtr universe;
VTKind kind;
RegionPtr exposed; /* for intermediate calculations */
{
int dx,
dy;
RegionRec childUniverse;
register WindowPtr pChild;
int oldVis, newVis;
BoxRec borderSize;
RegionRec childUnion;
Bool overlap;
RegionPtr borderVisible;
Bool resized;
/*
* Figure out the new visibility of this window.
* The extent of the universe should be the same as the extent of
* the borderSize region. If the window is unobscured, this rectangle
* will be completely inside the universe (the universe will cover it
* completely). If the window is completely obscured, none of the
* universe will cover the rectangle.
*/
borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent);
if (dx > 32767)
dx = 32767;
borderSize.x2 = dx;
dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent);
if (dy > 32767)
dy = 32767;
borderSize.y2 = dy;
oldVis = pParent->visibility;
switch (RECT_IN_REGION( pScreen, universe, &borderSize))
{
case rgnIN:
newVis = VisibilityUnobscured;
break;
case rgnPART:
newVis = VisibilityPartiallyObscured;
#ifdef SHAPE
{
RegionPtr pBounding;
if ((pBounding = wBoundingShape (pParent)))
{
switch (RootlessShapedWindowIn (pScreen, universe,
pBounding, &borderSize,
pParent->drawable.x,
pParent->drawable.y))
{
case rgnIN:
newVis = VisibilityUnobscured;
break;
case rgnOUT:
newVis = VisibilityFullyObscured;
break;
}
}
}
#endif
break;
default:
newVis = VisibilityFullyObscured;
break;
}
pParent->visibility = newVis;
if (oldVis != newVis &&
((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
SendVisibilityNotify(pParent);
dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
/*
* avoid computations when dealing with simple operations
*/
switch (kind) {
case VTMap:
case VTStack:
case VTUnmap:
break;
case VTMove:
if ((oldVis == newVis) &&
((oldVis == VisibilityFullyObscured) ||
(oldVis == VisibilityUnobscured)))
{
pChild = pParent;
while (1)
{
if (pChild->viewable)
{
if (pChild->visibility != VisibilityFullyObscured)
{
REGION_TRANSLATE( pScreen, &pChild->borderClip,
dx, dy);
REGION_TRANSLATE( pScreen, &pChild->clipList,
dx, dy);
pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
if (pScreen->ClipNotify)
(* pScreen->ClipNotify) (pChild, dx, dy);
}
if (pChild->valdata)
{
REGION_NULL(pScreen,
&pChild->valdata->after.borderExposed);
if (HasParentRelativeBorder(pChild))
{
REGION_SUBTRACT(pScreen,
&pChild->valdata->after.borderExposed,
&pChild->borderClip,
&pChild->winSize);
}
REGION_NULL(pScreen, &pChild->valdata->after.exposed);
}
if (pChild->firstChild)
{
pChild = pChild->firstChild;
continue;
}
}
while (!pChild->nextSib && (pChild != pParent))
pChild = pChild->parent;
if (pChild == pParent)
break;
pChild = pChild->nextSib;
}
return;
}
/* fall through */
default:
/*
* To calculate exposures correctly, we have to translate the old
* borderClip and clipList regions to the window's new location so there
* is a correspondence between pieces of the new and old clipping regions.
*/
if (dx || dy)
{
/*
* We translate the old clipList because that will be exposed or copied
* if gravity is right.
*/
REGION_TRANSLATE( pScreen, &pParent->borderClip, dx, dy);
REGION_TRANSLATE( pScreen, &pParent->clipList, dx, dy);
}
break;
case VTBroken:
REGION_EMPTY (pScreen, &pParent->borderClip);
REGION_EMPTY (pScreen, &pParent->clipList);
break;
}
borderVisible = pParent->valdata->before.borderVisible;
resized = pParent->valdata->before.resized;
REGION_NULL(pScreen, &pParent->valdata->after.borderExposed);
REGION_NULL(pScreen, &pParent->valdata->after.exposed);
/*
* Since the borderClip must not be clipped by the children, we do
* the border exposure first...
*
* 'universe' is the window's borderClip. To figure the exposures, remove
* the area that used to be exposed from the new.
* This leaves a region of pieces that weren't exposed before.
*/
if (HasBorder (pParent))
{
if (borderVisible)
{
/*
* when the border changes shape, the old visible portions
* of the border will be saved by DIX in borderVisible --
* use that region and destroy it
*/
REGION_SUBTRACT( pScreen, exposed, universe, borderVisible);
REGION_DESTROY( pScreen, borderVisible);
}
else
{
REGION_SUBTRACT( pScreen, exposed, universe, &pParent->borderClip);
}
if (HasParentRelativeBorder(pParent) && (dx || dy)) {
REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
universe,
&pParent->winSize);
} else {
REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
exposed, &pParent->winSize);
}
REGION_COPY( pScreen, &pParent->borderClip, universe);
/*
* To get the right clipList for the parent, and to make doubly sure
* that no child overlaps the parent's border, we remove the parent's
* border from the universe before proceeding.
*/
REGION_INTERSECT( pScreen, universe, universe, &pParent->winSize);
}
else
REGION_COPY( pScreen, &pParent->borderClip, universe);
if ((pChild = pParent->firstChild) && pParent->mapped)
{
REGION_NULL(pScreen, &childUniverse);
REGION_NULL(pScreen, &childUnion);
if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
((pChild->drawable.y == pParent->lastChild->drawable.y) &&
(pChild->drawable.x < pParent->lastChild->drawable.x)))
{
for (; pChild; pChild = pChild->nextSib)
{
if (pChild->viewable)
REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
}
}
else
{
for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
{
if (pChild->viewable)
REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
}
}
REGION_VALIDATE( pScreen, &childUnion, &overlap);
for (pChild = pParent->firstChild;
pChild;
pChild = pChild->nextSib)
{
if (pChild->viewable) {
/*
* If the child is viewable, we want to remove its extents
* from the current universe, but we only re-clip it if
* it's been marked.
*/
if (pChild->valdata) {
/*
* Figure out the new universe from the child's
* perspective and recurse.
*/
REGION_INTERSECT( pScreen, &childUniverse,
universe,
&pChild->borderSize);
RootlessComputeClips (pChild, pScreen, &childUniverse,
kind, exposed);
}
/*
* Once the child has been processed, we remove its extents
* from the current universe, thus denying its space to any
* other sibling.
*/
if (overlap)
REGION_SUBTRACT( pScreen, universe, universe,
&pChild->borderSize);
}
}
if (!overlap)
REGION_SUBTRACT( pScreen, universe, universe, &childUnion);
REGION_UNINIT( pScreen, &childUnion);
REGION_UNINIT( pScreen, &childUniverse);
} /* if any children */
/*
* 'universe' now contains the new clipList for the parent window.
*
* To figure the exposure of the window we subtract the old clip from the
* new, just as for the border.
*/
if (oldVis == VisibilityFullyObscured ||
oldVis == VisibilityNotViewable)
{
REGION_COPY( pScreen, &pParent->valdata->after.exposed, universe);
}
else if (newVis != VisibilityFullyObscured &&
newVis != VisibilityNotViewable)
{
REGION_SUBTRACT( pScreen, &pParent->valdata->after.exposed,
universe, &pParent->clipList);
}
/*
* One last thing: backing storage. We have to try to save what parts of
* the window are about to be obscured. We can just subtract the universe
* from the old clipList and get the areas that were in the old but aren't
* in the new and, hence, are about to be obscured.
*/
if (pParent->backStorage && !resized)
{
REGION_SUBTRACT( pScreen, exposed, &pParent->clipList, universe);
(* pScreen->SaveDoomedAreas)(pParent, exposed, dx, dy);
}
/* HACK ALERT - copying contents of regions, instead of regions */
{
RegionRec tmp;
tmp = pParent->clipList;
pParent->clipList = *universe;
*universe = tmp;
}
#ifdef NOTDEF
REGION_COPY( pScreen, &pParent->clipList, universe);
#endif
pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
if (pScreen->ClipNotify)
(* pScreen->ClipNotify) (pParent, dx, dy);
}
static void
RootlessTreeObscured(pParent)
register WindowPtr pParent;
{
register WindowPtr pChild;
register int oldVis;
pChild = pParent;
while (1)
{
if (pChild->viewable)
{
oldVis = pChild->visibility;
if (oldVis != (pChild->visibility = VisibilityFullyObscured) &&
((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask))
SendVisibilityNotify(pChild);
if (pChild->firstChild)
{
pChild = pChild->firstChild;
continue;
}
}
while (!pChild->nextSib && (pChild != pParent))
pChild = pChild->parent;
if (pChild == pParent)
break;
pChild = pChild->nextSib;
}
}
/*
*-----------------------------------------------------------------------
* RootlessMiValidateTree --
* Recomputes the clip list for pParent and all its inferiors.
*
* Results:
* Always returns 1.
*
* Side Effects:
* The clipList, borderClip, exposed, and borderExposed regions for
* each marked window are altered.
*
* Notes:
* This routine assumes that all affected windows have been marked
* (valdata created) and their winSize and borderSize regions
* adjusted to correspond to their new positions. The borderClip and
* clipList regions should not have been touched.
*
* The top-most level is treated differently from all lower levels
* because pParent is unchanged. For the top level, we merge the
* regions taken up by the marked children back into the clipList
* for pParent, thus forming a region from which the marked children
* can claim their areas. For lower levels, where the old clipList
* and borderClip are invalid, we can't do this and have to do the
* extra operations done in miComputeClips, but this is much faster
* e.g. when only one child has moved...
*
*-----------------------------------------------------------------------
*/
/*
Quartz version: used for validate from root in rootless mode.
We need to make sure top-level windows don't clip each other,
and that top-level windows aren't clipped to the root window.
*/
/*ARGSUSED*/
// fixme this is ugly
// Xprint/ValTree.c doesn't work, but maybe that method can?
int
RootlessMiValidateTree (pRoot, pChild, kind)
WindowPtr pRoot; /* Parent to validate */
WindowPtr pChild; /* First child of pRoot that was
* affected */
VTKind kind; /* What kind of configuration caused call */
{
RegionRec childClip; /* The new borderClip for the current
* child */
RegionRec exposed; /* For intermediate calculations */
register ScreenPtr pScreen;
register WindowPtr pWin;
pScreen = pRoot->drawable.pScreen;
if (pChild == NullWindow)
pChild = pRoot->firstChild;
REGION_NULL(pScreen, &childClip);
REGION_NULL(pScreen, &exposed);
if (REGION_BROKEN (pScreen, &pRoot->clipList) &&
!REGION_BROKEN (pScreen, &pRoot->borderClip))
{
// fixme this might not work, but hopefully doesn't happen anyway.
kind = VTBroken;
REGION_EMPTY (pScreen, &pRoot->clipList);
ErrorF("ValidateTree: BUSTED!\n");
}
/*
* Recursively compute the clips for all children of the root.
* They don't clip against each other or the root itself, so
* childClip is always reset to that child's size.
*/
for (pWin = pChild;
pWin != NullWindow;
pWin = pWin->nextSib)
{
if (pWin->viewable) {
if (pWin->valdata) {
REGION_COPY( pScreen, &childClip, &pWin->borderSize);
RootlessComputeClips (pWin, pScreen, &childClip, kind, &exposed);
} else if (pWin->visibility == VisibilityNotViewable) {
RootlessTreeObscured(pWin);
}
} else {
if (pWin->valdata) {
REGION_EMPTY( pScreen, &pWin->clipList);
if (pScreen->ClipNotify)
(* pScreen->ClipNotify) (pWin, 0, 0);
REGION_EMPTY( pScreen, &pWin->borderClip);
pWin->valdata = (ValidatePtr)NULL;
}
}
}
REGION_UNINIT(pScreen, &childClip);
/* The root is never clipped by its children, so nothing on the root
is ever exposed by moving or mapping its children. */
REGION_NULL(pScreen, &pRoot->valdata->after.exposed);
REGION_NULL(pScreen, &pRoot->valdata->after.borderExposed);
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
/*
* Rootless window management
*/
/*
* Copyright (c) 2001 Greg Parker. 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/miext/rootless/rootlessWindow.h,v 1.2 2003/06/30 01:45:13 torrey Exp $ */
#ifndef _ROOTLESSWINDOW_H
#define _ROOTLESSWINDOW_H
#include "rootlessCommon.h"
Bool RootlessCreateWindow(WindowPtr pWin);
Bool RootlessDestroyWindow(WindowPtr pWin);
#ifdef SHAPE
void RootlessSetShape(WindowPtr pWin);
#endif // SHAPE
Bool RootlessChangeWindowAttributes(WindowPtr pWin, unsigned long vmask);
Bool RootlessPositionWindow(WindowPtr pWin, int x, int y);
Bool RootlessRealizeWindow(WindowPtr pWin);
Bool RootlessUnrealizeWindow(WindowPtr pWin);
void RootlessRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib);
void RootlessCopyWindow(WindowPtr pWin,DDXPointRec ptOldOrg,RegionPtr prgnSrc);
void RootlessMoveWindow(WindowPtr pWin,int x,int y,WindowPtr pSib,VTKind kind);
void RootlessResizeWindow(WindowPtr pWin, int x, int y,
unsigned int w, unsigned int h, WindowPtr pSib);
void RootlessReparentWindow(WindowPtr pWin, WindowPtr pPriorParent);
void RootlessPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion,
int what);
void RootlessPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion,
int what);
void RootlessChangeBorderWidth(WindowPtr pWin, unsigned int width);
#endif

View File

@ -0,0 +1,46 @@
/*
* Replacement functions to protect the alpha channel
*/
/*
* Copyright (c) 2002-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/miext/rootless/safeAlpha/safeAlpha.h,v 1.2 2003/10/18 00:00:34 torrey Exp $ */
#ifndef _SAFEALPHA_H
#define _SAFEALPHA_H
#include "picturestr.h"
#include "rootlessCommon.h"
void SafeAlphaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
#ifdef RENDER
void
SafeAlphaComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
#endif /* RENDER */
#endif /* _SAFEALPHA_H */

View File

@ -0,0 +1,595 @@
/*
* Support for RENDER extension while protecting the alpha channel
*/
/*
* Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
* 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.
*/
/* This file is largely based on fbcompose.c and fbpict.c, which contain
* the following copyright:
*
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
*/
/* $XFree86: xc/programs/Xserver/miext/rootless/safeAlpha/safeAlphaPicture.c,v 1.3 2003/10/24 00:33:15 torrey Exp $ */
#ifdef RENDER
#include "fb.h"
#include "picturestr.h"
#include "mipict.h"
#include "fbpict.h"
#include "safeAlpha.h"
# define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
// Replacement for fbStore_x8r8g8b8 that sets the alpha channel
void
SafeAlphaStore_x8r8g8b8 (FbCompositeOperand *op, CARD32 value)
{
FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset;
((CARD32 *)line)[offset >> 5] = (value & ~RootlessAlphaMask(32)) |
RootlessAlphaMask(32);
}
// Defined in fbcompose.c
extern FbCombineFunc fbCombineFuncU[];
extern FbCombineFunc fbCombineFuncC[];
/* A bunch of macros from fbpict.c */
#define cvt0565to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
#if IMAGE_BYTE_ORDER == MSBFirst
#define Fetch24(a) ((unsigned long) (a) & 1 ? \
((*(a) << 16) | *((CARD16 *) ((a)+1))) : \
((*((CARD16 *) (a)) << 8) | *((a)+2)))
#define Store24(a,v) ((unsigned long) (a) & 1 ? \
((*(a) = (CARD8) ((v) >> 16)), \
(*((CARD16 *) ((a)+1)) = (CARD16) (v))) : \
((*((CARD16 *) (a)) = (CARD16) ((v) >> 8)), \
(*((a)+2) = (CARD8) (v))))
#else
#define Fetch24(a) ((unsigned long) (a) & 1 ? \
((*(a)) | (*((CARD16 *) ((a)+1)) << 8)) : \
((*((CARD16 *) (a))) | (*((a)+2) << 16)))
#define Store24(a,v) ((unsigned long) (a) & 1 ? \
((*(a) = (CARD8) (v)), \
(*((CARD16 *) ((a)+1)) = (CARD16) ((v) >> 8))) : \
((*((CARD16 *) (a)) = (CARD16) (v)),\
(*((a)+2) = (CARD8) ((v) >> 16))))
#endif
#define fbComposeGetSolid(pict, bits) { \
FbBits *__bits__; \
FbStride __stride__; \
int __bpp__; \
int __xoff__,__yoff__; \
\
fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
switch (__bpp__) { \
case 32: \
(bits) = *(CARD32 *) __bits__; \
break; \
case 24: \
(bits) = Fetch24 ((CARD8 *) __bits__); \
break; \
case 16: \
(bits) = *(CARD16 *) __bits__; \
(bits) = cvt0565to8888(bits); \
break; \
default: \
return; \
} \
/* manage missing src alpha */ \
if ((pict)->pFormat->direct.alphaMask == 0) \
(bits) |= 0xff000000; \
}
#define fbComposeGetStart(pict,x,y,type,stride,line,mul) {\
FbBits *__bits__; \
FbStride __stride__; \
int __bpp__; \
int __xoff__,__yoff__; \
\
fbGetDrawable((pict)->pDrawable,__bits__,__stride__,__bpp__,__xoff__,__yoff__); \
(stride) = __stride__ * sizeof (FbBits) / sizeof (type); \
(line) = ((type *) __bits__) + (stride) * ((y) - __yoff__) + (mul) * ((x) - __xoff__); \
}
/* Optimized version of fbCompositeSolidMask_nx8x8888 */
void
SafeAlphaCompositeSolidMask_nx8x8888(
CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height)
{
CARD32 src, srca;
CARD32 *dstLine, *dst, d, dstMask;
CARD8 *maskLine, *mask, m;
FbStride dstStride, maskStride;
CARD16 w;
fbComposeGetSolid(pSrc, src);
dstMask = FbFullMask (pDst->pDrawable->depth);
srca = src >> 24;
if (src == 0)
return;
fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
if (dstMask == FB_ALLONES && pDst->pDrawable->bitsPerPixel == 32 &&
width * height > rootless_CompositePixels_threshold &&
SCREENREC(pDst->pDrawable->pScreen)->imp->CompositePixels)
{
void *srcp[2], *destp[2];
unsigned int dest_rowbytes[2];
unsigned int fn;
srcp[0] = &src; srcp[1] = &src;
/* null rowbytes pointer means use first value as a constant */
destp[0] = dstLine; destp[1] = dstLine;
dest_rowbytes[0] = dstStride * 4; dest_rowbytes[1] = dest_rowbytes[0];
fn = RL_COMPOSITE_FUNCTION(RL_COMPOSITE_OVER, RL_DEPTH_ARGB8888,
RL_DEPTH_A8, RL_DEPTH_ARGB8888);
if (SCREENREC(pDst->pDrawable->pScreen)->imp->CompositePixels(
width, height, fn, srcp, NULL,
maskLine, maskStride,
destp, dest_rowbytes) == Success)
{
return;
}
}
while (height--)
{
dst = dstLine;
dstLine += dstStride;
mask = maskLine;
maskLine += maskStride;
w = width;
while (w--)
{
m = *mask++;
if (m == 0xff)
{
if (srca == 0xff)
*dst = src & dstMask;
else
*dst = fbOver (src, *dst) & dstMask;
}
else if (m)
{
d = fbIn (src, m);
*dst = fbOver (d, *dst) & dstMask;
}
dst++;
}
}
}
void
SafeAlphaCompositeGeneral(
CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height)
{
FbCompositeOperand src[4],msk[4],dst[4],*pmsk;
FbCompositeOperand *srcPict, *srcAlpha;
FbCompositeOperand *dstPict, *dstAlpha;
FbCompositeOperand *mskPict = 0, *mskAlpha = 0;
FbCombineFunc f;
int w;
if (!fbBuildCompositeOperand (pSrc, src, xSrc, ySrc, TRUE, TRUE))
return;
if (!fbBuildCompositeOperand (pDst, dst, xDst, yDst, FALSE, TRUE))
return;
// Use SafeAlpha operands for on screen picture formats
if (pDst->format == PICT_x8r8g8b8) {
dst[0].store = SafeAlphaStore_x8r8g8b8;
}
if (pSrc->alphaMap)
{
srcPict = &src[1];
srcAlpha = &src[2];
}
else
{
srcPict = &src[0];
srcAlpha = 0;
}
if (pDst->alphaMap)
{
dstPict = &dst[1];
dstAlpha = &dst[2];
}
else
{
dstPict = &dst[0];
dstAlpha = 0;
}
f = fbCombineFuncU[op];
if (pMask)
{
if (!fbBuildCompositeOperand (pMask, msk, xMask, yMask, TRUE, TRUE))
return;
pmsk = msk;
if (pMask->componentAlpha)
f = fbCombineFuncC[op];
if (pMask->alphaMap)
{
mskPict = &msk[1];
mskAlpha = &msk[2];
}
else
{
mskPict = &msk[0];
mskAlpha = 0;
}
}
else
pmsk = 0;
while (height--)
{
w = width;
while (w--)
{
(*f) (src, pmsk, dst);
(*src->over) (src);
(*dst->over) (dst);
if (pmsk)
(*pmsk->over) (pmsk);
}
(*src->down) (src);
(*dst->down) (dst);
if (pmsk)
(*pmsk->down) (pmsk);
}
}
void
SafeAlphaComposite(
CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height)
{
RegionRec region;
int n;
BoxPtr pbox;
CompositeFunc func;
Bool srcRepeat = pSrc->repeat;
Bool maskRepeat = FALSE;
Bool srcAlphaMap = pSrc->alphaMap != 0;
Bool maskAlphaMap = FALSE;
Bool dstAlphaMap = pDst->alphaMap != 0;
int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
int w, h, w_this, h_this;
int dstDepth = pDst->pDrawable->depth;
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
if (pMask)
{
xMask += pMask->pDrawable->x;
yMask += pMask->pDrawable->y;
maskRepeat = pMask->repeat;
maskAlphaMap = pMask->alphaMap != 0;
}
if (!miComputeCompositeRegion (&region,
pSrc,
pMask,
pDst,
xSrc,
ySrc,
xMask,
yMask,
xDst,
yDst,
width,
height))
return;
// To preserve the alpha channel we have a special,
// non-optimzied compositor.
func = SafeAlphaCompositeGeneral;
/*
* We can use the more optimized fbpict code, but it sets bits above
* the depth to zero. Temporarily adjust destination depth if needed.
*/
if (pDst->pDrawable->type == DRAWABLE_WINDOW
&& pDst->pDrawable->depth == 24
&& pDst->pDrawable->bitsPerPixel == 32)
{
pDst->pDrawable->depth = 32;
}
if (!pSrc->transform && !(pMask && pMask->transform))
if (!maskAlphaMap && !srcAlphaMap && !dstAlphaMap)
switch (op) {
case PictOpOver:
if (pMask)
{
if (srcRepeat &&
pSrc->pDrawable->width == 1 &&
pSrc->pDrawable->height == 1)
{
srcRepeat = FALSE;
if (PICT_FORMAT_COLOR(pSrc->format)) {
switch (pMask->format) {
case PICT_a8:
switch (pDst->format) {
case PICT_r5g6b5:
case PICT_b5g6r5:
func = fbCompositeSolidMask_nx8x0565;
break;
case PICT_r8g8b8:
case PICT_b8g8r8:
func = fbCompositeSolidMask_nx8x0888;
break;
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
case PICT_a8b8g8r8:
case PICT_x8b8g8r8:
func = SafeAlphaCompositeSolidMask_nx8x8888;
break;
}
break;
case PICT_a8r8g8b8:
if (pMask->componentAlpha) {
switch (pDst->format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
func = fbCompositeSolidMask_nx8888x8888C;
break;
case PICT_r5g6b5:
func = fbCompositeSolidMask_nx8888x0565C;
break;
}
}
break;
case PICT_a8b8g8r8:
if (pMask->componentAlpha) {
switch (pDst->format) {
case PICT_a8b8g8r8:
case PICT_x8b8g8r8:
func = fbCompositeSolidMask_nx8888x8888C;
break;
case PICT_b5g6r5:
func = fbCompositeSolidMask_nx8888x0565C;
break;
}
}
break;
case PICT_a1:
switch (pDst->format) {
case PICT_r5g6b5:
case PICT_b5g6r5:
case PICT_r8g8b8:
case PICT_b8g8r8:
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
case PICT_a8b8g8r8:
case PICT_x8b8g8r8:
func = fbCompositeSolidMask_nx1xn;
break;
}
}
}
}
}
else
{
switch (pSrc->format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
switch (pDst->format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
func = fbCompositeSrc_8888x8888;
break;
case PICT_r8g8b8:
func = fbCompositeSrc_8888x0888;
break;
case PICT_r5g6b5:
func = fbCompositeSrc_8888x0565;
break;
}
break;
case PICT_a8b8g8r8:
case PICT_x8b8g8r8:
switch (pDst->format) {
case PICT_a8b8g8r8:
case PICT_x8b8g8r8:
func = fbCompositeSrc_8888x8888;
break;
case PICT_b8g8r8:
func = fbCompositeSrc_8888x0888;
break;
case PICT_b5g6r5:
func = fbCompositeSrc_8888x0565;
break;
}
break;
case PICT_r5g6b5:
switch (pDst->format) {
case PICT_r5g6b5:
func = fbCompositeSrc_0565x0565;
break;
}
break;
case PICT_b5g6r5:
switch (pDst->format) {
case PICT_b5g6r5:
func = fbCompositeSrc_0565x0565;
break;
}
break;
}
}
break;
case PictOpAdd:
if (pMask == 0)
{
switch (pSrc->format) {
case PICT_a8r8g8b8:
switch (pDst->format) {
case PICT_a8r8g8b8:
func = fbCompositeSrcAdd_8888x8888;
break;
}
break;
case PICT_a8b8g8r8:
switch (pDst->format) {
case PICT_a8b8g8r8:
func = fbCompositeSrcAdd_8888x8888;
break;
}
break;
case PICT_a8:
switch (pDst->format) {
case PICT_a8:
func = fbCompositeSrcAdd_8000x8000;
break;
}
break;
case PICT_a1:
switch (pDst->format) {
case PICT_a1:
func = fbCompositeSrcAdd_1000x1000;
break;
}
break;
}
}
break;
}
n = REGION_NUM_RECTS (&region);
pbox = REGION_RECTS (&region);
while (n--)
{
h = pbox->y2 - pbox->y1;
y_src = pbox->y1 - yDst + ySrc;
y_msk = pbox->y1 - yDst + yMask;
y_dst = pbox->y1;
while (h)
{
h_this = h;
w = pbox->x2 - pbox->x1;
x_src = pbox->x1 - xDst + xSrc;
x_msk = pbox->x1 - xDst + xMask;
x_dst = pbox->x1;
if (maskRepeat)
{
y_msk = mod (y_msk, pMask->pDrawable->height);
if (h_this > pMask->pDrawable->height - y_msk)
h_this = pMask->pDrawable->height - y_msk;
}
if (srcRepeat)
{
y_src = mod (y_src, pSrc->pDrawable->height);
if (h_this > pSrc->pDrawable->height - y_src)
h_this = pSrc->pDrawable->height - y_src;
}
while (w)
{
w_this = w;
if (maskRepeat)
{
x_msk = mod (x_msk, pMask->pDrawable->width);
if (w_this > pMask->pDrawable->width - x_msk)
w_this = pMask->pDrawable->width - x_msk;
}
if (srcRepeat)
{
x_src = mod (x_src, pSrc->pDrawable->width);
if (w_this > pSrc->pDrawable->width - x_src)
w_this = pSrc->pDrawable->width - x_src;
}
(*func) (op, pSrc, pMask, pDst,
x_src, y_src, x_msk, y_msk, x_dst, y_dst,
w_this, h_this);
w -= w_this;
x_src += w_this;
x_msk += w_this;
x_dst += w_this;
}
h -= h_this;
y_src += h_this;
y_msk += h_this;
y_dst += h_this;
}
pbox++;
}
REGION_UNINIT (pDst->pDrawable->pScreen, &region);
// Reset destination depth to its true value
pDst->pDrawable->depth = dstDepth;
}
#endif /* RENDER */

View File

@ -0,0 +1,173 @@
/*
* Specialized window functions to protect the alpha channel
*/
/*
* Copyright (c) 2002-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.
*/
/* Portions of this file are based on fbwindow.c, which contains the
* following copyright:
*
* Copyright © 1998 Keith Packard
*/
/* $XFree86: xc/programs/Xserver/miext/rootless/safeAlpha/safeAlphaWindow.c,v 1.1 2003/09/16 00:36:20 torrey Exp $ */
#include "fb.h"
#include "safeAlpha.h"
#ifdef PANORAMIX
#include "panoramiX.h"
#include "panoramiXsrv.h"
#endif
/*
* SafeAlphaFillRegionTiled
* Fill using a tile while leaving the alpha channel untouched.
* Based on fbfillRegionTiled.
*/
void
SafeAlphaFillRegionTiled(
DrawablePtr pDrawable,
RegionPtr pRegion,
PixmapPtr pTile)
{
FbBits *dst;
FbStride dstStride;
int dstBpp;
int dstXoff, dstYoff;
FbBits *tile;
FbStride tileStride;
int tileBpp;
int tileXoff, tileYoff; /* XXX assumed to be zero */
int tileWidth, tileHeight;
int n = REGION_NUM_RECTS(pRegion);
BoxPtr pbox = REGION_RECTS(pRegion);
int xRot = pDrawable->x;
int yRot = pDrawable->y;
FbBits planeMask;
#ifdef PANORAMIX
if(!noPanoramiXExtension)
{
int index = pDrawable->pScreen->myNum;
if(&WindowTable[index]->drawable == pDrawable)
{
xRot -= panoramiXdataPtr[index].x;
yRot -= panoramiXdataPtr[index].y;
}
}
#endif
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp,
tileXoff, tileYoff);
tileWidth = pTile->drawable.width;
tileHeight = pTile->drawable.height;
xRot += dstXoff;
yRot += dstYoff;
planeMask = FB_ALLONES & ~RootlessAlphaMask(dstBpp);
while (n--)
{
fbTile (dst + (pbox->y1 + dstYoff) * dstStride,
dstStride,
(pbox->x1 + dstXoff) * dstBpp,
(pbox->x2 - pbox->x1) * dstBpp,
pbox->y2 - pbox->y1,
tile,
tileStride,
tileWidth * dstBpp,
tileHeight,
GXcopy,
planeMask,
dstBpp,
xRot * dstBpp,
yRot - pbox->y1);
pbox++;
}
}
/*
* SafeAlphaPaintWindow
* Paint the window while filling in the alpha channel with all on.
* We can't use fbPaintWindow because it zeros the alpha channel.
*/
void
SafeAlphaPaintWindow(
WindowPtr pWin,
RegionPtr pRegion,
int what)
{
switch (what) {
case PW_BACKGROUND:
switch (pWin->backgroundState) {
case None:
break;
case ParentRelative:
do {
pWin = pWin->parent;
} while (pWin->backgroundState == ParentRelative);
(*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
what);
break;
case BackgroundPixmap:
SafeAlphaFillRegionTiled (&pWin->drawable,
pRegion,
pWin->background.pixmap);
break;
case BackgroundPixel:
{
Pixel pixel = pWin->background.pixel |
RootlessAlphaMask(pWin->drawable.bitsPerPixel);
fbFillRegionSolid (&pWin->drawable, pRegion, 0,
fbReplicatePixel (pixel,
pWin->drawable.bitsPerPixel));
break;
}
}
break;
case PW_BORDER:
if (pWin->borderIsPixel)
{
Pixel pixel = pWin->border.pixel |
RootlessAlphaMask(pWin->drawable.bitsPerPixel);
fbFillRegionSolid (&pWin->drawable, pRegion, 0,
fbReplicatePixel (pixel,
pWin->drawable.bitsPerPixel));
}
else
{
WindowPtr pBgWin;
for (pBgWin = pWin; pBgWin->backgroundState == ParentRelative;
pBgWin = pBgWin->parent);
SafeAlphaFillRegionTiled (&pBgWin->drawable,
pRegion,
pWin->border.pixmap);
}
break;
}
fbValidateDrawable (&pWin->drawable);
}

610
os/log.c Normal file
View File

@ -0,0 +1,610 @@
/*
Copyright 1987, 1998 The Open Group
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
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 OPEN GROUP 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 of The Open Group shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from The Open Group.
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
Copyright 1994 Quarterdeck Office Systems.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Digital and
Quarterdeck not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
DIGITAL AND QUARTERDECK DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Copyright (c) 1997-2003 by The XFree86 Project, Inc.
*
* 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 COPYRIGHT HOLDER(S) OR AUTHOR(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 of the copyright holder(s)
* and author(s) shall not be used in advertising or otherwise to promote
* the sale, use or other dealings in this Software without prior written
* authorization from the copyright holder(s) and author(s).
*/
/* $XFree86: xc/programs/Xserver/os/log.c,v 1.6 2003/11/07 13:45:27 tsi Exp $ */
#include "Xos.h"
#include <stdio.h>
#include <time.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <stdlib.h> /* for malloc() */
#include <errno.h>
#include "site.h"
#include "opaque.h"
#ifdef DDXOSVERRORF
void (*OsVendorVErrorFProc)(const char *, va_list args) = NULL;
#endif
static FILE *logFile = NULL;
static Bool logFlush = FALSE;
static Bool logSync = FALSE;
static int logVerbosity = DEFAULT_LOG_VERBOSITY;
static int logFileVerbosity = DEFAULT_LOG_FILE_VERBOSITY;
/* Buffer to information logged before the log file is opened. */
static char *saveBuffer = NULL;
static int bufferSize = 0, bufferUnused = 0, bufferPos = 0;
static Bool needBuffer = TRUE;
/* Prefix strings for log messages. */
#ifndef X_UNKNOWN_STRING
#define X_UNKNOWN_STRING "(\?\?)"
#endif
#ifndef X_PROBE_STRING
#define X_PROBE_STRING "(--)"
#endif
#ifndef X_CONFIG_STRING
#define X_CONFIG_STRING "(**)"
#endif
#ifndef X_DEFAULT_STRING
#define X_DEFAULT_STRING "(==)"
#endif
#ifndef X_CMDLINE_STRING
#define X_CMDLINE_STRING "(++)"
#endif
#ifndef X_NOTICE_STRING
#define X_NOTICE_STRING "(!!)"
#endif
#ifndef X_ERROR_STRING
#define X_ERROR_STRING "(EE)"
#endif
#ifndef X_WARNING_STRING
#define X_WARNING_STRING "(WW)"
#endif
#ifndef X_INFO_STRING
#define X_INFO_STRING "(II)"
#endif
#ifndef X_NOT_IMPLEMENTED_STRING
#define X_NOT_IMPLEMENTED_STRING "(NI)"
#endif
/*
* LogInit is called to start logging to a file. It is also called (with
* NULL arguments) when logging to a file is not wanted. It must always be
* called, otherwise log messages will continue to accumulate in a buffer.
*
* %s, if present in the fname or backup strings, is expanded to the display
* string.
*/
const char *
LogInit(const char *fname, const char *backup)
{
char *logFileName = NULL;
if (fname && *fname) {
/* xalloc() can't be used yet. */
logFileName = malloc(strlen(fname) + strlen(display) + 1);
if (!logFileName)
FatalError("Cannot allocate space for the log file name\n");
sprintf(logFileName, fname, display);
if (backup && *backup) {
struct stat buf;
if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)) {
char *suffix;
char *oldLog;
oldLog = malloc(strlen(logFileName) + strlen(backup) +
strlen(display) + 1);
suffix = malloc(strlen(backup) + strlen(display) + 1);
if (!oldLog || !suffix)
FatalError("Cannot allocate space for the log file name\n");
sprintf(suffix, backup, display);
sprintf(oldLog, "%s%s", logFileName, suffix);
free(suffix);
#ifdef __UNIXOS2__
remove(oldLog);
#endif
if (rename(logFileName, oldLog) == -1) {
FatalError("Cannot move old log file (\"%s\" to \"%s\"\n",
logFileName, oldLog);
}
free(oldLog);
}
}
if ((logFile = fopen(logFileName, "w")) == NULL)
FatalError("Cannot open log file \"%s\"\n", logFileName);
setvbuf(logFile, NULL, _IONBF, 0);
/* Flush saved log information. */
if (saveBuffer && bufferSize > 0) {
fwrite(saveBuffer, bufferPos, 1, logFile);
fflush(logFile);
fsync(fileno(logFile));
}
}
/*
* Unconditionally free the buffer, and flag that the buffer is no longer
* needed.
*/
if (saveBuffer && bufferSize > 0) {
free(saveBuffer); /* Must be free(), not xfree() */
saveBuffer = NULL;
bufferSize = 0;
}
needBuffer = FALSE;
return logFileName;
}
void
LogClose()
{
if (logFile) {
fclose(logFile);
logFile = NULL;
}
}
Bool
LogSetParameter(LogParameter param, int value)
{
switch (param) {
case XLOG_FLUSH:
logFlush = value ? TRUE : FALSE;
return TRUE;
case XLOG_SYNC:
logSync = value ? TRUE : FALSE;
return TRUE;
case XLOG_VERBOSITY:
logVerbosity = value;
return TRUE;
case XLOG_FILE_VERBOSITY:
logFileVerbosity = value;
return TRUE;
default:
return FALSE;
}
}
/* This function does the actual log message writes. */
void
LogVWrite(int verb, const char *f, va_list args)
{
static char tmpBuffer[1024];
int len = 0;
/*
* Since a va_list can only be processed once, write the string to a
* buffer, and then write the buffer out to the appropriate output
* stream(s).
*/
if (verb < 0 || logFileVerbosity >= verb || logVerbosity >= verb) {
vsnprintf(tmpBuffer, sizeof(tmpBuffer), f, args);
len = strlen(tmpBuffer);
}
if ((verb < 0 || logVerbosity >= verb) && len > 0)
fwrite(tmpBuffer, len, 1, stderr);
if ((verb < 0 || logFileVerbosity >= verb) && len > 0) {
if (logFile) {
fwrite(tmpBuffer, len, 1, logFile);
if (logFlush) {
fflush(logFile);
if (logSync)
fsync(fileno(logFile));
}
} else if (needBuffer) {
/*
* Note, this code is used before OsInit() has been called, so
* xalloc() and friends can't be used.
*/
if (len > bufferUnused) {
bufferSize += 1024;
bufferUnused += 1024;
if (saveBuffer)
saveBuffer = realloc(saveBuffer, bufferSize);
else
saveBuffer = malloc(bufferSize);
if (!saveBuffer)
FatalError("realloc() failed while saving log messages\n");
}
bufferUnused -= len;
memcpy(saveBuffer + bufferPos, tmpBuffer, len);
bufferPos += len;
}
}
}
void
LogWrite(int verb, const char *f, ...)
{
va_list args;
va_start(args, f);
LogVWrite(verb, f, args);
va_end(args);
}
void
LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
{
const char *s = X_UNKNOWN_STRING;
char *tmpBuf = NULL;
/* Ignore verbosity for X_ERROR */
if (logVerbosity >= verb || logFileVerbosity >= verb || type == X_ERROR) {
switch (type) {
case X_PROBED:
s = X_PROBE_STRING;
break;
case X_CONFIG:
s = X_CONFIG_STRING;
break;
case X_DEFAULT:
s = X_DEFAULT_STRING;
break;
case X_CMDLINE:
s = X_CMDLINE_STRING;
break;
case X_NOTICE:
s = X_NOTICE_STRING;
break;
case X_ERROR:
s = X_ERROR_STRING;
if (verb > 0)
verb = 0;
break;
case X_WARNING:
s = X_WARNING_STRING;
break;
case X_INFO:
s = X_INFO_STRING;
break;
case X_NOT_IMPLEMENTED:
s = X_NOT_IMPLEMENTED_STRING;
break;
case X_UNKNOWN:
s = X_UNKNOWN_STRING;
break;
case X_NONE:
s = NULL;
break;
}
/*
* Prefix the format string with the message type. We do it this way
* so that LogVWrite() is only called once per message.
*/
if (s) {
tmpBuf = malloc(strlen(format) + strlen(s) + 1 + 1);
/* Silently return if malloc fails here. */
if (!tmpBuf)
return;
sprintf(tmpBuf, "%s ", s);
strcat(tmpBuf, format);
LogVWrite(verb, tmpBuf, args);
free(tmpBuf);
} else
LogVWrite(verb, format, args);
}
}
/* Log message with verbosity level specified. */
void
LogMessageVerb(MessageType type, int verb, const char *format, ...)
{
va_list ap;
va_start(ap, format);
LogVMessageVerb(type, verb, format, ap);
va_end(ap);
}
/* Log a message with the standard verbosity level of 1. */
void
LogMessage(MessageType type, const char *format, ...)
{
va_list ap;
va_start(ap, format);
LogVMessageVerb(type, 1, format, ap);
va_end(ap);
}
#ifdef __GNUC__
static void AbortServer(void) __attribute__((noreturn));
#endif
static void
AbortServer(void)
{
OsCleanup(TRUE);
AbortDDX();
fflush(stderr);
if (CoreDump)
abort();
exit (1);
}
#ifndef AUDIT_PREFIX
#define AUDIT_PREFIX "AUDIT: %s: %ld %s: "
#endif
#ifndef AUDIT_TIMEOUT
#define AUDIT_TIMEOUT ((CARD32)(120 * 1000)) /* 2 mn */
#endif
static int nrepeat = 0;
static int oldlen = -1;
static OsTimerPtr auditTimer = NULL;
void
FreeAuditTimer(void)
{
if (auditTimer != NULL) {
/* Force output of pending messages */
TimerForce(auditTimer);
TimerFree(auditTimer);
auditTimer = NULL;
}
}
static char *
AuditPrefix(void)
{
time_t tm;
char *autime, *s;
char *tmpBuf;
int len;
time(&tm);
autime = ctime(&tm);
if ((s = strchr(autime, '\n')))
*s = '\0';
if ((s = strrchr(argvGlobal[0], '/')))
s++;
else
s = argvGlobal[0];
len = strlen(AUDIT_PREFIX) + strlen(autime) + 10 + strlen(s) + 1;
tmpBuf = malloc(len);
if (!tmpBuf)
return NULL;
snprintf(tmpBuf, len, AUDIT_PREFIX, autime, (unsigned long)getpid(), s);
return tmpBuf;
}
void
AuditF(const char * f, ...)
{
va_list args;
va_start(args, f);
VAuditF(f, args);
va_end(args);
}
static CARD32
AuditFlush(OsTimerPtr timer, CARD32 now, pointer arg)
{
char *prefix;
if (nrepeat > 0) {
prefix = AuditPrefix();
ErrorF("%slast message repeated %d times\n",
prefix != NULL ? prefix : "", nrepeat);
nrepeat = 0;
if (prefix != NULL)
free(prefix);
return AUDIT_TIMEOUT;
} else {
/* if the timer expires without anything to print, flush the message */
oldlen = -1;
return 0;
}
}
void
VAuditF(const char *f, va_list args)
{
char *prefix;
char buf[1024];
int len;
static char oldbuf[1024];
prefix = AuditPrefix();
len = vsnprintf(buf, sizeof(buf), f, args);
if (len == oldlen && strcmp(buf, oldbuf) == 0) {
/* Message already seen */
nrepeat++;
} else {
/* new message */
if (auditTimer != NULL)
TimerForce(auditTimer);
ErrorF("%s%s", prefix != NULL ? prefix : "", buf);
strlcpy(oldbuf, buf, sizeof(oldbuf));
oldlen = len;
nrepeat = 0;
auditTimer = TimerSet(auditTimer, 0, AUDIT_TIMEOUT, AuditFlush, NULL);
}
if (prefix != NULL)
free(prefix);
}
void
FatalError(const char *f, ...)
{
va_list args;
static Bool beenhere = FALSE;
if (beenhere)
ErrorF("\nFatalError re-entered, aborting\n");
else
ErrorF("\nFatal server error:\n");
va_start(args, f);
VErrorF(f, args);
va_end(args);
ErrorF("\n");
#ifdef DDXOSFATALERROR
if (!beenhere)
OsVendorFatalError();
#endif
#ifdef ABORTONFATALERROR
abort();
#endif
if (!beenhere) {
beenhere = TRUE;
AbortServer();
} else
abort();
/*NOTREACHED*/
}
void
VErrorF(const char *f, va_list args)
{
#ifdef DDXOSVERRORF
if (OsVendorVErrorFProc)
OsVendorVErrorFProc(f, args);
else
LogVWrite(-1, f, args);
#else
LogVWrite(-1, f, args);
#endif
}
void
ErrorF(const char * f, ...)
{
va_list args;
va_start(args, f);
VErrorF(f, args);
va_end(args);
}
/* A perror() workalike. */
#ifndef NEED_STRERROR
#ifdef SYSV
#if !defined(ISC) || defined(ISC202) || defined(ISC22)
#define NEED_STRERROR
#endif
#endif
#endif
#if defined(NEED_STRERROR) && !defined(strerror)
extern char *sys_errlist[];
extern int sys_nerr;
#define strerror(n) \
((n) >= 0 && (n) < sys_nerr) ? sys_errlist[(n)] : "unknown error"
#endif
void
Error(char *str)
{
char *err = NULL;
int saveErrno = errno;
if (str) {
err = malloc(strlen(strerror(saveErrno)) + strlen(str) + 2 + 1);
if (!err)
return;
sprintf(err, "%s: ", str);
strcat(err, strerror(saveErrno));
LogWrite(-1, err);
} else
LogWrite(-1, strerror(saveErrno));
}
void
LogPrintMarkers()
{
/* Show what the message marker symbols mean. */
ErrorF("Markers: ");
LogMessageVerb(X_PROBED, -1, "probed, ");
LogMessageVerb(X_CONFIG, -1, "from config file, ");
LogMessageVerb(X_DEFAULT, -1, "default setting,\n\t");
LogMessageVerb(X_CMDLINE, -1, "from command line, ");
LogMessageVerb(X_NOTICE, -1, "notice, ");
LogMessageVerb(X_INFO, -1, "informational,\n\t");
LogMessageVerb(X_WARNING, -1, "warning, ");
LogMessageVerb(X_ERROR, -1, "error, ");
LogMessageVerb(X_NOT_IMPLEMENTED, -1, "not implemented, ");
LogMessageVerb(X_UNKNOWN, -1, "unknown.\n");
}

57
os/strlcat.c Normal file
View File

@ -0,0 +1,57 @@
/* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/lib/misc/strlcat.c,v 1.1 2003/10/26 12:17:14 herrb Exp $ */
#include <sys/types.h>
#include <string.h>
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(char *dst, const char *src, size_t siz)
{
register char *d = dst;
register const char *s = src;
register size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}

52
os/strlcpy.c Normal file
View File

@ -0,0 +1,52 @@
/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/lib/misc/strlcpy.c,v 1.1 2003/10/26 12:17:14 herrb Exp $ */
#include <sys/types.h>
#include <string.h>
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
register char *d = dst;
register const char *s = src;
register size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}

72
xkb/xkb.h Normal file
View File

@ -0,0 +1,72 @@
/* $XFree86: xc/programs/Xserver/xkb/xkb.h,v 1.1 2003/07/16 01:39:08 dawes Exp $ */
/* #include "XKBfile.h" */
extern int ProcXkbUseExtension(ClientPtr client);
extern int ProcXkbSelectEvents(ClientPtr client);
extern int ProcXkbBell(ClientPtr client);
extern int ProcXkbGetState(ClientPtr client);
extern int ProcXkbLatchLockState(ClientPtr client);
extern int ProcXkbGetControls(ClientPtr client);
extern int ProcXkbSetControls(ClientPtr client);
extern int ProcXkbGetMap(ClientPtr client);
extern int ProcXkbSetMap(ClientPtr client);
extern int ProcXkbGetCompatMap(ClientPtr client);
extern int ProcXkbSetCompatMap(ClientPtr client);
extern int ProcXkbGetIndicatorState(ClientPtr client);
extern int ProcXkbGetIndicatorMap(ClientPtr client);
extern int ProcXkbSetIndicatorMap(ClientPtr client);
extern int ProcXkbGetNamedIndicator(ClientPtr client);
extern int ProcXkbSetNamedIndicator(ClientPtr client);
extern int ProcXkbGetNames(ClientPtr client);
extern int ProcXkbSetNames(ClientPtr client);
extern int ProcXkbGetGeometry(ClientPtr client);
extern int ProcXkbSetGeometry(ClientPtr client);
extern int ProcXkbPerClientFlags(ClientPtr client);
extern int ProcXkbListComponents(ClientPtr client);
extern int ProcXkbGetKbdByName(ClientPtr client);
extern int ProcXkbGetDeviceInfo(ClientPtr client);
extern int ProcXkbSetDeviceInfo(ClientPtr client);
extern int ProcXkbSetDebuggingFlags(ClientPtr client);
extern int XkbSetRepeatRate(DeviceIntPtr dev, int timeout, int interval, int major, int minor);
extern int XkbGetRepeatRate(DeviceIntPtr dev, int *timeout, int *interval);
extern Status XkbComputeGetIndicatorMapReplySize(
XkbIndicatorPtr indicators,
xkbGetIndicatorMapReply *rep);
extern int XkbSendIndicatorMap(
ClientPtr client,
XkbIndicatorPtr indicators,
xkbGetIndicatorMapReply *rep);
extern void XkbComputeCompatState(XkbSrvInfoPtr xkbi);
extern void XkbSetPhysicalLockingKey(DeviceIntPtr dev, unsigned key);
extern Bool XkbFilterEvents(ClientPtr pClient, int nEvents, xEvent *xE);
extern Bool XkbApplyLEDChangeToKeyboard(
XkbSrvInfoPtr xkbi,
XkbIndicatorMapPtr map,
Bool on,
XkbChangesPtr change);
extern Bool XkbWriteRulesProp(ClientPtr client, pointer closure);
extern XkbAction XkbGetButtonAction(DeviceIntPtr kbd, DeviceIntPtr dev, int button);
/* extern Status XkbMergeFile(XkbDescPtr xkb, XkbFileInfo finfo); */
extern Bool XkbDDXCompileNamedKeymap(
XkbDescPtr xkb,
XkbComponentNamesPtr names,
char * nameRtrn,
int nameRtrnLen);
extern Bool XkbDDXCompileKeymapByNames(
XkbDescPtr xkb,
XkbComponentNamesPtr names,
unsigned want,
unsigned need,
char * nameRtrn,
int nameRtrnLen);