/* * Copyright © 2005 Novell, Inc. * * 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. * * Author: David Reveman */ #include #include #include #include #include #include #define ZOOM_POINTER_INVERT_Y_DEFAULT FALSE #define ZOOM_POINTER_SENSITIVITY_DEFAULT 1.0f #define ZOOM_POINTER_SENSITIVITY_MIN 0.01f #define ZOOM_POINTER_SENSITIVITY_MAX 100.0f #define ZOOM_POINTER_SENSITIVITY_PRECISION 0.01f #define ZOOM_POINTER_SENSITIVITY_FACTOR 0.001f #define ZOOM_INITIATE_BUTTON_DEFAULT Button3 #define ZOOM_INITIATE_MODIFIERS_DEFAULT CompSuperMask #define ZOOM_IN_BUTTON_DEFAULT Button4 #define ZOOM_IN_MODIFIERS_DEFAULT CompSuperMask #define ZOOM_OUT_BUTTON_DEFAULT Button5 #define ZOOM_OUT_MODIFIERS_DEFAULT CompSuperMask #define ZOOM_SPEED_DEFAULT 1.5f #define ZOOM_SPEED_MIN 0.1f #define ZOOM_SPEED_MAX 50.0f #define ZOOM_SPEED_PRECISION 0.1f #define ZOOM_STEP_DEFAULT 2.0f #define ZOOM_STEP_MIN 1.0f #define ZOOM_STEP_MAX 5.0f #define ZOOM_STEP_PRECISION 0.01f #define ZOOM_MIN_DEFAULT 0.1f #define ZOOM_MIN_MIN 0.0f #define ZOOM_MIN_MAX 1.0f #define ZOOM_MIN_PRECISION 0.01f #define ZOOM_MAX_DEFAULT 1.0f #define ZOOM_MAX_MIN 1.0f #define ZOOM_MAX_MAX 100.0f #define ZOOM_MAX_PRECISION 0.01f #define ZOOM_TIMESTEP_DEFAULT 1.2f #define ZOOM_TIMESTEP_MIN 0.1f #define ZOOM_TIMESTEP_MAX 50.0f #define ZOOM_TIMESTEP_PRECISION 0.1f #define ZOOM_FILTER_LINEAR_DEFAULT TRUE #define ZOOM_ALLOW_KEYBOARD_INPUT_DEFAULT TRUE static int displayPrivateIndex; #define ZOOM_DISPLAY_OPTION_INITIATE 0 #define ZOOM_DISPLAY_OPTION_IN 1 #define ZOOM_DISPLAY_OPTION_OUT 2 #define ZOOM_DISPLAY_OPTION_NUM 3 typedef struct _ZoomDisplay { int screenPrivateIndex; HandleEventProc handleEvent; CompOption opt[ZOOM_DISPLAY_OPTION_NUM]; } ZoomDisplay; #define ZOOM_SCREEN_OPTION_POINTER_INVERT_Y 0 #define ZOOM_SCREEN_OPTION_POINTER_SENSITIVITY 1 #define ZOOM_SCREEN_OPTION_SPEED 2 #define ZOOM_SCREEN_OPTION_STEP 3 #define ZOOM_SCREEN_OPTION_MIN 4 #define ZOOM_SCREEN_OPTION_MAX 5 #define ZOOM_SCREEN_OPTION_TIMESTEP 6 #define ZOOM_SCREEN_OPTION_FILTER_LINEAR 7 #define ZOOM_SCREEN_OPTION_ALLOW_KEYBOARD_INPUT 8 #define ZOOM_SCREEN_OPTION_NUM 9 typedef struct _ZoomScreen { PreparePaintScreenProc preparePaintScreen; DonePaintScreenProc donePaintScreen; PaintScreenProc paintScreen; SetScreenOptionForPluginProc setScreenOptionForPlugin; CompOption opt[ZOOM_SCREEN_OPTION_NUM]; Bool pointerInvertY; float pointerSensitivity; float speed; float step; float timestep; float minZoom; float maxZoom; int grabIndex; GLfloat currentZoom; GLfloat newZoom; GLfloat xVelocity; GLfloat yVelocity; GLfloat zVelocity; GLfloat xTranslate; GLfloat yTranslate; GLfloat xtrans; GLfloat ytrans; GLfloat ztrans; XPoint savedPointer; Bool grabbed; float maxTranslate; } ZoomScreen; #define GET_ZOOM_DISPLAY(d) \ ((ZoomDisplay *) (d)->privates[displayPrivateIndex].ptr) #define ZOOM_DISPLAY(d) \ ZoomDisplay *zd = GET_ZOOM_DISPLAY (d) #define GET_ZOOM_SCREEN(s, zd) \ ((ZoomScreen *) (s)->privates[(zd)->screenPrivateIndex].ptr) #define ZOOM_SCREEN(s) \ ZoomScreen *zs = GET_ZOOM_SCREEN (s, GET_ZOOM_DISPLAY (s->display)) #define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption)) static Bool zoomSetScreenOption(CompScreen * screen, char *name, CompOptionValue * value) { CompOption *o; int index; ZOOM_SCREEN(screen); o = compFindOption(zs->opt, NUM_OPTIONS(zs), name, &index); if (!o) return FALSE; switch (index) { case ZOOM_SCREEN_OPTION_POINTER_INVERT_Y: if (compSetBoolOption(o, value)) { zs->pointerInvertY = o->value.b; return TRUE; } break; case ZOOM_SCREEN_OPTION_POINTER_SENSITIVITY: if (compSetFloatOption(o, value)) { zs->pointerSensitivity = o->value.f * ZOOM_POINTER_SENSITIVITY_FACTOR; return TRUE; } break; case ZOOM_SCREEN_OPTION_STEP: if (compSetFloatOption(o, value)) { zs->step = o->value.f; return TRUE; } break; case ZOOM_SCREEN_OPTION_MIN: if (compSetFloatOption(o, value)) { zs->minZoom = o->value.f; return TRUE; } break; case ZOOM_SCREEN_OPTION_MAX: if (compSetFloatOption(o, value)) { zs->maxZoom = o->value.f; return TRUE; } break; case ZOOM_SCREEN_OPTION_SPEED: if (compSetFloatOption(o, value)) { zs->speed = o->value.f; return TRUE; } break; case ZOOM_SCREEN_OPTION_TIMESTEP: if (compSetFloatOption(o, value)) { zs->timestep = o->value.f; return TRUE; } break; case ZOOM_SCREEN_OPTION_FILTER_LINEAR: if (compSetBoolOption(o, value)) return TRUE; case ZOOM_SCREEN_OPTION_ALLOW_KEYBOARD_INPUT: if (compSetBoolOption(o, value)) return TRUE; default: break; } return FALSE; } static void zoomScreenInitOptions(ZoomScreen * zs) { CompOption *o; o = &zs->opt[ZOOM_SCREEN_OPTION_POINTER_INVERT_Y]; o->advanced = False; o->name = "invert_y"; o->group = N_("Misc. options"); o->subGroup = N_(""); o->displayHints = ""; o->shortDesc = N_("Pointer Invert Y"); o->longDesc = N_("Invert Y axis for Pointer movement."); o->type = CompOptionTypeBool; o->value.b = ZOOM_POINTER_INVERT_Y_DEFAULT; o = &zs->opt[ZOOM_SCREEN_OPTION_POINTER_SENSITIVITY]; o->advanced = False; o->name = "sensitivity"; o->group = N_("Misc. options"); o->subGroup = N_(""); o->displayHints = ""; o->shortDesc = N_("Pointer Sensitivity"); o->longDesc = N_("Sensitivity of Pointer movement."); o->type = CompOptionTypeFloat; o->value.f = ZOOM_POINTER_SENSITIVITY_DEFAULT; o->rest.f.min = ZOOM_POINTER_SENSITIVITY_MIN; o->rest.f.max = ZOOM_POINTER_SENSITIVITY_MAX; o->rest.f.precision = ZOOM_POINTER_SENSITIVITY_PRECISION; o = &zs->opt[ZOOM_SCREEN_OPTION_SPEED]; o->advanced = False; o->name = "speed"; o->group = N_("Misc. options"); o->subGroup = N_(""); o->displayHints = ""; o->shortDesc = N_("Speed"); o->longDesc = N_("Zoom Speed."); o->type = CompOptionTypeFloat; o->value.f = ZOOM_SPEED_DEFAULT; o->rest.f.min = ZOOM_SPEED_MIN; o->rest.f.max = ZOOM_SPEED_MAX; o->rest.f.precision = ZOOM_SPEED_PRECISION; o = &zs->opt[ZOOM_SCREEN_OPTION_STEP]; o->advanced = False; o->name = "step"; o->group = N_("Misc. options"); o->subGroup = N_(""); o->displayHints = ""; o->shortDesc = N_("Zoom Step"); o->longDesc = N_("Zoom factor multiplier for amount of Zooming " "in each ZoomIn/ZoomOut."); o->type = CompOptionTypeFloat; o->value.f = ZOOM_SPEED_DEFAULT; o->rest.f.min = ZOOM_SPEED_MIN; o->rest.f.max = ZOOM_SPEED_MAX; o->rest.f.precision = ZOOM_SPEED_PRECISION; o = &zs->opt[ZOOM_SCREEN_OPTION_MIN]; o->advanced = False; o->name = "min"; o->group = N_("Misc. options"); o->subGroup = N_(""); o->displayHints = ""; o->shortDesc = N_("Minimum Zoom"); o->longDesc = N_("Minimum Zoom Value (how close you can zoom)."); o->type = CompOptionTypeFloat; o->value.f = ZOOM_MIN_DEFAULT; o->rest.f.min = ZOOM_MIN_MIN; o->rest.f.max = ZOOM_MIN_MAX; o->rest.f.precision = ZOOM_MIN_PRECISION; o = &zs->opt[ZOOM_SCREEN_OPTION_MAX]; o->advanced = False; o->name = "max"; o->group = N_("Misc. options"); o->subGroup = N_(""); o->displayHints = ""; o->shortDesc = N_("Maximum Zoom"); o->longDesc = N_("Maximum Zoom Value (how far you can zoom away)."); o->type = CompOptionTypeFloat; o->value.f = ZOOM_MAX_DEFAULT; o->rest.f.min = ZOOM_MAX_MIN; o->rest.f.max = ZOOM_MAX_MAX; o->rest.f.precision = ZOOM_MAX_PRECISION; o = &zs->opt[ZOOM_SCREEN_OPTION_TIMESTEP]; o->advanced = False; o->name = "timestep"; o->group = N_("Misc. options"); o->subGroup = N_(""); o->displayHints = ""; o->shortDesc = N_("Zoom Timestep"); o->longDesc = N_("Zoom Timestep."); o->type = CompOptionTypeFloat; o->value.f = ZOOM_TIMESTEP_DEFAULT; o->rest.f.min = ZOOM_TIMESTEP_MIN; o->rest.f.max = ZOOM_TIMESTEP_MAX; o->rest.f.precision = ZOOM_TIMESTEP_PRECISION; o = &zs->opt[ZOOM_SCREEN_OPTION_FILTER_LINEAR]; o->advanced = False; o->name = "filter_linear"; o->group = N_("Misc. options"); o->subGroup = N_("Visual quality"); o->displayHints = ""; o->shortDesc = N_("Filter Linear"); o->longDesc = N_("USe Linear Filter when Zoomed in."); o->type = CompOptionTypeBool; o->value.b = ZOOM_FILTER_LINEAR_DEFAULT; o = &zs->opt[ZOOM_SCREEN_OPTION_ALLOW_KEYBOARD_INPUT]; o->advanced = False; o->name = "allow_keyboard_input"; o->group = N_("Misc. options"); o->subGroup = N_(""); o->displayHints = ""; o->shortDesc = N_("Allow Keyboard Input"); o->longDesc = N_("Allow Keyboard Input when Zoomed."); o->type = CompOptionTypeBool; o->value.b = ZOOM_ALLOW_KEYBOARD_INPUT_DEFAULT; } static CompOption *zoomGetScreenOptions(CompScreen * screen, int *count) { if (screen) { ZOOM_SCREEN(screen); *count = NUM_OPTIONS(zs); return zs->opt; } else { ZoomScreen *zs = malloc(sizeof(ZoomScreen)); zoomScreenInitOptions(zs); *count = NUM_OPTIONS(zs); return zs->opt; } } static int adjustZoomVelocity(ZoomScreen * zs) { float d, adjust, amount; d = (zs->newZoom - zs->currentZoom) * 75.0f; adjust = d * 0.002f; amount = fabs(d); if (amount < 1.0f) amount = 1.0f; else if (amount > 5.0f) amount = 5.0f; zs->zVelocity = (amount * zs->zVelocity + adjust) / (amount + 1.0f); return (fabs(d) < 0.1f && fabs(zs->zVelocity) < 0.005f); } static void zoomPreparePaintScreen(CompScreen * s, int msSinceLastPaint) { ZOOM_SCREEN(s); if (zs->grabIndex) { compDisplaySetRequestFlagForPlugin(s->display, "zoom", "ENABLE_3D"); int steps; float amount, chunk; amount = msSinceLastPaint * 0.05f * zs->speed; steps = amount / (0.5f * zs->timestep); if (!steps) steps = 1; chunk = amount / (float)steps; while (steps--) { zs->xVelocity /= 1.25f; zs->yVelocity /= 1.25f; if (fabs(zs->xVelocity) < 0.001f) zs->xVelocity = 0.0f; if (fabs(zs->yVelocity) < 0.001f) zs->yVelocity = 0.0f; zs->xTranslate += zs->xVelocity * chunk; if (zs->xTranslate < -zs->maxTranslate) { zs->xTranslate = -zs->maxTranslate; zs->xVelocity = 0.0f; } else if (zs->xTranslate > zs->maxTranslate) { zs->xTranslate = zs->maxTranslate; zs->xVelocity = 0.0f; } zs->yTranslate += zs->yVelocity * chunk; if (zs->yTranslate < -zs->maxTranslate) { zs->yTranslate = -zs->maxTranslate; zs->yVelocity = 0.0f; } else if (zs->yTranslate > zs->maxTranslate) { zs->yTranslate = zs->maxTranslate; zs->yVelocity = 0.0f; } if (adjustZoomVelocity(zs)) { zs->currentZoom = zs->newZoom; zs->zVelocity = 0.0f; } else { zs->currentZoom += (zs->zVelocity * msSinceLastPaint) / s->redrawTime; } zs->ztrans = DEFAULT_Z_CAMERA * zs->currentZoom; if (zs->ztrans <= 0.1f) { zs->zVelocity = 0.0f; zs->ztrans = 0.1f; } zs->xtrans = -zs->xTranslate * (1.0f - zs->currentZoom); zs->ytrans = zs->yTranslate * (1.0f - zs->currentZoom); if (!zs->grabbed) { if (zs->currentZoom == 1.0f && zs->zVelocity == 0.0f) { zs->xVelocity = zs->yVelocity = 0.0f; compDisplayClearRequestFlagForPlugin (s->display, "zoom", "ENABLE_3D"); removeScreenGrabKeyboardOptional(s, zs-> grabIndex, &zs-> savedPointer, !zs-> opt [ZOOM_SCREEN_OPTION_ALLOW_KEYBOARD_INPUT]. value.b); zs->grabIndex = FALSE; break; } } } } UNWRAP(zs, s, preparePaintScreen); (*s->preparePaintScreen) (s, msSinceLastPaint); WRAP(zs, s, preparePaintScreen, zoomPreparePaintScreen); } static void zoomDonePaintScreen(CompScreen * s) { ZOOM_SCREEN(s); if (zs->grabIndex) { if (zs->currentZoom != zs->newZoom || zs->xVelocity || zs->yVelocity || zs->zVelocity) damageScreen(s); } UNWRAP(zs, s, donePaintScreen); (*s->donePaintScreen) (s); WRAP(zs, s, donePaintScreen, zoomDonePaintScreen); } static Bool zoomPaintScreen(CompScreen * s, const ScreenPaintAttrib * sAttrib, Region region, int output, unsigned int mask) { Bool status; ZOOM_SCREEN(s); if (zs->grabIndex) { ScreenPaintAttrib sa = *sAttrib; int saveFilter; sa.xTranslate += zs->xtrans; sa.yTranslate += zs->ytrans; sa.zCamera = -zs->ztrans; /* hack to get sides rendered correctly */ if (zs->xtrans > 0.0f) sa.xRotate += 0.000001f; else sa.xRotate -= 0.000001f; mask &= ~PAINT_SCREEN_REGION_MASK; mask |= PAINT_SCREEN_TRANSFORMED_MASK | PAINT_SCREEN_CLEAR_MASK; saveFilter = s->filter[SCREEN_TRANS_FILTER]; if (zs->opt[ZOOM_SCREEN_OPTION_FILTER_LINEAR].value.b || zs->zVelocity != 0.0f) s->filter[SCREEN_TRANS_FILTER] = COMP_TEXTURE_FILTER_GOOD; else s->filter[SCREEN_TRANS_FILTER] = COMP_TEXTURE_FILTER_FAST; UNWRAP(zs, s, paintScreen); status = (*s->paintScreen) (s, &sa, region, output, mask); WRAP(zs, s, paintScreen, zoomPaintScreen); s->filter[SCREEN_TRANS_FILTER] = saveFilter; } else { UNWRAP(zs, s, paintScreen); status = (*s->paintScreen) (s, sAttrib, region, output, mask); WRAP(zs, s, paintScreen, zoomPaintScreen); } return status; } static Bool zoomIn(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption) { CompScreen *s; Window xid; xid = getIntOptionNamed(option, nOption, "root", 0); s = findScreenAtDisplay(d, xid); if (s) { ZOOM_SCREEN(s); if (otherScreenGrabExist(s, "zoom", "scale", 0)) return FALSE; if (!zs->grabIndex) { zs->grabIndex = pushScreenGrabKeyboardOptional (s, s->invisibleCursor, "zoom", !zs->opt[ZOOM_SCREEN_OPTION_ALLOW_KEYBOARD_INPUT].value. b); zs->savedPointer.x = d->pointerX; zs->savedPointer.y = d->pointerY; } if (zs->grabIndex) { int x, y; x = getIntOptionNamed(option, nOption, "x", 0); y = getIntOptionNamed(option, nOption, "y", 0); zs->grabbed = TRUE; zs->newZoom /= zs->step; if (zs->newZoom < zs->minZoom) zs->newZoom = zs->minZoom; damageScreen(s); if (zs->currentZoom == 1.0f) { zs->xTranslate = (x - s->width / 2) / (s->width * 2.0f); zs->yTranslate = (y - s->height / 2) / (s->height * 2.0f); zs->xTranslate /= zs->newZoom; zs->yTranslate /= zs->newZoom; } else if ((zs->currentZoom > 1.0f && zs->newZoom <= 1.0f) || (zs->newZoom > 0.98f && zs->newZoom < 1.02f)) { zs->newZoom = 1.0f; zs->grabbed = FALSE; damageScreen(s); } } } return FALSE; } static Bool zoomInitiate(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption) { zoomIn(d, action, state, option, nOption); if (state & CompActionStateInitKey) action->state |= CompActionStateTermKey; if (state & CompActionStateInitButton) action->state |= CompActionStateTermButton; return FALSE; } static Bool zoomOut(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption) { CompScreen *s; Window xid; xid = getIntOptionNamed(option, nOption, "root", 0); s = findScreenAtDisplay(d, xid); if (s) { ZOOM_SCREEN(s); if (otherScreenGrabExist(s, "zoom", "scale", 0)) return FALSE; if (!zs->grabIndex) { zs->grabIndex = pushScreenGrabKeyboardOptional (s, s->invisibleCursor, "zoom", !zs->opt[ZOOM_SCREEN_OPTION_ALLOW_KEYBOARD_INPUT].value. b); zs->savedPointer.x = d->pointerX; zs->savedPointer.y = d->pointerY; } if (zs->grabIndex && zs->currentZoom == 1.0 && zs->maxZoom == 1.0) { zs->grabbed = FALSE; damageScreen(s); return FALSE; } if (zs->grabIndex) { int x, y; x = getIntOptionNamed(option, nOption, "x", 0); y = getIntOptionNamed(option, nOption, "y", 0); zs->grabbed = TRUE; zs->newZoom *= zs->step; if (zs->newZoom > zs->maxZoom) zs->newZoom = zs->maxZoom; if (zs->currentZoom == 1.0f) { zs->xTranslate = (x - s->width / 2) / (s->width * 2.0f); zs->yTranslate = (y - s->height / 2) / (s->height * 2.0f); zs->xTranslate *= zs->newZoom; zs->yTranslate *= zs->newZoom; } if ((zs->currentZoom < 1.0f && zs->newZoom >= 1.0f) || (zs->newZoom > 0.98f && zs->newZoom < 1.02f)) { zs->grabbed = FALSE; zs->newZoom = 1.0f; } damageScreen(s); } } return FALSE; } static Bool zoomTerminate(CompDisplay * d, CompAction * action, CompActionState state, CompOption * option, int nOption) { CompScreen *s; Window xid; xid = getIntOptionNamed(option, nOption, "root", 0); for (s = d->screens; s; s = s->next) { ZOOM_SCREEN(s); if (xid && s->root != xid) continue; if (zs->grabIndex) { zs->newZoom = 1.0f; zs->grabbed = FALSE; damageScreen(s); } } action->state &= ~(CompActionStateTermKey | CompActionStateTermButton); return FALSE; } static void zoomHandleEvent(CompDisplay * d, XEvent * event) { CompScreen *s; ZOOM_DISPLAY(d); switch (event->type) { case MotionNotify: s = findScreenAtDisplay(d, event->xmotion.root); if (s) { ZOOM_SCREEN(s); if (zs->grabIndex && zs->grabbed) { GLfloat pointerDx; GLfloat pointerDy; pointerDx = d->pointerX - d->lastPointerX; pointerDy = d->pointerY - d->lastPointerY; if (event->xmotion.x_root < 50 || event->xmotion.y_root < 50 || event->xmotion.x_root > s->width - 50 || event->xmotion.y_root > s->height - 50) { warpPointer(d, (s->width / 2) - d->pointerX, (s->height / 2) - d->pointerY); } if (zs->pointerInvertY) pointerDy = -pointerDy; zs->xVelocity += pointerDx * zs->pointerSensitivity; zs->yVelocity += pointerDy * zs->pointerSensitivity; damageScreen(s); } } default: break; } UNWRAP(zd, d, handleEvent); (*d->handleEvent) (d, event); WRAP(zd, d, handleEvent, zoomHandleEvent); } static void zoomUpdateCubeOptions(CompScreen * s) { CompPlugin *p; ZOOM_SCREEN(s); p = findActivePlugin("cube"); if (p && p->vTable->getScreenOptions) { CompOption *options, *option; int nOptions; options = (*p->vTable->getScreenOptions) (s, &nOptions); option = compFindOption(options, nOptions, "in", 0); if (option) zs->maxTranslate = option->value.b ? 0.85f : 1.5f; } else { zs->maxTranslate = 1.5f; } } static Bool zoomSetScreenOptionForPlugin(CompScreen * s, char *plugin, char *name, CompOptionValue * value) { Bool status; ZOOM_SCREEN(s); UNWRAP(zs, s, setScreenOptionForPlugin); status = (*s->setScreenOptionForPlugin) (s, plugin, name, value); WRAP(zs, s, setScreenOptionForPlugin, zoomSetScreenOptionForPlugin); if (status && strcmp(plugin, "cube") == 0) zoomUpdateCubeOptions(s); return status; } static Bool zoomSetDisplayOption(CompDisplay * display, char *name, CompOptionValue * value) { CompOption *o; int index; ZOOM_DISPLAY(display); o = compFindOption(zd->opt, NUM_OPTIONS(zd), name, &index); if (!o) return FALSE; switch (index) { case ZOOM_DISPLAY_OPTION_INITIATE: case ZOOM_DISPLAY_OPTION_IN: case ZOOM_DISPLAY_OPTION_OUT: if (setDisplayAction(display, o, value)) return TRUE; break; default: break; } return FALSE; } static void zoomDisplayInitOptions(ZoomDisplay * zd) { CompOption *o; o = &zd->opt[ZOOM_DISPLAY_OPTION_INITIATE]; o->advanced = False; o->name = "initiate"; o->group = N_("Bindings"); o->subGroup = N_("Initiate"); o->displayHints = ""; o->shortDesc = N_("Initiate"); o->longDesc = N_("Initiate Zoom."); o->type = CompOptionTypeAction; o->value.action.initiate = zoomInitiate; o->value.action.terminate = zoomTerminate; o->value.action.bell = FALSE; o->value.action.edgeMask = 0; o->value.action.state = CompActionStateInitKey; o->value.action.state |= CompActionStateInitButton; o->value.action.type = CompBindingTypeButton; o->value.action.button.modifiers = ZOOM_INITIATE_MODIFIERS_DEFAULT; o->value.action.button.button = ZOOM_INITIATE_BUTTON_DEFAULT; o = &zd->opt[ZOOM_DISPLAY_OPTION_IN]; o->advanced = False; o->name = "zoom_in"; o->group = N_("Bindings"); o->subGroup = N_("Zoom In"); o->displayHints = ""; o->shortDesc = N_("Zoom In"); o->longDesc = N_("Zoom In."); o->type = CompOptionTypeAction; o->value.action.initiate = zoomIn; o->value.action.terminate = 0; o->value.action.bell = FALSE; o->value.action.edgeMask = 0; o->value.action.state = CompActionStateInitKey; o->value.action.state |= CompActionStateInitButton; o->value.action.type = CompBindingTypeButton; o->value.action.button.modifiers = ZOOM_IN_MODIFIERS_DEFAULT; o->value.action.button.button = ZOOM_IN_BUTTON_DEFAULT; o = &zd->opt[ZOOM_DISPLAY_OPTION_OUT]; o->advanced = False; o->name = "zoom_out"; o->group = N_("Bindings"); o->subGroup = N_("Zoom Out"); o->displayHints = ""; o->shortDesc = N_("Zoom Out"); o->longDesc = N_("Zoom Out."); o->type = CompOptionTypeAction; o->value.action.initiate = zoomOut; o->value.action.terminate = 0; o->value.action.bell = FALSE; o->value.action.edgeMask = 0; o->value.action.state = CompActionStateInitKey; o->value.action.state |= CompActionStateInitButton; o->value.action.type = CompBindingTypeButton; o->value.action.button.modifiers = ZOOM_OUT_MODIFIERS_DEFAULT; o->value.action.button.button = ZOOM_OUT_BUTTON_DEFAULT; } static CompOption *zoomGetDisplayOptions(CompDisplay * display, int *count) { if (display) { ZOOM_DISPLAY(display); *count = NUM_OPTIONS(zd); return zd->opt; } else { ZoomDisplay *zd = malloc(sizeof(ZoomDisplay)); zoomDisplayInitOptions(zd); *count = NUM_OPTIONS(zd); return zd->opt; } } static Bool zoomInitDisplay(CompPlugin * p, CompDisplay * d) { ZoomDisplay *zd; zd = malloc(sizeof(ZoomDisplay)); if (!zd) return FALSE; zd->screenPrivateIndex = allocateScreenPrivateIndex(d); if (zd->screenPrivateIndex < 0) { free(zd); return FALSE; } zoomDisplayInitOptions(zd); WRAP(zd, d, handleEvent, zoomHandleEvent); d->privates[displayPrivateIndex].ptr = zd; return TRUE; } static void zoomFiniDisplay(CompPlugin * p, CompDisplay * d) { ZOOM_DISPLAY(d); freeScreenPrivateIndex(d, zd->screenPrivateIndex); UNWRAP(zd, d, handleEvent); free(zd); } static Bool zoomInitScreen(CompPlugin * p, CompScreen * s) { ZoomScreen *zs; ZOOM_DISPLAY(s->display); zs = malloc(sizeof(ZoomScreen)); if (!zs) return FALSE; zs->grabIndex = 0; zs->currentZoom = 1.0f; zs->newZoom = 1.0f; zs->xVelocity = 0.0f; zs->yVelocity = 0.0f; zs->zVelocity = 0.0f; zs->xTranslate = 0.0f; zs->yTranslate = 0.0f; zs->maxTranslate = 0.85f; zs->savedPointer.x = 0; zs->savedPointer.y = 0; zs->grabbed = FALSE; zs->pointerInvertY = ZOOM_POINTER_INVERT_Y_DEFAULT; zs->pointerSensitivity = ZOOM_POINTER_SENSITIVITY_DEFAULT * ZOOM_POINTER_SENSITIVITY_FACTOR; zs->speed = ZOOM_SPEED_DEFAULT; zs->step = ZOOM_STEP_DEFAULT; zs->minZoom = ZOOM_MIN_DEFAULT; zs->maxZoom = ZOOM_MAX_DEFAULT; zs->timestep = ZOOM_TIMESTEP_DEFAULT; zoomScreenInitOptions(zs); addScreenAction(s, &zd->opt[ZOOM_DISPLAY_OPTION_INITIATE].value.action); addScreenAction(s, &zd->opt[ZOOM_DISPLAY_OPTION_IN].value.action); addScreenAction(s, &zd->opt[ZOOM_DISPLAY_OPTION_OUT].value.action); WRAP(zs, s, preparePaintScreen, zoomPreparePaintScreen); WRAP(zs, s, donePaintScreen, zoomDonePaintScreen); WRAP(zs, s, paintScreen, zoomPaintScreen); WRAP(zs, s, setScreenOptionForPlugin, zoomSetScreenOptionForPlugin); s->privates[zd->screenPrivateIndex].ptr = zs; zoomUpdateCubeOptions(s); return TRUE; } static void zoomFiniScreen(CompPlugin * p, CompScreen * s) { ZOOM_SCREEN(s); ZOOM_DISPLAY(s->display); UNWRAP(zs, s, preparePaintScreen); UNWRAP(zs, s, donePaintScreen); UNWRAP(zs, s, paintScreen); UNWRAP(zs, s, setScreenOptionForPlugin); removeScreenAction(s, &zd->opt[ZOOM_DISPLAY_OPTION_INITIATE].value.action); removeScreenAction(s, &zd->opt[ZOOM_DISPLAY_OPTION_IN].value.action); removeScreenAction(s, &zd->opt[ZOOM_DISPLAY_OPTION_OUT].value.action); free(zs); } static Bool zoomInit(CompPlugin * p) { displayPrivateIndex = allocateDisplayPrivateIndex(); if (displayPrivateIndex < 0) return FALSE; return TRUE; } static void zoomFini(CompPlugin * p) { if (displayPrivateIndex >= 0) freeDisplayPrivateIndex(displayPrivateIndex); } CompPluginFeature zoomFeatures[] = { {"zoom"} }; CompPluginVTable zoomVTable = { "zoom", N_("Zoom Desktop"), N_("Zoom and pan desktop cube"), zoomInit, zoomFini, zoomInitDisplay, zoomFiniDisplay, zoomInitScreen, zoomFiniScreen, 0, /* InitWindow */ 0, /* FiniWindow */ zoomGetDisplayOptions, zoomSetDisplayOption, zoomGetScreenOptions, zoomSetScreenOption, 0, 0, zoomFeatures, sizeof(zoomFeatures) / sizeof(zoomFeatures[0]), BERYL_ABI_INFO, "beryl-plugins-unsupported", "accessibility", 0, 0, False, }; CompPluginVTable *getCompPluginInfo(void) { return &zoomVTable; }