rendered paste body/**
*
* Beryl pager plugin
*
* pager.c
*
* Copyright (c) 2007 Atie H. <atie.at.matrix@gmail.com>
*
*
* 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.
*
**/
/*
Pager Features:
- pager by hsize * vsize
- pager orientation
- toggle to display pager - default super+alt+p
Pager TODO:
- draggable pager?
- size option for pager / resize w/ mouse if possible
- repaint pager when hsize or vsize updated
- manipulate vsize if =1 by dividing hsize(>=4) so 4x1 becomes 2x2
- perspective view of pager
- miniview of viewports
- switch viewport by click / swap viewport by drag-out : wall's job?
- animation for toggle pager ?
- animation for switch/swap viewport
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <beryl.h>
#include <cairo-xlib-xrender.h>
#include <cairo.h>
#define PI 3.14159265359f
#define PAGER_TOGGLE_KEY_DEFAULT "p"
#define PAGER_TOGGLE_MODIFIERS_DEFAULT (CompAltMask | CompSuperMask)
static int displayPrivateIndex;
enum {
PAGER_DISPLAY_OPTION_TOGGLE,
PAGER_DISPLAY_OPTION_WIDTH,
PAGER_DISPLAY_OPTION_HEIGHT,
PAGER_DISPLAY_OPTION_GRAVITY,
PAGER_DISPLAY_OPTION_OFFSET,
PAGER_DISPLAY_OPTION_NUM
};
typedef enum _PagerGravity
{
PagerGravityNorthWest = 0,
PagerGravityNorthEast,
PagerGravitySouthEast,
PagerGravitySouthWest,
PagerGravityNum
} PagerGravity;
#define PAGER_GRAVITY_DEFAULT PagerGravitySouthEast
static char *pagerGravities[] = {
N_("NorthWest"),
N_("NorthEast"),
N_("SouthEast"),
N_("SouthWest")
};
#define PAGER_GRAVITY_OFFSET_DEFAULT 5
#define PAGER_GRAVITY_OFFSET_MIN 0
#define PAGER_GRAVITY_OFFSET_MAX 50
#define PAGER_WIDTH_DEFAULT 300
#define PAGER_WIDTH_MIN 50
#define PAGER_WIDTH_MAX 500
#define PAGER_HEIGHT_DEFAULT 200
#define PAGER_HEIGHT_MIN 50
#define PAGER_HEIGHT_MAX 500
typedef struct _PagerCairoContext
{
Pixmap pixmap;
CompTexture texture;
cairo_surface_t *surface;
cairo_t *cr;
int width;
int height;
} PagerCairoContext;
typedef struct _PagerDisplay
{
int screenPrivateIndex;
HandleEventProc handleEvent;
Bool togglePager;
int pagerGravity;
int offset;
int pagerWidth;
int pagerHeight;
CompOption opt[PAGER_DISPLAY_OPTION_NUM];
} PagerDisplay;
typedef struct _PagerScreen
{
DonePaintScreenProc donePaintScreen;
PaintScreenProc paintScreen;
PreparePaintScreenProc preparePaintScreen;
PaintTransformedScreenProc paintTransformedScreen;
float firstViewportX;
float firstViewportY;
float viewportWidth;
float viewportHeight;
float viewportBorder;
WindowPaintAttrib mSAttribs;
float mSzCamera;
PagerCairoContext *pagerContext;
PagerCairoContext *thumbContext;
} PagerScreen;
/* Helpers */
#define GET_PAGER_DISPLAY(d) \
((PagerDisplay *) (d)->privates[displayPrivateIndex].ptr)
#define PAGER_DISPLAY(d) \
PagerDisplay *pd = GET_PAGER_DISPLAY(d);
#define GET_PAGER_SCREEN(s, pd) \
((PagerScreen *) (s)->privates[(pd)->screenPrivateIndex].ptr)
#define PAGER_SCREEN(s) \
PagerScreen *ps = GET_PAGER_SCREEN(s, GET_PAGER_DISPLAY(s->display));
#define NUM_OPTIONS(d) (sizeof ((d)->opt) / sizeof (CompOption))
static void pagerDrawPager(CompScreen *s)
{
PAGER_SCREEN(s);
cairo_t * cr = ps->pagerContext->cr;
cairo_save(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
cairo_paint(cr);
cairo_restore(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_save(cr);
int hsize = s->hsize;
int vsize = s->vsize;
float border = 10.0f;
float outline = 2.0f;
float width = (float) ps->pagerContext->width;
width -= outline;
float height = (float) ps->pagerContext->height;
height -= outline;
cairo_pattern_t *pattern;
cairo_translate(cr, outline/2.0f, outline/2.0f);
// set the pattern for the pager's background
pattern = cairo_pattern_create_linear(0, 0, width, height);
cairo_pattern_add_color_stop_rgba(pattern, 0.0f, 0.80, 0.80, 0.90 ,0.85);
cairo_pattern_add_color_stop_rgba(pattern, 0.65f, 0.95, 0.95, 1.0f, 0.85);
cairo_pattern_add_color_stop_rgba(pattern, 0.85f, 0.85, 0.85, 0.85 ,0.85);
cairo_set_source(cr, pattern);
// draw the border's shape
cairo_arc(cr, border, border, border, PI, 1.5f*PI);
cairo_arc(cr, border+width-2*border, border, border, 1.5f*PI, 2.0*PI);
cairo_arc(cr, width-border, height-border, border, 0, PI/2.0f);
cairo_arc(cr, border, height-border, border, PI/2.0f, PI);
cairo_close_path(cr);
// apply pattern to pager
cairo_fill_preserve(cr);
// draw an outline
cairo_set_line_width(cr, outline);
cairo_set_source_rgba(cr, 0.2,0.2,0.2,0.85);
cairo_stroke(cr);
cairo_pattern_destroy(pattern);
float viewportWidth = floor((width - border*(s->hsize+1))/hsize);
float viewportHeight = floor((height - border*(s->vsize+1))/vsize);
ps->viewportWidth = viewportWidth;
ps->viewportHeight = viewportHeight;
ps->viewportBorder = border;
cairo_translate(cr, border, border);
int i, j;
float vpX, vpY;
for (i = 0; i < hsize; i++)
{
for (j = 0; j < vsize; j++)
{
vpX = i*(viewportWidth+border);
vpY = j*(viewportHeight+border);
// this cuts a hole into our background
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
cairo_rectangle(cr, vpX, vpY, viewportWidth, viewportHeight);
cairo_fill_preserve(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_XOR);
cairo_fill(cr);
}
}
cairo_restore(cr);
}
static void pagerDrawThumb(CompScreen *s)
{
PAGER_SCREEN(s);
cairo_t * cr = ps->thumbContext->cr;
cairo_save(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
cairo_paint(cr);
cairo_restore(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_save(cr);
float border = 10.0f;
float outline = 2.0f;
float width = (float) ps->thumbContext->width;
float height = (float) ps->thumbContext->height;
ps->viewportWidth = width;
ps->viewportHeight = height;
ps->viewportBorder = border;
width -= outline;
height -= outline;
cairo_translate(cr, outline/2.0f, outline/2.0f);
cairo_pattern_t *pattern;
pattern = cairo_pattern_create_linear(0, 0, width, height);
cairo_pattern_add_color_stop_rgba(pattern, 0.0f, 0.2, 0.2, 0.2 ,0.35);
cairo_pattern_add_color_stop_rgba(pattern, 1.0f, 0.25, 0.25, 0.25, 0.25);
// apply the patter for thumb background
cairo_set_source(cr, pattern);
cairo_rectangle(cr, 0, 0, width, height);
cairo_fill_preserve(cr);
cairo_set_line_width(cr, outline);
cairo_set_source_rgba(cr, 0.2, 0.2, 0.2, 0.65);
cairo_stroke(cr);
cairo_pattern_destroy(pattern);
cairo_restore(cr);
}
static void pagerSetupCairoContext(CompScreen *s, PagerCairoContext *context)
{
XRenderPictFormat * format;
Screen * screen;
screen = ScreenOfDisplay(s->display->display, s->screenNum);
int width, height;
width = context->width;
height = context->height;
initTexture(s, &context->texture);
format = XRenderFindStandardFormat(s->display->display,
PictStandardARGB32);
context->pixmap = XCreatePixmap(s->display->display, s->root,
width, height, 32);
if (!bindPixmapToTexture(s, &context->texture, context->pixmap,
width, height, 32))
printf("Couldn't create cairo context for pager\n");
context->surface =
cairo_xlib_surface_create_with_xrender_format(s->display->display,
context->pixmap,
screen, format,
width, height);
context->cr = cairo_create(context->surface);
cairo_t *cr = context->cr;
cairo_save(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
cairo_paint(cr);
cairo_restore(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
}
static void pagerDestroyCairoContext(CompScreen *s, PagerCairoContext *context)
{
if (context->cr)
cairo_destroy(context->cr);
if (context->surface)
cairo_surface_destroy(context->surface);
finiTexture(s, &context->texture);
if (context->pixmap)
XFreePixmap(s->display->display, context->pixmap);
}
static void pagerDrawCairoTextureOnScreen(CompScreen *s,
int output, Region region)
{
PAGER_SCREEN(s);
PAGER_DISPLAY(s->display);
glPushMatrix();
prepareXCoords(s, output, -DEFAULT_Z_CAMERA);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_BLEND);
float border = 10.0f;
float width = (float) ps->pagerContext->width;
float height = (float) ps->pagerContext->height;
float topleftx = 0;
float toplefty = 0;
//?FIXME somehow need to read display options here again
pd->offset = pd->opt[PAGER_DISPLAY_OPTION_OFFSET].value.i;
pd->pagerWidth = pd->opt[PAGER_DISPLAY_OPTION_WIDTH].value.i;
pd->pagerHeight = pd->opt[PAGER_DISPLAY_OPTION_HEIGHT].value.i;
//FIXME, gravity doesn't the value from settings at init
pd->pagerGravity = PagerGravitySouthEast;
switch (pd->pagerGravity)
{
case PagerGravityNorthWest:
topleftx = pd->offset;
toplefty = pd->offset;
break;
case PagerGravityNorthEast:
topleftx = s->width - pd->pagerWidth - pd->offset;
toplefty = pd->offset;
break;
case PagerGravitySouthEast:
topleftx = s->width - pd->pagerWidth - pd->offset;
toplefty = s->height - pd->pagerHeight - pd->offset;
break;
case PagerGravitySouthWest:
topleftx = pd->offset;
toplefty = s->height - pd->pagerHeight - pd->offset;
break;
default:
break;
}
//draw pager
enableTexture(s, &ps->pagerContext->texture, COMP_TEXTURE_FILTER_GOOD);
CompMatrix matrix = ps->pagerContext->texture.matrix;
matrix.x0 -= topleftx * matrix.xx;
matrix.y0 -= toplefty * matrix.yy;
BOX box;
box.x1 = topleftx;
box.x2 = box.x1 + width;
box.y1 = toplefty;
box.y2 = box.y1 + height;
glBegin(GL_QUADS);
glTexCoord2f(COMP_TEX_COORD_X(&matrix, box.x1), COMP_TEX_COORD_Y(&matrix, box.y2));
glVertex2i(box.x1, box.y2);
glTexCoord2f(COMP_TEX_COORD_X(&matrix, box.x2), COMP_TEX_COORD_Y(&matrix, box.y2));
glVertex2i(box.x2, box.y2);
glTexCoord2f(COMP_TEX_COORD_X(&matrix, box.x2), COMP_TEX_COORD_Y(&matrix, box.y1));
glVertex2i(box.x2, box.y1);
glTexCoord2f(COMP_TEX_COORD_X(&matrix, box.x1), COMP_TEX_COORD_Y(&matrix, box.y1));
glVertex2i(box.x1, box.y1);
glEnd();
disableTexture(s, &ps->pagerContext->texture);
//draw thumb
width = (float) ps->thumbContext->width;
height = (float) ps->thumbContext->height;
int i,j;
enableTexture(s, &ps->thumbContext->texture, COMP_TEXTURE_FILTER_GOOD);
glBegin(GL_QUADS);
for (i = 0; i < s->hsize; i++)
{
for (j = 0; j < s->vsize; j++)
{
box.x1 = i*(width+border);
box.x1 += topleftx + border;
box.x2 = box.x1 + width;
box.y1 = j*(height+border);
box.y1 += toplefty + border;
box.y2 = box.y1 + height;
matrix = ps->thumbContext->texture.matrix;
matrix.x0 -= box.x1 * matrix.xx;
matrix.y0 -= box.y1 * matrix.yy;
glTexCoord2f(COMP_TEX_COORD_X(&matrix, box.x1), COMP_TEX_COORD_Y(&matrix, box.y2));
glVertex2i(box.x1, box.y2);
glTexCoord2f(COMP_TEX_COORD_X(&matrix, box.x2), COMP_TEX_COORD_Y(&matrix, box.y2));
glVertex2i(box.x2, box.y2);
glTexCoord2f(COMP_TEX_COORD_X(&matrix, box.x2), COMP_TEX_COORD_Y(&matrix, box.y1));
glVertex2i(box.x2, box.y1);
glTexCoord2f(COMP_TEX_COORD_X(&matrix, box.x1), COMP_TEX_COORD_Y(&matrix, box.y1));
glVertex2i(box.x1, box.y1);
}
}
glEnd();
disableTexture(s, &ps->thumbContext->texture);
glDisable(GL_BLEND);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();
screenTexEnvMode(s, GL_REPLACE);
glColor4usv(defaultColor);
}
static Bool pagerPaintScreen(CompScreen *s,
const ScreenPaintAttrib * sAttrib,
const CompTransform *transform,
Region region, int output, unsigned int mask)
{
Bool status;
PAGER_SCREEN(s);
PAGER_DISPLAY(s->display);
UNWRAP(ps, s, paintScreen);
status = (*s->paintScreen) (s, sAttrib, transform, region, output, mask);
WRAP(ps, s, paintScreen, pagerPaintScreen);
if (pd->togglePager)
{
pagerDrawCairoTextureOnScreen(s, output, region);
int i,j;
int origVX = s->x;
int origVY = s->y;
moveScreenViewport(s, s->x, s->y, FALSE);
for (j = 0; j < s->vsize; j++)
{
for (i = 0; i < s->hsize; i++)
{
float mx = ps->firstViewportX +
(i * (ps->viewportWidth + ps->viewportBorder));
float my = ps->firstViewportY +
(i * (ps->viewportHeight + ps->viewportBorder));
float mw = ps->viewportWidth;
float mh = ps->viewportHeight;
ps->mSAttribs.xTranslate = mx / s->outputDev[output].width;
ps->mSAttribs.yTranslate = -my / s->outputDev[output].height;
ps->mSAttribs.xScale = mw / s->width;
ps->mSAttribs.yScale = mh / s->height;
/* FIXME
(*s->paintTransformedScreen) (s, sAttrib, transform, region,
output, mask | PAINT_SCREEN_TRANSFORMED_MASK);
*/
moveScreenViewport(s, -1, 0, FALSE);
}
moveScreenViewport(s, 0, -1, FALSE);
}
moveScreenViewport(s, -origVX, -origVY, FALSE);
}
return status;
}
static void pagerPaintTransformedScreen(CompScreen * s,
const ScreenPaintAttrib * sAttrib,
const CompTransform *transform,
Region region, int output, unsigned int mask)
{
PAGER_SCREEN(s);
CompTransform sTransform = *transform;
//move each screen to the correct output position
matrixTranslate(&sTransform, -s->outputDev[output].region.extents.x1 /
s->outputDev[output].width,
s->outputDev[output].region.extents.y1 /
s->outputDev[output].height, 0.0f);
matrixTranslate(&sTransform, 0.0f, 0.0f, -DEFAULT_Z_CAMERA);
matrixTranslate(&sTransform, ps->mSAttribs.xTranslate, ps->mSAttribs.yTranslate, ps->mSzCamera);
// move orgin to top left
matrixTranslate(&sTransform, -0.5f, 0.5f, 0.0f);
matrixScale(&sTransform, ps->mSAttribs.xScale, ps->mSAttribs.yScale, 1.0);
// revert prepareXCoords region shift. Now all screens display the same
matrixTranslate(&sTransform, 0.5f, 0.5f, DEFAULT_Z_CAMERA);
matrixTranslate(&sTransform, s->outputDev[output].region.extents.x1 /
s->outputDev[output].width,
-s->outputDev[output].region.extents.y2 /
s->outputDev[output].height, 0.0f);
UNWRAP(ps, s, paintTransformedScreen);
(*s->paintTransformedScreen) (s, sAttrib, &sTransform, &s->region, output, mask);
WRAP(ps, s, paintTransformedScreen, pagerPaintTransformedScreen);
}
static void pagerHandleEvent(CompDisplay * d, XEvent * event)
{
PAGER_DISPLAY(d);
UNWRAP(pd, d, handleEvent);
(*d->handleEvent) (d, event);
WRAP(pd, d, handleEvent, pagerHandleEvent);
}
static Bool pagerToggle(CompDisplay * d, CompAction * action,
CompActionState state, CompOption * option, int nOption)
{
CompScreen *s;
Window xid;
PAGER_DISPLAY(d);
pd->togglePager = !pd->togglePager;
xid = getIntOptionNamed(option, nOption, "root", 0);
s = findScreenAtDisplay(d, xid);
damageScreen(s);
return TRUE;
}
static void pagerDisplayInitOptions(PagerDisplay *pd)
{
CompOption *o;
o = &pd->opt[PAGER_DISPLAY_OPTION_TOGGLE];
o->advanced = False;
o->name = "toggle_display";
o->group = N_("Bindings");
o->subGroup = N_("");
o->displayHints = "";
o->shortDesc = N_("Toggle Pager");
o->longDesc = N_("Toggle to display pager.");
o->type = CompOptionTypeAction;
o->value.action.initiate = pagerToggle;
o->value.action.terminate = 0;
o->value.action.bell = 0;
o->value.action.edgeMask = 0;
o->value.action.state = CompActionStateInitKey;
o->value.action.type = CompBindingTypeKey;
o->value.action.key.modifiers = PAGER_TOGGLE_MODIFIERS_DEFAULT;
o->value.action.key.keysym = XStringToKeysym(PAGER_TOGGLE_KEY_DEFAULT);
o = &pd->opt[PAGER_DISPLAY_OPTION_WIDTH];
o->advanced = False;
o->name = "pager_width";
o->group = N_("Pager");
o->subGroup = N_("");
o->displayHints = "";
o->shortDesc = N_("Pager Width");
o->longDesc = N_("Pager Width.");
o->type = CompOptionTypeInt;
o->value.i = PAGER_WIDTH_DEFAULT;
o->rest.i.min = PAGER_WIDTH_MIN;
o->rest.i.max = PAGER_WIDTH_MAX;
o = &pd->opt[PAGER_DISPLAY_OPTION_HEIGHT];
o->advanced = False;
o->name = "pager_height";
o->group = N_("Pager");
o->subGroup = N_("");
o->displayHints = "";
o->shortDesc = N_("Pager Height");
o->longDesc = N_("Pager Height.");
o->type = CompOptionTypeInt;
o->value.i = PAGER_HEIGHT_DEFAULT;
o->rest.i.min = PAGER_HEIGHT_MIN;
o->rest.i.max = PAGER_HEIGHT_MAX;
o = &pd->opt[PAGER_DISPLAY_OPTION_GRAVITY];
o->advanced = False;
o->name = "pager_gravity";
o->group = N_("Pager");
o->subGroup = N_("");
o->displayHints = "";
o->shortDesc = N_("Pager Gravity");
o->longDesc = N_("Orientation of pager.");
o->type = CompOptionTypeString;
o->value.s = strdup(pagerGravities[PAGER_GRAVITY_DEFAULT]);
o->rest.s.string = pagerGravities;
o->rest.s.nString = PagerGravityNum;
o = &pd->opt[PAGER_DISPLAY_OPTION_OFFSET];
o->advanced = False;
o->name = "offset";
o->group = N_("Pager");
o->subGroup = N_("");
o->displayHints = "";
o->shortDesc = N_("Offset");
o->longDesc = N_("Offset from corner.");
o->type = CompOptionTypeInt;
o->value.i = PAGER_GRAVITY_OFFSET_DEFAULT;
o->rest.i.min = PAGER_GRAVITY_OFFSET_MIN;
o->rest.i.max = PAGER_GRAVITY_OFFSET_MAX;
}
static CompOption *pagerGetDisplayOptions(CompDisplay * d, int *count)
{
if (d)
{
PAGER_DISPLAY(d);
*count = NUM_OPTIONS(pd);
return pd->opt;
}
else
{
PagerDisplay *pd = malloc(sizeof(PagerDisplay));
pagerDisplayInitOptions(pd);
*count = NUM_OPTIONS(pd);
return pd->opt;
}
}
static Bool
pagerSetDisplayOption(CompDisplay *d, char *name, CompOptionValue *value)
{
CompOption *o;
int index;
PAGER_DISPLAY(d);
o = compFindOption(pd->opt, NUM_OPTIONS(pd), name, &index);
if (!o)
return FALSE;
switch (index)
{
case PAGER_DISPLAY_OPTION_TOGGLE:
if (setDisplayAction(d, o, value))
return TRUE;
break;
case PAGER_DISPLAY_OPTION_WIDTH:
if (compSetIntOption(o, value))
{
pd->pagerWidth = o->value.i;
return TRUE;
}
break;
case PAGER_DISPLAY_OPTION_HEIGHT:
if (compSetIntOption(o, value))
{
pd->pagerHeight = o->value.i;
return TRUE;
}
break;
case PAGER_DISPLAY_OPTION_GRAVITY:
if (compSetStringOption(o, value))
{
int i;
for (i = 0; i < PagerGravityNum; i++)
{
if (strcmp(o->value.s, pagerGravities[i]) == 0)
{
pd->pagerGravity = i;
return TRUE;
}
}
}
break;
case PAGER_DISPLAY_OPTION_OFFSET:
if (compSetIntOption(o, value))
{
pd->offset = o->value.i;
return TRUE;
}
break;
default:
break;
}
return FALSE;
}
static Bool pagerInitScreen(CompPlugin * p, CompScreen * s)
{
PagerScreen *ps;
PAGER_DISPLAY(s->display);
ps = malloc(sizeof(PagerScreen));
if (!ps)
return FALSE;
addScreenAction(s, &pd->opt[PAGER_DISPLAY_OPTION_TOGGLE].value.action);
WRAP(ps, s, paintScreen, pagerPaintScreen);
s->privates[pd->screenPrivateIndex].ptr = ps;
ps->viewportWidth = 0.0f;
ps->viewportHeight = 0.0f;
ps->viewportBorder = 0.0f;
ps->pagerContext = (PagerCairoContext*) malloc(sizeof(PagerCairoContext));
ps->pagerContext->width = pd->opt[PAGER_DISPLAY_OPTION_WIDTH].value.i;
ps->pagerContext->height = pd->opt[PAGER_DISPLAY_OPTION_HEIGHT].value.i;
pagerSetupCairoContext(s, ps->pagerContext);
pagerDrawPager(s);
float border = 10.0f;
ps->thumbContext = (PagerCairoContext*) malloc(sizeof(PagerCairoContext));
ps->thumbContext->width = (int) (pd->opt[PAGER_DISPLAY_OPTION_WIDTH].value.i -
border*(s->hsize+1)) / s->hsize;
ps->thumbContext->height = (int) (pd->opt[PAGER_DISPLAY_OPTION_HEIGHT].value.i -
border*(s->vsize+1)) / s->vsize;
pagerSetupCairoContext(s, ps->thumbContext);
pagerDrawThumb(s);
return TRUE;
}
static void pagerFiniScreen(CompPlugin * p, CompScreen * s)
{
PAGER_SCREEN(s);
PAGER_DISPLAY(s->display);
pagerDestroyCairoContext(s, ps->pagerContext);
pagerDestroyCairoContext(s, ps->thumbContext);
removeScreenAction(s, &pd->opt[PAGER_DISPLAY_OPTION_TOGGLE].value.action);
UNWRAP(ps, s, paintScreen);
free(ps);
}
static Bool pagerInitDisplay(CompPlugin * p, CompDisplay * d)
{
PagerDisplay *pd;
pd = malloc(sizeof(PagerDisplay));
if (!pd)
return FALSE;
pd->screenPrivateIndex = allocateScreenPrivateIndex(d);
if (pd->screenPrivateIndex < 0)
{
free(pd);
return FALSE;
}
pagerDisplayInitOptions(pd);
pd->togglePager = TRUE;
WRAP(pd, d, handleEvent, pagerHandleEvent);
d->privates[displayPrivateIndex].ptr = pd;
return TRUE;
}
static void pagerFiniDisplay(CompPlugin * p, CompDisplay * d)
{
PAGER_DISPLAY(d);
UNWRAP(pd, d, handleEvent);
freeScreenPrivateIndex(d, pd->screenPrivateIndex);
free(pd);
}
static Bool pagerInit(CompPlugin * p)
{
displayPrivateIndex = allocateDisplayPrivateIndex();
if (displayPrivateIndex < 0)
return FALSE;
return TRUE;
}
static void pagerFini(CompPlugin * p)
{
if (displayPrivateIndex >= 0)
freeDisplayPrivateIndex(displayPrivateIndex);
}
CompPluginVTable pagerVTable = {
"pager",
N_("Pager"),
N_("Beryl pager plugin"),
pagerInit,
pagerFini,
pagerInitDisplay,
pagerFiniDisplay,
pagerInitScreen,
pagerFiniScreen,
0, /* pagerInitWindow */
0, /* pagerFiniWindow */
pagerGetDisplayOptions,
pagerSetDisplayOption,
0, /* pagerGetScreenOptions */
0, /* pagerSetScreenOption */
0, /* updateLibraryFunction */
0, /* deps */
0, /* nDeps */
0, /* features */
0, /* nFeatures */
BERYL_ABI_INFO,
"beryl-plugins-unsupported", /* gettext domain */
"desktop", /* category */
0, /* groupDesc */
0, /*nGroupDesc */
False, /* defaultEnabled */
};
CompPluginVTable *getCompPluginInfo(void)
{
return &pagerVTable;
}