merge latest (4.3.99.16) from XFree86 (vendor) branch

This commit is contained in:
Kaleb Keithley
2003-11-26 22:49:07 +00:00
parent c57959ad6a
commit 0097b6fe2d
796 changed files with 58012 additions and 26524 deletions

View File

@@ -1,5 +1,5 @@
/* English localized versions of strings used by the Mac OS X front end. */
/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/English.lproj/Localizable.strings,v 1.3 2002/01/30 06:50:46 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/bundle/English.lproj/Localizable.strings,v 1.4 2003/11/04 22:48:14 torrey Exp $ */
/* Title of alert panel */
"Quit X server?" = "Quit X server?";
@@ -14,10 +14,10 @@
"Cancel" = "Cancel";
/* Default keymapping file */
"USA.keymapping" = "USA.keymapping"
"USA.keymapping" = "USA.keymapping";
/* Default switch string */
"Cmd-Opt-a" = "Cmd-Opt-a"
"Cmd-Opt-a" = "Cmd-Opt-a";
/* Button title when changing switch key */
"Press key" = "Press key"
"Press key" = "Press key";

View File

@@ -41,14 +41,20 @@
},
{
ACTIONS = {
bringAllToFront = id;
closeHelpAndShow = id;
itemSelected = id;
nextWindow = id;
previousWindow = id;
showAction = id;
showSwitchPanel = id;
startFullScreen = id;
startRootless = id;
};
CLASS = XServer;
LANGUAGE = ObjC;
OUTLETS = {
dockMenu = NSMenu;
helpWindow = NSWindow;
modeWindow = NSWindow;
startFullScreenButton = NSButton;
@@ -56,6 +62,8 @@
startupHelpButton = NSButton;
startupModeButton = NSButton;
switchWindow = NSPanel;
windowMenu = NSMenu;
windowSeparator = NSMenuItem;
};
SUPERCLASS = NSObject;
}

View File

@@ -1,11 +1,11 @@
/**************************************************************
*
* Shared code for the Darwin X Server
* running with Quartz or the IOKit
* running with Quartz or IOKit display mode
*
**************************************************************/
/*
* Copyright (c) 2001-2002 Torrey T. Lyons. All Rights Reserved.
* 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"),
@@ -29,7 +29,7 @@
* 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/darwin.c,v 1.50 2003/02/26 09:21:33 dawes Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/darwin.c,v 1.55 2003/11/15 00:07:09 torrey Exp $ */
#include "X.h"
#include "Xproto.h"
@@ -52,6 +52,7 @@
#include <sys/syslimits.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#define NO_CFPLUGIN
#include <IOKit/IOKitLib.h>
@@ -60,8 +61,6 @@
#include "darwin.h"
#include "darwinClut8.h"
#include "quartz/quartz.h"
#include "xfIOKit.h"
/*
* X server shared global variables
@@ -69,9 +68,9 @@
int darwinScreensFound = 0;
int darwinScreenIndex = 0;
io_connect_t darwinParamConnect = 0;
int darwinEventFD = -1;
Bool quartz = FALSE;
int quartzMouseAccelChange = 1;
int darwinEventReadFD = -1;
int darwinEventWriteFD = -1;
int darwinMouseAccelChange = 1;
int darwinFakeButtons = 0;
// location of X11's (0,0) point in global screen coordinates
@@ -113,7 +112,7 @@ const int NUMFORMATS = sizeof(formats)/sizeof(formats[0]);
#define PRE_RELEASE XF86_VERSION_SNAP
#endif
static void
void
DarwinPrintBanner()
{
#if PRE_RELEASE
@@ -193,11 +192,7 @@ static Bool DarwinAddScreen(
SCREEN_PRIV(pScreen) = dfb;
// setup hardware/mode specific details
if (quartz) {
ret = QuartzAddScreen(foundIndex, pScreen);
} else {
ret = XFIOKitAddScreen(foundIndex, pScreen);
}
ret = DarwinModeAddScreen(foundIndex, pScreen);
foundIndex++;
if (! ret)
return FALSE;
@@ -276,14 +271,8 @@ static Bool DarwinAddScreen(
pScreen->SaveScreen = DarwinSaveScreen;
// finish mode dependent screen setup including cursor support
if (quartz) {
if (! QuartzSetupScreen(index, pScreen)) {
return FALSE;
}
} else {
if (! XFIOKitSetupScreen(index, pScreen)) {
return FALSE;
}
if (!DarwinModeSetupScreen(index, pScreen)) {
return FALSE;
}
// create and install the default colormap and
@@ -337,7 +326,7 @@ static void DarwinChangePointerControl(
kern_return_t kr;
double acceleration;
if (!quartzMouseAccelChange)
if (!darwinMouseAccelChange)
return;
acceleration = ctrl->num / ctrl->den;
@@ -378,13 +367,13 @@ static int DarwinMouseProc(
case DEVICE_ON:
pPointer->public.on = TRUE;
AddEnabledDevice( darwinEventFD );
AddEnabledDevice( darwinEventReadFD );
return Success;
case DEVICE_CLOSE:
case DEVICE_OFF:
pPointer->public.on = FALSE;
RemoveEnabledDevice( darwinEventFD );
RemoveEnabledDevice( darwinEventReadFD );
return Success;
}
@@ -404,11 +393,11 @@ static int DarwinKeybdProc( DeviceIntPtr pDev, int onoff )
break;
case DEVICE_ON:
pDev->public.on = TRUE;
AddEnabledDevice( darwinEventFD );
AddEnabledDevice( darwinEventReadFD );
break;
case DEVICE_OFF:
pDev->public.on = FALSE;
RemoveEnabledDevice( darwinEventFD );
RemoveEnabledDevice( darwinEventReadFD );
break;
case DEVICE_CLOSE:
break;
@@ -529,12 +518,61 @@ void InitInput( int argc, char **argv )
darwinKeyboard = AddInputDevice(DarwinKeybdProc, TRUE);
RegisterKeyboardDevice( darwinKeyboard );
DarwinEQInit( (DevicePtr)darwinKeyboard, (DevicePtr)darwinPointer );
if (serverGeneration == 1) {
DarwinEQInit( (DevicePtr)darwinKeyboard, (DevicePtr)darwinPointer );
}
if (quartz) {
QuartzInitInput(argc, argv);
} else {
XFIOKitInitInput(argc, argv);
DarwinModeInitInput(argc, argv);
}
/*
* DarwinAdjustScreenOrigins
* Shift all screens so the X11 (0, 0) coordinate is at the top
* left of the global screen coordinates.
*
* Screens can be arranged so the top left isn't on any screen, so
* instead use the top left of the leftmost screen as (0,0). This
* may mean some screen space is in -y, but it's better that (0,0)
* be onscreen, or else default xterms disappear. It's better that
* -y be used than -x, because when popup menus are forced
* "onscreen" by dumb window managers like twm, they'll shift the
* menus down instead of left, which still looks funny but is an
* easier target to hit.
*/
void
DarwinAdjustScreenOrigins(ScreenInfo *pScreenInfo)
{
int i, left, top;
left = dixScreenOrigins[0].x;
top = dixScreenOrigins[0].y;
/* Find leftmost screen. If there's a tie, take the topmost of the two. */
for (i = 1; i < pScreenInfo->numScreens; i++) {
if (dixScreenOrigins[i].x < left ||
(dixScreenOrigins[i].x == left &&
dixScreenOrigins[i].y < top))
{
left = dixScreenOrigins[i].x;
top = dixScreenOrigins[i].y;
}
}
darwinMainScreenX = left;
darwinMainScreenY = top;
/* Shift all screens so that there is a screen whose top left
is at X11 (0,0) and at global screen coordinate
(darwinMainScreenX, darwinMainScreenY). */
if (darwinMainScreenX != 0 || darwinMainScreenY != 0) {
for (i = 0; i < pScreenInfo->numScreens; i++) {
dixScreenOrigins[i].x -= darwinMainScreenX;
dixScreenOrigins[i].y -= darwinMainScreenY;
ErrorF("Screen %d placed at X11 coordinate (%d,%d).\n",
i, dixScreenOrigins[i].x, dixScreenOrigins[i].y);
}
}
}
@@ -554,7 +592,7 @@ void InitInput( int argc, char **argv )
*/
void InitOutput( ScreenInfo *pScreenInfo, int argc, char **argv )
{
int i, left, top;
int i;
static unsigned long generation = 0;
pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
@@ -574,55 +612,14 @@ void InitOutput( ScreenInfo *pScreenInfo, int argc, char **argv )
}
// Discover screens and do mode specific initialization
if (quartz) {
QuartzInitOutput(argc, argv);
} else {
XFIOKitInitOutput(argc, argv);
}
DarwinModeInitOutput(argc, argv);
// Add screens
for (i = 0; i < darwinScreensFound; i++) {
AddScreen( DarwinAddScreen, argc, argv );
}
// Shift all screens so the X11 (0, 0) coordinate is at the top left
// of the global screen coordinates.
// Screens can be arranged so the top left isn't on any screen,
// so instead use the top left of the leftmost screen as (0,0).
// This may mean some screen space is in -y, but it's better
// that (0,0) be onscreen, or else default xterms disappear.
// It's better that -y be used than -x, because when popup
// menus are forced "onscreen" by dumb window managers like twm,
// they'll shift the menus down instead of left, which still looks
// funny but is an easier target to hit.
left = dixScreenOrigins[0].x;
top = dixScreenOrigins[0].y;
// Find leftmost screen. If there's a tie, take the topmost of the two.
for (i = 1; i < pScreenInfo->numScreens; i++) {
if (dixScreenOrigins[i].x < left ||
(dixScreenOrigins[i].x == left &&
dixScreenOrigins[i].y < top))
{
left = dixScreenOrigins[i].x;
top = dixScreenOrigins[i].y;
}
}
darwinMainScreenX = left;
darwinMainScreenY = top;
// Shift all screens so that there is a screen whose top left
// is at X11 (0,0) and at global screen coordinate
// (darwinMainScreenX, darwinMainScreenY).
if (darwinMainScreenX != 0 || darwinMainScreenY != 0) {
for (i = 0; i < pScreenInfo->numScreens; i++) {
dixScreenOrigins[i].x -= darwinMainScreenX;
dixScreenOrigins[i].y -= darwinMainScreenY;
ErrorF("Screen %d placed at X11 coordinate (%d,%d).\n",
i, dixScreenOrigins[i].x, dixScreenOrigins[i].y);
}
}
DarwinAdjustScreenOrigins(pScreenInfo);
}
@@ -648,13 +645,16 @@ void OsVendorInit(void)
// Find the full path to the keymapping file.
if ( darwinKeymapFile ) {
char *tempStr = DarwinFindLibraryFile(darwinKeymapFile, "Keyboards");
if ( !tempStr )
FatalError("Could not find keymapping file %s.\n",
darwinKeymapFile);
if ( !tempStr ) {
ErrorF("Could not find keymapping file %s.\n", darwinKeymapFile);
} else {
ErrorF("Using keymapping provided in %s.\n", tempStr);
}
darwinKeymapFile = tempStr;
ErrorF("Using keymapping provided in %s.\n", darwinKeymapFile);
} else {
ErrorF("Reading keymapping from the kernel.\n");
}
if ( !darwinKeymapFile ) {
ErrorF("Reading keymap from the system.\n");
}
}
@@ -667,12 +667,10 @@ void OsVendorInit(void)
*/
int ddxProcessArgument( int argc, char *argv[], int i )
{
#ifdef DARWIN_WITH_QUARTZ
int numDone;
if ((numDone = QuartzProcessArgument( argc, argv, i )))
if ((numDone = DarwinModeProcessArgument( argc, argv, i )))
return numDone;
#endif
if ( !strcmp( argv[i], "-fakebuttons" ) ) {
darwinFakeButtons = TRUE;
@@ -833,11 +831,7 @@ void ddxGiveUp( void )
{
ErrorF( "Quitting XDarwin...\n" );
if (quartz) {
QuartzGiveUp();
} else {
XFIOKitGiveUp();
}
DarwinModeGiveUp();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2002 Torrey T. Lyons. All Rights Reserved.
* 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"),
@@ -23,16 +23,15 @@
* 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/darwin.h,v 1.15 2002/12/10 00:00:38 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/darwin.h,v 1.20 2003/11/15 00:07:09 torrey Exp $ */
#ifndef _DARWIN_H
#define _DARWIN_H
#include <IOKit/IOTypes.h>
#include "inputstr.h"
#include "screenint.h"
#include "scrnintstr.h"
#include "extensions/XKB.h"
#include "quartz/quartzShared.h"
typedef struct {
void *framebuffer;
@@ -48,6 +47,9 @@ typedef struct {
} DarwinFramebufferRec, *DarwinFramebufferPtr;
// From darwin.c
void DarwinPrintBanner();
void DarwinAdjustScreenOrigins(ScreenInfo *pScreenInfo);
void xf86SetRootClip (ScreenPtr pScreen, BOOL enable);
// From darwinEvents.c
@@ -64,6 +66,17 @@ int DarwinModifierNXKeyToNXMask(int key);
int DarwinModifierNXMaskToNXKey(int mask);
int DarwinModifierStringToNXKey(const char *string);
// Mode specific functions
Bool DarwinModeAddScreen(int index, ScreenPtr pScreen);
Bool DarwinModeSetupScreen(int index, ScreenPtr pScreen);
void DarwinModeInitOutput(int argc,char **argv);
void DarwinModeInitInput(int argc, char **argv);
int DarwinModeProcessArgument(int argc, char *argv[], int i);
void DarwinModeProcessEvent(xEvent *xe);
void DarwinModeGiveUp(void);
void DarwinModeBell(int volume, DeviceIntPtr pDevice, pointer ctrl, int class);
#undef assert
#define assert(x) { if ((x) == 0) \
FatalError("assert failed on line %d of %s!\n", __LINE__, __FILE__); }
@@ -76,31 +89,60 @@ int DarwinModifierStringToNXKey(const char *string);
#define MIN_KEYCODE XkbMinLegalKeyCode // unfortunately, this isn't 0...
/*
* Global variables from darwin.c
*/
extern int darwinScreenIndex; // index into pScreen.devPrivates
extern int darwinScreensFound;
extern io_connect_t darwinParamConnect;
extern int darwinEventFD;
extern Bool quartz;
extern int darwinEventReadFD;
extern int darwinEventWriteFD;
// User preferences
extern int darwinMouseAccelChange;
extern int darwinFakeButtons;
extern int darwinFakeMouse2Mask;
extern int darwinFakeMouse3Mask;
extern char *darwinKeymapFile;
extern unsigned int darwinDesiredWidth, darwinDesiredHeight;
extern int darwinDesiredDepth;
extern int darwinDesiredRefresh;
// location of X11's (0,0) point in global screen coordinates
extern int darwinMainScreenX;
extern int darwinMainScreenY;
/*
* Special ddx events understood by the X server
*/
enum {
kXDarwinUpdateModifiers // update all modifier keys
= LASTEvent+1, // (from X.h list of event names)
kXDarwinUpdateButtons, // update state of mouse buttons 2 and up
kXDarwinScrollWheel, // scroll wheel event
kXDarwinShow, // vt switch to X server;
// recapture screen and restore X drawing
kXDarwinHide, // vt switch away from X server;
// release screen and clip X drawing
kXDarwinSetRootClip, // enable or disable drawing to the X screen
kXDarwinQuit, // kill the X server and release the display
kXDarwinReadPasteboard, // copy Mac OS X pasteboard into X cut buffer
kXDarwinWritePasteboard // copy X cut buffer onto Mac OS X pasteboard
kXDarwinUpdateModifiers // update all modifier keys
= LASTEvent+1, // (from X.h list of event names)
kXDarwinUpdateButtons, // update state of mouse buttons 2 and up
kXDarwinScrollWheel, // scroll wheel event
/*
* Quartz-specific events -- not used in IOKit mode
*/
kXDarwinActivate, // restore X drawing and cursor
kXDarwinDeactivate, // clip X drawing and switch to Aqua cursor
kXDarwinSetRootClip, // enable or disable drawing to the X screen
kXDarwinQuit, // kill the X server and release the display
kXDarwinReadPasteboard, // copy Mac OS X pasteboard into X cut buffer
kXDarwinWritePasteboard, // copy X cut buffer onto Mac OS X pasteboard
/*
* AppleWM events
*/
kXDarwinControllerNotify, // send an AppleWMControllerNotify event
kXDarwinPasteboardNotify, // notify the WM to copy or paste
/*
* Xplugin notification events
*/
kXDarwinDisplayChanged, // display configuration has changed
kXDarwinWindowState, // window visibility state has changed
kXDarwinWindowMoved // window has moved on screen
};
#endif /* _DARWIN_H */

View File

@@ -1,7 +1,7 @@
/*
* Darwin default 8-bit Colormap for StaticColor
*/
/* $XFree86: xc/programs/Xserver/hw/darwin/darwinClut8.h,v 1.1.8.1 2003/03/04 01:31:43 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/darwinClut8.h,v 1.2 2003/03/04 01:37:59 torrey Exp $ */
#ifndef _DARWIN_CLUT8_
#define _DARWIN_CLUT8_

View File

@@ -28,6 +28,7 @@ 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.
*/
/* $XFree86: xc/programs/Xserver/hw/darwin/darwinEvents.c,v 1.5 2003/11/03 05:36:30 tsi Exp $ */
#define NEED_EVENTS
#include "X.h"
@@ -42,7 +43,6 @@ in this Software without prior written authorization from The Open Group.
#include "mipointer.h"
#include "darwin.h"
#include "quartz/quartz.h"
#include <sys/types.h>
#include <sys/uio.h>
@@ -181,6 +181,7 @@ DarwinEQEnqueue(
const xEvent *e)
{
HWEventQueueType oldtail, newtail;
char byte = 0;
oldtail = darwinEventQueue.tail;
@@ -209,6 +210,9 @@ DarwinEQEnqueue(
// Update the tail after the event is prepared
darwinEventQueue.tail = newtail;
// Signal there is an event ready to handle
write(darwinEventWriteFD, &byte, 1);
}
@@ -253,7 +257,7 @@ void ProcessInputEvents(void)
// Empty the signaling pipe
x = sizeof(xe);
while (x == sizeof(xe)) {
x = read(darwinEventFD, &xe, sizeof(xe));
x = read(darwinEventReadFD, &xe, sizeof(xe));
}
while (darwinEventQueue.head != darwinEventQueue.tail)
@@ -425,11 +429,8 @@ void ProcessInputEvents(void)
}
default:
if (quartz) {
QuartzProcessEvent(&xe);
} else {
ErrorF("Unknown X event caught: %d\n", xe.u.u.type);
}
// Check for mode specific event
DarwinModeProcessEvent(&xe);
}
}
}

View File

@@ -2,7 +2,8 @@
//
// Keyboard support for the Darwin X Server
//
// Copyright (c) 2001-2002 Torrey T. Lyons. All Rights Reserved.
// Copyright (c) 2001-2003 Torrey T. Lyons. All Rights Reserved.
// Copyright (c) 2003 Apple Computer, Inc. All Rights Reserved.
//
// The code to parse the Darwin keymap is derived from dumpkeymap.c
// by Eric Sunshine, which includes the following copyright:
@@ -36,7 +37,7 @@
//
//=============================================================================
/* $XFree86: xc/programs/Xserver/hw/darwin/darwinKeyboard.c,v 1.17 2002/12/10 00:00:38 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/darwinKeyboard.c,v 1.19 2003/11/01 08:13:08 torrey Exp $ */
/*
===========================================================================
@@ -59,26 +60,18 @@
// in determining how the X server is interpreting the Darwin keymap.
#undef DUMP_DARWIN_KEYMAP
/* Define this to use Alt for Mode_switch. */
#define ALT_IS_MODE_SWITCH 1
#include <drivers/event_status_driver.h>
#include <IOKit/hidsystem/ev_keymap.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <architecture/byte_order.h> // For the NXSwap*
#include "darwin.h"
#include "xfIOKit.h"
#include "quartz/quartzAudio.h"
#include "quartz/quartzShared.h"
#define XK_TECHNICAL // needed to get XK_Escape
#define XK_PUBLISHING
#include "keysym.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
#include "darwinKeyboard.h"
#define AltMask Mod1Mask
#define MetaMask Mod2Mask
@@ -224,11 +217,9 @@ static void DarwinChangeKeyboardControl( DeviceIntPtr device, KeybdCtrl *ctrl )
// keyclick, bell volume / pitch, autorepead, LED's
}
static CARD8 modMap[MAP_LENGTH];
static KeySym map[MAP_LENGTH * GLYPHS_PER_KEY];
static unsigned char modifierKeycodes[NX_NUMMODIFIERS][2];
static FILE *fref = NULL;
static char *inBuffer = NULL;
static darwinKeyboardInfo keyInfo;
static FILE *fref = NULL;
static char *inBuffer = NULL;
//-----------------------------------------------------------------------------
// Data Stream Object
@@ -449,34 +440,18 @@ Bool DarwinReadKeymapFile(
/*
* DarwinKeyboardInit
* Get the Darwin keyboard map and compute an equivalent
* X keyboard map and modifier map. Set the new keyboard
* device structure.
* DarwinParseNXKeyMapping
*/
void DarwinKeyboardInit(
DeviceIntPtr pDev )
Bool DarwinParseNXKeyMapping(
darwinKeyboardInfo *info)
{
KeySym *k;
int i;
short numMods, numKeys, numPadKeys = 0;
KeySymsRec keySyms;
Bool haveKeymap = FALSE;
NXKeyMapping keyMap;
DataStream *keyMapStream;
unsigned char const *numPadStart = 0;
BellProcPtr bellProc;
Bool haveKeymap = FALSE;
memset( modMap, NoSymbol, sizeof( modMap ) );
memset( map, 0, sizeof( map ) );
for (i = 0; i < NX_NUMMODIFIERS; i++) {
modifierKeycodes[i][0] = modifierKeycodes[i][1] = 0;
}
// Open a shared connection to the HID System.
// Note that the Event Status Driver is really just a wrapper
// for a kIOHIDParamConnectType connection.
assert( darwinParamConnect = NXOpenEventStatus() );
if (darwinKeymapFile) {
haveKeymap = DarwinReadKeymapFile(&keyMap);
@@ -494,7 +469,7 @@ void DarwinKeyboardInit(
keyMap.size = NXKeyMappingLength( darwinParamConnect );
keyMap.mapping = (char*) xalloc( keyMap.size );
if (!NXGetKeyMapping( darwinParamConnect, &keyMap )) {
FatalError("Could not get kernel keymapping! Load keymapping from file instead.\n");
return FALSE;
}
}
@@ -507,9 +482,7 @@ void DarwinKeyboardInit(
ErrorF("Current 16-bit keymapping may not be interpreted correctly.\n");
}
// Compute the modifier map and
// insert X modifier KeySyms into keyboard map.
// Store modifier keycodes in modifierKeycodes.
// Insert X modifier KeySyms into the keyboard map.
numMods = get_number(keyMapStream);
while (numMods-- > 0) {
int left = 1; // first keycode is left
@@ -526,40 +499,33 @@ void DarwinKeyboardInit(
while (numKeyCodes-- > 0) {
const short keyCode = get_number(keyMapStream);
if (charCode != NX_MODIFIERKEY_NUMERICPAD) {
modifierKeycodes[charCode][1-left] = keyCode;
switch (charCode) {
case NX_MODIFIERKEY_ALPHALOCK:
modMap[keyCode + MIN_KEYCODE] = LockMask;
map[keyCode * GLYPHS_PER_KEY] = XK_Caps_Lock;
info->keyMap[keyCode * GLYPHS_PER_KEY] = XK_Caps_Lock;
break;
case NX_MODIFIERKEY_SHIFT:
modMap[keyCode + MIN_KEYCODE] = ShiftMask;
map[keyCode * GLYPHS_PER_KEY] =
info->keyMap[keyCode * GLYPHS_PER_KEY] =
(left ? XK_Shift_L : XK_Shift_R);
break;
case NX_MODIFIERKEY_CONTROL:
modMap[keyCode + MIN_KEYCODE] = ControlMask;
map[keyCode * GLYPHS_PER_KEY] =
info->keyMap[keyCode * GLYPHS_PER_KEY] =
(left ? XK_Control_L : XK_Control_R);
break;
case NX_MODIFIERKEY_ALTERNATE:
modMap[keyCode + MIN_KEYCODE] = AltMask;
map[keyCode * GLYPHS_PER_KEY] =
info->keyMap[keyCode * GLYPHS_PER_KEY] =
(left ? XK_Mode_switch : XK_Alt_R);
break;
case NX_MODIFIERKEY_COMMAND:
modMap[keyCode + MIN_KEYCODE] = MetaMask;
map[keyCode * GLYPHS_PER_KEY] =
info->keyMap[keyCode * GLYPHS_PER_KEY] =
(left ? XK_Meta_L : XK_Meta_R);
break;
case NX_MODIFIERKEY_SECONDARYFN:
modMap[keyCode + MIN_KEYCODE] = FunctionMask;
map[keyCode * GLYPHS_PER_KEY] =
info->keyMap[keyCode * GLYPHS_PER_KEY] =
(left ? XK_Control_L : XK_Control_R);
break;
case NX_MODIFIERKEY_HELP:
// Help is not an X11 modifier; treat as normal key
map[keyCode * GLYPHS_PER_KEY] = XK_Help;
info->keyMap[keyCode * GLYPHS_PER_KEY] = XK_Help;
break;
}
}
@@ -567,12 +533,12 @@ void DarwinKeyboardInit(
}
}
// Convert the Darwin keyboard map to an X keyboard map.
// Convert the Darwin keyboard mapping to an X keyboard map.
// A key can have a different character code for each combination of
// modifiers. We currently ignore all modifier combinations except
// those with Shift, AlphaLock, and Alt.
numKeys = get_number(keyMapStream);
for (i = 0, k = map; i < numKeys; i++, k += GLYPHS_PER_KEY) {
for (i = 0, k = info->keyMap; i < numKeys; i++, k += GLYPHS_PER_KEY) {
short const charGenMask = get_number(keyMapStream);
if (charGenMask != 0xFF) { // is key bound?
short numKeyCodes = 1 << bits_set(charGenMask);
@@ -656,7 +622,7 @@ void DarwinKeyboardInit(
keyMapStream->data = numPadStart;
while(numPadKeys-- > 0) {
const short keyCode = get_number(keyMapStream);
k = &map[keyCode * GLYPHS_PER_KEY];
k = &info->keyMap[keyCode * GLYPHS_PER_KEY];
for (i = 0; i < NUM_KEYPAD; i++) {
if (*k == normal_to_keypad[i].normalSym) {
k[0] = normal_to_keypad[i].keypadSym;
@@ -671,7 +637,9 @@ void DarwinKeyboardInit(
#ifdef DUMP_DARWIN_KEYMAP
ErrorF("Darwin -> X converted keyboard map\n");
for (i = 0, k = map; i < NX_NUMKEYCODES; i++, k += GLYPHS_PER_KEY) {
for (i = 0, k = info->keyMap; i < NX_NUMKEYCODES;
i++, k += GLYPHS_PER_KEY)
{
int j;
ErrorF("0x%02x:", i);
for (j = 0; j < GLYPHS_PER_KEY; j++) {
@@ -685,18 +653,145 @@ void DarwinKeyboardInit(
}
#endif
keySyms.map = map;
return TRUE;
}
/*
* DarwinBuildModifierMaps
* Use the keyMap field of keyboard info structure to populate
* the modMap and modifierKeycodes fields.
*/
static void
DarwinBuildModifierMaps(
darwinKeyboardInfo *info)
{
int i;
KeySym *k;
int darwinSwapAltMeta = 0;
memset(info->modMap, NoSymbol, sizeof(info->modMap));
memset(info->modifierKeycodes, 0, sizeof(info->modifierKeycodes));
for (i = 0; i < NUM_KEYCODES; i++)
{
k = info->keyMap + i * GLYPHS_PER_KEY;
switch (k[0]) {
case XK_Shift_L:
info->modifierKeycodes[NX_MODIFIERKEY_SHIFT][0] = i;
info->modMap[MIN_KEYCODE + i] = ShiftMask;
break;
case XK_Shift_R:
info->modifierKeycodes[NX_MODIFIERKEY_SHIFT][1] = i;
info->modMap[MIN_KEYCODE + i] = ShiftMask;
break;
case XK_Control_L:
info->modifierKeycodes[NX_MODIFIERKEY_CONTROL][0] = i;
info->modMap[MIN_KEYCODE + i] = ControlMask;
break;
case XK_Control_R:
info->modifierKeycodes[NX_MODIFIERKEY_CONTROL][1] = i;
info->modMap[MIN_KEYCODE + i] = ControlMask;
break;
case XK_Caps_Lock:
info->modifierKeycodes[NX_MODIFIERKEY_ALPHALOCK][0] = i;
info->modMap[MIN_KEYCODE + i] = LockMask;
break;
case XK_Alt_L:
info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i;
info->modMap[MIN_KEYCODE + i] = Mod1Mask;
break;
case XK_Alt_R:
info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][1] = i;
info->modMap[MIN_KEYCODE + i] = Mod1Mask;
break;
case XK_Mode_switch:
info->modMap[MIN_KEYCODE + i] = Mod1Mask;
break;
case XK_Meta_L:
info->modifierKeycodes[NX_MODIFIERKEY_COMMAND][0] = i;
info->modMap[MIN_KEYCODE + i] = Mod2Mask;
break;
case XK_Meta_R:
info->modifierKeycodes[NX_MODIFIERKEY_COMMAND][1] = i;
info->modMap[MIN_KEYCODE + i] = Mod2Mask;
break;
case XK_Num_Lock:
info->modMap[MIN_KEYCODE + i] = Mod3Mask;
break;
}
if (darwinSwapAltMeta)
{
switch (k[0])
{
case XK_Alt_L:
k[0] = XK_Meta_L;
break;
case XK_Alt_R:
k[0] = XK_Meta_R;
break;
case XK_Meta_L:
k[0] = XK_Alt_L;
break;
case XK_Meta_R:
k[0] = XK_Alt_R;
break;
}
}
#if ALT_IS_MODE_SWITCH
if (k[0] == XK_Alt_L || k[0] == XK_Alt_R)
k[0] = XK_Mode_switch;
#endif
}
}
/*
* DarwinKeyboardInit
* Get the Darwin keyboard map and compute an equivalent
* X keyboard map and modifier map. Set the new keyboard
* device structure.
*/
void DarwinKeyboardInit(
DeviceIntPtr pDev )
{
KeySymsRec keySyms;
memset( keyInfo.keyMap, 0, sizeof( keyInfo.keyMap ) );
// Open a shared connection to the HID System.
// Note that the Event Status Driver is really just a wrapper
// for a kIOHIDParamConnectType connection.
assert( darwinParamConnect = NXOpenEventStatus() );
if (!DarwinParseNXKeyMapping(&keyInfo)) {
if (!DarwinModeReadSystemKeymap(&keyInfo)) {
FatalError("Could not build a valid keymap.");
}
}
DarwinBuildModifierMaps(&keyInfo);
keySyms.map = keyInfo.keyMap;
keySyms.mapWidth = GLYPHS_PER_KEY;
keySyms.minKeyCode = MIN_KEYCODE;
keySyms.maxKeyCode = MAX_KEYCODE;
if (quartz)
bellProc = QuartzBell;
else
bellProc = XFIOKitBell;
assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms, modMap,
bellProc,
assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms,
keyInfo.modMap, DarwinModeBell,
DarwinChangeKeyboardControl ));
}
@@ -718,7 +813,7 @@ void DarwinKeyboardInit(
*/
int DarwinModifierNXKeyToNXKeycode(int key, int side)
{
return modifierKeycodes[key][side];
return keyInfo.modifierKeycodes[key][side];
}
/*
@@ -734,7 +829,7 @@ int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide)
// search modifierKeycodes for this keycode+side
for (key = 0; key < NX_NUMMODIFIERS; key++) {
for (side = 0; side <= 1; side++) {
if (modifierKeycodes[key][side] == keycode) break;
if (keyInfo.modifierKeycodes[key][side] == keycode) break;
}
}
if (key == NX_NUMMODIFIERS) return -1;

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

View File

@@ -1,4 +1,31 @@
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/Preferences.h,v 1.2 2003/01/15 02:34:05 torrey Exp $ */
/*
* 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/Preferences.h,v 1.3 2003/09/16 00:36:12 torrey Exp $ */
#import <Cocoa/Cocoa.h>
@@ -35,14 +62,14 @@
- (IBAction)saveChanges:(id)sender;
- (IBAction)setKey:(id)sender;
- (BOOL)sendEvent:(NSEvent*)anEvent;
- (BOOL)sendEvent:(NSEvent *)anEvent;
- (void)awakeFromNib;
- (void)windowWillClose:(NSNotification *)aNotification;
+ (void)setUseKeymapFile:(BOOL)newUseKeymapFile;
+ (void)setKeymapFile:(NSString*)newFile;
+ (void)setSwitchString:(NSString*)newString;
+ (void)setKeymapFile:(NSString *)newFile;
+ (void)setSwitchString:(NSString *)newString;
+ (void)setKeyCode:(int)newKeyCode;
+ (void)setModifiers:(int)newModifiers;
+ (void)setDisplay:(int)newDisplay;
@@ -59,15 +86,16 @@
+ (void)setSystemBeep:(BOOL)newSystemBeep;
+ (void)setXinerama:(BOOL)newXinerama;
+ (void)setAddToPath:(BOOL)newAddToPath;
+ (void)setAddToPathString:(NSString*)newAddToPathString;
+ (void)setAddToPathString:(NSString *)newAddToPathString;
+ (void)setUseDefaultShell:(BOOL)newUseDefaultShell;
+ (void)setShellString:(NSString*)newShellString;
+ (void)setShellString:(NSString *)newShellString;
+ (void)setDepth:(int)newDepth;
+ (void)setDisplayModeBundles:(NSArray *)newBundles;
+ (void)saveToDisk;
+ (BOOL)useKeymapFile;
+ (NSString*)keymapFile;
+ (NSString*)switchString;
+ (NSString *)keymapFile;
+ (NSString *)switchString;
+ (unsigned int)keyCode;
+ (unsigned int)modifiers;
+ (int)display;
@@ -84,10 +112,11 @@
+ (BOOL)systemBeep;
+ (BOOL)xinerama;
+ (BOOL)addToPath;
+ (NSString*)addToPathString;
+ (NSString *)addToPathString;
+ (BOOL)useDefaultShell;
+ (NSString*)shellString;
+ (NSString *)shellString;
+ (int)depth;
+ (NSArray *)displayModeBundles;
@end

View File

@@ -3,10 +3,43 @@
//
// This class keeps track of the user preferences.
//
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/Preferences.m,v 1.2 2003/01/15 02:34:06 torrey Exp $ */
/*
* 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/Preferences.m,v 1.4 2003/09/16 00:36:12 torrey Exp $ */
#import "quartzCommon.h"
#define BOOL xBOOL
#include "darwin.h"
#undef BOOL
#import "Preferences.h"
#import "quartzCommon.h"
#include <IOKit/hidsystem/IOLLEvent.h> // for modifier masks
// Macros to build the path name
@@ -36,8 +69,8 @@
@"YES", @"ShowStartupHelp",
[NSNumber numberWithInt:0], @"SwitchKeyCode",
[NSNumber numberWithInt:(NSCommandKeyMask | NSAlternateKeyMask)],
@"SwitchModifiers", @"NO", @"UseSystemBeep",
@"YES", @"DockSwitch",
@"SwitchModifiers", @"NO", @"UseSystemBeep",
@"YES", @"DockSwitch",
@"NO", @"AllowMouseAccelChange",
[NSNumber numberWithInt:qdCursor_Not8Bit], @"UseQDCursor",
@"YES", @"Xinerama",
@@ -45,7 +78,13 @@
[NSString stringWithCString:XSTRPATH(XBINDIR)], @"AddToPathString",
@"YES", @"UseDefaultShell",
@"/bin/tcsh", @"Shell",
[NSNumber numberWithInt:depth_Current], @"Depth", nil];
[NSNumber numberWithInt:depth_Current], @"Depth",
#ifdef BUILD_XPR
[NSArray arrayWithObjects:@"xpr.bundle", @"cr.bundle", nil],
#else
[NSArray arrayWithObjects:@"cr.bundle", nil],
#endif
@"DisplayModeBundles", nil];
[super initialize];
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
@@ -207,7 +246,7 @@
[switchString setString:@""];
}
- (BOOL)sendEvent:(NSEvent*)anEvent
- (BOOL)sendEvent:(NSEvent *)anEvent
{
if(isGettingKeyCode) {
if([anEvent type]==NSKeyDown) // wait for keyup
@@ -240,7 +279,7 @@
return NO;
}
+ (void)setKeymapFile:(NSString*)newFile
+ (void)setKeymapFile:(NSString *)newFile
{
[[NSUserDefaults standardUserDefaults] setObject:newFile
forKey:@"KeymappingFile"];
@@ -252,7 +291,7 @@
forKey:@"UseKeymappingFile"];
}
+ (void)setSwitchString:(NSString*)newString
+ (void)setSwitchString:(NSString *)newString
{
[[NSUserDefaults standardUserDefaults] setObject:newString
forKey:@"SwitchString"];
@@ -311,7 +350,7 @@
[[NSUserDefaults standardUserDefaults] setBool:newMouseAccelChange
forKey:@"AllowMouseAccelChange"];
// Update the setting used by the X server thread
quartzMouseAccelChange = newMouseAccelChange;
darwinMouseAccelChange = newMouseAccelChange;
}
+ (void)setUseQDCursor:(int)newUseQDCursor
@@ -364,7 +403,7 @@
forKey:@"AddToPath"];
}
+ (void)setAddToPathString:(NSString*)newAddToPathString
+ (void)setAddToPathString:(NSString *)newAddToPathString
{
[[NSUserDefaults standardUserDefaults] setObject:newAddToPathString
forKey:@"AddToPathString"];
@@ -376,7 +415,7 @@
forKey:@"UseDefaultShell"];
}
+ (void)setShellString:(NSString*)newShellString
+ (void)setShellString:(NSString *)newShellString
{
[[NSUserDefaults standardUserDefaults] setObject:newShellString
forKey:@"Shell"];
@@ -388,6 +427,12 @@
forKey:@"Depth"];
}
+ (void)setDisplayModeBundles:(NSArray *)newBundles
{
[[NSUserDefaults standardUserDefaults] setObject:newBundles
forKey:@"DisplayModeBundles"];
}
+ (void)saveToDisk
{
[[NSUserDefaults standardUserDefaults] synchronize];
@@ -399,13 +444,13 @@
boolForKey:@"UseKeymappingFile"];
}
+ (NSString*)keymapFile
+ (NSString *)keymapFile
{
return [[NSUserDefaults standardUserDefaults]
stringForKey:@"KeymappingFile"];
}
+ (NSString*)switchString
+ (NSString *)switchString
{
return [[NSUserDefaults standardUserDefaults]
stringForKey:@"SwitchString"];
@@ -502,7 +547,7 @@
return [[NSUserDefaults standardUserDefaults] boolForKey:@"AddToPath"];
}
+ (NSString*)addToPathString
+ (NSString *)addToPathString
{
return [[NSUserDefaults standardUserDefaults]
stringForKey:@"AddToPathString"];
@@ -514,7 +559,7 @@
boolForKey:@"UseDefaultShell"];
}
+ (NSString*)shellString
+ (NSString *)shellString
{
return [[NSUserDefaults standardUserDefaults]
stringForKey:@"Shell"];
@@ -526,5 +571,10 @@
integerForKey:@"Depth"];
}
+ (NSArray *)displayModeBundles
{
return [[NSUserDefaults standardUserDefaults]
objectForKey:@"DisplayModeBundles"];
}
@end

View File

@@ -23,48 +23,6 @@
path = XApplication.h;
refType = 4;
};
014C68ED00ED6A9D7F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = XView.h;
refType = 4;
};
014C68EE00ED6A9D7F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = XView.m;
refType = 4;
};
014C68F200ED7AD67F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = fakeBoxRec.h;
refType = 4;
};
014C68F300EE5AB97F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessCommon.c;
refType = 4;
};
014C68F400EE5AB97F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessCommon.h;
refType = 4;
};
014C68F700EE678F7F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessWindow.c;
refType = 4;
};
014C68F800EE678F7F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessWindow.h;
refType = 4;
};
015698ED003DF345CE6F79C2 = {
isa = PBXFileReference;
path = XDarwin.icns;
@@ -99,18 +57,6 @@
path = /System/Library/Frameworks/IOKit.framework;
refType = 0;
};
017D6F4400E861FB7F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessGC.c;
refType = 4;
};
017D6F4500E861FB7F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessScreen.c;
refType = 4;
};
018F40F2003E1902CE6F79C2 = {
children = (
018F40F3003E1916CE6F79C2,
@@ -118,6 +64,7 @@
3E74E03600863F047F000001,
F5A94EF10314BAC70100011B,
018F40F6003E1974CE6F79C2,
6E5F5F0005537A1A008FEAD7,
);
isa = PBXGroup;
name = "X Server";
@@ -261,22 +208,6 @@
//042
//043
//044
//060
//061
//062
//063
//064
06EB6C3B004099E7CE6F79C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = quartzShared.h;
refType = 4;
};
//060
//061
//062
//063
//064
//080
//081
//082
@@ -290,8 +221,6 @@
0127909800074B1A0A000002,
01279092000747AA0A000002,
1C4A3109004D8F24CE6F79C2,
014C68EE00ED6A9D7F000001,
014C68ED00ED6A9D7F000001,
);
isa = PBXGroup;
name = Classes;
@@ -356,6 +285,8 @@
dependencies = (
6EF065C903D4F0CA006877C2,
6EF065C703D4EE19006877C2,
6E11A986048BDFFB006877C2,
6E7904110500F33B00EEC080,
);
isa = PBXApplicationTarget;
name = XDarwin;
@@ -368,10 +299,42 @@
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>x11app</string>
</array>
<key>CFBundleTypeName</key>
<string>X11 Application</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>****</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>tool</string>
<string>*</string>
</array>
<key>CFBundleTypeName</key>
<string>UNIX Application</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>****</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>XDarwin</string>
<key>CFBundleGetInfoString</key>
<string>XDarwin 1.2.0, ©2001-2003 XFree86 Project, Inc.</string>
<string>XDarwin 1.3b4, ©2001-2003 XFree86 Project, Inc.</string>
<key>CFBundleIconFile</key>
<string>XDarwin.icns</string>
<key>CFBundleIdentifier</key>
@@ -383,7 +346,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>XDarwin 1.2.0</string>
<string>XDarwin 1.3b4</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
@@ -548,7 +511,7 @@
};
};
1220774600712D75416877C2 = {
fileEncoding = 30;
fileEncoding = 10;
isa = PBXFileReference;
name = Japanese;
path = Japanese.lproj/Localizable.strings;
@@ -579,7 +542,7 @@
);
isa = PBXGroup;
name = IOKit;
path = ..;
path = ../iokit;
refType = 4;
};
//170
@@ -597,6 +560,8 @@
0A79E19E004499A1CE6F79C2,
6EF7C58703D3BC6D00000104,
6EF065C603D4EE19006877C2,
6E11A985048BDFEE006877C2,
6E7904100500F05600EEC080,
);
isa = PBXGroup;
name = Products;
@@ -770,7 +735,9 @@
targets = (
0A79E19F004499A1CE6F79C2,
6EF7C58603D3BC6D00000104,
6E11A984048BDFEE006877C2,
6EF065C503D4EE19006877C2,
6E79040F0500F05600EEC080,
);
};
29B97314FDCFA39411CA2CEA = {
@@ -780,7 +747,10 @@
170DFB0000729C86416877C2,
43B962CE00617089416877C2,
F5614B3D025112D901000114,
6EC4A64C042A9597006877C2,
32FEE13C00E07C3E7F000001,
6EE1214104968658006877C2,
6EC4A66D042A97FC006877C2,
29B97315FDCFA39411CA2CEA,
29B97317FDCFA39411CA2CEA,
29B97323FDCFA39411CA2CEA,
@@ -875,66 +845,14 @@
//324
32FEE13C00E07C3E7F000001 = {
children = (
F56CBD0D02EB84A801129B8A,
F56CBD0E02EB84A801129B8A,
F56CBD0F02EBDCFC01129B8A,
014C68F200ED7AD67F000001,
F5269C2D01D5BC3501000001,
F5269C2E01D5BC3501000001,
32FEE13E00E07CBE7F000001,
32FEE13F00E07CBE7F000001,
32FEE14000E07CBE7F000001,
32FEE14100E07CBE7F000001,
32FEE14200E07CBE7F000001,
014C68F300EE5AB97F000001,
014C68F400EE5AB97F000001,
017D6F4400E861FB7F000001,
017D6F4500E861FB7F000001,
014C68F700EE678F7F000001,
014C68F800EE678F7F000001,
32FEE14900E07D317F000001,
);
isa = PBXGroup;
name = Rootless;
name = "Old Cocoa Imp";
path = "";
refType = 4;
};
32FEE13E00E07CBE7F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootless.h;
refType = 4;
};
32FEE13F00E07CBE7F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessAqua.h;
refType = 4;
};
32FEE14000E07CBE7F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessAquaGlue.c;
refType = 4;
};
32FEE14100E07CBE7F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessAquaImp.h;
refType = 4;
};
32FEE14200E07CBE7F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessAquaImp.m;
refType = 4;
};
32FEE14900E07D317F000001 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessValTree.c;
refType = 4;
};
//320
//321
//322
@@ -979,17 +897,19 @@
//434
43B962CE00617089416877C2 = {
children = (
6EE9B21604E859C200CA7FEA,
6E97A0F505079F9100B8294C,
6E5F5F030553815A008FEAD7,
6E5F5F040553815A008FEAD7,
018F40F8003E1979CE6F79C2,
018F40FA003E197ECE6F79C2,
237A34C10076E37E7F000001,
237A34C40076F4F07F000001,
3576829A0077B8F17F000001,
0338412F0083BFE57F000001,
43B962D000617089416877C2,
43B962D100617089416877C2,
43B962CF00617089416877C2,
F5582948015DAD3B01000001,
06EB6C3B004099E7CE6F79C2,
6E5F5F0105537A5F008FEAD7,
43B962D000617089416877C2,
43B962D100617089416877C2,
02A1FEA8006D38F0416877C2,
);
isa = PBXGroup;
@@ -1051,6 +971,536 @@
//6E2
//6E3
//6E4
6E11A97F048BDFEE006877C2 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
6E11A980048BDFEE006877C2 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXResourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
6E11A981048BDFEE006877C2 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
6E11A982048BDFEE006877C2 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXFrameworksBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
6E11A983048BDFEE006877C2 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
6E11A984048BDFEE006877C2 = {
buildPhases = (
6E11A97F048BDFEE006877C2,
6E11A980048BDFEE006877C2,
6E11A981048BDFEE006877C2,
6E11A982048BDFEE006877C2,
6E11A983048BDFEE006877C2,
);
buildSettings = {
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = glxCGL;
SECTORDER_FLAGS = "";
WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
WRAPPER_EXTENSION = bundle;
};
dependencies = (
);
isa = PBXBundleTarget;
name = glxCGL;
productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
productName = glxCGL;
productReference = 6E11A985048BDFEE006877C2;
productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>glxCGL</string>
<key>CFBundleGetInfoString</key>
<string></string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string></string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>GLX bundle using Apple's OpenGL</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>0.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.1</string>
</dict>
</plist>
";
};
6E11A985048BDFEE006877C2 = {
isa = PBXBundleReference;
path = glxCGL.bundle;
refType = 3;
};
6E11A986048BDFFB006877C2 = {
isa = PBXTargetDependency;
target = 6E11A984048BDFEE006877C2;
};
6E5F5F0005537A1A008FEAD7 = {
fileEncoding = 30;
isa = PBXFileReference;
path = darwinKeyboard.h;
refType = 4;
};
6E5F5F0105537A5F008FEAD7 = {
fileEncoding = 30;
isa = PBXFileReference;
path = quartzKeyboard.c;
refType = 4;
};
6E5F5F030553815A008FEAD7 = {
fileEncoding = 30;
isa = PBXFileReference;
path = keysym2ucs.c;
refType = 4;
};
6E5F5F040553815A008FEAD7 = {
fileEncoding = 30;
isa = PBXFileReference;
path = keysym2ucs.h;
refType = 4;
};
6E6656EC048832CF006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = "x-hook.c";
refType = 4;
};
6E6656ED048832CF006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = "x-hook.h";
refType = 4;
};
6E6656F0048832EC006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = dri.c;
refType = 4;
};
6E6656F1048832EC006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = dri.h;
refType = 4;
};
6E6656F2048832EC006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = dristruct.h;
refType = 4;
};
6E6656F3048832F9006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = appledri.c;
refType = 4;
};
6E79040104FD5ED900EEC080 = {
children = (
6E79040204FD5EDA00EEC080,
6E79040304FD5EDA00EEC080,
6E79040404FD5EDA00EEC080,
);
isa = PBXGroup;
name = "Safe Alpha";
path = safeAlpha;
refType = 4;
};
6E79040204FD5EDA00EEC080 = {
fileEncoding = 30;
isa = PBXFileReference;
path = safeAlpha.h;
refType = 4;
};
6E79040304FD5EDA00EEC080 = {
fileEncoding = 30;
isa = PBXFileReference;
path = safeAlphaPicture.c;
refType = 4;
};
6E79040404FD5EDA00EEC080 = {
fileEncoding = 30;
isa = PBXFileReference;
path = safeAlphaWindow.c;
refType = 4;
};
6E79040A0500F05600EEC080 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
6E79040B0500F05600EEC080 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXResourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
6E79040C0500F05600EEC080 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
6E79040D0500F05600EEC080 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXFrameworksBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
6E79040E0500F05600EEC080 = {
buildActionMask = 2147483647;
files = (
);
isa = PBXRezBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
};
6E79040F0500F05600EEC080 = {
buildPhases = (
6E79040A0500F05600EEC080,
6E79040B0500F05600EEC080,
6E79040C0500F05600EEC080,
6E79040D0500F05600EEC080,
6E79040E0500F05600EEC080,
);
buildSettings = {
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = xpr;
SECTORDER_FLAGS = "";
WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
WRAPPER_EXTENSION = bundle;
};
dependencies = (
);
isa = PBXBundleTarget;
name = xpr;
productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
productName = xpr;
productReference = 6E7904100500F05600EEC080;
productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>xpr</string>
<key>CFBundleGetInfoString</key>
<string></string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string></string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Xplugin rootless implementation</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>0.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.1</string>
</dict>
</plist>
";
};
6E7904100500F05600EEC080 = {
isa = PBXBundleReference;
path = xpr.bundle;
refType = 3;
};
6E7904110500F33B00EEC080 = {
isa = PBXTargetDependency;
target = 6E79040F0500F05600EEC080;
};
6E97A0F2050798B100B8294C = {
fileEncoding = 4;
isa = PBXFileReference;
path = xprAppleWM.c;
refType = 4;
};
6E97A0F305079B6500B8294C = {
fileEncoding = 4;
isa = PBXFileReference;
path = crAppleWM.m;
refType = 4;
};
6E97A0F505079F9100B8294C = {
fileEncoding = 4;
isa = PBXFileReference;
path = applewmExt.h;
refType = 4;
};
6EA0B3AF0544A9CC006877C2 = {
children = (
6EA0B3B00544A9CC006877C2,
6EA0B3B10544A9CC006877C2,
6EA0B3B20544A9CC006877C2,
6EA0B3B30544A9CC006877C2,
6EA0B3B40544A9CC006877C2,
6EA0B3B50544A9CC006877C2,
6EA0B3B60544A9CC006877C2,
6EA0B3B70544A9CC006877C2,
);
isa = PBXGroup;
name = Acceleration;
path = accel;
refType = 4;
};
6EA0B3B00544A9CC006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rlAccel.h;
refType = 4;
};
6EA0B3B10544A9CC006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rlBlt.c;
refType = 4;
};
6EA0B3B20544A9CC006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rlCopy.c;
refType = 4;
};
6EA0B3B30544A9CC006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rlFill.c;
refType = 4;
};
6EA0B3B40544A9CC006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rlFillRect.c;
refType = 4;
};
6EA0B3B50544A9CC006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rlFillSpans.c;
refType = 4;
};
6EA0B3B60544A9CC006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rlGlyph.c;
refType = 4;
};
6EA0B3B70544A9CC006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rlSolid.c;
refType = 4;
};
6EA8EEC80445E25C006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessConfig.h;
refType = 4;
};
6EC4A64C042A9597006877C2 = {
children = (
6EC4A65D042A9654006877C2,
6EC4A65E042A9654006877C2,
6EC4A65F042A9654006877C2,
6EA8EEC80445E25C006877C2,
6EC4A661042A9654006877C2,
6EC4A662042A9654006877C2,
6EC4A660042A9654006877C2,
6EC4A663042A9654006877C2,
6EC4A664042A9654006877C2,
6EA0B3AF0544A9CC006877C2,
6E79040104FD5ED900EEC080,
);
isa = PBXGroup;
name = Rootless;
path = ../../../miext/rootless;
refType = 2;
};
6EC4A65D042A9654006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootless.h;
refType = 4;
};
6EC4A65E042A9654006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessCommon.c;
refType = 4;
};
6EC4A65F042A9654006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessCommon.h;
refType = 4;
};
6EC4A660042A9654006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessWindow.h;
refType = 4;
};
6EC4A661042A9654006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessScreen.c;
refType = 4;
};
6EC4A662042A9654006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessWindow.c;
refType = 4;
};
6EC4A663042A9654006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessGC.c;
refType = 4;
};
6EC4A664042A9654006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = rootlessValTree.c;
refType = 4;
};
6EC4A66D042A97FC006877C2 = {
children = (
6EF471A004478DE0006877C2,
6E6656F3048832F9006877C2,
6E6656F0048832EC006877C2,
6E6656F1048832EC006877C2,
6E6656F2048832EC006877C2,
6ECF218404589E4D006877C2,
6E97A0F2050798B100B8294C,
6ECF218604589F40006877C2,
6EF4719E04478B08006877C2,
6EDDB2DF04508B2C006877C2,
6EF471A204479263006877C2,
6EF471A404479263006877C2,
6E6656EC048832CF006877C2,
6E6656ED048832CF006877C2,
6EF471A504479263006877C2,
6EF471A304479263006877C2,
);
isa = PBXGroup;
path = xpr;
refType = 4;
};
6ECF218404589E4D006877C2 = {
fileEncoding = 4;
isa = PBXFileReference;
path = xpr.h;
refType = 4;
};
6ECF218604589F40006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = xprCursor.c;
refType = 4;
};
6EDDB2DF04508B2C006877C2 = {
fileEncoding = 4;
isa = PBXFileReference;
path = xprScreen.c;
refType = 4;
};
6EE1214104968658006877C2 = {
children = (
6EE1214304968692006877C2,
6EE1214404968692006877C2,
6EE1214204968692006877C2,
6E97A0F305079B6500B8294C,
6EE1214504968692006877C2,
6EE1214604968692006877C2,
);
isa = PBXGroup;
path = cr;
refType = 4;
};
6EE1214204968692006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = cr.h;
refType = 4;
};
6EE1214304968692006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = XView.m;
refType = 4;
};
6EE1214404968692006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = XView.h;
refType = 4;
};
6EE1214504968692006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = crFrame.m;
refType = 4;
};
6EE1214604968692006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = crScreen.m;
refType = 4;
};
6EE9B21604E859C200CA7FEA = {
fileEncoding = 30;
isa = PBXFileReference;
path = applewm.c;
refType = 4;
};
6EF065C003D4EE19006877C2 = {
buildActionMask = 2147483647;
files = (
@@ -1153,6 +1603,42 @@
isa = PBXTargetDependency;
target = 6EF7C58603D3BC6D00000104;
};
6EF4719E04478B08006877C2 = {
fileEncoding = 4;
isa = PBXFileReference;
path = xprFrame.c;
refType = 4;
};
6EF471A004478DE0006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = Xplugin.h;
refType = 4;
};
6EF471A204479263006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = "x-hash.c";
refType = 4;
};
6EF471A304479263006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = "x-list.h";
refType = 4;
};
6EF471A404479263006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = "x-hash.h";
refType = 4;
};
6EF471A504479263006877C2 = {
fileEncoding = 30;
isa = PBXFileReference;
path = "x-list.c";
refType = 4;
};
6EF7C58103D3BC6D00000104 = {
buildActionMask = 2147483647;
files = (
@@ -1209,7 +1695,7 @@
);
isa = PBXBundleTarget;
name = glxAGL;
productName = glxAqua;
productName = glxAGL;
productReference = 6EF7C58703D3BC6D00000104;
productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
@@ -1228,7 +1714,7 @@
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>GLX bundle with AGL</string>
<string>GLX bundle using AGL framework</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
@@ -1277,7 +1763,7 @@
refType = 4;
};
F51BF62D02026E1C01000001 = {
fileEncoding = 30;
fileEncoding = 10;
isa = PBXFileReference;
name = Portuguese;
path = Portuguese.lproj/Localizable.strings;
@@ -1336,7 +1822,7 @@
refType = 4;
};
F533213C0193CBC901000001 = {
fileEncoding = 30;
fileEncoding = 10;
isa = PBXFileReference;
name = German;
path = German.lproj/Localizable.strings;
@@ -1395,7 +1881,7 @@
refType = 4;
};
F533214501A4B42501000001 = {
fileEncoding = 30;
fileEncoding = 10;
isa = PBXFileReference;
name = Dutch;
path = Dutch.lproj/Localizable.strings;
@@ -1450,38 +1936,14 @@
path = fullscreen.c;
refType = 4;
};
F5614B3C0251124C01000114 = {
fileEncoding = 30;
isa = PBXFileReference;
path = fullscreen.h;
refType = 4;
};
F5614B3D025112D901000114 = {
children = (
F5614B3B0251124C01000114,
F5614B3C0251124C01000114,
3576829A0077B8F17F000001,
0338412F0083BFE57F000001,
);
isa = PBXGroup;
name = "Full Screen";
path = "";
refType = 4;
};
F56CBD0D02EB84A801129B8A = {
fileEncoding = 30;
isa = PBXFileReference;
path = aqua.h;
refType = 4;
};
F56CBD0E02EB84A801129B8A = {
fileEncoding = 30;
isa = PBXFileReference;
path = aquaPicture.c;
refType = 4;
};
F56CBD0F02EBDCFC01129B8A = {
fileEncoding = 30;
isa = PBXFileReference;
path = aquaWindow.c;
path = fullscreen;
refType = 4;
};
F587E16001924C1D01000001 = {
@@ -1505,7 +1967,7 @@
refType = 4;
};
F587E16301924C5E01000001 = {
fileEncoding = 30;
fileEncoding = 10;
isa = PBXFileReference;
name = Swedish;
path = Swedish.lproj/Localizable.strings;
@@ -1552,7 +2014,7 @@
refType = 4;
};
F58D65DE018F79A001000001 = {
fileEncoding = 30;
fileEncoding = 10;
isa = PBXFileReference;
name = French;
path = French.lproj/Localizable.strings;
@@ -1604,7 +2066,7 @@
refType = 4;
};
F5ACD25FC5B5E9AA01000001 = {
fileEncoding = 30;
fileEncoding = 10;
isa = PBXFileReference;
name = Spanish;
path = Spanish.lproj/Localizable.strings;
@@ -1651,7 +2113,7 @@
refType = 4;
};
F5ACD266C5BE03C501000001 = {
fileEncoding = 30;
fileEncoding = 10;
isa = PBXFileReference;
name = ko;
path = ko.lproj/Localizable.strings;

View File

@@ -38,16 +38,15 @@
* dealings in this Software without prior written authorization from
* Torrey T. Lyons.
*/
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XDarwinStartup.c,v 1.1 2002/03/28 02:21:18 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XDarwinStartup.c,v 1.2 2003/05/14 05:15:56 torrey Exp $ */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/syslimits.h>
#include <ApplicationServices/ApplicationServices.h>
extern int errno;
// Macros to build the path name
#ifndef XBINDIR
#define XBINDIR /usr/X11R6/bin

View File

@@ -29,7 +29,7 @@
* sale, use or other dealings in this Software without prior written
* authorization.
*/
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XServer.h,v 1.8 2003/01/23 00:34:26 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XServer.h,v 1.15 2003/11/14 20:27:58 torrey Exp $ */
#define BOOL xBOOL
#include "Xproto.h"
@@ -41,15 +41,14 @@
// server state
int serverState;
NSRecursiveLock *serverLock;
NSMutableArray *pendingClients;
BOOL serverVisible;
BOOL rootlessMenuBarVisible;
BOOL queueShowServer;
BOOL quitWithoutQuery;
UInt32 mouseState;
Class windowClass;
// server event queue
BOOL sendServerEvents;
int eventWriteFD;
BOOL x11Active;
// Aqua interface
IBOutlet NSWindow *modeWindow;
@@ -59,6 +58,12 @@
IBOutlet NSWindow *helpWindow;
IBOutlet NSButton *startupHelpButton;
IBOutlet NSPanel *switchWindow;
// Menu elements setable by Apple-WM extension
IBOutlet NSMenu *windowMenu;
IBOutlet NSMenuItem *windowSeparator;
IBOutlet NSMenu *dockMenu;
int checkedWindowItem;
}
- (id)init;
@@ -68,9 +73,11 @@
+ (void)append:(NSString *)value toEnv:(NSString *)name;
- (BOOL)loadDisplayBundle;
- (void)startX;
- (void)finishStartX;
- (BOOL)startXClients;
- (void)runClient:(NSString *)filename;
- (void)run;
- (void)toggle;
- (void)showServer:(BOOL)show;
@@ -82,19 +89,36 @@
- (void)sendXEvent:(xEvent *)xe;
- (void)sendShowHide:(BOOL)show;
- (void)clientProcessDone:(int)clientStatus;
- (void)activateX11:(BOOL)state;
- (void)windowBecameKey:(NSWindow *)window;
- (void)setX11WindowList:(NSArray *)list;
- (void)setX11WindowCheck:(NSNumber *)nn;
// Aqua interface actions
- (IBAction)startFullScreen:(id)sender;
- (IBAction)startRootless:(id)sender;
- (IBAction)closeHelpAndShow:(id)sender;
- (IBAction)showSwitchPanel:(id)sender;
- (IBAction)showAction:(id)sender;
- (IBAction)itemSelected:(id)sender;
- (IBAction)nextWindow:(id)sender;
- (IBAction)previousWindow:(id)sender;
- (IBAction)performClose:(id)sender;
- (IBAction)performMiniaturize:(id)sender;
- (IBAction)performZoom:(id)sender;
- (IBAction)bringAllToFront:(id)sender;
- (IBAction)copy:(id)sender;
// NSApplication delegate
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
- (void)applicationWillTerminate:(NSNotification *)aNotification;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
- (void)applicationDidHide:(NSNotification *)aNotification;
- (void)applicationDidUnhide:(NSNotification *)aNotification;
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag;
- (void)applicationWillResignActive:(NSNotification *)aNotification;
- (void)applicationWillBecomeActive:(NSNotification *)aNotification;
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
// NSPort delegate
- (void)handlePortMessage:(NSPortMessage *)portMessage;
@@ -109,4 +133,3 @@ enum {
server_Quitting,
server_Done
};

View File

@@ -34,7 +34,7 @@
* sale, use or other dealings in this Software without prior written
* authorization.
*/
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XServer.m,v 1.8 2003/01/23 00:34:26 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/XServer.m,v 1.17 2003/11/14 20:27:58 torrey Exp $ */
#include "quartzCommon.h"
@@ -42,7 +42,12 @@
#include "X.h"
#include "Xproto.h"
#include "os.h"
#include "opaque.h"
#include "darwin.h"
#include "quartz.h"
#define _APPLEWM_SERVER_
#include "applewm.h"
#include "applewmExt.h"
#undef BOOL
#import "XServer.h"
@@ -64,14 +69,6 @@
#import <IOKit/pwr_mgt/IOPMLib.h>
#import <IOKit/IOMessage.h>
#define ENQUEUE(xe) \
{ \
char byte = 0; \
DarwinEQEnqueue(xe); \
/* signal there is an event ready to handle */ \
write(eventWriteFD, &byte, 1); \
}
// Types of shells
enum {
shell_Unknown,
@@ -90,7 +87,7 @@ static shellList_t const shellList[] = {
{ "sh", shell_Bourne }, // standard Bourne shell
{ "zsh", shell_Bourne }, // Z shell
{ "bash", shell_Bourne }, // GNU Bourne again shell
{ NULL, shell_Unknown }
{ NULL, shell_Unknown }
};
extern int argcGlobal;
@@ -99,7 +96,6 @@ extern char **envpGlobal;
extern int main(int argc, char *argv[], char *envp[]);
extern void HideMenuBar(void);
extern void ShowMenuBar(void);
extern void QuartzReallySetCursor();
static void childDone(int sig);
static void powerDidChange(void *x, io_service_t y, natural_t messageType,
void *messageArgument);
@@ -122,15 +118,15 @@ static io_connect_t root_port;
serverState = server_NotStarted;
serverLock = [[NSRecursiveLock alloc] init];
pendingClients = nil;
clientPID = 0;
sendServerEvents = NO;
x11Active = YES;
serverVisible = NO;
rootlessMenuBarVisible = YES;
queueShowServer = YES;
quartzServerQuitting = NO;
mouseState = 0;
eventWriteFD = quartzEventWriteFD;
windowClass = [NSWindow class];
// set up a port to safely send messages to main thread from server thread
signalPort = [[NSPort port] retain];
@@ -145,6 +141,11 @@ static io_connect_t root_port;
[[NSRunLoop currentRunLoop] addPort:signalPort
forMode:NSModalPanelRunLoopMode];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowBecameKey:)
name:NSWindowDidBecomeKeyNotification
object:nil];
return self;
}
@@ -164,7 +165,7 @@ static io_connect_t root_port;
[self showServer:NO];
sendServerEvents = NO;
if (clientPID != 0 || !quartzStartClients) {
if (!quitWithoutQuery && (clientPID != 0 || !quartzStartClients)) {
int but;
but = NSRunAlertPanel(NSLocalizedString(@"Quit X server?",@""),
@@ -270,11 +271,18 @@ static io_connect_t root_port;
break;
case NSLeftMouseDown:
[self getMousePosition:&xe fromEvent:anEvent];
if (quartzRootless &&
! ([anEvent window] &&
[[anEvent window] isKindOfClass:windowClass])) {
// Click in non X window - ignore
return NO;
if (quartzRootless) {
// Check that event is in X11 window
if (!quartzProcs->IsX11Window([anEvent window],
[anEvent windowNumber]))
{
if (x11Active)
[self activateX11:NO];
return NO;
} else {
if (!x11Active)
[self activateX11:YES];
}
}
mouse1Pressed = YES;
xe.u.u.type = ButtonPress;
@@ -310,6 +318,8 @@ static io_connect_t root_port;
break;
case NSKeyDown:
case NSKeyUp:
if (!x11Active)
return NO;
// If the mouse is not on the valid X display area,
// we don't send the X server key events.
if (![self getMousePosition:&xe fromEvent:nil])
@@ -321,6 +331,8 @@ static io_connect_t root_port;
xe.u.u.detail = [anEvent keyCode];
break;
case NSFlagsChanged:
if (!x11Active)
return NO;
[self getMousePosition:&xe fromEvent:nil];
xe.u.u.type = kXDarwinUpdateModifiers;
xe.u.clientMessage.u.l.longs0 = flags;
@@ -335,14 +347,13 @@ static io_connect_t root_port;
[self sendXEvent:&xe];
// Rootless: Send first NSLeftMouseDown to windows and views so window
// ordering can be suppressed.
// Rootless: Send first NSLeftMouseDown to Cocoa windows and views so
// window ordering can be suppressed.
// Don't pass further events - they (incorrectly?) bring the window
// forward no matter what.
if (quartzRootless &&
(type == NSLeftMouseDown || type == NSLeftMouseUp) &&
[anEvent clickCount] == 1 &&
[[anEvent window] isKindOfClass:windowClass])
[anEvent clickCount] == 1 && [anEvent window])
{
return NO;
}
@@ -429,6 +440,27 @@ static io_connect_t root_port;
}
}
// Load the appropriate display mode bundle
- (BOOL)loadDisplayBundle
{
if (quartzRootless) {
NSEnumerator *enumerator = [[Preferences displayModeBundles]
objectEnumerator];
NSString *bundleName;
while ((bundleName = [enumerator nextObject])) {
if (QuartzLoadDisplayBundle([bundleName cString]))
return YES;
}
return NO;
} else {
return QuartzLoadDisplayBundle("fullscreen.bundle");
}
}
// Start the X server thread and the client process
- (void)startX
{
@@ -455,6 +487,9 @@ static io_connect_t root_port;
else
NSLog(@"No version");
if (![self loadDisplayBundle])
[NSApp terminate:nil];
// Start the X server thread
serverState = server_Starting;
[NSThread detachNewThreadSelector:@selector(run) toTarget:self
@@ -517,6 +552,19 @@ static io_connect_t root_port;
if (quartzServerQuitting) {
[self quitServer];
[NSApp replyToApplicationShouldTerminate:YES];
return;
}
if (pendingClients) {
NSEnumerator *enumerator = [pendingClients objectEnumerator];
NSString *filename;
while ((filename = [enumerator nextObject])) {
[self runClient:filename];
}
[pendingClients release];
pendingClients = nil;
}
}
@@ -666,6 +714,87 @@ static io_connect_t root_port;
return YES;
}
// Start the specified client in its own task
// FIXME: This should be unified with startXClients
- (void)runClient:(NSString *)filename
{
const char *command = [filename UTF8String];
const char *shell;
const char *argv[5];
int child1, child2 = 0;
int status;
shell = getenv("SHELL");
if (shell == NULL)
shell = "/bin/bash";
/* At least [ba]sh, [t]csh and zsh all work with this syntax. We
need to use an interactive shell to force it to load the user's
environment. */
argv[0] = shell;
argv[1] = "-i";
argv[2] = "-c";
argv[3] = command;
argv[4] = NULL;
/* Do the fork-twice trick to avoid having to reap zombies */
child1 = fork();
switch (child1) {
case -1: /* error */
break;
case 0: /* child1 */
child2 = fork();
switch (child2) {
int max_files, i;
char buf[1024], *tem;
case -1: /* error */
_exit(1);
case 0: /* child2 */
/* close all open files except for standard streams */
max_files = sysconf(_SC_OPEN_MAX);
for (i = 3; i < max_files; i++)
close(i);
/* ensure stdin is on /dev/null */
close(0);
open("/dev/null", O_RDONLY);
/* cd $HOME */
tem = getenv("HOME");
if (tem != NULL)
chdir(tem);
/* Setup environment */
snprintf(buf, sizeof(buf), ":%s", display);
setenv("DISPLAY", buf, TRUE);
tem = getenv("PATH");
if (tem != NULL && tem[0] != NULL)
snprintf(buf, sizeof(buf), "%s:/usr/X11R6/bin", tem);
else
snprintf(buf, sizeof(buf), "/bin:/usr/bin:/usr/X11R6/bin");
setenv("PATH", buf, TRUE);
execvp(argv[0], (char **const) argv);
_exit(2);
default: /* parent (child1) */
_exit(0);
}
break;
default: /* parent */
waitpid(child1, &status, 0);
}
}
// Run the X server thread
- (void)run
{
@@ -712,6 +841,12 @@ static io_connect_t root_port;
[NSApp activateIgnoringOtherApps:YES];
}
// Show the Aqua-X11 switch panel useful for fullscreen mode
- (IBAction)showSwitchPanel:(id)sender
{
[switchWindow orderFront:nil];
}
// Show the X server when sent message from GUI
- (IBAction)showAction:(id)sender
{
@@ -787,11 +922,10 @@ static io_connect_t root_port;
if (show) {
if (!quartzRootless) {
QuartzFSCapture();
quartzProcs->CaptureScreens();
HideMenuBar();
}
xe.u.u.type = kXDarwinShow;
[self sendXEvent:&xe];
[self activateX11:YES];
// the mouse location will have moved; track it
xe.u.u.type = MotionNotify;
@@ -802,14 +936,19 @@ static io_connect_t root_port;
xe.u.clientMessage.u.l.longs0 = [[NSApp currentEvent] modifierFlags];
[self sendXEvent:&xe];
// put the pasteboard into the X cut buffer
[self readPasteboard];
// If there is no AppleWM-aware cut and paste manager, do what we can.
if ((AppleWMSelectedEvents() & AppleWMPasteboardNotifyMask) == 0) {
// put the pasteboard into the X cut buffer
[self readPasteboard];
}
} else {
// put the X cut buffer on the pasteboard
[self writePasteboard];
// If there is no AppleWM-aware cut and paste manager, do what we can.
if ((AppleWMSelectedEvents() & AppleWMPasteboardNotifyMask) == 0) {
// put the X cut buffer on the pasteboard
[self writePasteboard];
}
xe.u.u.type = kXDarwinHide;
[self sendXEvent:&xe];
[self activateX11:NO];
}
serverVisible = show;
@@ -877,7 +1016,7 @@ static io_connect_t root_port;
}
#endif
ENQUEUE(xe);
DarwinEQEnqueue(xe);
}
// Handle messages from the X server thread
@@ -885,12 +1024,12 @@ static io_connect_t root_port;
{
unsigned msg = [portMessage msgid];
switch(msg) {
switch (msg) {
case kQuartzServerHidden:
// Make sure the X server wasn't queued to be shown again while
// the hide was pending.
if (!quartzRootless && !serverVisible) {
QuartzFSRelease();
quartzProcs->ReleaseScreens();
ShowMenuBar();
}
break;
@@ -908,13 +1047,43 @@ static io_connect_t root_port;
break;
case kQuartzCursorUpdate:
QuartzReallySetCursor();
if (quartzProcs->CursorUpdate)
quartzProcs->CursorUpdate();
break;
case kQuartzPostEvent:
{
const xEvent *xe = [[[portMessage components] lastObject] bytes];
ENQUEUE(xe);
DarwinEQEnqueue(xe);
break;
}
case kQuartzSetWindowMenu:
{
NSArray *list;
[[[portMessage components] lastObject] getBytes:&list];
[self setX11WindowList:list];
[list release];
break;
}
case kQuartzSetWindowMenuCheck:
{
int n;
[[[portMessage components] lastObject] getBytes:&n];
[self setX11WindowCheck:[NSNumber numberWithInt:n]];
break;
}
case kQuartzSetFrontProcess:
[NSApp activateIgnoringOtherApps:YES];
break;
case kQuartzSetCanQuit:
{
int n;
[[[portMessage components] lastObject] getBytes:&n];
quitWithoutQuery = (BOOL) n;
break;
}
@@ -939,6 +1108,234 @@ static io_connect_t root_port;
}
}
// User selected an X11 window from a menu
- (IBAction)itemSelected:(id)sender
{
xEvent xe;
[NSApp activateIgnoringOtherApps:YES];
// Notify the client of the change through the X server thread
xe.u.u.type = kXDarwinControllerNotify;
xe.u.clientMessage.u.l.longs0 = AppleWMWindowMenuItem;
xe.u.clientMessage.u.l.longs1 = [sender tag];
[self sendXEvent:&xe];
}
// User selected Next from window menu
- (IBAction)nextWindow:(id)sender
{
QuartzMessageServerThread(kXDarwinControllerNotify, 1,
AppleWMNextWindow);
}
// User selected Previous from window menu
- (IBAction)previousWindow:(id)sender
{
QuartzMessageServerThread(kXDarwinControllerNotify, 1,
AppleWMPreviousWindow);
}
/*
* The XPR implementation handles close, minimize, and zoom actions for X11
* windows here, while CR handles these in the NSWindow class.
*/
// Handle Close from window menu for X11 window in XPR implementation
- (IBAction)performClose:(id)sender
{
QuartzMessageServerThread(kXDarwinControllerNotify, 1,
AppleWMCloseWindow);
}
// Handle Minimize from window menu for X11 window in XPR implementation
- (IBAction)performMiniaturize:(id)sender
{
QuartzMessageServerThread(kXDarwinControllerNotify, 1,
AppleWMMinimizeWindow);
}
// Handle Zoom from window menu for X11 window in XPR implementation
- (IBAction)performZoom:(id)sender
{
QuartzMessageServerThread(kXDarwinControllerNotify, 1,
AppleWMZoomWindow);
}
// Handle "Bring All to Front" from window menu
- (IBAction)bringAllToFront:(id)sender
{
if ((AppleWMSelectedEvents() & AppleWMControllerNotifyMask) != 0) {
QuartzMessageServerThread(kXDarwinControllerNotify, 1,
AppleWMBringAllToFront);
} else {
[NSApp arrangeInFront:nil];
}
}
// This ends up at the end of the responder chain.
- (IBAction)copy:(id)sender
{
QuartzMessageServerThread(kXDarwinPasteboardNotify, 1,
AppleWMCopyToPasteboard);
}
// Set whether or not X11 is active and should receive all key events
- (void)activateX11:(BOOL)state
{
if (state) {
QuartzMessageServerThread(kXDarwinActivate, 0);
}
else {
QuartzMessageServerThread(kXDarwinDeactivate, 0);
}
x11Active = state;
}
// Some NSWindow became the key window
- (void)windowBecameKey:(NSWindow *)window
{
if (quartzProcs->IsX11Window(window, [window windowNumber])) {
if (!x11Active)
[self activateX11:YES];
} else {
if (x11Active)
[self activateX11:NO];
}
}
// Set the Apple-WM specifiable part of the window menu
- (void)setX11WindowList:(NSArray *)list
{
NSMenuItem *item;
int first, count, i;
xEvent xe;
/* Work backwards so we don't mess up the indices */
first = [windowMenu indexOfItem:windowSeparator] + 1;
if (first > 0) {
count = [windowMenu numberOfItems];
for (i = count - 1; i >= first; i--)
[windowMenu removeItemAtIndex:i];
} else {
windowSeparator = (NSMenuItem *)[windowMenu addItemWithTitle:@""
action:nil
keyEquivalent:@""];
}
count = [dockMenu numberOfItems];
for (i = 0; i < count; i++)
[dockMenu removeItemAtIndex:0];
count = [list count];
for (i = 0; i < count; i++)
{
NSString *name, *shortcut;
name = [[list objectAtIndex:i] objectAtIndex:0];
shortcut = [[list objectAtIndex:i] objectAtIndex:1];
item = (NSMenuItem *)[windowMenu addItemWithTitle:name
action:@selector(itemSelected:)
keyEquivalent:shortcut];
[item setTarget:self];
[item setTag:i];
[item setEnabled:YES];
item = (NSMenuItem *)[dockMenu insertItemWithTitle:name
action:@selector(itemSelected:)
keyEquivalent:shortcut atIndex:i];
[item setTarget:self];
[item setTag:i];
[item setEnabled:YES];
}
if (checkedWindowItem >= 0 && checkedWindowItem < count)
{
item = (NSMenuItem *)[windowMenu itemAtIndex:first + checkedWindowItem];
[item setState:NSOnState];
item = (NSMenuItem *)[dockMenu itemAtIndex:checkedWindowItem];
[item setState:NSOnState];
}
// Notify the client of the change through the X server thread
xe.u.u.type = kXDarwinControllerNotify;
xe.u.clientMessage.u.l.longs0 = AppleWMWindowMenuNotify;
[self sendXEvent:&xe];
}
// Set the checked item on the Apple-WM specifiable window menu
- (void)setX11WindowCheck:(NSNumber *)nn
{
NSMenuItem *item;
int first, count;
int n = [nn intValue];
first = [windowMenu indexOfItem:windowSeparator] + 1;
count = [windowMenu numberOfItems] - first;
if (checkedWindowItem >= 0 && checkedWindowItem < count)
{
item = (NSMenuItem *)[windowMenu itemAtIndex:first + checkedWindowItem];
[item setState:NSOffState];
item = (NSMenuItem *)[dockMenu itemAtIndex:checkedWindowItem];
[item setState:NSOffState];
}
if (n >= 0 && n < count)
{
item = (NSMenuItem *)[windowMenu itemAtIndex:first + n];
[item setState:NSOnState];
item = (NSMenuItem *)[dockMenu itemAtIndex:n];
[item setState:NSOnState];
}
checkedWindowItem = n;
}
// Return whether or not a menu item should be enabled
- (BOOL)validateMenuItem:(NSMenuItem *)item
{
NSMenu *menu = [item menu];
if (menu == windowMenu && [item tag] == 30) {
// Mode switch panel is for fullscreen only
return !quartzRootless;
}
else if ((menu == windowMenu && [item tag] != 40) || menu == dockMenu) {
// The special window and dock menu items should not be active unless
// there is an AppleWM-aware window manager running.
return (AppleWMSelectedEvents() & AppleWMControllerNotifyMask) != 0;
}
else {
return TRUE;
}
}
/*
* Application Delegate Methods
*/
- (void)applicationDidHide:(NSNotification *)aNotification
{
if ((AppleWMSelectedEvents() & AppleWMControllerNotifyMask) != 0) {
QuartzMessageServerThread(kXDarwinControllerNotify, 1,
AppleWMHideAll);
} else {
// FIXME: We need to hide Xplugin windows here
}
}
- (void)applicationDidUnhide:(NSNotification *)aNotification
{
if ((AppleWMSelectedEvents() & AppleWMControllerNotifyMask) != 0) {
QuartzMessageServerThread(kXDarwinControllerNotify, 1,
AppleWMShowAll);
} else {
[NSApp arrangeInFront:nil];
}
}
// Called when the user clicks the application icon,
// but not when Cmd-Tab is used.
// Rootless: Don't switch until applicationWillBecomeActive.
@@ -958,8 +1355,38 @@ static io_connect_t root_port;
- (void)applicationWillBecomeActive:(NSNotification *)aNotification
{
if (quartzRootless)
if (quartzRootless) {
[self showServer:YES];
// If there is no AppleWM-aware window manager, we can't allow
// interleaving of Aqua and X11 windows.
if ((AppleWMSelectedEvents() & AppleWMControllerNotifyMask) == 0) {
[NSApp arrangeInFront:nil];
}
}
}
// Called when the user opens a document type that we claim (ie. an X11 executable).
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
if (serverState == server_Running) {
[self runClient:filename];
return YES;
}
else if (serverState == server_NotStarted || serverState == server_Starting) {
if ([filename UTF8String][0] != ':') { // Ignore display names
if (!pendingClients) {
pendingClients = [[NSMutableArray alloc] initWithCapacity:1];
}
[pendingClients addObject:filename];
return YES; // Assume it will launch successfully
}
return NO;
}
// If the server is quitting or done,
// its too late to launch new clients this time.
return NO;
}
@end
@@ -970,7 +1397,7 @@ static io_connect_t root_port;
// NSPort is not thread safe.
void QuartzMessageMainThread(unsigned msg, void *data, unsigned length)
{
if (msg == kQuartzPostEvent) {
if (length > 0) {
NSData *eventData = [NSData dataWithBytes:data length:length];
NSArray *eventArray = [NSArray arrayWithObject:eventData];
NSPortMessage *newMessage =
@@ -986,6 +1413,36 @@ void QuartzMessageMainThread(unsigned msg, void *data, unsigned length)
}
}
void
QuartzSetWindowMenu(int nitems, const char **items,
const char *shortcuts)
{
NSMutableArray *array;
int i;
array = [[NSMutableArray alloc] initWithCapacity:nitems];
for (i = 0; i < nitems; i++) {
NSMutableArray *subarray = [NSMutableArray arrayWithCapacity:2];
NSString *string = [NSString stringWithUTF8String:items[i]];
[subarray addObject:string];
if (shortcuts[i] != 0) {
NSString *number = [NSString stringWithFormat:@"%d",
shortcuts[i]];
[subarray addObject:number];
} else
[subarray addObject:@""];
[array addObject:subarray];
}
/* Send the array of strings over to the main thread. */
/* Will be released in main thread. */
QuartzMessageMainThread(kQuartzSetWindowMenu, &array, sizeof(NSArray *));
}
// Handle SIGCHLD signals
static void childDone(int sig)
{
@@ -1025,5 +1482,5 @@ static void powerDidChange(
}
break;
}
}

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

@@ -32,7 +32,7 @@ shall not be used in advertising or otherwise to promote the sale, use or other
dealings in this Software without prior written authorization from Digital
Equipment Corporation.
******************************************************************/
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/pseudoramiX.c,v 1.2 2002/10/16 21:13:33 dawes Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/pseudoramiX.c,v 1.3 2003/04/30 23:15:39 torrey Exp $ */
#include "pseudoramiX.h"
@@ -111,7 +111,7 @@ void PseudoramiXExtensionInit(int argc, char *argv[])
if (noPseudoramiXExtension) return;
if (pseudoramiXNumScreens == 1 || aquaNumScreens == 1) {
if (pseudoramiXNumScreens == 1) {
// Only one screen - disable Xinerama extension.
noPseudoramiXExtension = TRUE;
return;

View File

@@ -1,10 +1,9 @@
/*
* Minimal implementation of PanoramiX/Xinerama
*/
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/pseudoramiX.h,v 1.1 2002/03/28 02:21:18 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/pseudoramiX.h,v 1.2 2003/04/30 23:15:39 torrey Exp $ */
extern int noPseudoramiXExtension;
extern int aquaNumScreens;
void PseudoramiXAddScreen(int x, int y, int w, int h);
void PseudoramiXExtensionInit(int argc, char *argv[]);

View File

@@ -29,16 +29,16 @@
* 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/quartz.c,v 1.7 2003/01/23 00:34:26 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartz.c,v 1.13 2003/11/12 20:21:51 torrey Exp $ */
#include "quartzCommon.h"
#include "quartz.h"
#include "darwin.h"
#include "quartzAudio.h"
#include "quartzCursor.h"
#include "fullscreen.h"
#include "rootlessAqua.h"
#include "pseudoramiX.h"
#define _APPLEWM_SERVER_
#include "applewm.h"
#include "applewmExt.h"
// X headers
#include "scrnintstr.h"
@@ -61,8 +61,8 @@ int quartzServerQuitting = FALSE;
int quartzScreenIndex = 0;
int aquaMenuBarHeight = 0;
int noPseudoramiXExtension = TRUE;
int aquaNumScreens = 0;
QuartzModeProcsPtr quartzProcs = NULL;
const char *quartzOpenGLBundle = NULL;
/*
===========================================================================
@@ -73,10 +73,10 @@ int aquaNumScreens = 0;
*/
/*
* QuartzAddScreen
* DarwinModeAddScreen
* Do mode dependent initialization of each screen for Quartz.
*/
Bool QuartzAddScreen(
Bool DarwinModeAddScreen(
int index,
ScreenPtr pScreen)
{
@@ -84,34 +84,25 @@ Bool QuartzAddScreen(
QuartzScreenPtr displayInfo = xcalloc(sizeof(QuartzScreenRec), 1);
QUARTZ_PRIV(pScreen) = displayInfo;
// do full screen or rootless specific initialization
if (quartzRootless) {
return AquaAddScreen(index, pScreen);
} else {
return QuartzFSAddScreen(index, pScreen);
}
// do Quartz mode specific initialization
return quartzProcs->AddScreen(index, pScreen);
}
/*
* QuartzSetupScreen
* DarwinModeSetupScreen
* Finalize mode specific setup of each screen.
*/
Bool QuartzSetupScreen(
Bool DarwinModeSetupScreen(
int index,
ScreenPtr pScreen)
{
// do full screen or rootless specific setup
if (quartzRootless) {
if (! AquaSetupScreen(index, pScreen))
return FALSE;
} else {
if (! QuartzFSSetupScreen(index, pScreen))
return FALSE;
}
// do Quartz mode specific setup
if (! quartzProcs->SetupScreen(index, pScreen))
return FALSE;
// setup cursor support
if (! QuartzInitCursor(pScreen))
if (! quartzProcs->InitCursor(pScreen))
return FALSE;
return TRUE;
@@ -119,10 +110,10 @@ Bool QuartzSetupScreen(
/*
* QuartzInitOutput
* DarwinModeInitOutput
* Quartz display initialization.
*/
void QuartzInitOutput(
void DarwinModeInitOutput(
int argc,
char **argv )
{
@@ -145,13 +136,8 @@ void QuartzInitOutput(
FatalError("Could not register block and wakeup handlers.");
}
if (quartzRootless) {
ErrorF("Display mode: Rootless Quartz\n");
AquaDisplayInit();
} else {
ErrorF("Display mode: Full screen Quartz\n");
QuartzFSDisplayInit();
}
// Do display mode specific initialization
quartzProcs->DisplayInit();
// Init PseudoramiX implementation of Xinerama.
// This should be in InitExtensions, but that causes link errors
@@ -163,21 +149,28 @@ void QuartzInitOutput(
/*
* QuartzInitInput
* DarwinModeInitInput
* Inform the main thread the X server is ready to handle events.
*/
void QuartzInitInput(
void DarwinModeInitInput(
int argc,
char **argv )
{
QuartzMessageMainThread(kQuartzServerStarted, NULL, 0);
if (serverGeneration == 1) {
QuartzMessageMainThread(kQuartzServerStarted, NULL, 0);
}
// Do final display mode specific initialization before handling events
if (quartzProcs->InitInput)
quartzProcs->InitInput(argc, argv);
}
/*
* QuartzShow
* Show the X server on screen. Does nothing if already shown.
* Restore the X clip regions and the X server cursor state.
* Calls mode specific screen resume to restore the X clip regions
* (if needed) and the X server cursor state.
*/
static void QuartzShow(
int x, // cursor location
@@ -189,9 +182,7 @@ static void QuartzShow(
quartzServerVisible = TRUE;
for (i = 0; i < screenInfo.numScreens; i++) {
if (screenInfo.screens[i]) {
QuartzResumeXCursor(screenInfo.screens[i], x, y);
if (!quartzRootless)
xf86SetRootClip(screenInfo.screens[i], TRUE);
quartzProcs->ResumeScreen(screenInfo.screens[i], x, y);
}
}
}
@@ -201,8 +192,8 @@ static void QuartzShow(
/*
* QuartzHide
* Remove the X server display from the screen. Does nothing if already
* hidden. Set X clip regions to prevent drawing, and restore the Aqua
* cursor.
* hidden. Calls mode specific screen suspend to set X clip regions to
* prevent drawing (if needed) and restore the Aqua cursor.
*/
static void QuartzHide(void)
{
@@ -211,9 +202,7 @@ static void QuartzHide(void)
if (quartzServerVisible) {
for (i = 0; i < screenInfo.numScreens; i++) {
if (screenInfo.screens[i]) {
QuartzSuspendXCursor(screenInfo.screens[i]);
if (!quartzRootless)
xf86SetRootClip(screenInfo.screens[i], FALSE);
quartzProcs->SuspendScreen(screenInfo.screens[i]);
}
}
}
@@ -243,20 +232,58 @@ static void QuartzSetRootClip(
/*
* QuartzProcessEvent
* QuartzMessageServerThread
* Send the X server thread a message by placing it on the event queue.
*/
void
QuartzMessageServerThread(
int type,
int argc, ...)
{
xEvent xe;
INT32 *argv;
int i, max_args;
va_list args;
memset(&xe, 0, sizeof(xe));
xe.u.u.type = type;
xe.u.clientMessage.u.l.type = type;
argv = &xe.u.clientMessage.u.l.longs0;
max_args = 4;
if (argc > 0 && argc <= max_args) {
va_start (args, argc);
for (i = 0; i < argc; i++)
argv[i] = (int) va_arg (args, int);
va_end (args);
}
DarwinEQEnqueue(&xe);
}
/*
* DarwinModeProcessEvent
* Process Quartz specific events.
*/
void QuartzProcessEvent(
void DarwinModeProcessEvent(
xEvent *xe)
{
switch (xe->u.u.type) {
case kXDarwinShow:
case kXDarwinActivate:
QuartzShow(xe->u.keyButtonPointer.rootX,
xe->u.keyButtonPointer.rootY);
AppleWMSendEvent(AppleWMActivationNotify,
AppleWMActivationNotifyMask,
AppleWMIsActive, 0);
break;
case kXDarwinHide:
case kXDarwinDeactivate:
AppleWMSendEvent(AppleWMActivationNotify,
AppleWMActivationNotifyMask,
AppleWMIsInactive, 0);
QuartzHide();
break;
@@ -276,18 +303,42 @@ void QuartzProcessEvent(
QuartzWritePasteboard();
break;
/*
* AppleWM events
*/
case kXDarwinControllerNotify:
AppleWMSendEvent(AppleWMControllerNotify,
AppleWMControllerNotifyMask,
xe->u.clientMessage.u.l.longs0,
xe->u.clientMessage.u.l.longs1);
break;
case kXDarwinPasteboardNotify:
AppleWMSendEvent(AppleWMPasteboardNotify,
AppleWMPasteboardNotifyMask,
xe->u.clientMessage.u.l.longs0,
xe->u.clientMessage.u.l.longs1);
break;
case kXDarwinDisplayChanged:
case kXDarwinWindowState:
case kXDarwinWindowMoved:
// FIXME: Not implemented yet
break;
default:
ErrorF("Unknown application defined event.\n");
ErrorF("Unknown application defined event type %d.\n",
xe->u.u.type);
}
}
/*
* QuartzGiveUp
* DarwinModeGiveUp
* Cleanup before X server shutdown
* Release the screen and restore the Aqua cursor.
*/
void QuartzGiveUp(void)
void DarwinModeGiveUp(void)
{
#if 0
// Trying to switch cursors when quitting causes deadlock
@@ -301,5 +352,5 @@ void QuartzGiveUp(void)
#endif
if (!quartzRootless)
QuartzFSRelease();
quartzProcs->ReleaseScreens();
}

View File

@@ -1,11 +1,11 @@
/*
* quartz.h
*
* External interface of the Quartz modes seen by the generic, mode
* External interface of the Quartz display modes seen by the generic, mode
* independent parts of the Darwin X server.
*/
/*
* Copyright (c) 2001-2002 Greg Parker and Torrey T. Lyons.
* Copyright (c) 2001-2003 Greg Parker and Torrey T. Lyons.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -30,21 +30,88 @@
* 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/quartz.h,v 1.4 2002/11/20 23:51:58 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartz.h,v 1.7 2003/11/12 20:21:51 torrey Exp $ */
#ifndef _QUARTZ_H
#define _QUARTZ_H
#include "screenint.h"
#include "Xproto.h"
#include "quartzPasteboard.h"
int QuartzProcessArgument(int argc, char *argv[], int i);
void QuartzInitOutput(int argc, char **argv);
void QuartzInitInput(int argc, char **argv);
Bool QuartzAddScreen(int index, ScreenPtr pScreen);
Bool QuartzSetupScreen(int index, ScreenPtr pScreen);
void QuartzGiveUp(void);
void QuartzProcessEvent(xEvent *xe);
#include "screenint.h"
#include "window.h"
/*------------------------------------------
Quartz display mode function types
------------------------------------------*/
/*
* Display mode initialization
*/
typedef void (*DisplayInitProc)(void);
typedef Bool (*AddScreenProc)(int index, ScreenPtr pScreen);
typedef Bool (*SetupScreenProc)(int index, ScreenPtr pScreen);
typedef void (*InitInputProc)(int argc, char **argv);
/*
* Cursor functions
*/
typedef Bool (*InitCursorProc)(ScreenPtr pScreen);
typedef void (*CursorUpdateProc)(void);
/*
* Suspend and resume X11 activity
*/
typedef void (*SuspendScreenProc)(ScreenPtr pScreen);
typedef void (*ResumeScreenProc)(ScreenPtr pScreen, int x, int y);
typedef void (*CaptureScreensProc)(void);
typedef void (*ReleaseScreensProc)(void);
/*
* Rootless helper functions
*/
typedef Bool (*IsX11WindowProc)(void *nsWindow, int windowNumber);
/*
* Rootless functions for optional export to GLX layer
*/
typedef void * (*FrameForWindowProc)(WindowPtr pWin, Bool create);
typedef WindowPtr (*TopLevelParentProc)(WindowPtr pWindow);
typedef Bool (*CreateSurfaceProc)
(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
unsigned int client_id, unsigned int *surface_id,
unsigned int key[2], void (*notify) (void *arg, void *data),
void *notify_data);
typedef Bool (*DestroySurfaceProc)
(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
void (*notify) (void *arg, void *data), void *notify_data);
/*
* Quartz display mode function list
*/
typedef struct _QuartzModeProcs {
DisplayInitProc DisplayInit;
AddScreenProc AddScreen;
SetupScreenProc SetupScreen;
InitInputProc InitInput;
InitCursorProc InitCursor;
CursorUpdateProc CursorUpdate; // Not used if NULL
SuspendScreenProc SuspendScreen;
ResumeScreenProc ResumeScreen;
CaptureScreensProc CaptureScreens; // Only called in fullscreen
ReleaseScreensProc ReleaseScreens; // Only called in fullscreen
IsX11WindowProc IsX11Window;
FrameForWindowProc FrameForWindow;
TopLevelParentProc TopLevelParent;
CreateSurfaceProc CreateSurface;
DestroySurfaceProc DestroySurface;
} QuartzModeProcsRec, *QuartzModeProcsPtr;
extern QuartzModeProcsPtr quartzProcs;
Bool QuartzLoadDisplayBundle(const char *dpyBundleName);
#endif

View File

@@ -35,7 +35,7 @@
* 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/quartzAudio.c,v 1.1 2002/03/28 02:21:18 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzAudio.c,v 1.2 2003/05/14 05:27:56 torrey Exp $ */
#include "quartzCommon.h"
#include "quartzAudio.h"
@@ -242,10 +242,10 @@ static void QuartzCoreAudioBell(
/*
* QuartzBell
* DarwinModeBell
* Ring the bell
*/
void QuartzBell(
void DarwinModeBell(
int volume, // volume in percent of max
DeviceIntPtr pDevice,
pointer ctrl,

View File

@@ -33,12 +33,17 @@
* 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/quartzCocoa.m,v 1.3 2003/01/19 06:52:54 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzCocoa.m,v 1.4 2003/05/14 05:27:56 torrey Exp $ */
#include "quartzCommon.h"
#define BOOL xBOOL
#include "darwin.h"
#undef BOOL
#include <Cocoa/Cocoa.h>
#import "Preferences.h"
#include "quartzCommon.h"
#include "pseudoramiX.h"
extern void FatalError(const char *, ...);
@@ -57,7 +62,7 @@ void QuartzReadPreferences(void)
darwinFakeButtons = [Preferences fakeButtons];
darwinFakeMouse2Mask = [Preferences button2Mask];
darwinFakeMouse3Mask = [Preferences button3Mask];
quartzMouseAccelChange = [Preferences mouseAccelChange];
darwinMouseAccelChange = [Preferences mouseAccelChange];
quartzUseSysBeep = [Preferences systemBeep];
// quartzRootless has already been set

View File

@@ -31,7 +31,7 @@
* 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/quartzCommon.h,v 1.8 2003/01/23 00:34:26 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzCommon.h,v 1.14 2003/11/12 20:21:51 torrey Exp $ */
#ifndef _QUARTZCOMMON_H
#define _QUARTZCOMMON_H
@@ -48,8 +48,6 @@
#undef WindowPtr
#undef Picture
#include "quartzShared.h"
// Quartz specific per screen storage structure
typedef struct {
// List of CoreGraphics displays that this X11 screen covers.
@@ -78,11 +76,17 @@ extern int quartzServerQuitting;
extern int quartzScreenIndex;
extern int aquaMenuBarHeight;
// Name of GLX bundle for native OpenGL
extern const char *quartzOpenGLBundle;
void QuartzReadPreferences(void);
void QuartzMessageMainThread(unsigned msg, void *data, unsigned length);
void QuartzMessageServerThread(int type, int argc, ...);
void QuartzSetWindowMenu(int nitems, const char **items,
const char *shortcuts);
void QuartzFSCapture(void);
void QuartzFSRelease(void);
int QuartzFSUseQDCursor(int depth);
int QuartzFSUseQDCursor(int depth);
void QuartzBlockHandler(void *blockData, void *pTimeout, void *pReadmask);
void QuartzWakeupHandler(void *blockData, int result, void *pReadmask);
@@ -92,7 +96,11 @@ enum {
kQuartzServerStarted,
kQuartzServerDied,
kQuartzCursorUpdate,
kQuartzPostEvent
kQuartzPostEvent,
kQuartzSetWindowMenu,
kQuartzSetWindowMenuCheck,
kQuartzSetFrontProcess,
kQuartzSetCanQuit
};
#endif /* _QUARTZCOMMON_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

@@ -28,13 +28,14 @@
* 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/quartzStartup.c,v 1.3 2003/01/19 06:35:13 torrey Exp $ */
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzStartup.c,v 1.9 2003/11/15 00:07:09 torrey Exp $ */
#include <fcntl.h>
#include <unistd.h>
#include <CoreFoundation/CoreFoundation.h>
#include "quartzCommon.h"
#include "darwin.h"
#include "quartz.h"
#include "opaque.h"
#include "micmap.h"
@@ -50,6 +51,8 @@ static GlxExtensionInitPtr GlxExtensionInit = NULL;
typedef void (*GlxWrapInitVisualsPtr)(miInitVisualsProcPtr *);
static GlxWrapInitVisualsPtr GlxWrapInitVisuals = NULL;
typedef Bool (*QuartzModeBundleInitPtr)(void);
/*
* DarwinHandleGUI
@@ -76,19 +79,25 @@ void DarwinHandleGUI(
// Make a pipe to pass events
assert( pipe(fd) == 0 );
darwinEventFD = fd[0];
quartzEventWriteFD = fd[1];
fcntl(darwinEventFD, F_SETFL, O_NONBLOCK);
darwinEventReadFD = fd[0];
darwinEventWriteFD = fd[1];
fcntl(darwinEventReadFD, F_SETFL, O_NONBLOCK);
// Store command line arguments to pass back to main()
argcGlobal = argc;
argvGlobal = argv;
envpGlobal = envp;
// Determine if we need to start X clients
// and what display mode to use
quartzStartClients = 1;
for (i = 1; i < argc; i++) {
// Display version info without starting Mac OS X UI if requested
if (!strcmp( argv[i], "-showconfig" ) || !strcmp( argv[i], "-version" )) {
DarwinPrintBanner();
exit(0);
}
// Determine if we need to start X clients
// and what display mode to use
if (!strcmp(argv[i], "-nostartx")) {
quartzStartClients = 0;
} else if (!strcmp( argv[i], "-fullscreen")) {
@@ -98,12 +107,69 @@ void DarwinHandleGUI(
}
}
quartz = TRUE;
main_exit = NSApplicationMain(argc, argv);
exit(main_exit);
}
/*
* QuartzLoadDisplayBundle
* Try to load the appropriate bundle containing the back end display code.
*/
Bool QuartzLoadDisplayBundle(
const char *dpyBundleName)
{
CFBundleRef mainBundle;
CFStringRef bundleName;
CFURLRef bundleURL;
CFBundleRef dpyBundle;
QuartzModeBundleInitPtr bundleInit;
// Get the main bundle for the application
mainBundle = CFBundleGetMainBundle();
// Make CFString from bundle name
bundleName = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault,
dpyBundleName,
kCFStringEncodingASCII,
kCFAllocatorNull);
// Look for the appropriate bundle in the main bundle
bundleURL = CFBundleCopyResourceURL(mainBundle, bundleName,
NULL, NULL);
if (!bundleURL) {
ErrorF("Could not find display mode bundle %s.\n", dpyBundleName);
return FALSE;
}
// Make a bundle instance using the URLRef
dpyBundle = CFBundleCreate(kCFAllocatorDefault, bundleURL);
if (!CFBundleLoadExecutable(dpyBundle)) {
ErrorF("Could not load display mode bundle %s.\n", dpyBundleName);
return FALSE;
}
// Lookup the bundle initialization function
bundleInit = (void *)
CFBundleGetFunctionPointerForName(dpyBundle,
CFSTR("QuartzModeBundleInit"));
if (!bundleInit) {
ErrorF("Could not initialize display mode bundle %s.\n",
dpyBundleName);
return FALSE;
}
if (!bundleInit())
return FALSE;
// Release the CF objects
CFRelease(bundleName);
CFRelease(bundleURL);
return TRUE;
}
/*
* LoadGlxBundle
* The Quartz mode X server needs to dynamically load the appropriate
@@ -122,10 +188,14 @@ static void LoadGlxBundle(void)
// Choose the bundle to load
ErrorF("Loading GLX bundle ");
if (quartzUseAGL) {
bundleName = CFSTR("glxAGL.bundle");
ErrorF("glxAGL.bundle (using Apple's OpenGL)\n");
bundleName = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault,
quartzOpenGLBundle,
kCFStringEncodingASCII,
kCFAllocatorNull);
ErrorF("%s (using Apple's OpenGL)\n", quartzOpenGLBundle);
} else {
bundleName = CFSTR("glxMesa.bundle");
CFRetain(bundleName); // so we can release later
ErrorF("glxMesa.bundle (using Mesa)\n");
}
@@ -155,7 +225,7 @@ static void LoadGlxBundle(void)
}
// Release the CF objects
CFRelease(mainBundle);
CFRelease(bundleName);
CFRelease(bundleURL);
}
@@ -186,7 +256,7 @@ void DarwinGlxWrapInitVisuals(
}
int QuartzProcessArgument( int argc, char *argv[], int i )
int DarwinModeProcessArgument( int argc, char *argv[], int i )
{
// fullscreen: CoreGraphics full-screen mode
// rootless: Cocoa rootless mode
@@ -208,7 +278,7 @@ int QuartzProcessArgument( int argc, char *argv[], int i )
QUARTZ_SAFETY_DELAY );
#endif
return 1;
}
}
if ( !strcmp( argv[i], "-quartz" ) ) {
ErrorF( "Running in parallel with Mac OS X Quartz window server.\n" );

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

@@ -1,4 +1,4 @@
// $XFree86: xc/programs/Xserver/hw/darwin/utils/dumpkeymap.c,v 1.3 2000/12/05 21:18:34 dawes Exp $
// $XFree86: xc/programs/Xserver/hw/darwin/utils/dumpkeymap.c,v 1.4 2003/04/13 14:52:51 herrb Exp $
//=============================================================================
//
// Copyright (C) 1999,2000 by Eric Sunshine <sunshine@sunshineco.com>
@@ -141,6 +141,7 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#if !defined(DUMPKEYMAP_FILE_ONLY)
#include <drivers/event_status_driver.h>