/*
 *  CGS.h
 *  CaptureDaemon
 *
 *  Created by rudy on 12/21/07.
 *  Copyright 2007 Ambrosia Software, Inc. All rights reserved.
 *
 */

#include <ApplicationServices/ApplicationServices.h>

#ifdef __cplusplus
extern "C" {
#endif

//defintions from CGSConnection.h
#define kCGSNullConnectionID ((CGSConnectionID)0)
typedef uint32_t CGSConnectionID;

extern CGError CGSConnectionGetPID(CGSConnectionID cid, pid_t *outPID);
//extern CGError CGSConnectionGetPID(const CGSConnectionID cid, pid_t *pid, const CGSConnectionID ownerCid);
extern CGSConnectionID _CGSDefaultConnection(void) __attribute__((weak_import));

//definitions from CGSWindow.h
typedef int32_t CGSWindowID;
typedef CGWindowLevel CGSWindowLevel;
typedef long long CGSWindowCount;
typedef CGSWindowID * CGSWindowIDList;
typedef unsigned long long CGSDepth;
typedef CGFloat CGSAlphaValue;

enum _CGSDepth {
	kCGSDefaultDepth = 0,
	kCGSEightBitGray,
	kCGSEightBitColor,
	kCGSSixteenBitColor,
	kCGSThirtytwoBitColor,
	kCGSSixtyfourBitColor
};

typedef enum {
	CGSTagNone          = 0,        // No tags
	CGSTagExposeFade    = 0x0002,    // Fade out when Expose activates.
	CGSTagNoShadow      = 0x0008,    // No window shadow.
	CGSTagTransparent   = 0x0200,   // Transparent to mouse clicks.
	CGSTagSticky        = 0x080,    // Appears on all workspaces.
} CGSWindowTag;
	
typedef unsigned char CGSBoolean;
enum {
    kCGSFalse		= 0,
    kCGSTrue		= 1
};

	// Transitions we can apply
	typedef enum {
		CGSNone = 0,			// No transition effect.
		CGSFade,				// Cross-fade.
		CGSZoom,				// Zoom/fade towards us.
		CGSReveal,				// Reveal new desktop under old.
		CGSSlide,				// Slide old out and new in.
		CGSWarpFade,			// Warp old and fade out revealing new.
		CGSSwap,				// Swap desktops over graphically.
		CGSCube,				// The well-known cube effect.
		CGSWarpSwitch,			// Warp old, switch and un-warp.
		CGSFlip					// Flip over
	} CGSTransitionType;
	
	// All our transition styles - passed under "option" when invoking
	// Transparent Mask "(1<<7)" goes with option if applied.
	typedef enum {
		CGSDown,			// Old desktop moves down.
		CGSLeft,			// Old desktop moves left.
		CGSRight,			// Old desktop moves right.
		CGSInRight,			// CGSSwap: Old desktop moves into screen,
		// new comes from right.
		CGSBottomLeft = 5,	// CGSSwap: Old desktop moves to bottom-left,
		// new comes from top-right.
		CGSBottomRight,		// Old desktop to br, New from tl.
		CGSDownTopRight,	// CGSSwap: Old desktop moves down, new from tr.
		CGSUp,				// Old desktop moves up.
		CGSTopLeft,			// Old desktop moves tl.
		CGSTopRight,		// CGSSwap: old to tr. new from bl.
		CGSUpBottomRight,	// CGSSwap: old desktop up, new from br.
		CGSInBottom,		// CGSSwap: old in, new from bottom.
		CGSLeftBottomRight,	// CGSSwap: old one moves left, new from br.
		CGSRightBottomLeft,	// CGSSwap: old one moves right, new from bl.
		CGSInBottomRight,	// CGSSwap: onl one in, new from br.
		CGSInOut			// CGSSwap: old in, new out.
	} CGSTransitionOption;

	typedef struct {
		uint32_t unknown1;
		CGSTransitionType type;
		CGSTransitionOption option;
		CGSWindowID wid;			/* Can be 0 for full-screen */
		float *backColour;	/* Null for black otherwise pointer to 3 float array with RGB value */
	} CGSTransitionSpec;
	
extern CGError CGSGetWindowDepth(const CGSConnectionID cid, CGSWindowID wid, CGSDepth * depth);
extern CGError CGSGetWindowOwner(const CGSConnectionID cid, CGSWindowID wid, CGSConnectionID  *ownerCid);
extern CGError CGSGetWindowLevel(const CGSConnectionID cid, CGSWindowID wid, CGSWindowLevel *level);

extern CGError CGSGetOnScreenWindowCount(const CGSConnectionID cid, const CGSConnectionID owner, CGSWindowCount  * cnt);
extern CGError CGSGetOnScreenWindowList(const CGSConnectionID cid, const CGSConnectionID owner, CGSWindowCount listCapacity, CGSWindowIDList list, CGSWindowCount * listCount);

extern CGError CGSGetScreenRectForWindow(const CGSConnectionID cid, CGSWindowID wid, CGRect *rect);
extern CGError CGSGetWindowBounds(const CGSConnectionID cid, CGSWindowID wid, CGRect *bounds);

extern CGError CGSCaptureWindowsContentsToRect(CGSConnectionID cid, const CGSWindowID windows[], CGSWindowCount windowCount, CGRect rect, CGImageRef *outImage);

extern CGError CGSSetWindowShadowParameters(const CGSConnectionID cid, CGSWindowID wid, CGFloat standardDeviation,CGFloat density, NSInteger offsetX,NSInteger offsetY);
extern CGError CGSGetWindowShadowAndRimParameters(const CGSConnectionID cid, CGSWindowID wid, CGFloat *standardDeviation, CGFloat *density, NSInteger *offsetX, NSInteger *offsetY, NSUInteger *flags);

extern CGError CGSSetWindowAlpha(const CGSConnectionID cid, CGSWindowID wid, CGSAlphaValue alpha);
extern CGError CGSGetWindowAlpha(const CGSConnectionID cid, CGSWindowID wid, CGSAlphaValue *alpha);

extern CGError CGSSetWindowOpacity(const CGSConnectionID cid, CGSWindowID wid, CGSBoolean opacity);
extern CGError CGSGetWindowOpacity(const CGSConnectionID cid, CGSWindowID wid, CGSBoolean * opacity);

extern CGError CGSGetCurrentCursorLocation(const CGSConnectionID cid, CGPoint *point) __attribute__((weak_import));

extern OSStatus CGSGetWindowTags(const CGSConnectionID cid, const CGSWindowID wid, int *tags, int thirtyTwo);
extern OSStatus CGSSetWindowTags(const CGSConnectionID cid, const CGSWindowID wid, int *tags, int thirtyTwo);
extern OSStatus CGSClearWindowTags(const CGSConnectionID cid, const CGSWindowID wid, int *tags, int thirtyTwo);
	
extern CGSWindowID GetNativeWindowFromWindowRef(WindowRef ref);

/* Transition handling. */
extern OSStatus CGSNewTransition(const CGSConnectionID cid, const CGSTransitionSpec* spec, int *pTransitionHandle);
extern OSStatus CGSInvokeTransition(const CGSConnectionID cid, int transitionHandle, float duration);
extern OSStatus CGSReleaseTransition(const CGSConnectionID cid, int transitionHandle);
	
#ifdef __cplusplus
}
#endif
