Logo Search packages:      
Sourcecode: beryl-plugins version File versions

put.c

/*
 * Copyright (c) 2006 Darryll Truchan <moppsy@comcast.net>
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <beryl.h>
#include <X11/Xatom.h>

/* defaults */
#define PUT_SPEED_DEFAULT       2.5f
#define PUT_SPEED_MIN           0.1f
#define PUT_SPEED_MAX           50.0f
#define PUT_SPEED_PRECISION     0.1f

#define PUT_TIMESTEP_DEFAULT    0.5f
#define PUT_TIMESTEP_MIN        0.1f
#define PUT_TIMESTEP_MAX        50.0f
#define PUT_TIMESTEP_PRECISION  0.1f

#define PUT_LEFT_PAD_DEFAULT    0
#define PUT_LEFT_PAD_MIN        0
#define PUT_LEFT_PAD_MAX        500

#define PUT_TOP_PAD_DEFAULT     0
#define PUT_TOP_PAD_MIN         0
#define PUT_TOP_PAD_MAX         500

#define PUT_RIGHT_PAD_DEFAULT   0
#define PUT_RIGHT_PAD_MIN       0
#define PUT_RIGHT_PAD_MAX       500

#define PUT_BOTTOM_PAD_DEFAULT  0
#define PUT_BOTTOM_PAD_MIN      0
#define PUT_BOTTOM_PAD_MAX      500

#define PUT_RESTORE_MODIFIERS_DEFAULT       CompSuperMask
#define PUT_RESTORE_KEY_DEFAULT             "KP_Insert"

#define PUT_CENTER_MODIFIERS_DEFAULT        CompSuperMask
#define PUT_CENTER_KEY_DEFAULT              "KP_Begin"

#define PUT_LEFT_MODIFIERS_DEFAULT          CompSuperMask
#define PUT_LEFT_KEY_DEFAULT                "KP_Left"

#define PUT_TOPLEFT_MODIFIERS_DEFAULT       CompSuperMask
#define PUT_TOPLEFT_KEY_DEFAULT             "KP_Home"

#define PUT_TOP_MODIFIERS_DEFAULT           CompSuperMask
#define PUT_TOP_KEY_DEFAULT                 "KP_Up"

#define PUT_TOPRIGHT_MODIFIERS_DEFAULT      CompSuperMask
#define PUT_TOPRIGHT_KEY_DEFAULT            "KP_Prior"

#define PUT_RIGHT_MODIFIERS_DEFAULT         CompSuperMask
#define PUT_RIGHT_KEY_DEFAULT               "KP_Right"

#define PUT_BOTTOMRIGHT_MODIFIERS_DEFAULT   CompSuperMask
#define PUT_BOTTOMRIGHT_KEY_DEFAULT         "KP_Next"

#define PUT_BOTTOM_MODIFIERS_DEFAULT        CompSuperMask
#define PUT_BOTTOM_KEY_DEFAULT              "KP_Down"

#define PUT_BOTTOMLEFT_MODIFIERS_DEFAULT    CompSuperMask
#define PUT_BOTTOMLEFT_KEY_DEFAULT          "KP_End"

#define PUT_POINTER_MODIFIERS_DEFAULT       CompSuperMask
#define PUT_POINTER_KEY_DEFAULT             "z"

#define PUT_SELF_ANIMATE_DEFAULT            TRUE
#define PUT_CENTER_INITIAL_DEFAULT          FALSE
#define PUT_UNFOCUS_WINDOW_DEFAULT          FALSE
#define PUT_WINDOW_CENTER_DEFAULT           FALSE
#define PUT_AVOID_OFFSCREEN_DEFAULT         FALSE

#define PUT_DISPLAY_OPTION_CENTER           0
#define PUT_DISPLAY_OPTION_LEFT             1
#define PUT_DISPLAY_OPTION_TOPLEFT          2
#define PUT_DISPLAY_OPTION_TOP              3
#define PUT_DISPLAY_OPTION_TOPRIGHT         4
#define PUT_DISPLAY_OPTION_RIGHT            5
#define PUT_DISPLAY_OPTION_BOTTOMRIGHT      6
#define PUT_DISPLAY_OPTION_BOTTOM           7
#define PUT_DISPLAY_OPTION_BOTTOMLEFT       8
#define PUT_DISPLAY_OPTION_RESTORE          9
#define PUT_DISPLAY_OPTION_VIEWPORT_LEFT    10
#define PUT_DISPLAY_OPTION_VIEWPORT_RIGHT   11
#define PUT_DISPLAY_OPTION_VIEWPORT         12
#define PUT_DISPLAY_OPTION_VIEWPORT_1       13
#define PUT_DISPLAY_OPTION_VIEWPORT_2       14
#define PUT_DISPLAY_OPTION_VIEWPORT_3       15
#define PUT_DISPLAY_OPTION_VIEWPORT_4       16
#define PUT_DISPLAY_OPTION_VIEWPORT_5       17
#define PUT_DISPLAY_OPTION_VIEWPORT_6       18
#define PUT_DISPLAY_OPTION_VIEWPORT_7       19
#define PUT_DISPLAY_OPTION_VIEWPORT_8       20
#define PUT_DISPLAY_OPTION_VIEWPORT_9       21
#define PUT_DISPLAY_OPTION_VIEWPORT_10      22
#define PUT_DISPLAY_OPTION_VIEWPORT_11      23
#define PUT_DISPLAY_OPTION_VIEWPORT_12      24
#define PUT_DISPLAY_OPTION_EXACT            25
#define PUT_DISPLAY_OPTION_POINTER          26
#define PUT_DISPLAY_OPTION_VIEWPORT_UP      27
#define PUT_DISPLAY_OPTION_VIEWPORT_DOWN    28
#define PUT_DISPLAY_OPTION_NUM              29

#define PUT_SCREEN_OPTION_SPEED             0
#define PUT_SCREEN_OPTION_TIMESTEP          1
#define PUT_SCREEN_OPTION_LEFT_PAD          2
#define PUT_SCREEN_OPTION_TOP_PAD           3
#define PUT_SCREEN_OPTION_RIGHT_PAD         4
#define PUT_SCREEN_OPTION_BOTTOM_PAD        5
#define PUT_SCREEN_OPTION_UNFOCUS_WINDOW    6
#define PUT_SCREEN_OPTION_WINDOW_CENTER     7
#define PUT_SCREEN_OPTION_AVOID_OFFSCREEN   8
#define PUT_SCREEN_OPTION_NUM               9

#define GET_PUT_DISPLAY(d) ((PutDisplay *) (d)->privates[displayPrivateIndex].ptr)
#define PUT_DISPLAY(d) PutDisplay *pd = GET_PUT_DISPLAY (d)
#define GET_PUT_SCREEN(s, pd) ((PutScreen *) (s)->privates[(pd)->screenPrivateIndex].ptr)
#define PUT_SCREEN(s) PutScreen *ps = GET_PUT_SCREEN (s, GET_PUT_DISPLAY (s->display))
#define GET_PUT_WINDOW(w, ps) ((PutWindow *) (w)->privates[(ps)->windowPrivateIndex].ptr)
#define PUT_WINDOW(w) PutWindow *pw = GET_PUT_WINDOW  (w, GET_PUT_SCREEN  (w->screen, GET_PUT_DISPLAY (w->screen->display)))

#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))

/* using the plane plugin flag
 * seemed appropriate as a global
 */
static Bool usePlane = FALSE;

static int displayPrivateIndex;

typedef enum
{
      PutUnknown = 0,
      PutBottomLeft = 1,
      PutBottom = 2,
      PutBottomRight = 3,
      PutLeft = 4,
      PutCenter = 5,
      PutRight = 6,
      PutTopLeft = 7,
      PutTop = 8,
      PutTopRight = 9,
      PutRestore = 10,
      PutViewport = 11,
      PutViewportLeft = 12,
      PutViewportRight = 13,
      PutExact = 14,
      PutPointer = 15,
      PutViewportUp = 16,
      PutViewportDown = 17
} PutType;

typedef struct _PutDisplay
{
      int screenPrivateIndex;
      CompOption opt[PUT_DISPLAY_OPTION_NUM];   /* array of display options      */
      HandleEventProc handleEvent;  /* handle event function pointer */
      Atom berylPutWindowAtom;      /* client event atom             */
} PutDisplay;

typedef struct _PutScreen
{
      int windowPrivateIndex;
      CompOption opt[PUT_SCREEN_OPTION_NUM];    /* array of screen options  */
      PreparePaintScreenProc preparePaintScreen;      /* function pointer         */
      DonePaintScreenProc donePaintScreen;      /* function pointer         */
      PaintScreenProc paintScreen;  /* function pointer         */
      PaintWindowProc paintWindow;  /* function pointer         */
      float speed;                        /* animation speed          */
      float timestep;                     /* animation time step      */
      int moreAdjust;                     /* animation flag           */
      int grabIndex;                      /* screen grab index        */
      int padLeft, padTop, padRight, padBottom; /* position padding         */
      Bool vpMoving;                      /* viewport move flag       */
      Bool unfocusWindow;                 /* unfocus after move flag  */
      Bool windowcenter;                  /* put pointer - window center */
      Bool avoidoffscreen;          /* avoid windows offscreen using put pointer */
      CompWindow *current;          /* window being moved       */
} PutScreen;

typedef struct _PutWindow
{
      GLfloat xVelocity, yVelocity; /* animation velocity       */
      GLfloat tx, ty;                     /* animation translation    */
      int dx, dy;                         /* change in position       */
      int x, y;                           /* current position         */
      int lastX, lastY;             /* starting position        */

      Bool adjust;                        /* animation flag           */
} PutWindow;

static Bool
putSetScreenOption(CompScreen * screen, char *name, CompOptionValue * value)
{
      CompOption *o;
      int index;

      PUT_SCREEN(screen);

      o = compFindOption(ps->opt, NUM_OPTIONS(ps), name, &index);
      if (!o)
            return FALSE;

      switch (index)
      {
      case PUT_SCREEN_OPTION_SPEED:
            if (compSetFloatOption(o, value))
            {
                  ps->speed = o->value.f;
                  return TRUE;
            }
            break;

      case PUT_SCREEN_OPTION_TIMESTEP:
            if (compSetFloatOption(o, value))
            {
                  ps->timestep = o->value.f;
                  return TRUE;
            }
            break;

      case PUT_SCREEN_OPTION_LEFT_PAD:
            if (compSetIntOption(o, value))
            {
                  ps->padLeft = o->value.i;
                  return TRUE;
            }
            break;

      case PUT_SCREEN_OPTION_TOP_PAD:
            if (compSetIntOption(o, value))
            {
                  ps->padTop = o->value.i;
                  return TRUE;
            }
            break;

      case PUT_SCREEN_OPTION_RIGHT_PAD:
            if (compSetIntOption(o, value))
            {
                  ps->padRight = o->value.i;
                  return TRUE;
            }
            break;

      case PUT_SCREEN_OPTION_BOTTOM_PAD:
            if (compSetIntOption(o, value))
            {
                  ps->padBottom = o->value.i;
                  return TRUE;
            }
            break;

      case PUT_SCREEN_OPTION_UNFOCUS_WINDOW:
            if (compSetBoolOption(o, value))
            {
                  ps->unfocusWindow = o->value.b;
                  return TRUE;
            }
            break;

      case PUT_SCREEN_OPTION_WINDOW_CENTER:
            if (compSetBoolOption(o, value))
            {
                  ps->windowcenter = o->value.b;
                  return TRUE;
            }
            break;

      case PUT_SCREEN_OPTION_AVOID_OFFSCREEN:
            if (compSetBoolOption(o, value))
            {
                  ps->avoidoffscreen = o->value.b;
                  return TRUE;
            }
            break;

      default:
            break;
      }

      return FALSE;
}

static void putScreenInitOptions(PutScreen * ps)
{
      CompOption *o;

      o = &ps->opt[PUT_SCREEN_OPTION_SPEED];
      o->advanced = False;
      o->name = "speed";
      o->group = N_("Animation");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Animation Speed");
      o->longDesc = N_("Animation Speed.");
      o->type = CompOptionTypeFloat;
      o->value.f = PUT_SPEED_DEFAULT;
      o->rest.f.min = PUT_SPEED_MIN;
      o->rest.f.max = PUT_SPEED_MAX;
      o->rest.f.precision = PUT_SPEED_PRECISION;

      o = &ps->opt[PUT_SCREEN_OPTION_TIMESTEP];
      o->advanced = False;
      o->name = "timestep";
      o->group = N_("Animation");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Timestep");
      o->longDesc = N_("Animation Timestep.");
      o->type = CompOptionTypeFloat;
      o->value.f = PUT_TIMESTEP_DEFAULT;
      o->rest.f.min = PUT_TIMESTEP_MIN;
      o->rest.f.max = PUT_TIMESTEP_MAX;
      o->rest.f.precision = PUT_TIMESTEP_PRECISION;

      o = &ps->opt[PUT_SCREEN_OPTION_LEFT_PAD];
      o->advanced = False;
      o->name = "pad_left";
      o->group = N_("Misc. options");
      o->subGroup = N_("Padding");
      o->displayHints = "";
      o->shortDesc = N_("Pad Left");
      o->longDesc =
                  N_
                  ("Number of pixels from the Left edge where the active window will come to rest.");
      o->type = CompOptionTypeInt;
      o->value.i = PUT_LEFT_PAD_DEFAULT;
      o->rest.i.min = PUT_LEFT_PAD_MIN;
      o->rest.i.max = PUT_LEFT_PAD_MAX;

      o = &ps->opt[PUT_SCREEN_OPTION_TOP_PAD];
      o->advanced = False;
      o->name = "pad_top";
      o->group = N_("Misc. options");
      o->subGroup = N_("Padding");
      o->displayHints = "";
      o->shortDesc = N_("Pad Top");
      o->longDesc =
                  N_
                  ("Number of pixels from the Top edge where the active window will come to rest.");
      o->type = CompOptionTypeInt;
      o->value.i = PUT_TOP_PAD_DEFAULT;
      o->rest.i.min = PUT_TOP_PAD_MIN;
      o->rest.i.max = PUT_TOP_PAD_MAX;

      o = &ps->opt[PUT_SCREEN_OPTION_RIGHT_PAD];
      o->advanced = False;
      o->name = "pad_right";
      o->group = N_("Misc. options");
      o->subGroup = N_("Padding");
      o->displayHints = "";
      o->shortDesc = N_("Pad Right");
      o->longDesc =
                  N_
                  ("Number of pixels from the Right edge where the active window will come to rest.");
      o->type = CompOptionTypeInt;
      o->value.i = PUT_RIGHT_PAD_DEFAULT;
      o->rest.i.min = PUT_RIGHT_PAD_MIN;
      o->rest.i.max = PUT_RIGHT_PAD_MAX;

      o = &ps->opt[PUT_SCREEN_OPTION_BOTTOM_PAD];
      o->advanced = False;
      o->name = "pad_bottom";
      o->group = N_("Misc. options");
      o->subGroup = N_("Padding");
      o->displayHints = "";
      o->shortDesc = N_("Pad Bottom");
      o->longDesc =
                  N_
                  ("Number of pixels from the Bottom edge where the active window will come to rest.");
      o->type = CompOptionTypeInt;
      o->value.i = PUT_BOTTOM_PAD_DEFAULT;
      o->rest.i.min = PUT_BOTTOM_PAD_MIN;
      o->rest.i.max = PUT_BOTTOM_PAD_MAX;

      o = &ps->opt[PUT_SCREEN_OPTION_UNFOCUS_WINDOW];
      o->advanced = False;
      o->name = "unfocus_window";
      o->group = N_("Misc. options");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Unfocus Window");
      o->longDesc = N_("Unfocus Windows that are moved off the viewport.");
      o->type = CompOptionTypeBool;
      o->value.b = PUT_UNFOCUS_WINDOW_DEFAULT;

      o = &ps->opt[PUT_SCREEN_OPTION_WINDOW_CENTER];
      o->advanced = False;
      o->name = "window_center";
      o->group = N_("Misc. options");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Window Center");
      o->longDesc = N_("Put pointer uses the Center of the Window.");
      o->type = CompOptionTypeBool;
      o->value.b = PUT_WINDOW_CENTER_DEFAULT;

      o = &ps->opt[PUT_SCREEN_OPTION_AVOID_OFFSCREEN];
      o->advanced = False;
      o->name = "avoid_offscreen";
      o->group = N_("Misc. options");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Avoid Offscreen");
      o->longDesc = N_("Avoids putting window borders Offscreen.");
      o->type = CompOptionTypeBool;
      o->value.b = PUT_AVOID_OFFSCREEN_DEFAULT;

}

static CompOption *putGetScreenOptions(CompScreen * screen, int *count)
{
      if (screen)
      {
            PUT_SCREEN(screen);
            *count = NUM_OPTIONS(ps);
            return ps->opt;
      }
      else
      {
            PutScreen *ps = malloc(sizeof(PutScreen));

            putScreenInitOptions(ps);
            *count = NUM_OPTIONS(ps);
            return ps->opt;
      }
}



/*
 * calculate the velocity for the moving window
 */
static int adjustPutVelocity(CompWindow * w)
{
      float dx, dy, adjust, amount;
      float x1, y1;

      PUT_WINDOW(w);

      x1 = pw->lastX + pw->dx;
      y1 = pw->lastY + pw->dy;

      dx = x1 - (pw->lastX + pw->tx);
      dy = y1 - (pw->lastY + pw->ty);

      adjust = dx * 0.15f;
      amount = fabs(dx) * 1.5;
      if (amount < 0.5f)
            amount = 0.5f;
      else if (amount > 5.0f)
            amount = 5.0f;

      pw->xVelocity = (amount * pw->xVelocity + adjust) / (amount + 1.0f);

      adjust = dy * 0.15f;
      amount = fabs(dy) * 1.5f;
      if (amount < 0.5f)
            amount = 0.5f;
      else if (amount > 5.0f)
            amount = 5.0f;

      pw->yVelocity = (amount * pw->yVelocity + adjust) / (amount + 1.0f);

      if (fabs(dx) < 0.1f && fabs(pw->xVelocity) < 0.2f &&
            fabs(dy) < 0.1f && fabs(pw->yVelocity) < 0.2f)
      {
            /* animation done */
            pw->xVelocity = pw->yVelocity = 0.0f;

            pw->tx = x1 - pw->lastX;
            pw->ty = y1 - pw->lastY;

            pw->dx = pw->dy = 0;

            /* sync position with X server */
            syncWindowPosition(w);
            return 0;
      }
      return 1;
}

/*
 * setup for paint screen
 */
static void putPreparePaintScreen(CompScreen * s, int msSinceLastPaint)
{
      PUT_SCREEN(s);

      if (ps->moreAdjust && ps->grabIndex)
      {
            CompWindow *w;
            int steps, dx, dy;
            float amount, chunk;

            amount = msSinceLastPaint * 0.025f * ps->speed;
            steps = amount / (0.5f * ps->timestep);
            if (!steps)
                  steps = 1;
            chunk = amount / (float)steps;

            while (steps--)
            {
                  ps->moreAdjust = 0;
                  for (w = s->windows; w; w = w->next)
                  {
                        PUT_WINDOW(w);

                        if (pw->adjust)
                        {
                              pw->adjust = adjustPutVelocity(w);
                              ps->moreAdjust |= pw->adjust;

                              pw->tx += pw->xVelocity * chunk;
                              pw->ty += pw->yVelocity * chunk;

                              dx = (pw->lastX + pw->tx) - pw->x;
                              dy = (pw->lastY + pw->ty) - pw->y;

                              moveWindow(w, dx, dy, TRUE, TRUE);

                              pw->x += dx;
                              pw->y += dy;

                        }
                  }
                  if (!ps->moreAdjust)
                  {
                        /* unfocus moved window if enabled */
                        if (ps->unfocusWindow)
                              focusDefaultWindow(s->display);
                        break;
                  }
            }
      }

      UNWRAP(ps, s, preparePaintScreen);
      (*s->preparePaintScreen) (s, msSinceLastPaint);
      WRAP(ps, s, preparePaintScreen, putPreparePaintScreen);
}

/*
 * after painting clean up
 */
static void putDonePaintScreen(CompScreen * s)
{
      PUT_SCREEN(s);

      if (ps->moreAdjust && ps->grabIndex)
      {
            CompWindow *w;

            for (w = s->windows; w; w = w->next)
            {
                  PUT_WINDOW(w);

                  if (pw->adjust)
                  {
                        /* more animating to do */
                        addWindowDamage(w);
                  }
            }
      }
      else
      {
            if (ps->grabIndex)
            {
                  /* release the screen grab */
                  /* removeScreenGrab (s, ps->grabIndex, NULL); */
                  ps->grabIndex = 0;
                  ps->current = NULL;
            }
      }

      UNWRAP(ps, s, donePaintScreen);
      (*s->donePaintScreen) (s);
      WRAP(ps, s, donePaintScreen, putDonePaintScreen);
}

static Bool
putPaintScreen(CompScreen * s, const ScreenPaintAttrib * sAttrib,
                     Region region, int output, unsigned int mask)
{
      Bool status;

      PUT_SCREEN(s);

      if (ps->moreAdjust)
            mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;

      UNWRAP(ps, s, paintScreen);
      status = (*s->paintScreen) (s, sAttrib, region, output, mask);
      WRAP(ps, s, paintScreen, putPaintScreen);

      return status;
}

static Bool
putPaintWindow(CompWindow * w, const WindowPaintAttrib * attrib,
                     Region region, unsigned int mask)
{
      CompScreen *s = w->screen;
      Bool status;

      PUT_SCREEN(s);
      PUT_WINDOW(w);

      if (pw->adjust)
            mask |= PAINT_WINDOW_TRANSFORMED_MASK;

      UNWRAP(ps, s, paintWindow);
      status = (*s->paintWindow) (w, attrib, region, mask);
      WRAP(ps, s, paintWindow, putPaintWindow);

      return status;
}

/*
 * initiate action callback
 */
static Bool
putInitiate(CompDisplay * d, CompAction * action, CompActionState state,
                  CompOption * option, int nOption)
{
      CompWindow *w;
      Window xid;
      int px, py, x, y, dx, dy, head, width, height, hx, hy, face,
                  face_x, face_y, hdirection, vdirection;
      PutType type;
      XRectangle workArea;
      CompPlugin *p;

      xid = getIntOptionNamed(option, nOption, "window", 0);
      type = getIntOptionNamed(option, nOption, "type", PutCenter);
      px = getIntOptionNamed(option, nOption, "x", 0);
      py = getIntOptionNamed(option, nOption, "y", 0);

      if (!xid)
            xid = d->activeWindow;

      w = findWindowAtDisplay(d, xid);

      if (w)
      {
            PUT_SCREEN(w->screen);
            PUT_WINDOW(w);

            if (!ps->grabIndex)
            {
                  /* this will keep put from working while something else has a screen grab */
                  if (otherScreenGrabExist(w->screen, "put", 0))
                        return FALSE;

                  /* we are ok, so grab the screen */
                  ps->grabIndex = 1;
                  /* pushScreenGrab (w->screen, w->screen->invisibleCursor, "put"); */
            }

            if (ps->grabIndex)
            {
                  /* save a pointer to the moving window for later */
                  ps->current = w;

                  /* reset the viewport moving flag */
                  ps->vpMoving = FALSE;

                  /* we don't want to do anything with override redirect windows */
                  if (w->attrib.override_redirect)
                        return FALSE;

                  /* we dont want to be moving the desktop, docks, or fullscree window */
                  if (w->type & CompWindowTypeDesktopMask ||
                        w->type & CompWindowTypeDockMask ||
                        w->type & CompWindowTypeFullscreenMask)
                  {
                        return FALSE;
                  }

                  /* get the Xinerama head from the options list */
                  head = getIntOptionNamed(option, nOption, "head", -1);

                  /* no head in options list so we use the current head */
                  if (head == -1)
                        head = screenGetCurrentOutputDev(w->screen);

                  /* make sure the head number is not out of bounds */
                  head = MIN(head,w->screen->nOutputDev -1);

                  /* some error has occured so we bail out */
                  if (head < 0)
                        return FALSE;

                  /* working area of the screen */
                  screenGetOutputDevWorkArea(w->screen, head, &workArea);
                  width = workArea.width;
                  height = workArea.height;
                  hx = workArea.x;
                  hy = workArea.y;

                  /* the windows location */
                  x = w->attrib.x;
                  y = w->attrib.y;

                  /*
                   * Check to see if we are using the plane plugin
                   * The user could have changed it between initiates
                   */
                  for (p = getPlugins(); p; p = p->next)
                  {
                        if (strcmp(p->vTable->name, "plane") == 0)
                              usePlane = TRUE;
                  }

                  /* handle the put types
                   *
                   */
                  switch (type)
                  {
                  case PutCenter:
                        /* center of the screen */
                        dx = (width / 2) - (w->width / 2) - (x - hx);
                        dy = (height / 2) - (w->height / 2) - (y - hy);
                        break;

                  case PutLeft:
                        /* center of the left edge */
                        dx = -(x - hx) + w->input.left + ps->padLeft;
                        dy = (height / 2) - (w->height / 2) - (y - hy);
                        break;

                  case PutTopLeft:
                        /* top left corner */
                        dx = -(x - hx) + w->input.left + ps->padLeft;
                        dy = -(y - hy) + w->input.top + ps->padTop;
                        break;

                  case PutTop:
                        /* center of top edge */
                        dx = (width / 2) - (w->width / 2) - (x - hx);
                        dy = -(y - hy) + w->input.top + ps->padTop;
                        break;

                  case PutTopRight:
                        /* top right corner */
                        dx = width - w->width - (x - hx) -
                                    w->input.right - ps->padRight;
                        dy = -(y - hy) + w->input.top + ps->padTop;
                        break;

                  case PutRight:
                        /* center of right edge */
                        dx = width - w->width - (x - hx) -
                                    w->input.right - ps->padRight;
                        dy = (height / 2) - (w->height / 2) - (y - hy);
                        break;

                  case PutBottomRight:
                        /* bottom right corner */
                        dx = width - w->width - (x - hx) -
                                    w->input.right - ps->padRight;
                        dy = height - w->height - (y - hy) -
                                    w->input.bottom - ps->padBottom;
                        break;

                  case PutBottom:
                        /* center of bottom edge */
                        dx = (width / 2) - (w->width / 2) - (x - hx);
                        dy = height - w->height - (y - hy) -
                                    w->input.bottom - ps->padBottom;
                        break;

                  case PutBottomLeft:
                        /* bottom left corner */
                        dx = -(x - hx) + w->input.left + ps->padLeft;
                        dy = height - w->height - (y - hy) -
                                    w->input.bottom - ps->padBottom;
                        break;

                  case PutRestore:
                        /* back to last position */
                        dx = pw->lastX - x;
                        dy = pw->lastY - y;
                        break;

                  case PutViewport:
                        /* get the fave to move to from the options list */
                        face = getIntOptionNamed(option, nOption, "face", -1);

                        /* if it wasn't supplied, bail out */
                        if (face < 0)
                              return FALSE;

                        /* if we are using the plane plugin, we need to handle y movment */
                        if (usePlane)
                        {
                              /* split 1D face value into 2D x and y face */
                              face_x = face % w->screen->hsize;
                              face_y = face / w->screen->hsize;
                        }
                        else
                        {
                              /* we are not using plane, so it must be cube (for now) */
                              face_x = face;
                              face_y = 0;
                        }

                        /* take the shortest horizontal path to the destination viewport */
                        hdirection = (face_x - w->screen->x);
                        if (hdirection > w->screen->hsize / 2)
                              hdirection = (hdirection - w->screen->hsize);
                        else if (hdirection < -w->screen->hsize / 2)
                              hdirection = (hdirection + w->screen->hsize);

                        /* we need to do this for the vertical destination viewport too
                         * if we are using plane
                         */
                        if (usePlane)
                        {
                              vdirection = (face_y - w->screen->y);
                              if (vdirection > w->screen->vsize / 2)
                                    vdirection = (vdirection - w->screen->vsize);
                              else if (vdirection < -w->screen->hsize / 2)
                                    vdirection = (vdirection + w->screen->vsize);

                              dx = w->screen->width * hdirection;
                              dy = w->screen->height * vdirection;
                        }
                        else
                        {
                              /* we must be using cube, so we by pass vertical
                               * destination calculations
                               */
                              dx = w->screen->width * hdirection;
                              dy = 0;
                        }

                        /* this is a viewport move so we flag it */
                        ps->vpMoving = TRUE;
                        break;

                  case PutViewportLeft:
                        /* move to the viewport on the left */
                        dx = -w->screen->workArea.width;
                        dy = 0;
                        ps->vpMoving = TRUE;
                        break;

                  case PutViewportRight:
                        /* move to the viewport on the right */
                        dx = w->screen->workArea.width;
                        dy = 0;
                        ps->vpMoving = TRUE;
                        break;

                  case PutViewportUp:
                        /* move to the viewport above if we are using plane */
                        dx = 0;
                        dy = 0;
                        if (usePlane)
                              dy = -w->screen->workArea.height;
                        ps->vpMoving = TRUE;
                        break;

                  case PutViewportDown:
                        /* move to the viewport below if we are using plane */
                        dx = 0;
                        dy = 0;
                        if (usePlane)
                              dy = w->screen->workArea.height;
                        ps->vpMoving = TRUE;
                        break;

                  case PutExact:
                        /* move the window to an exact position */
                        if (px < 0)
                              /* account for a specified negative position, like geometry without (-0) */
                              dx = px +
                                          w->screen->workArea.width -
                                          w->width - x - w->input.right;
                        else
                              dx = px - x + w->input.left;

                        if (py < 0)
                              /* account for a specified negative position, like geometry without (-0) */
                              dy = py +
                                          w->screen->workArea.height -
                                          w->height - y - w->input.bottom;
                        else
                              dy = py - y + w->input.top;

                        break;

                  case PutPointer:
                  {
                        /* move the window to the pointers position
                         * using the current quad of the screen to determine
                         * which corner to move to the pointer
                         */
                        int rx, ry;
                        Window root, child;
                        int winx, winy;
                        unsigned int pmask;

                        /* get the pointers position from the X server */
                        XQueryPointer(d->display, w->id,
                                            &root, &child, &rx, &ry, &winx, &winy, &pmask);

                        if (ps->windowcenter)
                        {
                              /* window center */
                              dx = rx - (w->width / 2) - x;
                              dy = ry - (w->height / 2) - y;
                        }
                        else if (rx <
                                     w->screen->workArea.
                                     width / 2 && ry < w->screen->workArea.height / 2)
                        {
                              /* top left quad */
                              dx = rx - x + w->input.left;
                              dy = ry - y + w->input.top;
                        }
                        else if (rx <
                                     w->screen->workArea.
                                     width / 2 && ry >= w->screen->workArea.height / 2)
                        {
                              /* bottom left quad */
                              dx = rx - x + w->input.left;
                              dy = ry - w->height - y - w->input.bottom;
                        }
                        else if (rx >=
                                     w->screen->workArea.
                                     width / 2 && ry < w->screen->workArea.height / 2)
                        {
                              /* top right quad */
                              dx = rx - w->width - x - w->input.right;
                              dy = ry - y + w->input.top;
                        }
                        else
                        {
                              /* bottom right quad */
                              dx = rx - w->width - x - w->input.right;
                              dy = ry - w->height - y - w->input.bottom;
                        }
                  }
                        break;

                  default:
                        /* if an unknown type is specified, do nothing */
                        dx = dy = 0;
                        break;
                  }

                  /* don't do anything if there is nothing to do */
                  if (dx != 0 || dy != 0)
                  {
                        if (ps->avoidoffscreen)
                        {
                              /* avoids window borders offscreen */
                              if ((-(x - hx) + w->input.left + ps->padLeft) > dx)
                                    dx = -(x - hx) + w->input.left + ps->padLeft;
                              else if ((width - w->width -
                                            (x - hx) - w->input.right - ps->padRight) < dx)
                                    dx = width - w->width -
                                                (x - hx) - w->input.right - ps->padRight;

                              if ((-(y - hy) + w->input.top + ps->padTop) > dy)
                                    dy = -(y - hy) + w->input.top + ps->padTop;
                              else if ((height - w->height -
                                            (y - hy) -
                                            w->input.bottom - ps->padBottom) < dy)
                                    dy = height - w->height -
                                                (y - hy) - w->input.bottom - ps->padBottom;
                        }
                        /* save the windows position in the saveMask
                         * this is used when unmaximizing the window
                         */
                        if (w->saveMask & CWX)
                              w->saveWc.x += dx;

                        if (w->saveMask & CWY)
                              w->saveWc.y += dy;

                        /* Make sure everyting starts out at the windows current position */
                        pw->lastX = pw->x = x;
                        pw->lastY = pw->y = y;

                        /* save the change in position to the window */
                        pw->dx = dx;
                        pw->dy = dy;

                        /* mark for animation */
                        pw->adjust = TRUE;
                        ps->moreAdjust = TRUE;

                        /* reset values */
                        pw->tx = pw->ty = 0;

                        /* cause repainting */
                        addWindowDamage(w);
                  }
            }
      }

      /* tell event.c handleEvent to not call XAllowEvents */
      return FALSE;
}

static Bool
putToViewport(CompDisplay * d, CompAction * action, CompActionState state,
                    CompOption * option, int nOption)
{
      int face, i;

      PUT_DISPLAY(d);

      /* get the face option */
      face = getIntOptionNamed(option, nOption, "face", -1);

      /* if it's not supplied, lets figure it out */
      if (face < 0)
      {
            i = PUT_DISPLAY_OPTION_VIEWPORT_1;

            while (i <= PUT_DISPLAY_OPTION_VIEWPORT_12)
            {
                  if (action == &pd->opt[i].value.action)
                  {
                        face = i - PUT_DISPLAY_OPTION_VIEWPORT_1;

                        break;
                  }
                  i++;
            }
      }

      /* setup the options for putInitiate */
      CompOption o[5];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "face";
      o[2].value.i = face;

      o[3].type = CompOptionTypeInt;
      o[3].name = "type";
      o[3].value.i = PutViewport;

      o[4].type = CompOptionTypeInt;
      o[4].name = "window";
      o[4].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 5);

      return FALSE;
}

static Bool
putViewportLeft(CompDisplay * d, CompAction * action,
                        CompActionState state, CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutViewportLeft;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putViewportRight(CompDisplay * d, CompAction * action,
                         CompActionState state, CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutViewportRight;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putViewportUp(CompDisplay * d, CompAction * action, CompActionState state,
                    CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutViewportUp;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putViewportDown(CompDisplay * d, CompAction * action,
                        CompActionState state, CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutViewportDown;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
restore(CompDisplay * d, CompAction * action, CompActionState state,
            CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutRestore;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putPointer(CompDisplay * d, CompAction * action, CompActionState state,
               CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutPointer;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putExact(CompDisplay * d, CompAction * action, CompActionState state,
             CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutExact;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putCenter(CompDisplay * d, CompAction * action, CompActionState state,
              CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutCenter;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putLeft(CompDisplay * d, CompAction * action, CompActionState state,
            CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutLeft;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putTopLeft(CompDisplay * d, CompAction * action, CompActionState state,
               CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutTopLeft;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putTop(CompDisplay * d, CompAction * action, CompActionState state,
         CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutTop;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putTopRight(CompDisplay * d, CompAction * action, CompActionState state,
                  CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutTopRight;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putRight(CompDisplay * d, CompAction * action, CompActionState state,
             CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutRight;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putBottomRight(CompDisplay * d, CompAction * action, CompActionState state,
                     CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutBottomRight;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putBottom(CompDisplay * d, CompAction * action, CompActionState state,
              CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutBottom;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static Bool
putBottomLeft(CompDisplay * d, CompAction * action, CompActionState state,
                    CompOption * option, int nOption)
{
      /* setup the options for putInitiate */
      CompOption o[4];

      o[0].type = CompOptionTypeInt;
      o[0].name = "x";
      o[0].value.i = getIntOptionNamed(option, nOption, "x", 0);

      o[1].type = CompOptionTypeInt;
      o[1].name = "y";
      o[1].value.i = getIntOptionNamed(option, nOption, "y", 0);

      o[2].type = CompOptionTypeInt;
      o[2].name = "type";
      o[2].value.i = PutBottomLeft;

      o[3].type = CompOptionTypeInt;
      o[3].name = "window";
      o[3].value.i = getIntOptionNamed(option, nOption, "window", 0);

      putInitiate(d, NULL, 0, o, 4);

      return FALSE;
}

static void putHandleEvent(CompDisplay * d, XEvent * event)
{
      PUT_DISPLAY(d);

      switch (event->type)
      {
            /* handle client events */
      case ClientMessage:
            /* accept the custom atom for putting windows */
            if (event->xclient.message_type == pd->berylPutWindowAtom)
            {
                  CompWindow *w;

                  w = findWindowAtDisplay(d, event->xclient.window);
                  if (w)
                  {
                        /*
                         * get the values from the xclientmessage event and populate
                         * the options for put initiate
                         *
                         * the format is 32
                         * and the data is
                         * l[0] = x position - unused (for future PutExact)
                         * l[1] = y position - unused (for future PutExact)
                         * l[2] = face number
                         * l[3] = put type, int value from enum
                         * l[4] = Xinerama head number
                         */
                        CompOption opt[6];

                        opt[0].type = CompOptionTypeInt;
                        opt[0].name = "window";
                        opt[0].value.i = event->xclient.window;

                        opt[1].type = CompOptionTypeInt;
                        opt[1].name = "x";
                        opt[1].value.i = event->xclient.data.l[0];

                        opt[2].type = CompOptionTypeInt;
                        opt[2].name = "y";
                        opt[2].value.i = event->xclient.data.l[1];

                        opt[3].type = CompOptionTypeInt;
                        opt[3].name = "face";
                        opt[3].value.i = event->xclient.data.l[2];

                        opt[4].type = CompOptionTypeInt;
                        opt[4].name = "type";
                        opt[4].value.i = event->xclient.data.l[3];

                        opt[5].type = CompOptionTypeInt;
                        opt[5].name = "head";
                        opt[5].value.i = event->xclient.data.l[4];

                        putInitiate(w->screen->display, NULL, 0, opt, 6);

                  }
            }
            break;

      default:
            break;
      }

      UNWRAP(pd, d, handleEvent);
      (*d->handleEvent) (d, event);
      WRAP(pd, d, handleEvent, putHandleEvent);
}

static Bool
putSetDisplayOption(CompDisplay * display, char *name,
                              CompOptionValue * value)
{
      CompOption *o;
      int index;

      PUT_DISPLAY(display);

      o = compFindOption(pd->opt, NUM_OPTIONS(pd), name, &index);

      if (!o)
            return FALSE;

      switch (index)
      {
      case PUT_DISPLAY_OPTION_RESTORE:
      case PUT_DISPLAY_OPTION_CENTER:
      case PUT_DISPLAY_OPTION_LEFT:
      case PUT_DISPLAY_OPTION_TOPLEFT:
      case PUT_DISPLAY_OPTION_TOP:
      case PUT_DISPLAY_OPTION_TOPRIGHT:
      case PUT_DISPLAY_OPTION_RIGHT:
      case PUT_DISPLAY_OPTION_BOTTOMRIGHT:
      case PUT_DISPLAY_OPTION_BOTTOM:
      case PUT_DISPLAY_OPTION_BOTTOMLEFT:
      case PUT_DISPLAY_OPTION_VIEWPORT_LEFT:
      case PUT_DISPLAY_OPTION_VIEWPORT_RIGHT:
      case PUT_DISPLAY_OPTION_VIEWPORT_UP:
      case PUT_DISPLAY_OPTION_VIEWPORT_DOWN:
      case PUT_DISPLAY_OPTION_VIEWPORT:
      case PUT_DISPLAY_OPTION_VIEWPORT_1:
      case PUT_DISPLAY_OPTION_VIEWPORT_2:
      case PUT_DISPLAY_OPTION_VIEWPORT_3:
      case PUT_DISPLAY_OPTION_VIEWPORT_4:
      case PUT_DISPLAY_OPTION_VIEWPORT_5:
      case PUT_DISPLAY_OPTION_VIEWPORT_6:
      case PUT_DISPLAY_OPTION_VIEWPORT_7:
      case PUT_DISPLAY_OPTION_VIEWPORT_8:
      case PUT_DISPLAY_OPTION_VIEWPORT_9:
      case PUT_DISPLAY_OPTION_VIEWPORT_10:
      case PUT_DISPLAY_OPTION_VIEWPORT_11:
      case PUT_DISPLAY_OPTION_VIEWPORT_12:
      case PUT_DISPLAY_OPTION_EXACT:
      case PUT_DISPLAY_OPTION_POINTER:
            if (setDisplayAction(display, o, value))
                  return TRUE;
      default:
            break;
      }
      return FALSE;
}

static void putDisplayInitOptions(PutDisplay * pd)
{
      CompOption *o;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT];
      o->advanced = False;
      o->name = "put_viewport";
      o->group = N_("");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Put on Face");
      o->longDesc = N_("Move Window to a Face of the Cube.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putToViewport;
      o->value.action.terminate = 0;
      o->value.action.bell = FALSE;
      o->value.action.edgeMask = 0;
      o->value.action.state = 0;
      o->value.action.type = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_1];
      o->advanced = False;
      o->name = "put_viewport_1";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to arbitrary face");
      o->displayHints = "";
      o->shortDesc = N_("Put on Face 1");
      o->longDesc = N_("Move Window to Face 1.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putToViewport;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_2];
      o->advanced = False;
      o->name = "put_viewport_2";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to arbitrary face");
      o->displayHints = "";
      o->shortDesc = N_("Put on Face 2");
      o->longDesc = N_("Move Window to Face 2.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putToViewport;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_3];
      o->advanced = False;
      o->name = "put_viewport_3";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to arbitrary face");
      o->displayHints = "";
      o->shortDesc = N_("Put on Face 3");
      o->longDesc = N_("Move Window to Face 3.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putToViewport;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_4];
      o->advanced = False;
      o->name = "put_viewport_4";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to arbitrary face");
      o->displayHints = "";
      o->shortDesc = N_("Put on Face 4");
      o->longDesc = N_("Move Window to Face 4.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putToViewport;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_5];
      o->advanced = False;
      o->name = "put_viewport_5";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to arbitrary face");
      o->displayHints = "";
      o->shortDesc = N_("Put on Face 5");
      o->longDesc = N_("Move Window to Face 5.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putToViewport;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_6];
      o->advanced = False;
      o->name = "put_viewport_6";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to arbitrary face");
      o->displayHints = "";
      o->shortDesc = N_("Put on Face 6");
      o->longDesc = N_("Move Window to Face 6.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putToViewport;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_7];
      o->advanced = False;
      o->name = "put_viewport_7";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to arbitrary face");
      o->displayHints = "";
      o->shortDesc = N_("Put on Face 7");
      o->longDesc = N_("Move Window to Face 7.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putToViewport;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_8];
      o->advanced = False;
      o->name = "put_viewport_8";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to arbitrary face");
      o->displayHints = "";
      o->shortDesc = N_("Put on Face 8");
      o->longDesc = N_("Move Window to Face 8.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putToViewport;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_9];
      o->advanced = False;
      o->name = "put_viewport_9";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to arbitrary face");
      o->displayHints = "";
      o->shortDesc = N_("Put on Face 9");
      o->longDesc = N_("Move Window to Face 9.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putToViewport;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_10];
      o->advanced = False;
      o->name = "put_viewport_10";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to arbitrary face");
      o->displayHints = "";
      o->shortDesc = N_("Put on Face 10");
      o->longDesc = N_("Move Window to Face 10.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putToViewport;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_11];
      o->advanced = False;
      o->name = "put_viewport_11";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to arbitrary face");
      o->displayHints = "";
      o->shortDesc = N_("Put on Face 11");
      o->longDesc = N_("Move Window to Face 11.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putToViewport;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_12];
      o->advanced = False;
      o->name = "put_viewport_12";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to arbitrary face");
      o->displayHints = "";
      o->shortDesc = N_("Put on Face 12");
      o->longDesc = N_("Move Window to Face 12.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putToViewport;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_LEFT];
      o->advanced = False;
      o->name = "put_viewport_left";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to adjacent face");
      o->displayHints = "";
      o->shortDesc = N_("Viewport Left");
      o->longDesc = N_("Move Window to the Viewport on Left.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putViewportLeft;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_RIGHT];
      o->advanced = False;
      o->name = "put_viewport_right";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to adjacent face");
      o->displayHints = "";
      o->shortDesc = N_("Viewport Right");
      o->longDesc = N_("Move Window to the Viewport on Right.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putViewportRight;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_UP];
      o->advanced = False;
      o->name = "put_viewport_up";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to adjacent face");
      o->displayHints = "";
      o->shortDesc = N_("Viewport Up");
      o->longDesc = N_("Move Window to the Viewport on Top.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putViewportUp;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_VIEWPORT_DOWN];
      o->advanced = False;
      o->name = "put_viewport_down";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to adjacent face");
      o->displayHints = "";
      o->shortDesc = N_("Viewport Down");
      o->longDesc = N_("Move Window to the Viewport on Bottom.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putViewportDown;
      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 = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_RESTORE];
      o->advanced = False;
      o->name = "put_restore";
      o->group = N_("Bindings");
      o->subGroup = N_("Restore position");
      o->displayHints = "";
      o->shortDesc = N_("Restore Position");
      o->longDesc = N_("Move Window to the Last Position.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = restore;
      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 = CompBindingTypeKey;
      o->value.action.key.modifiers = PUT_RESTORE_MODIFIERS_DEFAULT;
      o->value.action.key.keysym = XStringToKeysym(PUT_RESTORE_KEY_DEFAULT);

      o = &pd->opt[PUT_DISPLAY_OPTION_POINTER];
      o->advanced = False;
      o->name = "put_pointer";
      o->group = N_("Bindings");
      o->subGroup = N_("Put to pointer");
      o->displayHints = "";
      o->shortDesc = N_("Put Pointer");
      o->longDesc =
                  N_("Move Window to the Pointer position using screen quadrant.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putPointer;
      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 = CompBindingTypeKey;
      o->value.action.key.modifiers = PUT_POINTER_MODIFIERS_DEFAULT;
      o->value.action.key.keysym = XStringToKeysym(PUT_POINTER_KEY_DEFAULT);

      o = &pd->opt[PUT_DISPLAY_OPTION_EXACT];
      o->advanced = False;
      o->name = "put_exact";
      o->group = N_("");
      o->subGroup = N_("");
      o->displayHints = "";
      o->shortDesc = N_("Put Exact");
      o->longDesc = N_("Move Window to x, y.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putExact;
      o->value.action.terminate = 0;
      o->value.action.bell = FALSE;
      o->value.action.edgeMask = 0;
      o->value.action.state = 0;
      o->value.action.type = CompBindingTypeNone;

      o = &pd->opt[PUT_DISPLAY_OPTION_CENTER];
      o->advanced = False;
      o->name = "put_center";
      o->group = N_("Bindings");
      o->subGroup = N_("Put within face");
      o->displayHints = "";
      o->shortDesc = N_("Put Center");
      o->longDesc = N_("Move Window to the Center.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putCenter;
      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 = CompBindingTypeKey;
      o->value.action.key.modifiers = PUT_CENTER_MODIFIERS_DEFAULT;
      o->value.action.key.keysym = XStringToKeysym(PUT_CENTER_KEY_DEFAULT);

      o = &pd->opt[PUT_DISPLAY_OPTION_LEFT];
      o->advanced = False;
      o->name = "put_left";
      o->group = N_("Bindings");
      o->subGroup = N_("Put within face");
      o->displayHints = "";
      o->shortDesc = N_("Put Left");
      o->longDesc = N_("Move Window to the Center of the Left edge.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putLeft;
      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 = CompBindingTypeKey;
      o->value.action.key.modifiers = PUT_LEFT_MODIFIERS_DEFAULT;
      o->value.action.key.keysym = XStringToKeysym(PUT_LEFT_KEY_DEFAULT);

      o = &pd->opt[PUT_DISPLAY_OPTION_TOPLEFT];
      o->advanced = False;
      o->name = "put_top_left";
      o->group = N_("Bindings");
      o->subGroup = N_("Put within face");
      o->displayHints = "";
      o->shortDesc = N_("Put Top Left");
      o->longDesc = N_("Move Window to the Top Left corner.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putTopLeft;
      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 = CompBindingTypeKey;
      o->value.action.key.modifiers = PUT_TOPLEFT_MODIFIERS_DEFAULT;
      o->value.action.key.keysym = XStringToKeysym(PUT_TOPLEFT_KEY_DEFAULT);

      o = &pd->opt[PUT_DISPLAY_OPTION_TOP];
      o->advanced = False;
      o->name = "put_top";
      o->group = N_("Bindings");
      o->subGroup = N_("Put within face");
      o->displayHints = "";
      o->shortDesc = N_("Put Top");
      o->longDesc = N_("Move Window to the Center of the Top edge.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putTop;
      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 = CompBindingTypeKey;
      o->value.action.key.modifiers = PUT_TOP_MODIFIERS_DEFAULT;
      o->value.action.key.keysym = XStringToKeysym(PUT_TOP_KEY_DEFAULT);

      o = &pd->opt[PUT_DISPLAY_OPTION_TOPRIGHT];
      o->advanced = False;
      o->name = "put_top_right";
      o->group = N_("Bindings");
      o->subGroup = N_("Put within face");
      o->displayHints = "";
      o->shortDesc = N_("Put Top Right");
      o->longDesc = N_("Move Window to the Top Right corner.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putTopRight;
      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 = CompBindingTypeKey;
      o->value.action.key.modifiers = PUT_TOPRIGHT_MODIFIERS_DEFAULT;
      o->value.action.key.keysym = XStringToKeysym(PUT_TOPRIGHT_KEY_DEFAULT);

      o = &pd->opt[PUT_DISPLAY_OPTION_RIGHT];
      o->advanced = False;
      o->name = "put_right";
      o->group = N_("Bindings");
      o->subGroup = N_("Put within face");
      o->displayHints = "";
      o->shortDesc = N_("Put Right");
      o->longDesc = N_("Move Window to the Center of the Right edge.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putRight;
      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 = CompBindingTypeKey;
      o->value.action.key.modifiers = PUT_RIGHT_MODIFIERS_DEFAULT;
      o->value.action.key.keysym = XStringToKeysym(PUT_RIGHT_KEY_DEFAULT);

      o = &pd->opt[PUT_DISPLAY_OPTION_BOTTOMRIGHT];
      o->advanced = False;
      o->name = "put_bottom_right";
      o->group = N_("Bindings");
      o->subGroup = N_("Put within face");
      o->displayHints = "";
      o->shortDesc = N_("Put Bottom Right");
      o->longDesc = N_("Move Window to the Bottom Right corner.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putBottomRight;
      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 = CompBindingTypeKey;
      o->value.action.key.modifiers = PUT_BOTTOMRIGHT_MODIFIERS_DEFAULT;
      o->value.action.key.keysym = XStringToKeysym(PUT_BOTTOMRIGHT_KEY_DEFAULT);

      o = &pd->opt[PUT_DISPLAY_OPTION_BOTTOM];
      o->advanced = False;
      o->name = "put_bottom";
      o->group = N_("Bindings");
      o->subGroup = N_("Put within face");
      o->displayHints = "";
      o->shortDesc = N_("Put Bottom");
      o->longDesc = N_("Move Window to the Center of the Bottom edge.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putBottom;
      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 = CompBindingTypeKey;
      o->value.action.key.modifiers = PUT_BOTTOM_MODIFIERS_DEFAULT;
      o->value.action.key.keysym = XStringToKeysym(PUT_BOTTOM_KEY_DEFAULT);

      o = &pd->opt[PUT_DISPLAY_OPTION_BOTTOMLEFT];
      o->advanced = False;
      o->name = "put_bottom_left";
      o->group = N_("Bindings");
      o->subGroup = N_("Put within face");
      o->displayHints = "";
      o->shortDesc = N_("Put Bottom Left");
      o->longDesc = N_("Move Window to the Bottom Left corner.");
      o->type = CompOptionTypeAction;
      o->value.action.initiate = putBottomLeft;
      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 = CompBindingTypeKey;
      o->value.action.key.modifiers = PUT_BOTTOMLEFT_MODIFIERS_DEFAULT;
      o->value.action.key.keysym = XStringToKeysym(PUT_BOTTOMLEFT_KEY_DEFAULT);
}

static CompOption *putGetDisplayOptions(CompDisplay * display, int *count)
{
      if (display)
      {
            PUT_DISPLAY(display);
            *count = NUM_OPTIONS(pd);
            return pd->opt;
      }
      else
      {
            PutDisplay *pd = malloc(sizeof(PutDisplay));

            putDisplayInitOptions(pd);
            *count = NUM_OPTIONS(pd);
            return pd->opt;
      }
}

static Bool putInitDisplay(CompPlugin * p, CompDisplay * d)
{
      PutDisplay *pd;

      pd = malloc(sizeof(PutDisplay));
      if (!pd)
            return FALSE;

      pd->screenPrivateIndex = allocateScreenPrivateIndex(d);
      if (pd->screenPrivateIndex < 0)
      {
            free(pd);
            return FALSE;
      }

      /* custom atom for client events */
      pd->berylPutWindowAtom = XInternAtom(d->display, "_BERYL_PUT_WINDOW", 0);

      putDisplayInitOptions(pd);
      WRAP(pd, d, handleEvent, putHandleEvent);
      d->privates[displayPrivateIndex].ptr = pd;

      return TRUE;
}

static void putFiniDisplay(CompPlugin * p, CompDisplay * d)
{
      PUT_DISPLAY(d);
      freeScreenPrivateIndex(d, pd->screenPrivateIndex);
      UNWRAP(pd, d, handleEvent);
      free(pd);
}

static Bool putInitScreen(CompPlugin * p, CompScreen * s)
{
      PutScreen *ps;

      PUT_DISPLAY(s->display);

      ps = malloc(sizeof(PutScreen));
      if (!ps)
            return FALSE;

      ps->windowPrivateIndex = allocateWindowPrivateIndex(s);
      if (ps->windowPrivateIndex < 0)
      {
            free(ps);
            return FALSE;
      }

      /* initialize variables
       * bad stuff happens if we don't do this
       */
      ps->speed = PUT_SPEED_DEFAULT;
      ps->timestep = PUT_TIMESTEP_DEFAULT;
      ps->moreAdjust = FALSE;
      ps->padLeft = PUT_LEFT_PAD_DEFAULT;
      ps->padTop = PUT_TOP_PAD_DEFAULT;
      ps->padRight = PUT_RIGHT_PAD_DEFAULT;
      ps->padBottom = PUT_BOTTOM_PAD_DEFAULT;
      ps->vpMoving = FALSE;
      ps->unfocusWindow = PUT_UNFOCUS_WINDOW_DEFAULT;
      ps->windowcenter = PUT_WINDOW_CENTER_DEFAULT;
      ps->avoidoffscreen = PUT_AVOID_OFFSCREEN_DEFAULT;
      ps->current = NULL;
      ps->grabIndex = 0;

      /* Initialize the screen options
       * again, bad stuff if we forget
       */
      putScreenInitOptions(ps);

      /* add the screen actions */
      addScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_POINTER].value.action);
      addScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_RESTORE].value.action);
      addScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_CENTER].value.action);
      addScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_LEFT].value.action);
      addScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_TOPLEFT].value.action);
      addScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_TOP].value.action);
      addScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_TOPRIGHT].value.action);
      addScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_RIGHT].value.action);
      addScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_BOTTOMRIGHT].value.action);
      addScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_BOTTOM].value.action);
      addScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_BOTTOMLEFT].value.action);

      /* wrap the overloaded functions */
      WRAP(ps, s, preparePaintScreen, putPreparePaintScreen);
      WRAP(ps, s, donePaintScreen, putDonePaintScreen);
      WRAP(ps, s, paintScreen, putPaintScreen);
      WRAP(ps, s, paintWindow, putPaintWindow);

      s->privates[pd->screenPrivateIndex].ptr = ps;
      return TRUE;
}

static void putFiniScreen(CompPlugin * p, CompScreen * s)
{
      PUT_SCREEN(s);
      PUT_DISPLAY(s->display);
      freeWindowPrivateIndex(s, ps->windowPrivateIndex);
      UNWRAP(ps, s, preparePaintScreen);
      UNWRAP(ps, s, donePaintScreen);
      UNWRAP(ps, s, paintScreen);
      UNWRAP(ps, s, paintWindow);

      removeScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_POINTER].value.action);
      removeScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_RESTORE].value.action);
      removeScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_CENTER].value.action);
      removeScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_LEFT].value.action);
      removeScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_TOPLEFT].value.action);
      removeScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_TOP].value.action);
      removeScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_TOPRIGHT].value.action);
      removeScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_RIGHT].value.action);
      removeScreenAction(s,
                                 &pd->opt[PUT_DISPLAY_OPTION_BOTTOMRIGHT].value.action);
      removeScreenAction(s, &pd->opt[PUT_DISPLAY_OPTION_BOTTOM].value.action);
      removeScreenAction(s,
                                 &pd->opt[PUT_DISPLAY_OPTION_BOTTOMLEFT].value.action);
      free(ps);
}

static Bool putInitWindow(CompPlugin * p, CompWindow * w)
{
      PutWindow *pw;

      PUT_SCREEN(w->screen);

      pw = malloc(sizeof(PutWindow));
      if (!pw)
            return FALSE;

      /* initialize variables
       * I don't need to repeat it
       */
      pw->tx = pw->ty = pw->xVelocity = pw->yVelocity = 0.0f;
      pw->dx = pw->dy = 0;
      pw->lastX = pw->x = w->serverX;
      pw->lastY = pw->y = w->serverY;
      pw->adjust = FALSE;

      w->privates[ps->windowPrivateIndex].ptr = pw;

      return TRUE;
}

static void putFiniWindow(CompPlugin * p, CompWindow * w)
{
      PUT_WINDOW(w);
      free(pw);
}

static Bool putInit(CompPlugin * p)
{
      displayPrivateIndex = allocateDisplayPrivateIndex();
      if (displayPrivateIndex < 0)
            return FALSE;

      return TRUE;
}

static void putFini(CompPlugin * p)
{
      if (displayPrivateIndex >= 0)
            freeDisplayPrivateIndex(displayPrivateIndex);
}

/*
 * vTable tells the dl
 * what we offer
 */
CompPluginVTable putVTable = {
      "put",
      N_("Put"),
      N_("Put window"),
      putInit,
      putFini,
      putInitDisplay,
      putFiniDisplay,
      putInitScreen,
      putFiniScreen,
      putInitWindow,
      putFiniWindow,
      putGetDisplayOptions,
      putSetDisplayOption,
      putGetScreenOptions,
      putSetScreenOption,
      0,
      0,
      0,
      0,
      BERYL_ABI_INFO,
      "beryl-plugins",
      "wm",
      0,
      0,
      False,
};

CompPluginVTable *getCompPluginInfo(void)
{
      return &putVTable;
}

Generated by  Doxygen 1.6.0   Back to index