diff options
Diffstat (limited to 'plugins/zoom')
-rw-r--r-- | plugins/zoom/CMakeLists.txt | 5 | ||||
-rw-r--r-- | plugins/zoom/src/zoom.cpp | 774 | ||||
-rw-r--r-- | plugins/zoom/src/zoom.h | 127 | ||||
-rw-r--r-- | plugins/zoom/zoom.xml.in | 62 |
4 files changed, 968 insertions, 0 deletions
diff --git a/plugins/zoom/CMakeLists.txt b/plugins/zoom/CMakeLists.txt new file mode 100644 index 0000000..5ab0315 --- /dev/null +++ b/plugins/zoom/CMakeLists.txt @@ -0,0 +1,5 @@ +find_package (Compiz REQUIRED) + +include (CompizPlugin) + +compiz_plugin(zoom PLUGINDEPS composite opengl)
\ No newline at end of file diff --git a/plugins/zoom/src/zoom.cpp b/plugins/zoom/src/zoom.cpp new file mode 100644 index 0000000..4f7a05b --- /dev/null +++ b/plugins/zoom/src/zoom.cpp @@ -0,0 +1,774 @@ +/* + * Copyright © 2005 Novell, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Novell, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Novell, Inc. makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: David Reveman <davidr@novell.com> + */ + +#include "zoom.h" + +COMPIZ_PLUGIN_20081216 (zoom, ZoomPluginVTable) + +static int +adjustZoomVelocity (ZoomScreen *zs) +{ + float d, adjust, amount; + + d = (1.0f - zs->scale) * 10.0f; + + adjust = d * 0.002f; + amount = fabs (d); + if (amount < 1.0f) + amount = 1.0f; + else if (amount > 5.0f) + amount = 5.0f; + + zs->velocity = (amount * zs->velocity + adjust) / (amount + 1.0f); + + return (fabs (d) < 0.02f && fabs (zs->velocity) < 0.005f); +} + +void +ZoomScreen::zoomInEvent () +{ + CompOption::Vector o (0); + + o.push_back (CompOption ("root", CompOption::TypeInt)); + o.push_back (CompOption ("output", CompOption::TypeInt)); + o.push_back (CompOption ("x1", CompOption::TypeInt)); + o.push_back (CompOption ("y1", CompOption::TypeInt)); + o.push_back (CompOption ("x2", CompOption::TypeInt)); + o.push_back (CompOption ("y2", CompOption::TypeInt)); + + o[0].value ().set ((int) screen->root ()); + o[1].value ().set ((int) zoomOutput); + o[2].value ().set ((int) current[zoomOutput].x1); + o[3].value ().set ((int) current[zoomOutput].y1); + o[4].value ().set ((int) current[zoomOutput].x2); + o[5].value ().set ((int) current[zoomOutput].y2); + + screen->handleCompizEvent ("zoom", "in", o); +} + +void +ZoomScreen::zoomOutEvent () +{ + CompOption::Vector o (0); + + o.push_back (CompOption ("root", CompOption::TypeInt)); + o.push_back (CompOption ("output", CompOption::TypeInt)); + + o[0].value ().set ((int) screen->root ()); + o[1].value ().set ((int) zoomOutput); + + screen->handleCompizEvent ("zoom", "out", o); +} + +void +ZoomScreen::preparePaint (int ms) +{ + if (adjust) + { + int steps; + float amount; + + amount = ms * 0.35f * opt[ZOOM_OPTION_SPEED].value ().f (); + steps = amount / (0.5f * opt[ZOOM_OPTION_TIMESTEP].value ().f ()); + if (!steps) steps = 1; + + while (steps--) + { + if (adjustZoomVelocity (this)) + { + BoxPtr pBox = + &screen->outputDevs ()[zoomOutput].region ()->extents; + + scale = 1.0f; + velocity = 0.0f; + adjust = false; + + if (current[zoomOutput].x1 == pBox->x1 && + current[zoomOutput].y1 == pBox->y1 && + current[zoomOutput].x2 == pBox->x2 && + current[zoomOutput].y2 == pBox->y2) + { + zoomed &= ~(1 << zoomOutput); + zoomOutEvent (); + } + else + { + zoomInEvent (); + } + + break; + } + else + { + scale += (velocity * ms) / (float) cScreen->redrawTime (); + } + } + } + + cScreen->preparePaint (ms); +} + +void +ZoomScreen::donePaint () +{ + if (adjust) + cScreen->damageScreen (); + + if (!adjust && zoomed == 0) + { + cScreen->preparePaintSetEnabled (this, false); + cScreen->donePaintSetEnabled (this, false); + gScreen->glPaintOutputSetEnabled (this, false); + } + + cScreen->donePaint (); +} + +bool +ZoomScreen::glPaintOutput (const GLScreenPaintAttrib &sAttrib, + const GLMatrix &transform, + const CompRegion ®ion, + CompOutput *output, + unsigned int mask) +{ + GLMatrix zTransform (transform); + bool status; + + if (output->id () != ~0 && (zoomed & (1 << output->id ()))) + { + GLTexture::Filter saveFilter; + ZoomBox box; + float scale, x, y, x1, y1; + float oWidth = output->width (); + float oHeight = output->height (); + + mask &= ~PAINT_SCREEN_REGION_MASK; + + getCurrentZoom (output->id (), &box); + + x1 = box.x1 - output->x1 (); + y1 = box.y1 - output->y1 (); + + scale = oWidth / (box.x2 - box.x1); + + x = ((oWidth / 2.0f) - x1) / oWidth; + y = ((oHeight / 2.0f) - y1) / oHeight; + + x = 0.5f - x * scale; + y = 0.5f - y * scale; + + zTransform.translate (-x, y, 0.0f); + zTransform.scale (scale, scale, 1.0f); + + mask |= PAINT_SCREEN_TRANSFORMED_MASK; + + saveFilter = gScreen->filter (SCREEN_TRANS_FILTER); + + if ((zoomOutput != output->id () || !adjust) && scale > 3.9f && + !opt[ZOOM_OPTION_FILTER_LINEAR].value ().b ()) + gScreen->setFilter (SCREEN_TRANS_FILTER, GLTexture::Fast); + + status = gScreen->glPaintOutput (sAttrib, zTransform, region, output, + mask); + + gScreen->setFilter (SCREEN_TRANS_FILTER, saveFilter); + } + else + { + status = gScreen->glPaintOutput (sAttrib, transform, region, output, + mask); + } + + if (status && grab) + { + int x1, x2, y1, y2; + + x1 = MIN (this->x1, this->x2); + y1 = MIN (this->y1, this->y2); + x2 = MAX (this->x1, this->x2); + y2 = MAX (this->y1, this->y2); + + if (grabIndex) + { + zTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA); + + glPushMatrix (); + glLoadMatrixf (zTransform.getMatrix ()); + glDisableClientState (GL_TEXTURE_COORD_ARRAY); + glEnable (GL_BLEND); + glColor4us (0x2fff, 0x2fff, 0x4fff, 0x4fff); + glRecti (x1, y2, x2, y1); + glColor4us (0x2fff, 0x2fff, 0x4fff, 0x9fff); + glBegin (GL_LINE_LOOP); + glVertex2i (x1, y1); + glVertex2i (x2, y1); + glVertex2i (x2, y2); + glVertex2i (x1, y2); + glEnd (); + glColor4usv (defaultColor); + glDisable (GL_BLEND); + glEnableClientState (GL_TEXTURE_COORD_ARRAY); + glPopMatrix (); + } + } + + return status; +} + + +void +ZoomScreen::initiateForSelection (int output) +{ + int tmp; + + if (x1 > x2) + { + tmp = x1; + x1 = x2; + x2 = tmp; + } + + if (y1 > y2) + { + tmp = y1; + y1 = y2; + y2 = tmp; + } + + if (x1 < x2 && y1 < y2) + { + float oWidth, oHeight; + float xScale, yScale, scale; + BoxRec box; + int cx, cy; + int width, height; + + oWidth = screen->outputDevs ()[output].width (); + oHeight = screen->outputDevs ()[output].height (); + + cx = (int) ((x1 + x2) / 2.0f + 0.5f); + cy = (int) ((y1 + y2) / 2.0f + 0.5f); + + width = x2 - x1; + height = y2 - y1; + + xScale = oWidth / width; + yScale = oHeight / height; + + scale = MAX (MIN (xScale, yScale), 1.0f); + + box.x1 = cx - (oWidth / scale) / 2.0f; + box.y1 = cy - (oHeight / scale) / 2.0f; + box.x2 = cx + (oWidth / scale) / 2.0f; + box.y2 = cy + (oHeight / scale) / 2.0f; + + if (box.x1 < screen->outputDevs ()[output].x1 ()) + { + box.x2 += screen->outputDevs ()[output].x1 () - box.x1; + box.x1 = screen->outputDevs ()[output].x1 (); + } + else if (box.x2 > screen->outputDevs ()[output].x2 ()) + { + box.x1 -= box.x2 - screen->outputDevs ()[output].x2 (); + box.x2 = screen->outputDevs ()[output].x2 (); + } + + if (box.y1 < screen->outputDevs ()[output].y1 ()) + { + box.y2 += screen->outputDevs ()[output].y1 () - box.y1; + box.y1 = screen->outputDevs ()[output].y1 (); + } + else if (box.y2 > screen->outputDevs ()[output].y2 ()) + { + box.y1 -= box.y2 - screen->outputDevs ()[output].y2 (); + box.y2 = screen->outputDevs ()[output].y2 (); + } + + if (zoomed & (1 << output)) + { + getCurrentZoom (output, &last[output]); + } + else + { + last[output].x1 = screen->outputDevs ()[output].x1 (); + last[output].y1 = screen->outputDevs ()[output].y1 (); + last[output].x2 = screen->outputDevs ()[output].x2 (); + last[output].y2 = screen->outputDevs ()[output].y2 (); + } + + current[output].x1 = box.x1; + current[output].y1 = box.y1; + current[output].x2 = box.x2; + current[output].y2 = box.y2; + + this->scale = 0.0f; + adjust = true; + cScreen->preparePaintSetEnabled (this, true); + cScreen->donePaintSetEnabled (this, true); + gScreen->glPaintOutputSetEnabled (this, true); + zoomOutput = output; + zoomed |= (1 << output); + + cScreen->damageScreen (); + } +} + +static bool +zoomIn (CompAction *action, + CompAction::State state, + CompOption::Vector &options) +{ + float w, h, x0, y0; + int output; + ZoomBox box; + + ZOOM_SCREEN (screen); + + output = screen->outputDeviceForPoint (pointerX, pointerY); + + if (!zs->grabIndex) + { + zs->grabIndex = screen->pushGrab (None, "zoom"); + screen->handleEventSetEnabled (zs, true); + } + + if (zs->zoomed & (1 << output)) + { + zs->getCurrentZoom (output, &box); + } + else + { + box.x1 = screen->outputDevs ()[output].x1 (); + box.y1 = screen->outputDevs ()[output].y1 (); + box.x2 = screen->outputDevs ()[output].x2 (); + box.y2 = screen->outputDevs ()[output].y2 (); + } + + w = (box.x2 - box.x1) / + zs->opt[ZOOM_OPTION_ZOOM_FACTOR].value ().f (); + h = (box.y2 - box.y1) / + zs->opt[ZOOM_OPTION_ZOOM_FACTOR].value ().f (); + + x0 = (pointerX - screen->outputDevs ()[output].x1 ()) / (float) + screen->outputDevs ()[output].width (); + y0 = (pointerY - screen->outputDevs ()[output].y1 ()) / (float) + screen->outputDevs ()[output].height (); + + zs->x1 = box.x1 + (x0 * (box.x2 - box.x1) - x0 * w + 0.5f); + zs->y1 = box.y1 + (y0 * (box.y2 - box.y1) - y0 * h + 0.5f); + zs->x2 = zs->x1 + w; + zs->y2 = zs->y1 + h; + + zs->initiateForSelection (output); + + return TRUE; +} + +static bool +zoomInitiate (CompAction *action, + CompAction::State state, + CompOption::Vector &options) +{ + int output, x1, y1; + float scale; + + ZOOM_SCREEN (screen); + + if (screen->otherGrabExist ("zoom", 0)) + return false; + + if (!zs->grabIndex) + { + zs->grabIndex = screen->pushGrab (None, "zoom"); + screen->handleEventSetEnabled (zs, true); + } + + if (state & CompAction::StateInitButton) + action->setState (action->state () | CompAction::StateTermButton); + + /* start selection zoom rectangle */ + + output = screen->outputDeviceForPoint (pointerX, pointerY); + + if (zs->zoomed & (1 << output)) + { + ZoomBox box; + float oWidth; + + zs->getCurrentZoom (output, &box); + + oWidth = screen->outputDevs ()[output].width (); + scale = oWidth / (box.x2 - box.x1); + + x1 = box.x1; + y1 = box.y1; + } + else + { + scale = 1.0f; + x1 = screen->outputDevs ()[output].x1 (); + y1 = screen->outputDevs ()[output].y1 (); + } + + zs->x1 = zs->x2 = x1 + + ((pointerX - screen->outputDevs ()[output].x1 ()) / + scale + 0.5f); + zs->y1 = zs->y2 = y1 + + ((pointerY - screen->outputDevs ()[output].y1 ()) / + scale + 0.5f); + + zs->zoomOutput = output; + + zs->grab = true; + zs->gScreen->glPaintOutputSetEnabled (zs, true); + + zs->cScreen->damageScreen (); + + return true; +} + +static bool +zoomOut (CompAction *action, + CompAction::State state, + CompOption::Vector &options) +{ + int output; + + ZOOM_SCREEN (screen); + + output = screen->outputDeviceForPoint (pointerX, pointerY); + + zs->getCurrentZoom (output, &zs->last[output]); + + zs->current[output].x1 = screen->outputDevs ()[output].x1 (); + zs->current[output].y1 = screen->outputDevs ()[output].y1 (); + zs->current[output].x2 = screen->outputDevs ()[output].x2 (); + zs->current[output].y2 = screen->outputDevs ()[output].y2 (); + + zs->zoomOutput = output; + zs->scale = 0.0f; + zs->adjust = true; + zs->grab = false; + + if (zs->grabIndex) + { + screen->removeGrab (zs->grabIndex, NULL); + zs->grabIndex = 0; + screen->handleEventSetEnabled (zs, false); + } + + zs->cScreen->damageScreen (); + + return true; +} + +static bool +zoomTerminate (CompAction *action, + CompAction::State state, + CompOption::Vector &options) +{ + ZOOM_SCREEN (screen); + + if (zs->grab) + { + int output; + + output = screen->outputDeviceForPoint (zs->x1, zs->y1); + + if (zs->x2 > screen->outputDevs ()[output].x2 ()) + zs->x2 = screen->outputDevs ()[output].x2 (); + + if (zs->y2 > screen->outputDevs ()[output].y2 ()) + zs->y2 = screen->outputDevs ()[output].y2 (); + + zs->initiateForSelection (output); + + zs->grab = false; + } + else + { + zoomOut (action, state, noOptions); + } + action->setState (action->state () & ~(CompAction::StateTermKey | + CompAction::StateTermButton)); +} + +static bool +zoomInitiatePan (CompAction *action, + CompAction::State state, + CompOption::Vector &options) +{ + int output; + + ZOOM_SCREEN (screen); + + output = screen->outputDeviceForPoint (pointerX, pointerY); + + if (!(zs->zoomed & (1 << output))) + return false; + + if (screen->otherGrabExist ("zoom", 0)) + return false; + + if (state & CompAction::StateInitButton) + action->setState (action->state () | CompAction::StateTermButton); + + if (!zs->panGrabIndex) + zs->panGrabIndex = screen->pushGrab (zs->panCursor, "zoom-pan"); + + zs->zoomOutput = output; + + return true; +} + +static bool +zoomTerminatePan (CompAction *action, + CompAction::State state, + CompOption::Vector &options) +{ + ZOOM_SCREEN (screen); + + if (zs->panGrabIndex) + { + screen->removeGrab (zs->panGrabIndex, NULL); + zs->panGrabIndex = 0; + + zs->zoomInEvent (); + } + + return true; +} + +void +ZoomScreen::getCurrentZoom (int output, ZoomBox *pBox) +{ + if (output == zoomOutput) + { + float inverse; + + inverse = 1.0f - scale; + + pBox->x1 = scale * current[output].x1 + + inverse * last[output].x1; + pBox->y1 = scale * current[output].y1 + + inverse * last[output].y1; + pBox->x2 = scale * current[output].x2 + + inverse * last[output].x2; + pBox->y2 = scale * current[output].y2 + + inverse * last[output].y2; + } + else + { + pBox->x1 = current[output].x1; + pBox->y1 = current[output].y1; + pBox->x2 = current[output].x2; + pBox->y2 = current[output].y2; + } +} + +void +ZoomScreen::handleMotionEvent (int xRoot, int yRoot) +{ + if (grabIndex) + { + int output = zoomOutput; + ZoomBox box; + float scale, oWidth = screen->outputDevs ()[output].width (); + + getCurrentZoom (output, &box); + + if (zoomed & (1 << output)) + scale = oWidth / (box.x2 - box.x1); + else + scale = 1.0f; + + if (panGrabIndex) + { + float dx, dy; + + dx = (xRoot - lastPointerX) / scale; + dy = (yRoot - lastPointerY) / scale; + + box.x1 -= dx; + box.y1 -= dy; + box.x2 -= dx; + box.y2 -= dy; + + if (box.x1 < screen->outputDevs ()[output].x1 ()) + { + box.x2 += screen->outputDevs ()[output].x1 () - box.x1; + box.x1 = screen->outputDevs ()[output].x1 (); + } + else if (box.x2 > screen->outputDevs ()[output].x2 ()) + { + box.x1 -= box.x2 - screen->outputDevs ()[output].x2 (); + box.x2 = screen->outputDevs ()[output].x2 (); + } + + if (box.y1 < screen->outputDevs ()[output].y1 ()) + { + box.y2 += screen->outputDevs ()[output].y1 () - box.y1; + box.y1 = screen->outputDevs ()[output].y1 (); + } + else if (box.y2 > screen->outputDevs ()[output].y2 ()) + { + box.y1 -= box.y2 - screen->outputDevs ()[output].y2 (); + box.y2 = screen->outputDevs ()[output].y2 (); + } + + current[output] = box; + + cScreen->damageScreen (); + } + else + { + int x1, y1; + + if (zoomed & (1 << output)) + { + x1 = box.x1; + y1 = box.y1; + } + else + { + x1 = screen->outputDevs ()[output].x1 (); + y1 = screen->outputDevs ()[output].y1 (); + } + + this->x2 = x1 + + ((xRoot - screen->outputDevs ()[output].x1 ()) / + scale + 0.5f); + this->y2 = y1 + + ((yRoot - screen->outputDevs ()[output].y1 ()) / + scale + 0.5f); + + cScreen->damageScreen (); + } + } +} + +void +ZoomScreen::handleEvent (XEvent *event) +{ + switch (event->type) { + case MotionNotify: + if (event->xmotion.root == screen->root ()) + handleMotionEvent (pointerX, pointerY); + break; + case EnterNotify: + case LeaveNotify: + if (event->xcrossing.root == screen->root ()) + handleMotionEvent (pointerX, pointerY); + default: + break; + } + + screen->handleEvent (event); +} + + +CompOption::Vector & +ZoomScreen::getOptions () +{ + return opt; +} + +bool +ZoomScreen::setOption (const char *name, + CompOption::Value &value) +{ + CompOption *o; + unsigned int index; + + o = CompOption::findOption (opt, name, &index); + if (!o) + return false; + + return CompOption::setOption (*o, value); +} + +static const CompMetadata::OptionInfo zoomOptionInfo[] = { + { "initiate_button", "button", 0, zoomInitiate, zoomTerminate }, + { "zoom_in_button", "button", 0, zoomIn, 0 }, + { "zoom_out_button", "button", 0, zoomOut, 0 }, + { "zoom_pan_button", "button", 0, zoomInitiatePan, zoomTerminatePan }, + { "speed", "float", "<min>0.1</min>", 0, 0 }, + { "timestep", "float", "<min>0.1</min>", 0, 0 }, + { "zoom_factor", "float", "<min>1.01</min>", 0, 0 }, + { "filter_linear", "bool", 0, 0, 0 } +}; + +ZoomScreen::ZoomScreen (CompScreen *screen) : + PrivateHandler<ZoomScreen,CompScreen> (screen), + cScreen (CompositeScreen::get (screen)), + gScreen (GLScreen::get (screen)), + opt(ZOOM_OPTION_NUM), + grabIndex (0), + grab (false), + zoomed (0), + adjust (false), + panGrabIndex (0), + velocity (0.0), + scale (0.0), + zoomOutput (0) +{ + if (!zoomVTable->getMetadata ()->initOptions (zoomOptionInfo, + ZOOM_OPTION_NUM, opt)) + { + setFailed (); + return; + } + + panCursor = XCreateFontCursor (screen->dpy (), XC_fleur); + + memset (¤t, 0, sizeof (current)); + memset (&last, 0, sizeof (last)); + + ScreenInterface::setHandler (screen, false); + CompositeScreenInterface::setHandler (cScreen, false); + GLScreenInterface::setHandler (gScreen, false); +} + + +ZoomScreen::~ZoomScreen () +{ + if (panCursor) + XFreeCursor (screen->dpy (), panCursor); +} + +bool +ZoomPluginVTable::init () +{ + if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) | + !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) | + !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI)) + return false; + + getMetadata ()->addFromOptionInfo (zoomOptionInfo, ZOOM_OPTION_NUM); + getMetadata ()->addFromFile (name ()); + + return true; +} + diff --git a/plugins/zoom/src/zoom.h b/plugins/zoom/src/zoom.h new file mode 100644 index 0000000..41e64a1 --- /dev/null +++ b/plugins/zoom/src/zoom.h @@ -0,0 +1,127 @@ +/* + * Copyright © 2005 Novell, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Novell, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Novell, Inc. makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: David Reveman <davidr@novell.com> + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <sys/time.h> + +#include <X11/cursorfont.h> + +#include <core/core.h> +#include <core/privatehandler.h> + +#include <composite/composite.h> +#include <opengl/opengl.h> + +#define ZOOM_OPTION_INITIATE_BUTTON 0 +#define ZOOM_OPTION_IN_BUTTON 1 +#define ZOOM_OPTION_OUT_BUTTON 2 +#define ZOOM_OPTION_PAN_BUTTON 3 +#define ZOOM_OPTION_SPEED 4 +#define ZOOM_OPTION_TIMESTEP 5 +#define ZOOM_OPTION_ZOOM_FACTOR 6 +#define ZOOM_OPTION_FILTER_LINEAR 7 +#define ZOOM_OPTION_NUM 8 + +#define ZOOM_SCREEN(s) \ + ZoomScreen *zs = ZoomScreen::get (s) + +struct ZoomBox { + float x1; + float y1; + float x2; + float y2; +}; + +class ZoomScreen : + public ScreenInterface, + public CompositeScreenInterface, + public GLScreenInterface, + public PrivateHandler<ZoomScreen,CompScreen> +{ + public: + + ZoomScreen (CompScreen *screen); + ~ZoomScreen (); + + CompOption::Vector & getOptions (); + bool setOption (const char *name, CompOption::Value &value); + + void handleEvent (XEvent *); + + void preparePaint (int); + void donePaint (); + + bool glPaintOutput (const GLScreenPaintAttrib &, + const GLMatrix &, const CompRegion &, + CompOutput *, unsigned int); + + void getCurrentZoom (int output, ZoomBox *pBox); + void handleMotionEvent (int xRoot, int yRoot); + void initiateForSelection (int output); + + void zoomInEvent (); + void zoomOutEvent (); + + CompositeScreen *cScreen; + GLScreen *gScreen; + + CompOption::Vector opt; + + float pointerSensitivity; + + CompScreen::GrabHandle grabIndex; + bool grab; + + int zoomed; + + bool adjust; + + CompScreen::GrabHandle panGrabIndex; + Cursor panCursor; + + GLfloat velocity; + GLfloat scale; + + ZoomBox current[16]; + ZoomBox last[16]; + + int x1, y1, x2, y2; + + int zoomOutput; +}; + +class ZoomPluginVTable : + public CompPlugin::VTableForScreen<ZoomScreen> +{ + public: + + bool init (); + + PLUGIN_OPTION_HELPER (ZoomScreen); + +}; diff --git a/plugins/zoom/zoom.xml.in b/plugins/zoom/zoom.xml.in new file mode 100644 index 0000000..ff8bb5a --- /dev/null +++ b/plugins/zoom/zoom.xml.in @@ -0,0 +1,62 @@ +<compiz> + <plugin name="zoom"> + <_short>Zoom Desktop</_short> + <_long>Zoom and pan desktop cube</_long> + <deps> + <requirement> + <plugin>opengl</plugin> + </requirement> + </deps> + <options> + <option name="initiate_button" type="button"> + <_short>Initiate</_short> + <_long>Zoom In</_long> + <default><Super>Button3</default> + </option> + <option name="zoom_in_button" type="button"> + <_short>Zoom In</_short> + <_long>Zoom In</_long> + <default><Super>Button4</default> + </option> + <option name="zoom_out_button" type="button"> + <_short>Zoom Out</_short> + <_long>Zoom Out</_long> + <default><Super>Button5</default> + </option> + <option name="zoom_pan_button" type="button"> + <_short>Zoom Pan</_short> + <_long>Zoom pan</_long> + <default><Super>Button2</default> + </option> + <option name="speed" type="float"> + <_short>Speed</_short> + <_long>Zoom Speed</_long> + <default>1.5</default> + <min>0.1</min> + <max>50</max> + <precision>0.1</precision> + </option> + <option name="timestep" type="float"> + <_short>Timestep</_short> + <_long>Zoom Timestep</_long> + <default>1.2</default> + <min>0.1</min> + <max>50</max> + <precision>0.1</precision> + </option> + <option name="zoom_factor" type="float"> + <_short>Zoom factor</_short> + <_long>Zoom factor</_long> + <default>2</default> + <min>1.01</min> + <max>3</max> + <precision>0.01</precision> + </option> + <option name="filter_linear" type="bool"> + <_short>Filter Linear</_short> + <_long>Use linear filter when zoomed in</_long> + <default>false</default> + </option> + </options> + </plugin> +</compiz> |