#ifndef _GROUP_H
#define _GROUP_H

/**
 *
 * Beryl group plugin
 *
 * group.h
 *
 * Copyright : (C) 2006 by Patrick Niklaus, Roi Cohen, Danny Baumann
 * Authors: Patrick Niklaus <patrick.niklaus@googlemail.com>
 *          Roi Cohen       <roico@beryl-project.org>
 *          Danny Baumann   <maniac@beryl-project.org>
 *
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 **/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef __FreeBSD__
#include <malloc.h>
#endif
#include <time.h>
#include <X11/Xlib.h>
#include <cairo-xlib-xrender.h>
#include <beryl.h>
#include <beryl_ipcs.h>
#include <beryl-text.h>
#include <X11/Xatom.h>

#include <math.h>
#include <limits.h>

#include "group_glow.h"

/*
 * Constants
 *
 */
#define PI 3.1415926535897

#define GROUP_DISPLAY_OPTION_SELECT		0
#define GROUP_DISPLAY_OPTION_SELECT_SINGLE	1
#define GROUP_DISPLAY_OPTION_GROUPING		2
#define GROUP_DISPLAY_OPTION_UNGROUPING		3
#define GROUP_DISPLAY_OPTION_REMOVING		4
#define GROUP_DISPLAY_OPTION_CLOSING		5
#define GROUP_DISPLAY_OPTION_IGNORE		6
#define GROUP_DISPLAY_OPTION_TABMODE		7
#define GROUP_DISPLAY_OPTION_CHANGE_TAB_LEFT	8
#define GROUP_DISPLAY_OPTION_CHANGE_TAB_RIGHT	9
#define GROUP_DISPLAY_OPTION_CHANGE_COLOR	10
#define GROUP_DISPLAY_OPTION_NUM		11

#define GROUP_SCREEN_OPTION_TYPES			0
#define GROUP_SCREEN_OPTION_OPACITY			1
#define GROUP_SCREEN_OPTION_SATURATION			2
#define GROUP_SCREEN_OPTION_BRIGHTNESS			3
#define GROUP_SCREEN_OPTION_GLOW			4
#define GROUP_SCREEN_OPTION_MOVE			5
#define GROUP_SCREEN_OPTION_RESIZE			6
#define GROUP_SCREEN_OPTION_RAISE			7
#define GROUP_SCREEN_OPTION_AUTO_UNGROUP		8
#define GROUP_SCREEN_OPTION_AUTO_GROUP			9
#define GROUP_SCREEN_OPTION_RELATIVE_DISTANCE		10
#define GROUP_SCREEN_OPTION_SELECTION_COLOR		11
#define GROUP_SCREEN_OPTION_LINE_COLOR			12
#define GROUP_SCREEN_OPTION_PRECISION			13
#define GROUP_SCREEN_OPTION_TABBING_SPEED		14
#define GROUP_SCREEN_OPTION_TABBING_TIMESTEP		15
#define GROUP_SCREEN_OPTION_THUMB_SIZE			16
#define GROUP_SCREEN_OPTION_BORDER_WIDTH		17
#define GROUP_SCREEN_OPTION_BORDER_RADIUS		18
#define GROUP_SCREEN_OPTION_TAB_BORDER_COLOR		19
#define GROUP_SCREEN_OPTION_TAB_FILL_COLOR		20
#define GROUP_SCREEN_OPTION_GLOW_SIZE			21
#define GROUP_SCREEN_OPTION_GLOW_TYPE			22
#define GROUP_SCREEN_OPTION_FADE_TIME			23
#define GROUP_SCREEN_OPTION_VISIBILITY_TIME		24
#define GROUP_SCREEN_OPTION_UNTAB_ON_CLOSE		25
#define GROUP_SCREEN_OPTION_TABBAR_FONTSIZE		26
#define GROUP_SCREEN_OPTION_FADE_TEXT_TIME		27
#define GROUP_SCREEN_OPTION_TABBAR_FONTCOLOR		28
#define GROUP_SCREEN_OPTION_TAB_CREATE_MIPMAPS		29
#define GROUP_SCREEN_OPTION_CHANGE_ANIMATION_TIME	30
#define GROUP_SCREEN_OPTION_TAB_DRAG_HOVER_TIME		31
#define GROUP_SCREEN_OPTION_TAB_DRAG_SPRING_K		32
#define GROUP_SCREEN_OPTION_TAB_DRAG_FRICTION		33
#define GROUP_SCREEN_OPTION_TAB_DRAG_Y_DISTANCE		34
#define GROUP_SCREEN_OPTION_TAB_DRAG_SPEED_LIMIT	35
#define GROUP_SCREEN_OPTION_SPRING_MODEL_ON_MOVE	36
#define GROUP_SCREEN_OPTION_AUTOTAB			37
#define GROUP_SCREEN_OPTION_DND_UNGROUP_WINDOW		38
#define GROUP_SCREEN_OPTION_RESIZE_UNMAXIMIZE		39
#define GROUP_SCREEN_OPTION_MINIMIZE_ALL		40
#define GROUP_SCREEN_OPTION_SHADE_ALL			41
#define GROUP_SCREEN_OPTION_NUM				42

/*
 * Helpers
 *
 */
#define GET_GROUP_DISPLAY(d) ((GroupDisplay *) (d)->privates[displayPrivateIndex].ptr)
#define GROUP_DISPLAY(d) GroupDisplay *gd = GET_GROUP_DISPLAY (d)
#define GET_GROUP_SCREEN(s, gd) ((GroupScreen *) (s)->privates[ (gd)->screenPrivateIndex].ptr)
#define GROUP_SCREEN(s) GroupScreen *gs = GET_GROUP_SCREEN (s, GET_GROUP_DISPLAY (s->display))
#define GET_GROUP_WINDOW(w, gs) ((GroupWindow *) (w)->privates[ (gs)->windowPrivateIndex].ptr)
#define GROUP_WINDOW(w) GroupWindow *gw = GET_GROUP_WINDOW (w, GET_GROUP_SCREEN  (w->screen, GET_GROUP_DISPLAY (w->screen->display)))

#define WIN_X(w) (w->attrib.x)
#define WIN_Y(w) (w->attrib.y)
#define WIN_WIDTH(w) (w->attrib.width)
#define WIN_HEIGHT(w) (w->attrib.height)
#define WIN_BORDER(w) (w->attrib.border_width)

/* definitions used for glow painting */
#define WIN_REAL_X(w) (w->attrib.x - w->input.left)
#define WIN_REAL_Y(w) (w->attrib.y - w->input.top)
#define WIN_REAL_WIDTH(w) (w->width + 2 * w->attrib.border_width + w->input.left + w->input.right)
#define WIN_REAL_HEIGHT(w) (w->height + 2 * w->attrib.border_width + w->input.top + w->input.bottom)

#define NUM_OPTIONS(s) (sizeof ( (s)->opt) / sizeof (CompOption))
#define N_WIN_TYPE (sizeof (groupDefaultTypes) / sizeof (groupDefaultTypes[0]))
#define N_SEL_MODE (sizeof (groupSelectionModes) / sizeof (groupSelectionModes[0]))

#define REAL_POSITION(x, s) ( (x >= 0)? x: x + (s)->hsize * (s)->width )
#define VIEWPORT(x, s) ( ( REAL_POSITION(x, s) / (s)->width ) % (s)->hsize )

#define TOP_TAB(g) ((g)->topTab->window)
#define PREV_TOP_TAB(g) ((g)->prevTopTab->window)
#define NEXT_TOP_TAB(g) ((g)->nextTopTab->window)

#define HAS_TOP_WIN(group) (((group)->topTab) && ((group)->topTab->window))
#define HAS_PREV_TOP_WIN(group) (((group)->prevTopTab) && ((group)->prevTopTab->window))

#define IS_TOP_TAB(w, group) (HAS_TOP_WIN(group) && ((TOP_TAB(group)->id) == (w)->id))
#define IS_PREV_TOP_TAB(w, group) (HAS_PREV_TOP_WIN(group) && ((PREV_TOP_TAB(group)->id) == (w)->id))

/*
 * Debug
 *
 */
#define GROUP_DEBUG(msg, level) (groupDebugPrint(msg, level))

typedef enum {
	DEBUG_OFF = 0,
	DEBUG_IMPORTANT,
	DEBUG_INFO,
	DEBUG_ALL
} DebugLevel;

/*
 * Structs
 *
 */

/*
 * window states  
*/
typedef enum {
	WindowNormal = 0,
	WindowMinimized,
	WindowShaded
} GroupWindowState;

/*
 * screengrab states
 */
typedef enum {
	ScreenGrabNone = 0,
	ScreenGrabSelect,
	ScreenGrabTabDrag
} GroupScreenGrabState;

/*
 * ungrouping states
 */
typedef enum {
	UngroupNone = 0,
	UngroupAll,
	UngroupSingle
} GroupUngroupState;

/*
 * rotation direction for change tab animation
 */
typedef enum {
	RotateUncertain = 0,
	RotateLeft,
	RotateRight
} ChangeTabAnimationDirection;

/*
 * structs for glow type
 */
typedef enum {
	GlowTextureRectangular = 0,
	GlowTextureRing,
	GlowTextureNum
} GlowTextureType;

static const char *glowTextureName[] = {
	N_("Rectangular glow"),
	N_("Glow ring")
};
static const int nGlowTextureNames =
    sizeof (glowTextureName) / sizeof (glowTextureName[0]);

typedef struct _GlowTextureProperties {
	char * textureData;
	int textureSize;
	int glowOffset;
} GlowTextureProperties;

static const GlowTextureProperties glowTextureProperties[GlowTextureNum] = {
	// GlowTextureRectangular
	{glowTexRect, 32, 21},
	// GlowTextureRing
	{glowTexRing, 32, 16}
};

/*
 * structs for pending callbacks
 */
typedef struct _GroupPendingMoves GroupPendingMoves;
struct _GroupPendingMoves {
	CompWindow *w;
	int dx;
	int dy;
	Bool sync;
	GroupPendingMoves *next;
};

typedef struct _GroupPendingGrabs GroupPendingGrabs;
struct _GroupPendingGrabs {
	CompWindow *w;
	int x;
	int y;
	unsigned int state;
	unsigned int mask;
	GroupPendingGrabs *next;
};

typedef struct _GroupPendingUngrabs GroupPendingUngrabs;
struct _GroupPendingUngrabs {
	CompWindow *w;
	GroupPendingUngrabs *next;
};

/*
 * pointer to display list
 */
int displayPrivateIndex;

/*
 * PaintState
 */

/* mask values for groupTabSetVisibility */
#define SHOW_BAR_INSTANTLY_MASK		(1 << 0)
#define PERMANENT			(1 << 1)

/* mask values for tabbing animation */
#define IS_ANIMATED		(1 << 0)
#define FINISHED_ANIMATION	(1 << 1)
#define CONSTRAINED_X		(1 << 2)
#define CONSTRAINED_Y		(1 << 3)
#define DONT_CONSTRAIN		(1 << 4)

typedef enum {
	PaintOff = 0,
	PaintFadeIn,
	PaintFadeOut,
	PaintOn,
	PaintPermanentOn
} PaintState;


typedef struct _GroupCairoLayer {
	unsigned char		*texBuf;
	Pixmap			pixmap;
	CompTexture		texture;
	cairo_surface_t		*surface;
	cairo_t			*cairo;

	int texWidth, texHeight;

	PaintState		state;
	int			animationTime;
} GroupCairoLayer;

/*
 * GroupTabBarSlot
 */
typedef struct _GroupTabBarSlot GroupTabBarSlot;
struct _GroupTabBarSlot {
	GroupTabBarSlot	*prev;
	GroupTabBarSlot	*next;

	Region		region;

	char		*name;
	CompWindow	*window;
	
	//for DnD animations.
	int		springX;
	int		speed;
	float		msSinceLastMove;
};

/*
 * GroupTabBar
 */
typedef struct _GroupTabBar {
	GroupTabBarSlot	*slots;
	GroupTabBarSlot	*revSlots;
	int		nSlots;

	GroupTabBarSlot	*hoveredSlot;
	GroupTabBarSlot *textSlot;

	GroupCairoLayer	*textLayer;
	GroupCairoLayer	*bgLayer;
	GroupCairoLayer	*selectionLayer;

	PaintState	state;
	int		timeoutHandle;
	int		animationTime;
	Region		region;
	
	//for DnD animations.
	int		leftSpringX, rightSpringX;
	int		leftSpeed, rightSpeed;
	float		leftMsSinceLastMove, rightMsSinceLastMove;
} GroupTabBar;

/*
 * GroupGlow
 */

typedef struct _GlowQuad {
	BoxRec box;
	CompMatrix matrix;
} GlowQuad;

#define GLOWQUAD_TOPLEFT	0
#define GLOWQUAD_TOPRIGHT	1
#define GLOWQUAD_BOTTOMLEFT	2
#define GLOWQUAD_BOTTOMRIGHT	3
#define GLOWQUAD_TOP		4
#define GLOWQUAD_BOTTOM		5
#define GLOWQUAD_LEFT		6
#define GLOWQUAD_RIGHT		7
#define NUM_GLOWQUADS		8

/*
 * GroupSelection
 */
typedef struct _GroupSelection GroupSelection;
struct _GroupSelection {
	GroupSelection *prev;
	GroupSelection *next;

	CompScreen *screen;
	CompWindow **windows;
	int nWins;

	GroupTabBarSlot* topTab;
	GroupTabBarSlot* prevTopTab;
	
	//Those two are only for the change-tab animation, when the tab was changed again during animation.
	//Another animation should be started again, switching for this window.
	ChangeTabAnimationDirection nextDirection;
	GroupTabBarSlot* nextTopTab;	
	
	GroupTabBarSlot* activateTab;

	GroupTabBar *tabBar;

	int changeAnimationTime;
	int changeAnimationDirection;
	PaintState changeState;
	Bool	changeTab;

	Bool doTabbing;
	PaintState tabbingState;

	GroupUngroupState ungroupState;

	Window grabWindow;
	unsigned int grabMask;

	int oldTopTabCenterX;
	int oldTopTabCenterY;

	Window inputPrevention;

	GLushort color[4];
};

/*
 * GroupDisplay structure
 */
typedef struct _GroupDisplay {
	int screenPrivateIndex;
	CompOption opt[GROUP_DISPLAY_OPTION_NUM];
	HandleEventProc handleEvent;

	GroupSelection tmpSel;
	Bool ignoreMode;
	
	CompTimeoutHandle timeoutHandle;
} GroupDisplay;

/*
 * GroupScreen structure
 */
typedef struct _GroupScreen {
	int windowPrivateIndex;
	CompOption opt[GROUP_SCREEN_OPTION_NUM];

	WindowMoveNotifyProc windowMoveNotify;
	WindowResizeNotifyProc windowResizeNotify;
	GetOutputExtentsForWindowProc getOutputExtentsForWindow;
	PreparePaintScreenProc preparePaintScreen;
	PaintScreenProc paintScreen;
	DrawWindowProc drawWindow;
	PaintWindowProc paintWindow;
	PaintTransformedScreenProc paintTransformedScreen;
	DonePaintScreenProc donePaintScreen;
	WindowGrabNotifyProc windowGrabNotify;
	WindowUngrabNotifyProc windowUngrabNotify;
	DamageWindowRectProc damageWindowRect;
	WindowStateChangeNotifyProc windowStateChangeNotify;
	GroupPendingMoves *pendingMoves;
	GroupPendingGrabs *pendingGrabs;
	GroupPendingUngrabs *pendingUngrabs;

	GroupSelection *groups;

	int wMask;
	Bool queued;
	Bool tabBarVisible;

	GlowTextureType glowType; 

	GroupScreenGrabState grabState;
	int grabIndex;

	// for selection
	Bool painted;
	int vpX, vpY;
	Bool isRotating;
	int x1;
	int y1;
	int x2;
	int y2;
	
	//For d&d
	GroupTabBarSlot	*draggedSlot;
	int dragHoverTimeoutHandle;
	Bool dragged;
	int prevX, prevY;	//buffer for mouse coordinates

	CompTexture glowTexture;
} GroupScreen;

/*
 * GroupWindow structure
 */
typedef struct _GroupWindow {
	GroupSelection *group;
	Bool inSelection;

	// for the tab bar
	GroupTabBarSlot *slot;
	int oldWindowState;

	// for resize notify...
	Bool needsPosSync;

	GlowQuad *glowQuads;

	GroupWindowState windowState;

	// for tab animation
	Bool ungroup;
	int animateState;
	XPoint mainTabOffset;
	XPoint destination;
	XPoint orgPos;
	float tx,ty;
	float xVelocity, yVelocity;

	int lastState;
} GroupWindow;

/*
 * Pre-Definitions
 *
 */

/*
 * options.c
 */
void groupDisplayInitOptions(GroupDisplay * gd);
CompOption *groupGetDisplayOptions(CompDisplay * d, int *count);
Bool groupSetDisplayOption(CompDisplay * d, char *name, CompOptionValue * value);
void groupScreenInitOptions(GroupScreen * gs);
CompOption *groupGetScreenOptions(CompScreen * s, int *count);
Bool groupSetScreenOption(CompScreen * s, char *name, CompOptionValue * value);

/*
 * group.c
 */
void groupGrabScreen(CompScreen * s, GroupScreenGrabState newState);
void groupHandleEvent(CompDisplay * d, XEvent * event);
Bool groupGroupWindows(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption);
Bool groupUnGroupWindows(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption);
int groupFindWindowIndex(CompWindow *w, GroupSelection *g);
void groupDeleteGroupWindow(CompWindow * w, Bool allowRegroup);
void groupDeleteGroup(GroupSelection *group);
void groupAddWindowToGroup(CompWindow * w, GroupSelection *group);
void groupSyncWindows(GroupSelection *group);
void groupRaiseWindows(CompWindow * top, GroupSelection *group);
Bool groupRemoveWindow(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption);
Bool groupCloseWindows(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption);
Bool groupChangeColor(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption);
Bool groupSetIgnore(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption);
Bool groupUnsetIgnore(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption);
void groupWindowResizeNotify(CompWindow * w, int dx, int dy, int dwidth, int dheight, Bool preview);
void groupWindowGrabNotify(CompWindow * w, int x, int y, unsigned int state, unsigned int mask);
void groupWindowUngrabNotify(CompWindow * w);
void groupWindowMoveNotify(CompWindow * w, int dx, int dy, Bool immediate);
void groupWindowStateChangeNotify(CompWindow *w);
void groupGetOutputExtentsForWindow(CompWindow * w, CompWindowExtents * output);

Bool groupDamageWindowRect(CompWindow * w, Bool initial, BoxPtr rect);

/*
 * tab.c
 */
void groupHandleChanges(CompScreen* s);
void groupHandleHoverDetection(GroupSelection *group);
void groupHandleTabBarFade(GroupSelection *group, int msSinceLastPaint);
void groupHandleTextFade(GroupSelection *group, int msSinceLastPaint);
void groupDrawTabAnimation(CompScreen * s, int msSinceLastPaint);
Bool groupUpdateTabBars(void* display);
void groupCheckForVisibleTabBars(CompScreen *s);
void groupGetDrawOffsetForSlot(GroupTabBarSlot *slot, int *hoffset, int *voffset);
void groupTabSetVisibility(GroupSelection *group, Bool visible, unsigned int mask);
Bool groupGetCurrentMousePosition(CompScreen *s, int *x, int *y);
void groupClearCairoLayer(GroupCairoLayer *layer);
void groupDestroyCairoLayer(CompScreen *s, GroupCairoLayer *layer);
GroupCairoLayer *groupRebuildCairoLayer(CompScreen *s, GroupCairoLayer *layer, int width, int height);
GroupCairoLayer *groupCreateCairoLayer(CompScreen *s, int width, int height);
void groupRecalcTabBarPos(GroupSelection *group, int middleX, int minX1, int maxX2);
void groupInsertTabBarSlotAfter(GroupTabBar *bar, GroupTabBarSlot *slot, GroupTabBarSlot *prevSlot);
void groupInsertTabBarSlotBefore(GroupTabBar *bar, GroupTabBarSlot *slot, GroupTabBarSlot *nextSlot);
void groupInsertTabBarSlot(GroupTabBar *bar, GroupTabBarSlot *slot);
void groupUnhookTabBarSlot(GroupTabBar *bar, GroupTabBarSlot *slot, Bool temporary);
void groupDeleteTabBarSlot(GroupTabBar *bar, GroupTabBarSlot *slot);
void groupCreateSlot(GroupSelection *group, CompWindow *w);
void groupApplyForces(CompScreen *s, GroupTabBar *bar, GroupTabBarSlot* draggedSlot);
void groupApplySpeeds(CompScreen* s, GroupTabBar* bar, int msSinceLastRepaint);
void groupInitTabBar(GroupSelection *group, CompWindow* topTab);
void groupDeleteTabBar(GroupSelection *group);
void groupStartTabbingAnimation(GroupSelection *group, Bool tab);
void groupTabGroup(CompWindow * main);
void groupUntabGroup(GroupSelection *group);
Bool groupInitTab(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption);
Bool groupChangeTab(GroupTabBarSlot* topTab, ChangeTabAnimationDirection direction);
Bool groupChangeTabLeft(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption);
Bool groupChangeTabRight(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption);
void groupUpdateInputPreventionWindow(GroupSelection* group);
void groupSwitchTopTabInput(GroupSelection *group, Bool enable);
void groupCreateInputPreventionWindow(GroupSelection* group); 
void groupDestroyInputPreventionWindow(GroupSelection* group); 
Region groupGetClippingRegion(CompWindow *w);

/*
 * paint.c
 */
void groupRecomputeGlow(CompScreen *s);
void groupComputeGlowQuads(CompWindow *w, CompMatrix *matrix);
void groupRenderTopTabHighlight(GroupSelection *group);
void groupRenderTabBarBackground(GroupSelection *group);
void groupRenderWindowTitle(GroupSelection *group);
void groupPaintThumb(GroupSelection *group, GroupTabBarSlot *slot, int targetOpacity);
void groupPaintTabBar(GroupSelection * group, const WindowPaintAttrib *wAttrib, Region clipRegion);
void groupPreparePaintScreen(CompScreen * s, int msSinceLastPaint);
Bool groupPaintScreen(CompScreen * s, const ScreenPaintAttrib * sAttrib, Region region, int output, unsigned int mask);
void groupPaintTransformedScreen(CompScreen * s, const ScreenPaintAttrib * sa, Region region, int output, unsigned int mask);
void groupDonePaintScreen(CompScreen * s);
Bool groupDrawWindow(CompWindow * w,	const WindowPaintAttrib * attrib, Region region, unsigned int mask);
Bool groupPaintWindow(CompWindow * w, const WindowPaintAttrib * attrib, Region region, unsigned int mask);

/*
 * init.c
 */
Bool groupInitDisplay(CompPlugin * p, CompDisplay * d);
void groupFiniDisplay(CompPlugin * p, CompDisplay * d);
Bool groupInitScreen(CompPlugin * p, CompScreen * s);
void groupFiniScreen(CompPlugin * p, CompScreen * s);
Bool groupInitWindow(CompPlugin * p, CompWindow * w);
void groupFiniWindow(CompPlugin * p, CompWindow * w);
Bool groupInit(CompPlugin * p);
void groupFini(CompPlugin * p);

/*
 * queues.c
 */
void groupEnqueueMoveNotify (CompWindow *w, int dx, int dy, Bool sync);
void groupDequeueMoveNotifies (CompScreen *s);
void groupEnqueueGrabNotify (CompWindow *w, int x, int y, unsigned int state, unsigned int mask);
void groupDequeueGrabNotifies (CompScreen *s);
void groupEnqueueUngrabNotify (CompWindow *w);
void groupDequeueUngrabNotifies (CompScreen *s);

/*
 * selection.c
 */
CompWindow **groupFindWindowsInRegion(CompScreen * s, Region reg, int *c);
void groupDeleteSelectionWindow(CompDisplay * d, CompWindow * w);
void groupAddWindowToSelection(CompDisplay * d, CompWindow * w);
void groupSelectWindow(CompDisplay * d, CompWindow * w);
Bool groupSelectSingle(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption);
Bool groupSelect(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption);
Bool groupSelectTerminate(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption);
void groupDamageSelectionRect(CompScreen* s, int xRoot, int yRoot);

/*
 * debug.c
 */
void groupDebugPrintMsg(char* msg, DebugLevel level);
void groupDebugPrintGroup(GroupSelection *group);
void groupDebugPrintScreen(GroupScreen *gs);
void groupDebugPrintWindow(GroupWindow *gw);
void groupDebugPrintTabBar(GroupTabBar *bar);
void groupDebugPrintTabBarSlot(GroupTabBarSlot *slot);

#endif


syntax highlighted by Code2HTML, v. 0.9.1