/**
*
* Compiz group plugin
*
* init.c
*
* Copyright : (C) 2006-2007 by Patrick Niklaus, Roi Cohen, Danny Baumann
* Authors: Patrick Niklaus <patrick.niklaus@googlemail.com>
* Roi Cohen <roico.beryl@gmail.com>
* Danny Baumann <maniac@opencompositing.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 "group-internal.h"
#include "group_glow.h"
int groupDisplayPrivateIndex;
static const GlowTextureProperties glowTextureProperties[2] = {
/* GlowTextureRectangular */
{glowTexRect, 32, 21},
/* GlowTextureRing */
{glowTexRing, 32, 16}
};
static void
groupScreenOptionChanged (CompScreen *s,
CompOption *opt,
GroupScreenOptions num)
{
GroupSelection *group;
GROUP_SCREEN (s);
switch (num)
{
case GroupScreenOptionTabBaseColor:
case GroupScreenOptionTabHighlightColor:
case GroupScreenOptionTabBorderColor:
case GroupScreenOptionTabStyle:
case GroupScreenOptionBorderRadius:
case GroupScreenOptionBorderWidth:
for (group = gs->groups; group; group = group->next)
if (group->tabBar)
groupRenderTabBarBackground (group);
break;
case GroupScreenOptionTabbarFontSize:
case GroupScreenOptionTabbarFontColor:
for (group = gs->groups; group; group = group->next)
groupRenderWindowTitle (group);
break;
case GroupScreenOptionThumbSize:
case GroupScreenOptionThumbSpace:
for (group = gs->groups; group; group = group->next)
if (group->tabBar)
groupRecalcTabBarPos (group,
(group->tabBar->region->extents.x1 +
group->tabBar->region->extents.x2) / 2,
group->tabBar->region->extents.x1,
group->tabBar->region->extents.x2);
break;
case GroupScreenOptionGlow:
case GroupScreenOptionGlowSize:
{
CompWindow *w;
groupRecomputeGlow (s);
for (w = s->windows; w; w = w->next)
{
GROUP_WINDOW (w);
if (gw->glowQuads)
{
damageWindowOutputExtents (w);
updateWindowOutputExtents (w);
damageWindowOutputExtents (w);
}
}
break;
}
case GroupScreenOptionGlowType:
{
GroupGlowTypeEnum glowType;
GROUP_DISPLAY (s->display);
glowType = groupGetGlowType (s);
finiTexture (s, &gs->glowTexture);
initTexture (s, &gs->glowTexture);
imageDataToTexture (s, &gs->glowTexture,
gd->glowTextureProperties[glowType].textureData,
gd->glowTextureProperties[glowType].textureSize,
gd->glowTextureProperties[glowType].textureSize,
GL_RGBA, GL_UNSIGNED_BYTE);
if (groupGetGlow (s) && gs->groups)
{
groupRecomputeGlow (s);
damageScreen (s);
}
break;
}
default:
break;
}
}
/*
* groupApplyInitialActions
*
* timer callback for stuff that needs to be called after all
* screens and windows are initialized
*
*/
static Bool
groupApplyInitialActions (void *closure)
{
CompScreen *s = (CompScreen *) closure;
CompWindow *w;
/* we need to do it from top to buttom of the stack to avoid problems
with a reload of Compiz and tabbed static groups. (topTab will always
be above the other windows in the group) */
for (w = s->reverseWindows; w; w = w->prev)
{
Bool tabbed;
long int id;
GLushort color[3];
GROUP_WINDOW (w);
/* read window property to see if window was grouped
before - if it was, regroup */
if (groupCheckWindowProperty (w, &id, &tabbed, color))
{
GroupSelection *group = groupFindGroupByID (w->screen, id);
groupAddWindowToGroup (w, group, id);
if (tabbed)
groupTabGroup (w);
gw->group->color[0] = color[0];
gw->group->color[1] = color[1];
gw->group->color[2] = color[2];
groupRenderTopTabHighlight (gw->group);
damageScreen (w->screen);
}
if (groupGetAutotabCreate (s) && groupIsGroupWindow (w))
{
if (!gw->group && (gw->windowState == WindowNormal))
{
groupAddWindowToGroup (w, NULL, 0);
groupTabGroup (w);
}
}
}
return FALSE;
}
/*
* groupInitDisplay
*
*/
static Bool
groupInitDisplay (CompPlugin *p,
CompDisplay *d)
{
GroupDisplay *gd;
gd = malloc (sizeof (GroupDisplay));
if (!gd)
return FALSE;
gd->screenPrivateIndex = allocateScreenPrivateIndex (d);
if (gd->screenPrivateIndex < 0)
{
free (gd);
return FALSE;
}
gd->glowTextureProperties =
(GlowTextureProperties*) glowTextureProperties;
gd->ignoreMode = FALSE;
gd->lastRestackedGroup = NULL;
gd->resizeInfo = NULL;
gd->groupWinPropertyAtom = XInternAtom (d->display,
"_COMPIZ_GROUP", 0);
gd->resizeNotifyAtom = XInternAtom (d->display,
"_COMPIZ_RESIZE_NOTIFY", 0);
WRAP (gd, d, handleEvent, groupHandleEvent);
groupSetSelectInitiate (d, groupSelect);
groupSetSelectTerminate (d, groupSelectTerminate);
groupSetSelectSingleInitiate (d, groupSelectSingle);
groupSetGroupInitiate (d, groupGroupWindows);
groupSetUngroupInitiate (d, groupUnGroupWindows);
groupSetTabmodeInitiate (d, groupInitTab);
groupSetChangeTabLeftInitiate (d, groupChangeTabLeft);
groupSetChangeTabRightInitiate (d, groupChangeTabRight);
groupSetRemoveInitiate (d, groupRemoveWindow);
groupSetCloseInitiate (d, groupCloseWindows);
groupSetIgnoreInitiate (d, groupSetIgnore);
groupSetIgnoreTerminate (d, groupUnsetIgnore);
groupSetChangeColorInitiate (d, groupChangeColor);
d->privates[groupDisplayPrivateIndex].ptr = gd;
srand (time (NULL));
return TRUE;
}
/*
* groupFiniDisplay
*
*/
static void
groupFiniDisplay (CompPlugin *p,
CompDisplay *d)
{
GROUP_DISPLAY (d);
freeScreenPrivateIndex (d, gd->screenPrivateIndex);
UNWRAP (gd, d, handleEvent);
free (gd);
}
/*
* groupInitScreen
*
*/
static Bool
groupInitScreen (CompPlugin *p,
CompScreen *s)
{
GroupScreen *gs;
GroupGlowTypeEnum glowType;
GROUP_DISPLAY (s->display);
gs = malloc (sizeof (GroupScreen));
if (!gs)
return FALSE;
gs->windowPrivateIndex = allocateWindowPrivateIndex (s);
if (gs->windowPrivateIndex < 0)
{
free (gs);
return FALSE;
}
WRAP (gs, s, windowMoveNotify, groupWindowMoveNotify);
WRAP (gs, s, windowResizeNotify, groupWindowResizeNotify);
WRAP (gs, s, getOutputExtentsForWindow, groupGetOutputExtentsForWindow);
WRAP (gs, s, preparePaintScreen, groupPreparePaintScreen);
WRAP (gs, s, paintOutput, groupPaintOutput);
WRAP (gs, s, drawWindow, groupDrawWindow);
WRAP (gs, s, paintWindow, groupPaintWindow);
WRAP (gs, s, paintTransformedOutput, groupPaintTransformedOutput);
WRAP (gs, s, donePaintScreen, groupDonePaintScreen);
WRAP (gs, s, windowGrabNotify, groupWindowGrabNotify);
WRAP (gs, s, windowUngrabNotify, groupWindowUngrabNotify);
WRAP (gs, s, damageWindowRect, groupDamageWindowRect);
WRAP (gs, s, windowStateChangeNotify, groupWindowStateChangeNotify);
s->privates[gd->screenPrivateIndex].ptr = gs;
groupSetTabHighlightColorNotify (s, groupScreenOptionChanged);
groupSetTabBaseColorNotify (s, groupScreenOptionChanged);
groupSetTabBorderColorNotify (s, groupScreenOptionChanged);
groupSetTabbarFontSizeNotify (s, groupScreenOptionChanged);
groupSetTabbarFontColorNotify (s, groupScreenOptionChanged);
groupSetGlowNotify (s, groupScreenOptionChanged);
groupSetGlowTypeNotify (s, groupScreenOptionChanged);
groupSetGlowSizeNotify (s, groupScreenOptionChanged);
groupSetTabStyleNotify (s, groupScreenOptionChanged);
groupSetThumbSizeNotify (s, groupScreenOptionChanged);
groupSetThumbSpaceNotify (s, groupScreenOptionChanged);
groupSetBorderWidthNotify (s, groupScreenOptionChanged);
groupSetBorderRadiusNotify (s, groupScreenOptionChanged);
gs->groups = NULL;
gs->tmpSel.windows = NULL;
gs->tmpSel.nWins = 0;
gs->grabIndex = 0;
gs->grabState = ScreenGrabNone;
gs->queued = FALSE;
gs->tabBarVisible = FALSE;
gs->lastHoveredGroup = NULL;
gs->pendingMoves = NULL;
gs->pendingGrabs = NULL;
gs->pendingUngrabs = NULL;
gs->dequeueTimerSet = FALSE;
gs->draggedSlot = NULL;
gs->dragged = FALSE;
gs->dragHoverTimeoutHandle = 0;
gs->prevX = 0;
gs->prevY = 0;
gs->showDelayTimeoutHandle = 0;
/* one-shot timeout for stuff that needs to be initialized after
all screens and windows are initialized */
compAddTimeout (0, groupApplyInitialActions, (void *) s);
initTexture (s, &gs->glowTexture);
glowType = groupGetGlowType (s);
imageDataToTexture (s, &gs->glowTexture,
glowTextureProperties[glowType].textureData,
glowTextureProperties[glowType].textureSize,
glowTextureProperties[glowType].textureSize,
GL_RGBA, GL_UNSIGNED_BYTE);
return TRUE;
}
/*
* groupFiniScreen
*
*/
static void
groupFiniScreen (CompPlugin *p,
CompScreen *s)
{
GROUP_SCREEN (s);
if (gs->groups)
{
GroupSelection *group, *nextGroup;
for (group = gs->groups; group;)
{
if (group->tabBar)
{
GroupTabBarSlot *slot, *nextSlot;
for (slot = group->tabBar->slots; slot;)
{
if (slot->region)
XDestroyRegion (slot->region);
nextSlot = slot->next;
free (slot);
slot = nextSlot;
}
groupDestroyCairoLayer (group->screen,
group->tabBar->textLayer);
groupDestroyCairoLayer (group->screen,
group->tabBar->bgLayer);
groupDestroyCairoLayer (group->screen,
group->tabBar->selectionLayer);
if (group->inputPrevention)
XDestroyWindow (s->display->display,
group->inputPrevention);
if (group->tabBar->region)
XDestroyRegion (group->tabBar->region);
free (group->tabBar);
}
nextGroup = group->next;
free (group);
group = nextGroup;
}
}
if (gs->tmpSel.windows)
free (gs->tmpSel.windows);
freeWindowPrivateIndex (s, gs->windowPrivateIndex);
UNWRAP (gs, s, windowMoveNotify);
UNWRAP (gs, s, windowResizeNotify);
UNWRAP (gs, s, getOutputExtentsForWindow);
UNWRAP (gs, s, preparePaintScreen);
UNWRAP (gs, s, paintOutput);
UNWRAP (gs, s, drawWindow);
UNWRAP (gs, s, paintWindow);
UNWRAP (gs, s, paintTransformedOutput);
UNWRAP (gs, s, donePaintScreen);
UNWRAP (gs, s, windowGrabNotify);
UNWRAP (gs, s, windowUngrabNotify);
UNWRAP (gs, s, damageWindowRect);
UNWRAP (gs, s, windowStateChangeNotify);
finiTexture (s, &gs->glowTexture);
free (gs);
}
/*
* groupInitWindow
*
*/
static Bool groupInitWindow(CompPlugin * p, CompWindow * w)
{
GroupWindow *gw;
GROUP_SCREEN (w->screen);
gw = malloc (sizeof (GroupWindow));
if (!gw)
return FALSE;
gw->group = NULL;
gw->inSelection = FALSE;
gw->needsPosSync = FALSE;
/* for tab */
gw->animateState = 0;
gw->ungroup = FALSE;
gw->slot = NULL;
gw->tx = gw->ty = 0;
gw->xVelocity = gw->yVelocity = 0;
gw->orgPos.x = 0;
gw->orgPos.y = 0;
gw->mainTabOffset.x = 0;
gw->mainTabOffset.y = 0;
gw->destination.x = 0;
gw->destination.y = 0;
gw->windowHideInfo = NULL;
gw->resizeGeometry = NULL;
if (w->minimized)
gw->windowState = WindowMinimized;
else if (w->shaded)
gw->windowState = WindowShaded;
else
gw->windowState = WindowNormal;
w->privates[gs->windowPrivateIndex].ptr = gw;
gw->glowQuads = NULL;
groupComputeGlowQuads (w, &gs->glowTexture.matrix);
return TRUE;
}
/*
* groupFiniWindow
*
*/
static void
groupFiniWindow (CompPlugin *p,
CompWindow *w)
{
GROUP_WINDOW(w);
if (gw->windowHideInfo)
groupSetWindowVisibility (w, TRUE);
if (gw->glowQuads)
free (gw->glowQuads);
free (gw);
}
/*
* groupInit
*
*/
static Bool
groupInit (CompPlugin *p)
{
groupDisplayPrivateIndex = allocateDisplayPrivateIndex ();
if (groupDisplayPrivateIndex < 0)
return FALSE;
return TRUE;
}
/*
* groupFini
*
*/
static void
groupFini (CompPlugin *p)
{
freeDisplayPrivateIndex (groupDisplayPrivateIndex);
}
static int
groupGetVersion (CompPlugin *plugin,
int version)
{
return ABIVERSION;
}
/*
* groupVTable
*
*/
CompPluginVTable groupVTable = {
"group",
groupGetVersion,
0,
groupInit,
groupFini,
groupInitDisplay,
groupFiniDisplay,
groupInitScreen,
groupFiniScreen,
groupInitWindow,
groupFiniWindow,
0,
0,
0,
0
};
/*
* getCompPluginInfo
*
*/
CompPluginVTable*
getCompPluginInfo (void)
{
return &groupVTable;
}
syntax highlighted by Code2HTML, v. 0.9.1