summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Spilsbury <Sam@XPS-SUSE.site>2008-11-29 11:31:42 +0900
committerSam Spilsbury <Sam@XPS-SUSE.site>2008-11-29 11:31:42 +0900
commita4398d8ccdf5f8bed2aa4e7281caa572f779182c (patch)
tree7a1b89863820ac128872acb4d0ea4c52f184dace
parent7d35ef86384f0e8d85f1aaadaf2eeab6fcbf768b (diff)
downloadcompiz-mpx-ir-a4398d8ccdf5f8bed2aa4e7281caa572f779182c.tar.gz
compiz-mpx-ir-a4398d8ccdf5f8bed2aa4e7281caa572f779182c.tar.bz2
Added peek patch
-rw-r--r--fusion/plugins/mag/0001-MPX-Inclusion.patch~1373
-rw-r--r--fusion/plugins/peek/0001-MPX-Support-Patch.patch368
2 files changed, 1741 insertions, 0 deletions
diff --git a/fusion/plugins/mag/0001-MPX-Inclusion.patch~ b/fusion/plugins/mag/0001-MPX-Inclusion.patch~
new file mode 100644
index 0000000..ec2cf65
--- /dev/null
+++ b/fusion/plugins/mag/0001-MPX-Inclusion.patch~
@@ -0,0 +1,1373 @@
+From 78b452dda80c9b8b2fc700de728f4d4bfb6daa12 Mon Sep 17 00:00:00 2001
+From: Sam Spilsbury <Sam@XPS-SUSE.site>
+Date: Wed, 29 Oct 2008 15:22:12 +0900
+Subject: [PATCH] * MPX Inclusion
+
+---
+ mag.c | 913 +++++++++++++++++++++++++++++++++++++++--------------------------
+ 1 files changed, 553 insertions(+), 360 deletions(-)
+
+diff --git a/mag.c b/mag.c
+index 5496927..59e06dd 100644
+--- a/mag.c
++++ b/mag.c
+@@ -60,8 +60,10 @@ typedef struct _MagImage
+ }
+ MagImage;
+
+-typedef struct _MagScreen
++typedef struct _MagDevice
+ {
++ CompDevice *dev;
++
+ int posX;
+ int posY;
+
+@@ -71,18 +73,25 @@ typedef struct _MagScreen
+ GLfloat zTarget;
+ GLfloat zoom;
+
+- MagModeEnum mode;
+-
+- GLuint texture;
++ GLuint program;
+ GLenum target;
++ GLuint texture;
+
+ int width;
+ int height;
+
++ struct _MagDevice *next;
++
++} MagDevice;
++
++typedef struct _MagScreen
++{
++ MagDevice *devices;
++
+ MagImage overlay;
+ MagImage mask;
+
+- GLuint program;
++ MagModeEnum mode;
+
+ PositionPollingHandle pollHandle;
+
+@@ -122,43 +131,18 @@ static const char *fisheyeFpString =
+
+ "END";
+
+-static void
+-magCleanup (CompScreen *s)
+-{
+- MAG_SCREEN (s);
+-
+- if (ms->overlay.loaded)
+- {
+- ms->overlay.loaded = FALSE;
+- finiTexture (s, &ms->overlay.tex);
+- initTexture (s, &ms->overlay.tex);
+- }
+- if (ms->mask.loaded)
+- {
+- ms->mask.loaded = FALSE;
+- finiTexture (s, &ms->mask.tex);
+- initTexture (s, &ms->mask.tex);
+- }
+
+- if (ms->program)
+- {
+- (*s->deletePrograms) (1, &ms->program);
+- ms->program = 0;
+- }
+-}
+
+ static Bool
+-loadFragmentProgram (CompScreen *s)
++loadFragmentProgram (CompScreen *s, MagDevice *dev)
+ {
+ char buffer[1024];
+ GLint errorPos;
+
+- MAG_SCREEN (s);
+-
+ if (!s->fragmentProgram)
+ return FALSE;
+
+- if (ms->target == GL_TEXTURE_2D)
++ if (dev->target == GL_TEXTURE_2D)
+ sprintf (buffer, fisheyeFpString, "2D");
+ else
+ sprintf (buffer, fisheyeFpString, "RECT");
+@@ -166,10 +150,10 @@ loadFragmentProgram (CompScreen *s)
+ /* clear errors */
+ glGetError ();
+
+- if (!ms->program)
+- (*s->genPrograms) (1, &ms->program);
++ if (!dev->program)
++ (*s->genPrograms) (1, &dev->program);
+
+- (*s->bindProgram) (GL_FRAGMENT_PROGRAM_ARB, ms->program);
++ (*s->bindProgram) (GL_FRAGMENT_PROGRAM_ARB, dev->program);
+ (*s->programString) (GL_FRAGMENT_PROGRAM_ARB,
+ GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen (buffer), buffer);
+@@ -180,8 +164,8 @@ loadFragmentProgram (CompScreen *s)
+ compLogMessage ("mag", CompLogLevelError,
+ "failed to fisheye program");
+
+- (*s->deletePrograms) (1, &ms->program);
+- ms->program = 0;
++ (*s->deletePrograms) (1, &dev->program);
++ dev->program = 0;
+
+ return FALSE;
+ }
+@@ -245,11 +229,180 @@ loadImages (CompScreen *s)
+ }
+
+ static void
++magCleanup (CompScreen *s)
++{
++ MAG_SCREEN (s);
++
++ if (ms->overlay.loaded)
++ {
++ ms->overlay.loaded = FALSE;
++ finiTexture (s, &ms->overlay.tex);
++ initTexture (s, &ms->overlay.tex);
++ }
++ if (ms->mask.loaded)
++ {
++ ms->mask.loaded = FALSE;
++ finiTexture (s, &ms->mask.tex);
++ initTexture (s, &ms->mask.tex);
++ }
++}
++
++static void
++magCleanupDevice (CompScreen *s, MagDevice *dev)
++{
++ glDeleteTextures (1, &dev->target);
++
++ if (dev->program)
++ {
++ (*s->deletePrograms) (1, &dev->program);
++ dev->program = 0;
++ }
++}
++
++
++/* Get device info, add to list, etc */
++
++static void
++magInitDevice (CompScreen *s,
++ MagDevice *dev)
++{
++
++ MAG_SCREEN (s);
++
++ glGenTextures (1, &dev->texture);
++
++ if (s->textureNonPowerOfTwo)
++ dev->target = GL_TEXTURE_2D;
++ else
++ dev->target = GL_TEXTURE_RECTANGLE_ARB;
++
++ glEnable (dev->target);
++
++ /* Bind the texture */
++ glBindTexture (dev->target, dev->texture);
++
++ /* Load the parameters */
++ glTexParameteri (dev->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++ glTexParameteri (dev->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++ glTexParameteri (dev->target, GL_TEXTURE_WRAP_S, GL_CLAMP);
++ glTexParameteri (dev->target, GL_TEXTURE_WRAP_T, GL_CLAMP);
++
++ glTexImage2D (dev->target, 0, GL_RGB, 0, 0, 0,
++ GL_RGB, GL_UNSIGNED_BYTE, NULL);
++
++ dev->zoom = 1.0;
++ dev->zVelocity = 0.0;
++ dev->zTarget = 1.0;
++
++ dev->width = 0;
++ dev->height = 0;
++
++ glBindTexture (dev->target, 0);
++
++ glDisable (dev->target);
++
++ dev->program = 0;
++
++ switch (magGetMode (s))
++ {
++ case ModeImageOverlay:
++ if (loadImages (s))
++ ms->mode = ModeImageOverlay;
++ else
++ ms->mode = ModeSimple;
++ break;
++ case ModeFisheye:
++ if (loadFragmentProgram (s, dev))
++ ms->mode = ModeFisheye;
++ else
++ ms->mode = ModeSimple;
++ break;
++ default:
++ ms->mode = ModeSimple;
++ }
++
++}
++
++static MagDevice *
++magAddDeviceToList (CompScreen *s,
++ CompDevice *dev)
++{
++ MAG_SCREEN (s);
++ MagDevice *mDev;
++
++ if (!ms->devices)
++ {
++ ms->devices = calloc (1, sizeof (MagDevice));
++ if (!ms->devices)
++ return NULL;
++ ms->devices->dev = dev;
++ ms->devices->next = NULL;
++ magInitDevice (s, ms->devices);
++ return ms->devices;
++ }
++ else
++ {
++ for (mDev = ms->devices; mDev->next; mDev = mDev->next);
++ /* List exhausted */
++
++ mDev->next = calloc (1, sizeof (MagDevice));
++ if (!mDev->next)
++ return NULL;
++ mDev->next->dev = dev;
++ mDev->next->next = NULL;
++ magInitDevice (s, mDev->next);
++ return mDev->next;
++ }
++ return NULL;
++}
++
++static void
++magRemoveDeviceFromList (CompScreen *s,
++ MagDevice *dev)
++{
++ MAG_SCREEN (s);
++ MagDevice *run;
++
++ if (!ms->devices)
++ return;
++
++ if (dev == ms->devices)
++ {
++ if (ms->devices->next)
++ ms->devices = ms->devices->next;
++ else
++ ms->devices = NULL;
++
++ magCleanupDevice (s, dev);
++ if (dev)
++ free (dev);
++ }
++ else
++ {
++ for (run = ms->devices; run; run = run->next)
++ {
++ if (run->next)
++ if (run->next == dev)
++ {
++ if (run->next->next)
++ run->next = run->next->next;
++ else
++ run = NULL;
++
++ magCleanupDevice (s, dev);
++ if (dev)
++ free (dev);
++ }
++ }
++ }
++}
++static void
+ magOptionsChanged (CompScreen *s,
+ CompOption *opt,
+ MagScreenOptions num)
+ {
+ MAG_SCREEN (s);
++ MagDevice *dev;
+
+ magCleanup (s);
+
+@@ -262,21 +415,31 @@ magOptionsChanged (CompScreen *s,
+ ms->mode = ModeSimple;
+ break;
+ case ModeFisheye:
+- if (loadFragmentProgram (s))
+- ms->mode = ModeFisheye;
+- else
+- ms->mode = ModeSimple;
++ {
++ MagDevice *dev;
++ for (dev = ms->devices; dev; dev = dev->next)
++ {
++ if (loadFragmentProgram (s, dev))
++ ms->mode = ModeFisheye;
++ else
++ {
++ ms->mode = ModeSimple;
++ break;
++ }
++ }
+ break;
++ }
+ default:
+ ms->mode = ModeSimple;
+ }
+
+- if (ms->zoom != 1.0)
+- damageScreen (s);
++ for (dev = ms->devices; dev; dev = dev->next)
++ if (dev->zoom != 1.0)
++ damageScreen (s);
+ }
+
+ static void
+-damageRegion (CompScreen *s)
++damageRegion (CompScreen *s, MagDevice *dev)
+ {
+ REGION r;
+
+@@ -297,26 +460,26 @@ damageRegion (CompScreen *s)
+ w += 2 * b;
+ h += 2 * b;
+
+- r.extents.x1 = MAX (0, MIN (ms->posX - (w / 2), s->width - w));
++ r.extents.x1 = MAX (0, MIN (dev->posX - (w / 2), s->width - w));
+ r.extents.x2 = r.extents.x1 + w;
+- r.extents.y1 = MAX (0, MIN (ms->posY - (h / 2), s->height - h));
++ r.extents.y1 = MAX (0, MIN (dev->posY - (h / 2), s->height - h));
+ r.extents.y2 = r.extents.y1 + h;
+ }
+ break;
+ case ModeImageOverlay:
+- r.extents.x1 = ms->posX - magGetXOffset (s);
++ r.extents.x1 = dev->posX - magGetXOffset (s);
+ r.extents.x2 = r.extents.x1 + ms->overlay.width;
+- r.extents.y1 = ms->posY - magGetYOffset (s);
++ r.extents.y1 = dev->posY - magGetYOffset (s);
+ r.extents.y2 = r.extents.y1 + ms->overlay.height;
+ break;
+ case ModeFisheye:
+ {
+ int radius = magGetRadius (s);
+
+- r.extents.x1 = MAX (0.0, ms->posX - radius);
+- r.extents.x2 = MIN (s->width, ms->posX + radius);
+- r.extents.y1 = MAX (0.0, ms->posY - radius);
+- r.extents.y2 = MIN (s->height, ms->posY + radius);
++ r.extents.x1 = MAX (0.0, dev->posX - radius);
++ r.extents.x2 = MIN (s->width, dev->posX + radius);
++ r.extents.y1 = MAX (0.0, dev->posY - radius);
++ r.extents.y2 = MIN (s->height, dev->posY + radius);
+ }
+ break;
+ }
+@@ -326,28 +489,37 @@ damageRegion (CompScreen *s)
+
+ static void
+ positionUpdate (CompScreen *s,
+- int x,
+- int y)
++ MousepollDevice *dev)
+ {
+ MAG_SCREEN (s);
+
+- damageRegion (s);
++ MagDevice *mDev;
++
++ for (; dev; dev = dev->next)
++ {
++ for (mDev = ms->devices; mDev; mDev = mDev->next)
++ {
++ if (dev->dev == mDev->dev)
++ {
++
++ damageRegion (s, mDev);
+
+- ms->posX = x;
+- ms->posY = y;
++ mDev->posX = dev->posX;
++ mDev->posY = dev->posY;
+
+- damageRegion (s);
++ damageRegion (s, mDev);
++ }
++ }
++ }
+ }
+
+ static int
+-adjustZoom (CompScreen *s, float chunk)
++adjustZoom (MagDevice *dev, float chunk)
+ {
+ float dx, adjust, amount;
+ float change;
+
+- MAG_SCREEN(s);
+-
+- dx = ms->zTarget - ms->zoom;
++ dx = dev->zTarget - dev->zoom;
+
+ adjust = dx * 0.15f;
+ amount = fabs(dx) * 1.5f;
+@@ -356,23 +528,23 @@ adjustZoom (CompScreen *s, float chunk)
+ else if (amount > 2.0f)
+ amount = 2.0f;
+
+- ms->zVelocity = (amount * ms->zVelocity + adjust) / (amount + 1.0f);
++ dev->zVelocity = (amount * dev->zVelocity + adjust) / (amount + 1.0f);
+
+- if (fabs (dx) < 0.002f && fabs (ms->zVelocity) < 0.004f)
++ if (fabs (dx) < 0.002f && fabs (dev->zVelocity) < 0.004f)
+ {
+- ms->zVelocity = 0.0f;
+- ms->zoom = ms->zTarget;
++ dev->zVelocity = 0.0f;
++ dev->zoom = dev->zTarget;
+ return FALSE;
+ }
+
+- change = ms->zVelocity * chunk;
++ change = dev->zVelocity * chunk;
+ if (!change)
+ {
+- if (ms->zVelocity)
++ if (dev->zVelocity)
+ change = (dx > 0) ? 0.01 : -0.01;
+ }
+
+- ms->zoom += change;
++ dev->zoom += change;
+
+ return TRUE;
+ }
+@@ -384,36 +556,42 @@ magPreparePaintScreen (CompScreen *s,
+ MAG_SCREEN (s);
+ MAG_DISPLAY (s->display);
+
+- if (ms->adjust)
++ MagDevice *dev;
++
++ for (dev = ms->devices; dev; dev = dev->next)
+ {
+- int steps;
+- float amount, chunk;
+
+- amount = time * 0.35f * magGetSpeed (s);
+- steps = amount / (0.5f * magGetTimestep (s));
++ if (dev->adjust)
++ {
++ int steps;
++ float amount, chunk;
+
+- if (!steps)
+- steps = 1;
++ amount = time * 0.35f * magGetSpeed (s);
++ steps = amount / (0.5f * magGetTimestep (s));
+
+- chunk = amount / (float) steps;
++ if (!steps)
++ steps = 1;
+
+- while (steps--)
+- {
+- ms->adjust = adjustZoom (s, chunk);
+- if (ms->adjust)
+- break;
+- }
+- }
++ chunk = amount / (float) steps;
+
+- if (ms->zoom != 1.0)
+- {
+- if (!ms->pollHandle)
++ while (steps--)
++ {
++ dev->adjust = adjustZoom (dev, chunk);
++ if (dev->adjust)
++ break;
++ }
++ }
++
++ if (dev->zoom != 1.0)
+ {
+- (*md->mpFunc->getCurrentPosition) (s, &ms->posX, &ms->posY);
+- ms->pollHandle =
+- (*md->mpFunc->addPositionPolling) (s, positionUpdate);
++ if (!ms->pollHandle)
++ {
++ (*md->mpFunc->getCurrentPosition) (s, dev, &dev->posX, &dev->posY);
++ ms->pollHandle =
++ (*md->mpFunc->addPositionPolling) (s, NULL, positionUpdate);
++ }
++ damageRegion (s, dev);
+ }
+- damageRegion (s);
+ }
+
+ UNWRAP (ms, s, preparePaintScreen);
+@@ -427,39 +605,51 @@ magDonePaintScreen (CompScreen *s)
+ MAG_SCREEN (s);
+ MAG_DISPLAY (s->display);
+
+- if (ms->adjust)
+- damageRegion (s);
++ MagDevice *dev;
+
+- if (!ms->adjust && ms->zoom == 1.0 && (ms->width || ms->height))
++ if (ms->devices)
++ for (dev = ms->devices; dev; dev = dev->next)
+ {
+- glEnable (ms->target);
+
+- glBindTexture (ms->target, ms->texture);
++ if (dev->adjust)
++ damageRegion (s, dev);
++
++ if (!dev->adjust && dev->zoom == 1.0 && (dev->width || dev->height))
++ {
++ glEnable (dev->target);
++
++ glBindTexture (dev->target, dev->texture);
+
+- glTexImage2D (ms->target, 0, GL_RGB, 0, 0, 0,
++ glTexImage2D (dev->target, 0, GL_RGB, 0, 0, 0,
+ GL_RGB, GL_UNSIGNED_BYTE, NULL);
+
+- ms->width = 0;
+- ms->height = 0;
+-
+- glBindTexture (ms->target, 0);
++ dev->width = 0;
++ dev->height = 0;
+
+- glDisable (ms->target);
+- }
++ glBindTexture (dev->target, 0);
+
+- if (ms->zoom == 1.0 && !ms->adjust && ms->pollHandle)
+- {
+- (*md->mpFunc->removePositionPolling) (s, ms->pollHandle);
+- ms->pollHandle = 0;
+- }
++ glDisable (dev->target);
++ }
++
++ if (dev->zoom == 1.0 && !dev->adjust && dev->zTarget == 1.0)
++ {
++ magRemoveDeviceFromList (s, dev);
+
++ if (!ms->devices)
++ {
++ (*md->mpFunc->removePositionPolling) (s, ms->pollHandle);
++ ms->pollHandle = 0;
++ }
++ }
++
++ }
+ UNWRAP (ms, s, donePaintScreen);
+ (*s->donePaintScreen) (s);
+ WRAP (ms, s, donePaintScreen, magDonePaintScreen);
+ }
+
+ static void
+-magPaintSimple (CompScreen *s)
++magPaintSimple (CompScreen *s, MagDevice *dev)
+ {
+ float pw, ph, bw, bh;
+ int x1, x2, y1, y2;
+@@ -470,171 +660,170 @@ magPaintSimple (CompScreen *s)
+ unsigned short *color;
+ float tmp;
+
+- MAG_SCREEN (s);
+-
+ w = magGetBoxWidth (s);
+ h = magGetBoxHeight (s);
+
+ kScreen = magGetKeepScreen (s);
+
+- x1 = ms->posX - (w / 2);
+- if (kScreen)
++ x1 = dev->posX - (w / 2);
++ if (kScreen)
+ x1 = MAX (0, MIN (x1, s->width - w));
+- x2 = x1 + w;
+- y1 = ms->posY - (h / 2);
+- if (kScreen)
++ x2 = x1 + w;
++ y1 = dev->posY - (h / 2);
++ if (kScreen)
+ y1 = MAX (0, MIN (y1, s->height - h));
+- y2 = y1 + h;
+-
+- cw = ceil ((float)w / (ms->zoom * 2.0)) * 2.0;
+- ch = ceil ((float)h / (ms->zoom * 2.0)) * 2.0;
+- cw = MIN (w, cw + 2);
+- ch = MIN (h, ch + 2);
+- cx = (w - cw) / 2;
+- cy = (h - ch) / 2;
++ y2 = y1 + h;
+
+- cx = MAX (0, MIN (w - cw, cx));
+- cy = MAX (0, MIN (h - ch, cy));
++ cw = ceil ((float)w / (dev->zoom * 2.0)) * 2.0;
++ ch = ceil ((float)h / (dev->zoom * 2.0)) * 2.0;
++ cw = MIN (w, cw + 2);
++ ch = MIN (h, ch + 2);
++ cx = (w - cw) / 2;
++ cy = (h - ch) / 2;
+
+- if (x1 != (ms->posX - (w / 2)))
+- {
++ cx = MAX (0, MIN (w - cw, cx));
++ cy = MAX (0, MIN (h - ch, cy));
++
++ if (x1 != (dev->posX - (w / 2)))
++ {
+ cx = 0;
+ cw = w;
+- }
+- if (y1 != (ms->posY - (h / 2)))
+- {
++ }
++ if (y1 != (dev->posY - (h / 2)))
++ {
+ cy = 0;
+ ch = h;
+- }
++ }
+
+- glEnable (ms->target);
++ glEnable (dev->target);
+
+- glBindTexture (ms->target, ms->texture);
++ glBindTexture (dev->target, dev->texture);
+
+- if (ms->width != w || ms->height != h)
+- {
+- glCopyTexImage2D(ms->target, 0, GL_RGB, x1, s->height - y2,
++ if (dev->width != w || dev->height != h)
++ {
++ glCopyTexImage2D(dev->target, 0, GL_RGB, x1, s->height - y2,
+ w, h, 0);
+- ms->width = w;
+- ms->height = h;
+- }
+- else
+- glCopyTexSubImage2D (ms->target, 0, cx, cy,
++ dev->width = w;
++ dev->height = h;
++ }
++ else
++ glCopyTexSubImage2D (dev->target, 0, cx, cy,
+ x1 + cx, s->height - y2 + cy, cw, ch);
+
+- if (ms->target == GL_TEXTURE_2D)
+- {
+- pw = 1.0 / ms->width;
+- ph = 1.0 / ms->height;
+- }
+- else
+- {
++ if (dev->target == GL_TEXTURE_2D)
++ {
++ pw = 1.0 / dev->width;
++ ph = 1.0 / dev->height;
++ }
++ else
++ {
+ pw = 1.0;
+ ph = 1.0;
+- }
++ }
+
+- glMatrixMode (GL_PROJECTION);
+- glPushMatrix ();
+- glLoadIdentity ();
+- glMatrixMode (GL_MODELVIEW);
+- glPushMatrix ();
+- glLoadIdentity ();
++ glMatrixMode (GL_PROJECTION);
++ glPushMatrix ();
++ glLoadIdentity ();
++ glMatrixMode (GL_MODELVIEW);
++ glPushMatrix ();
++ glLoadIdentity ();
+
+- vc[0] = ((x1 * 2.0) / s->width) - 1.0;
+- vc[1] = ((x2 * 2.0) / s->width) - 1.0;
+- vc[2] = ((y1 * -2.0) / s->height) + 1.0;
+- vc[3] = ((y2 * -2.0) / s->height) + 1.0;
++ vc[0] = ((x1 * 2.0) / s->width) - 1.0;
++ vc[1] = ((x2 * 2.0) / s->width) - 1.0;
++ vc[2] = ((y1 * -2.0) / s->height) + 1.0;
++ vc[3] = ((y2 * -2.0) / s->height) + 1.0;
+
+- tc[0] = 0.0;
+- tc[1] = w * pw;
+- tc[2] = h * ph;
+- tc[3] = 0.0;
++ tc[0] = 0.0;
++ tc[1] = w * pw;
++ tc[2] = h * ph;
++ tc[3] = 0.0;
+
+- glColor4usv (defaultColor);
++ glColor4usv (defaultColor);
+
+- glPushMatrix ();
++ glPushMatrix ();
+
+- glTranslatef ((float)(ms->posX - (s->width / 2)) * 2 / s->width,
+- (float)(ms->posY - (s->height / 2)) * 2 / -s->height, 0.0);
++ glTranslatef ((float)(dev->posX - (s->width / 2)) * 2 / s->width,
++ (float)(dev->posY - (s->height / 2)) * 2 / -s->height, 0.0);
+
+- glScalef (ms->zoom, ms->zoom, 1.0);
++ glScalef (dev->zoom, dev->zoom, 1.0);
+
+- glTranslatef ((float)((s->width / 2) - ms->posX) * 2 / s->width,
+- (float)((s->height / 2) - ms->posY) * 2 / -s->height, 0.0);
++ glTranslatef ((float)((s->width / 2) - dev->posX) * 2 / s->width,
++ (float)((s->height / 2) - dev->posY) * 2 / -s->height, 0.0);
+
+- glScissor (x1, s->height - y2, w, h);
++ glScissor (x1, s->height - y2, w, h);
+
+- glEnable (GL_SCISSOR_TEST);
++ glEnable (GL_SCISSOR_TEST);
+
+- glBegin (GL_QUADS);
+- glTexCoord2f (tc[0], tc[2]);
+- glVertex2f (vc[0], vc[2]);
+- glTexCoord2f (tc[0], tc[3]);
+- glVertex2f (vc[0], vc[3]);
+- glTexCoord2f (tc[1], tc[3]);
+- glVertex2f (vc[1], vc[3]);
+- glTexCoord2f (tc[1], tc[2]);
+- glVertex2f (vc[1], vc[2]);
+- glEnd ();
++ glBegin (GL_QUADS);
++ glTexCoord2f (tc[0], tc[2]);
++ glVertex2f (vc[0], vc[2]);
++ glTexCoord2f (tc[0], tc[3]);
++ glVertex2f (vc[0], vc[3]);
++ glTexCoord2f (tc[1], tc[3]);
++ glVertex2f (vc[1], vc[3]);
++ glTexCoord2f (tc[1], tc[2]);
++ glVertex2f (vc[1], vc[2]);
++ glEnd ();
+
+- glDisable (GL_SCISSOR_TEST);
++ glDisable (GL_SCISSOR_TEST);
+
+- glPopMatrix ();
++ glPopMatrix ();
+
+- glBindTexture (ms->target, 0);
++ glBindTexture (dev->target, 0);
+
+- glDisable (ms->target);
++ glDisable (dev->target);
+
+- glEnable (GL_BLEND);
+- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
++ glEnable (GL_BLEND);
++ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+- tmp = MIN (1.0, (ms->zoom - 1) * 3.0);
++ tmp = MIN (1.0, (dev->zoom - 1) * 3.0);
+
+- bw = bh = magGetBorder (s);
++ bw = bh = magGetBorder (s);
+
+- bw = bw * 2.0 / s->width;
+- bh = bh * 2.0 / s->height;
++ bw = bw * 2.0 / s->width;
++ bh = bh * 2.0 / s->height;
+
+- bw = bh = magGetBorder (s);
++ bw = bh = magGetBorder (s);
+
+- bw *= 2.0 / (float)s->width;
+- bh *= 2.0 / (float)s->height;
++ bw *= 2.0 / (float)s->width;
++ bh *= 2.0 / (float)s->height;
+
+- color = magGetBoxColor (s);
++ color = magGetBoxColor (s);
+
+- glColor4us (color[0], color[1], color[2], color[3] * tmp);
++ glColor4us (color[0], color[1], color[2], color[3] * tmp);
+
+- glBegin (GL_QUADS);
+- glVertex2f (vc[0] - bw, vc[2] + bh);
+- glVertex2f (vc[0] - bw, vc[2]);
+- glVertex2f (vc[1] + bw, vc[2]);
+- glVertex2f (vc[1] + bw, vc[2] + bh);
+- glVertex2f (vc[0] - bw, vc[3]);
+- glVertex2f (vc[0] - bw, vc[3] - bh);
+- glVertex2f (vc[1] + bw, vc[3] - bh);
+- glVertex2f (vc[1] + bw, vc[3]);
+- glVertex2f (vc[0] - bw, vc[2]);
+- glVertex2f (vc[0] - bw, vc[3]);
+- glVertex2f (vc[0], vc[3]);
+- glVertex2f (vc[0], vc[2]);
+- glVertex2f (vc[1], vc[2]);
+- glVertex2f (vc[1], vc[3]);
+- glVertex2f (vc[1] + bw, vc[3]);
+- glVertex2f (vc[1] + bw, vc[2]);
+- glEnd();
++ glBegin (GL_QUADS);
++ glVertex2f (vc[0] - bw, vc[2] + bh);
++ glVertex2f (vc[0] - bw, vc[2]);
++ glVertex2f (vc[1] + bw, vc[2]);
++ glVertex2f (vc[1] + bw, vc[2] + bh);
++ glVertex2f (vc[0] - bw, vc[3]);
++ glVertex2f (vc[0] - bw, vc[3] - bh);
++ glVertex2f (vc[1] + bw, vc[3] - bh);
++ glVertex2f (vc[1] + bw, vc[3]);
++ glVertex2f (vc[0] - bw, vc[2]);
++ glVertex2f (vc[0] - bw, vc[3]);
++ glVertex2f (vc[0], vc[3]);
++ glVertex2f (vc[0], vc[2]);
++ glVertex2f (vc[1], vc[2]);
++ glVertex2f (vc[1], vc[3]);
++ glVertex2f (vc[1] + bw, vc[3]);
++ glVertex2f (vc[1] + bw, vc[2]);
++ glEnd();
+
+- glColor4usv (defaultColor);
+- glDisable (GL_BLEND);
+- glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
++ glColor4usv (defaultColor);
++ glDisable (GL_BLEND);
++ glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
++
++ glPopMatrix();
++ glMatrixMode (GL_PROJECTION);
++ glPopMatrix ();
++ glMatrixMode (GL_MODELVIEW);
+
+- glPopMatrix();
+- glMatrixMode (GL_PROJECTION);
+- glPopMatrix ();
+- glMatrixMode (GL_MODELVIEW);
+ }
+
+ static void
+-magPaintImage (CompScreen *s)
++magPaintImage (CompScreen *s, MagDevice *dev)
+ {
+ float pw, ph;
+ int x1, x2, y1, y2;
+@@ -651,42 +840,42 @@ magPaintImage (CompScreen *s)
+ xOff = MIN (w, magGetXOffset (s));
+ yOff = MIN (h, magGetYOffset (s));
+
+- x1 = ms->posX - xOff;
++ x1 = dev->posX - xOff;
+ x2 = x1 + w;
+- y1 = ms->posY - yOff;
++ y1 = dev->posY - yOff;
+ y2 = y1 + h;
+
+- cw = ceil ((float)w / (ms->zoom * 2.0)) * 2.0;
+- ch = ceil ((float)h / (ms->zoom * 2.0)) * 2.0;
++ cw = ceil ((float)w / (dev->zoom * 2.0)) * 2.0;
++ ch = ceil ((float)h / (dev->zoom * 2.0)) * 2.0;
+ cw = MIN (w, cw + 2);
+ ch = MIN (h, ch + 2);
+- cx = floor (xOff - (xOff / ms->zoom));
+- cy = h - ch - floor (yOff - (yOff / ms->zoom));
++ cx = floor (xOff - (xOff / dev->zoom));
++ cy = h - ch - floor (yOff - (yOff / dev->zoom));
+
+ cx = MAX (0, MIN (w - cw, cx));
+ cy = MAX (0, MIN (h - ch, cy));
+
+ glPushAttrib (GL_TEXTURE_BIT);
+
+- glEnable (ms->target);
++ glEnable (dev->target);
+
+- glBindTexture (ms->target, ms->texture);
++ glBindTexture (dev->target, dev->texture);
+
+- if (ms->width != w || ms->height != h)
++ if (dev->width != w || dev->height != h)
+ {
+- glCopyTexImage2D(ms->target, 0, GL_RGB, x1, s->height - y2,
++ glCopyTexImage2D(dev->target, 0, GL_RGB, x1, s->height - y2,
+ w, h, 0);
+- ms->width = w;
+- ms->height = h;
++ dev->width = w;
++ dev->height = h;
+ }
+ else
+- glCopyTexSubImage2D (ms->target, 0, cx, cy,
++ glCopyTexSubImage2D (dev->target, 0, cx, cy,
+ x1 + cx, s->height - y2 + cy, cw, ch);
+
+- if (ms->target == GL_TEXTURE_2D)
++ if (dev->target == GL_TEXTURE_2D)
+ {
+- pw = 1.0 / ms->width;
+- ph = 1.0 / ms->height;
++ pw = 1.0 / dev->width;
++ ph = 1.0 / dev->height;
+ }
+ else
+ {
+@@ -706,11 +895,11 @@ magPaintImage (CompScreen *s)
+ vc[2] = ((y1 * -2.0) / s->height) + 1.0;
+ vc[3] = ((y2 * -2.0) / s->height) + 1.0;
+
+- tc[0] = xOff - (xOff / ms->zoom);
+- tc[1] = tc[0] + (w / ms->zoom);
++ tc[0] = xOff - (xOff / dev->zoom);
++ tc[1] = tc[0] + (w / dev->zoom);
+
+- tc[2] = h - (yOff - (yOff / ms->zoom));
+- tc[3] = tc[2] - (h / ms->zoom);
++ tc[2] = h - (yOff - (yOff / dev->zoom));
++ tc[3] = tc[2] - (h / dev->zoom);
+
+ tc[0] *= pw;
+ tc[1] *= pw;
+@@ -752,11 +941,11 @@ magPaintImage (CompScreen *s)
+ disableTexture (s, &ms->mask.tex);
+ (*s->activeTexture) (GL_TEXTURE0_ARB);
+
+- glBindTexture (ms->target, 0);
++ glBindTexture (dev->target, 0);
+
+- glDisable (ms->target);
++ glDisable (dev->target);
+
+- tmp = MIN (1.0, (ms->zoom - 1) * 3.0);
++ tmp = MIN (1.0, (dev->zoom - 1) * 3.0);
+
+ glColor4f (tmp, tmp, tmp, tmp);
+
+@@ -794,7 +983,7 @@ magPaintImage (CompScreen *s)
+ }
+
+ static void
+-magPaintFisheye (CompScreen *s)
++magPaintFisheye (CompScreen *s, MagDevice *dev)
+ {
+ float pw, ph;
+ float radius, zoom, base;
+@@ -802,37 +991,35 @@ magPaintFisheye (CompScreen *s)
+ float vc[4];
+ int size;
+
+- MAG_SCREEN (s);
+-
+ radius = magGetRadius (s);
+ base = 0.5 + (0.0015 * radius);
+- zoom = (ms->zoom * base) + 1.0 - base;
++ zoom = (dev->zoom * base) + 1.0 - base;
+
+ size = radius + 1;
+
+- x1 = MAX (0.0, ms->posX - size);
+- x2 = MIN (s->width, ms->posX + size);
+- y1 = MAX (0.0, ms->posY - size);
+- y2 = MIN (s->height, ms->posY + size);
++ x1 = MAX (0.0, dev->posX - size);
++ x2 = MIN (s->width, dev->posX + size);
++ y1 = MAX (0.0, dev->posY - size);
++ y2 = MIN (s->height, dev->posY + size);
+
+- glEnable (ms->target);
++ glEnable (dev->target);
+
+- glBindTexture (ms->target, ms->texture);
++ glBindTexture (dev->target, dev->texture);
+
+- if (ms->width != 2 * size || ms->height != 2 * size)
++ if (dev->width != 2 * size || dev->height != 2 * size)
+ {
+- glCopyTexImage2D(ms->target, 0, GL_RGB, x1, s->height - y2,
++ glCopyTexImage2D(dev->target, 0, GL_RGB, x1, s->height - y2,
+ size * 2, size * 2, 0);
+- ms->width = ms->height = 2 * size;
++ dev->width = dev->height = 2 * size;
+ }
+ else
+- glCopyTexSubImage2D (ms->target, 0, 0, 0,
++ glCopyTexSubImage2D (dev->target, 0, 0, 0,
+ x1, s->height - y2, x2 - x1, y2 - y1);
+
+- if (ms->target == GL_TEXTURE_2D)
++ if (dev->target == GL_TEXTURE_2D)
+ {
+- pw = 1.0 / ms->width;
+- ph = 1.0 / ms->height;
++ pw = 1.0 / dev->width;
++ ph = 1.0 / dev->height;
+ }
+ else
+ {
+@@ -850,10 +1037,10 @@ magPaintFisheye (CompScreen *s)
+ glColor4usv (defaultColor);
+
+ glEnable (GL_FRAGMENT_PROGRAM_ARB);
+- (*s->bindProgram) (GL_FRAGMENT_PROGRAM_ARB, ms->program);
++ (*s->bindProgram) (GL_FRAGMENT_PROGRAM_ARB, dev->program);
+
+ (*s->programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, 0,
+- ms->posX, s->height - ms->posY,
++ dev->posX, s->height - dev->posY,
+ 1.0 / radius, 0.0f);
+ (*s->programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, 1,
+ pw, ph, M_PI / radius,
+@@ -862,10 +1049,10 @@ magPaintFisheye (CompScreen *s)
+ -x1 * pw, -(s->height - y2) * ph,
+ -M_PI / 2.0, 0.0);
+
+- x1 = MAX (0.0, ms->posX - radius);
+- x2 = MIN (s->width, ms->posX + radius);
+- y1 = MAX (0.0, ms->posY - radius);
+- y2 = MIN (s->height, ms->posY + radius);
++ x1 = MAX (0.0, dev->posX - radius);
++ x2 = MIN (s->width, dev->posX + radius);
++ y1 = MAX (0.0, dev->posY - radius);
++ y2 = MIN (s->height, dev->posY + radius);
+
+ vc[0] = ((x1 * 2.0) / s->width) - 1.0;
+ vc[1] = ((x2 * 2.0) / s->width) - 1.0;
+@@ -895,9 +1082,9 @@ magPaintFisheye (CompScreen *s)
+ glPopMatrix ();
+ glMatrixMode (GL_MODELVIEW);
+
+- glBindTexture (ms->target, 0);
++ glBindTexture (dev->target, 0);
+
+- glDisable (ms->target);
++ glDisable (dev->target);
+ }
+
+ static void
+@@ -907,6 +1094,7 @@ magPaintScreen (CompScreen *s,
+ unsigned int mask)
+ {
+ XRectangle r;
++ MagDevice *dev;
+
+ MAG_SCREEN (s);
+
+@@ -914,7 +1102,10 @@ magPaintScreen (CompScreen *s,
+ (*s->paintScreen) (s, outputs, numOutput, mask);
+ WRAP (ms, s, paintScreen, magPaintScreen);
+
+- if (ms->zoom == 1.0)
++ for (dev = ms->devices; dev; dev = dev->next)
++ {
++
++ if (dev->zoom == 1.0)
+ return;
+
+ r.x = 0;
+@@ -934,13 +1125,14 @@ magPaintScreen (CompScreen *s,
+ switch (ms->mode)
+ {
+ case ModeImageOverlay:
+- magPaintImage (s);
++ magPaintImage (s, dev);
+ break;
+ case ModeFisheye:
+- magPaintFisheye (s);
++ magPaintFisheye (s, dev);
+ break;
+ default:
+- magPaintSimple (s);
++ magPaintSimple (s, dev);
++ }
+ }
+
+ }
+@@ -953,6 +1145,7 @@ magTerminate (CompDisplay *d,
+ int nOption)
+ {
+ CompScreen *s;
++ MagDevice *dev;
+ Window xid;
+
+ xid = getIntOptionNamed (option, nOption, "root", 0);
+@@ -962,9 +1155,12 @@ magTerminate (CompDisplay *d,
+ {
+ MAG_SCREEN (s);
+
+- ms->zTarget = 1.0;
+- ms->adjust = TRUE;
+- damageScreen (s);
++ for (dev = ms->devices; dev; dev = dev->next)
++ {
++ dev->zTarget = 1.0;
++ dev->adjust = TRUE;
++ damageScreen (s);
++ }
+
+ return TRUE;
+ }
+@@ -981,6 +1177,8 @@ magInitiate (CompDisplay *d,
+ CompScreen *s;
+ Window xid;
+ float factor;
++ MagDevice *mDev;
++ CompDevice *dev;
+
+ xid = getIntOptionNamed (option, nOption, "root", 0);
+ factor = getFloatOptionNamed (option, nOption, "factor", 0.0);
+@@ -990,27 +1188,49 @@ magInitiate (CompDisplay *d,
+ {
+ MAG_SCREEN (s);
+
+- if (factor == 0.0 && ms->zTarget != 1.0)
+- return magTerminate (d, action, state, option, nOption);
+-
+- if (ms->mode == ModeFisheye)
++ for (dev = s->display->devices; dev->id != -1; dev++)
+ {
+- if (factor != 1.0)
+- factor = magGetZoomFactor (s) * 3;
+-
+- ms->zTarget = MAX (1.0, MIN (10.0, factor));
++ if (dev->use != IsXPointer)
++ continue;
++
++ for (mDev = ms->devices; mDev; mDev = mDev->next)
++ if (mDev->dev == dev)
++ break;
++
++ if (!mDev) /* This devices is not in the list */
++ mDev = magAddDeviceToList (s, dev);
++
++ if (!mDev)
++ return FALSE;
++
++ if (factor == 0.0 && mDev->zTarget != 1.0)
++ return magTerminate (d, action, state, option, nOption);
++
++ if (ms->mode == ModeFisheye)
++ {
++ if (factor != 1.0)
++ factor = magGetZoomFactor (s) * 3;
++
++ mDev->zTarget = MAX (1.0, MIN (10.0, factor));
++ }
++ else
++ {
++ if (factor != 1.0)
++ factor = magGetZoomFactor (s);
++
++ mDev->zTarget = MAX (1.0, MIN (64.0, factor));
++ }
++ mDev->adjust = TRUE;
++ damageScreen (s);
+ }
+- else
+- {
+- if (factor != 1.0)
+- factor = magGetZoomFactor (s);
+-
+- ms->zTarget = MAX (1.0, MIN (64.0, factor));
+- }
+- ms->adjust = TRUE;
+- damageScreen (s);
+
+ return TRUE;
++ if (state & CompActionStateInitButton)
++ action->state |= CompActionStateTermButton;
++
++ if (state & CompActionStateInitKey)
++ action->state |= CompActionStateTermKey;
++
+ }
+ return FALSE;
+ }
+@@ -1023,20 +1243,36 @@ magZoomIn (CompDisplay *d,
+ int nOption)
+ {
+ CompScreen *s;
++ CompDevice *dev;
++ int deviceid;
+ Window xid;
+
+ xid = getIntOptionNamed (option, nOption, "root", 0);
++ deviceid = getIntOptionNamed (option, nOption, "device", -1);
++
+
++ dev = compFindDeviceById (d, deviceid);
+ s = findScreenAtDisplay (d, xid);
+- if (s)
++ if (s && dev)
+ {
+ MAG_SCREEN (s);
++ MagDevice *run;
++
++ for (run = ms->devices; run; run = run->next)
++ if (run->dev == dev)
++ break;
++
++ if (!run)
++ run = magAddDeviceToList (s, dev);
++
++ if (!run)
++ return FALSE;
+
+ if (ms->mode == ModeFisheye)
+- ms->zTarget = MIN (10.0, ms->zTarget + 1.0);
++ run->zTarget = MIN (10.0, run->zTarget + 1.0);
+ else
+- ms->zTarget = MIN (64.0, ms->zTarget * 1.2);
+- ms->adjust = TRUE;
++ run->zTarget = MIN (64.0, run->zTarget * 1.2);
++ run->adjust = TRUE;
+ damageScreen (s);
+
+ return TRUE;
+@@ -1052,20 +1288,32 @@ magZoomOut (CompDisplay *d,
+ int nOption)
+ {
+ CompScreen *s;
++ CompDevice *dev;
++ int deviceid;
+ Window xid;
+
+ xid = getIntOptionNamed (option, nOption, "root", 0);
++ deviceid = getIntOptionNamed (option, nOption, "device", -1);
+
+ s = findScreenAtDisplay (d, xid);
+- if (s)
++ dev = compFindDeviceById (d, deviceid);
++ if (s && dev)
+ {
++ MagDevice *run;
+ MAG_SCREEN (s);
+
++ for (run = ms->devices; run; run = run->next)
++ if (run->dev == dev)
++ break;
++
++ if (!run)
++ return FALSE;
++
+ if (ms->mode == ModeFisheye)
+- ms->zTarget = MAX (1.0, ms->zTarget - 1.0);
++ run->zTarget = MAX (1.0, run->zTarget - 1.0);
+ else
+- ms->zTarget = MAX (1.0, ms->zTarget / 1.2);
+- ms->adjust = TRUE;
++ run->zTarget = MAX (1.0, run->zTarget / 1.2);
++ run->adjust = TRUE;
+ damageScreen (s);
+
+ return TRUE;
+@@ -1092,69 +1340,17 @@ magInitScreen (CompPlugin *p,
+ WRAP (ms, s, preparePaintScreen, magPreparePaintScreen);
+ WRAP (ms, s, donePaintScreen, magDonePaintScreen);
+
+- ms->zoom = 1.0;
+- ms->zVelocity = 0.0;
+- ms->zTarget = 1.0;
+-
+ ms->pollHandle = 0;
+
+- glGenTextures (1, &ms->texture);
+-
+- if (s->textureNonPowerOfTwo)
+- ms->target = GL_TEXTURE_2D;
+- else
+- ms->target = GL_TEXTURE_RECTANGLE_ARB;
+-
+- glEnable (ms->target);
+-
+- /* Bind the texture */
+- glBindTexture (ms->target, ms->texture);
+-
+- /* Load the parameters */
+- glTexParameteri (ms->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+- glTexParameteri (ms->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+- glTexParameteri (ms->target, GL_TEXTURE_WRAP_S, GL_CLAMP);
+- glTexParameteri (ms->target, GL_TEXTURE_WRAP_T, GL_CLAMP);
+-
+- glTexImage2D (ms->target, 0, GL_RGB, 0, 0, 0,
+- GL_RGB, GL_UNSIGNED_BYTE, NULL);
+-
+- ms->width = 0;
+- ms->height = 0;
+-
+- glBindTexture (ms->target, 0);
+-
+- glDisable (ms->target);
+-
+ initTexture (s, &ms->overlay.tex);
+ initTexture (s, &ms->mask.tex);
+ ms->overlay.loaded = FALSE;
+ ms->mask.loaded = FALSE;
+
+- ms->program = 0;
+-
+ magSetOverlayNotify (s, magOptionsChanged);
+ magSetMaskNotify (s, magOptionsChanged);
+ magSetModeNotify (s, magOptionsChanged);
+
+- switch (magGetMode (s))
+- {
+- case ModeImageOverlay:
+- if (loadImages (s))
+- ms->mode = ModeImageOverlay;
+- else
+- ms->mode = ModeSimple;
+- break;
+- case ModeFisheye:
+- if (loadFragmentProgram (s))
+- ms->mode = ModeFisheye;
+- else
+- ms->mode = ModeSimple;
+- break;
+- default:
+- ms->mode = ModeSimple;
+- }
+-
+ if (!s->fragmentProgram)
+ compLogMessage ("mag", CompLogLevelWarn,
+ "GL_ARB_fragment_program not supported. "
+@@ -1179,10 +1375,7 @@ magFiniScreen (CompPlugin *p,
+ if (ms->pollHandle)
+ (*md->mpFunc->removePositionPolling) (s, ms->pollHandle);
+
+- if (ms->zoom)
+- damageScreen (s);
+-
+- glDeleteTextures (1, &ms->target);
++ damageScreen (s);
+
+ magCleanup (s);
+
+--
+1.5.6
+
diff --git a/fusion/plugins/peek/0001-MPX-Support-Patch.patch b/fusion/plugins/peek/0001-MPX-Support-Patch.patch
new file mode 100644
index 0000000..7dace8a
--- /dev/null
+++ b/fusion/plugins/peek/0001-MPX-Support-Patch.patch
@@ -0,0 +1,368 @@
+From 22fb79cd8c6f9201bc50c289a35bea5d3ff3b6e8 Mon Sep 17 00:00:00 2001
+From: Sam Spilsbury <Sam@XPS-SUSE.site>
+Date: Sat, 29 Nov 2008 11:28:20 +0900
+Subject: [PATCH] MPX Support Patch
+
+---
+ peek.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
+ 1 files changed, 220 insertions(+), 18 deletions(-)
+
+diff --git a/peek.c b/peek.c
+index 9bdb11d..06031dc 100644
+--- a/peek.c
++++ b/peek.c
+@@ -191,11 +191,21 @@ static char windowTex[4096] = {
+ "\341\341\341\326\341\341\341\326\341\341\341\326\341\341\341\326"
+ };
+
+-static void positionUpdate (CompScreen *s, int x, int y);
++static void positionUpdate (CompScreen *s, MousepollDevice *mDev);
+ static CompWindow *
+ peekFindDockAt (CompScreen *s,
+ int x,
+- int y)
++ int y);
++
++typedef struct _PeekDevice
++{
++ CompDevice *dev;
++ int posX;
++ int posY;
++ CompWindow *activeWindow;
++ CompWindow *dock;
++ struct _PeekDevice *next;
++} PeekDevice;
+
+ typedef struct _PeekDisplay
+ {
+@@ -218,6 +228,7 @@ typedef struct _PeekScreen
+ PaintOutputProc paintOutput;
+
+ CompWindow *activeWindow;
++ PeekDevice *devices;
+
+ CompTexture windowTex;
+
+@@ -268,6 +279,8 @@ peekHandleEnter (CompScreen *s,
+ PEEK_SCREEN (s);
+ PEEK_DISPLAY (s->display);
+
++ fprintf(stderr, "handling enter\n");
++
+ if (!w)
+ return;
+
+@@ -288,7 +301,7 @@ peekHandleEnter (CompScreen *s,
+ if (!ps->pollHandle)
+ {
+ ps->pollHandle =
+- (*pd->mpFunc->addPositionPolling) (s, positionUpdate);
++ (*pd->mpFunc->addPositionPolling) (s, NULL, positionUpdate);
+ }
+ }
+ else
+@@ -322,14 +335,21 @@ handleTimeout (void *data)
+ {
+ int x, y;
+ CompWindow *w = (CompWindow *) data;
++ PeekDevice *pDev;
+
+ PEEK_DISPLAY (w->screen->display);
++ PEEK_SCREEN (w->screen);
+
+ pd->timeoutHandle = 0;
+
+- (*pd->mpFunc->getCurrentPosition) (s, &x, &y);
+- if (peekFindDockAt (s, x, y) == w)
++
++
++ for (pDev = ps->devices; pDev; pDev = pDev->next)
++ {
++ (*pd->mpFunc->getCurrentPosition) (w->screen, pDev->dev, &x, &y);
++ if (peekFindDockAt (w->screen, x, y) == w)
+ peekHandleEnter (w->screen, w);
++ }
+
+ return FALSE;
+ }
+@@ -575,13 +595,15 @@ peekHandleEvent (CompDisplay *d,
+ pd->timeoutHandle = 0;
+ }
+
++ fprintf(stderr, "got event\n");
++
+ if (checkDelay (w))
+ pd->timeoutHandle = compAddTimeout (peekGetTimeout (d),
+ (float)
+ peekGetTimeout (d) * 1.2,
+ handleTimeout, w);
+ else
+- handleTimeout ((void *) w);
++ peekHandleEnter (s, w);
+
+
+ }
+@@ -656,6 +678,16 @@ peekFindDockAt (CompScreen *s,
+ return NULL;
+ }
+
++static Bool
++peekWindowInDock (CompWindow *dock,
++ CompWindow *win)
++{
++ if (dock)
++ if (peekFindWindowAt (win->screen, WIN_X (dock), WIN_Y (dock)))
++ return TRUE;
++ return FALSE;
++}
++
+ static void
+ peekUpdateHover (CompScreen *s)
+ {
+@@ -663,14 +695,19 @@ peekUpdateHover (CompScreen *s)
+ PEEK_DISPLAY (s->display);
+
+ CompWindow *w, *dock, *win;
++ PeekDevice *pDev;
++ Bool removePoll = TRUE;;
++
++ for (pDev = ps->devices; pDev; pDev = pDev->next)
++ {
+
+- dock = peekFindDockAt (s, ps->posX, ps->posY);
++ dock = peekFindDockAt (s, pDev->posX, pDev->posY);
+
+ if (dock)
+ {
+- w = peekFindWindowAt (s, ps->posX, ps->posY);
++ w = peekFindWindowAt (s, pDev->posX, pDev->posY);
+
+- if (w && w != ps->activeWindow);
++ if (w && w != pDev->activeWindow);
+ for (win = s->windows; win; win = win->next)
+ {
+ PEEK_WINDOW (win);
+@@ -681,7 +718,7 @@ peekUpdateHover (CompScreen *s)
+ {
+ setOpacity (win, MIN (OPAQUE,
+ OPAQUE));
+- ps->activeWindow = win;
++ pDev->activeWindow = win;
+ pw->transparent = FALSE;
+ }
+ }
+@@ -696,31 +733,193 @@ peekUpdateHover (CompScreen *s)
+ }
+ }
+ }
++
++ removePoll = FALSE;
+ }
+ else
+ {
+ for (win = s->windows; win; win = win->next)
+ {
+ if (!win->shaded
+- && matchEval (peekGetWindowMatch (s), win))
++ && matchEval (peekGetWindowMatch (s), win)
++ && peekWindowInDock (peekFindDockAt (s, pDev->posX, pDev->posY), win))
+ setOpacity (win, MIN (OPAQUE, OPAQUE));
+ }
++
++ }
++ }
++ if (ps->pollHandle && removePoll)
++ {
++ (*pd->mpFunc->removePositionPolling) (s, ps->pollHandle);
++ ps->pollHandle = 0;
++ }
++}
+
+- if (ps->pollHandle)
++static Bool
++peekAddDevToList (CompScreen *s,
++ CompDevice *dev)
++{
++ PEEK_SCREEN (s);
++
++ PeekDevice *run;
++
++ if (!ps->devices)
++ {
++ ps->devices = calloc (1, sizeof(PeekDevice));
++ if (!ps->devices)
++ return FALSE;
++ ps->devices->dev = dev;
++ ps->devices->next = NULL;
++ }
++ else
++ {
++ for (run = ps->devices; run->next; run = run->next);
++
++ run->next = calloc (1, sizeof(PeekDevice));
++ if (!run->next)
++ return FALSE;
++ run->next->dev = dev;
++ run->next->next = NULL;
++ }
++ return TRUE;
++}
++
++static void
++peekRemoveDevFromList (CompScreen *s,
++ CompDevice *dev)
++{
++ PEEK_SCREEN (s);
++
++ PeekDevice *run = NULL;
++
++ for (run = ps->devices; run; run = run->next)
++ if (run->dev == dev)
++ break;
++
++ if (run == ps->devices)
++ {
++ if (ps->devices->next)
++ ps->devices = ps->devices->next;
++ else
++ ps->devices = NULL;
++
++ if (run)
++ free (run);
++ }
++ else
++ {
++ for (run = ps->devices; run; run = run->next)
++ {
++ if (run->dev == dev)
++ break;
++ }
++
++ PeekDevice *selected = run;
++
++ if (selected)
++ if (selected->next)
++ {
++ run = run->next;
++ free(selected);
++ }
++ }
++}
++
++static void
++peekCreateList (CompScreen *s)
++{
++ CompDevice *dev;
++ PeekDevice *pDev;
++
++ PEEK_SCREEN (s);
++
++ for (dev = s->display->devices; dev->id != -1; dev++)
++ {
++ if (dev->use == IsXPointer)
+ {
+- (*pd->mpFunc->removePositionPolling) (s, ps->pollHandle);
+- ps->pollHandle = 0;
+- }
++ Bool add = TRUE;
++ for (pDev = ps->devices; pDev; pDev = pDev->next)
++ if (pDev->dev == dev)
++ add = FALSE;
++
++ if (add)
++ peekAddDevToList (s, dev);
++ }
+ }
+ }
+
+ static void
+-positionUpdate (CompScreen *s, int x, int y)
++peekCheckList (CompScreen *s,
++ MousepollDevice *list)
++{
++ PEEK_SCREEN (s);
++ Bool ok = FALSE;
++ MousepollDevice *run;
++ PeekDevice *ptr;
++ CompDevice *addDev = NULL, *removeDev = NULL;
++
++ do
++ {
++ for (run = list; run; run = run->next)
++ {
++ addDev = run->dev;
++ for (ptr = ps->devices; ptr; ptr = ptr->next)
++ {
++ if (ptr->dev == run->dev)
++ {
++ addDev = NULL;
++ break;
++ }
++ }
++ if (addDev) break;
++ }
++
++ for (ptr = ps->devices; ptr; ptr = ptr->next)
++ {
++ removeDev = ptr->dev;
++ for (run = list; run; run = run->next)
++ {
++ if (run->dev == ptr->dev)
++ {
++ removeDev = NULL;
++ break;
++ }
++ }
++ if (removeDev) break;
++ }
++
++ if (addDev)
++ peekAddDevToList (s, addDev);
++
++ if (removeDev)
++ peekRemoveDevFromList (s, removeDev);
++
++ if (addDev || removeDev)
++ ok = FALSE;
++ else
++ ok = TRUE;
++ } while (!ok);
++}
++
++static void
++positionUpdate (CompScreen *s, MousepollDevice *mDev)
+ {
++ PeekDevice *pDev;
+ PEEK_SCREEN (s);
+
+- ps->posX = x;
+- ps->posY = y;
++ peekCheckList (s, mDev);
++
++ for (; mDev; mDev = mDev->next)
++ {
++ for (pDev = ps->devices; pDev; pDev = pDev->next)
++ {
++ if (pDev->dev == mDev->dev)
++ {
++ pDev->posX = mDev->posX;
++ pDev->posY = mDev->posY;
++ }
++ }
++ }
+
+ peekUpdateHover (s);
+ }
+@@ -780,6 +979,9 @@ peekInitScreen (CompPlugin *p,
+
+ s->base.privates[pd->screenPrivateIndex].ptr = ps;
+ ps->pollHandle = 0;
++ ps->devices = NULL;
++
++ peekCreateList (s);
+
+ initTexture (s, &ps->windowTex);
+
+--
+1.5.6
+