summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--screensaver.xml.in4
-rw-r--r--src/effect.cpp67
-rw-r--r--src/effect.h6
-rw-r--r--src/flyingwindows.cpp381
-rw-r--r--src/flyingwindows.h83
-rw-r--r--src/matrix.cpp57
-rw-r--r--src/matrix.h66
-rw-r--r--src/rotatingcube.cpp101
-rw-r--r--src/rotatingcube.h29
-rw-r--r--src/screensaver.cpp312
-rw-r--r--src/screensaver.h238
-rw-r--r--src/vector.cpp14
-rw-r--r--src/vector.h160
-rw-r--r--src/wrapper.cpp68
-rw-r--r--src/wrapper.h5
15 files changed, 1591 insertions, 0 deletions
diff --git a/screensaver.xml.in b/screensaver.xml.in
index 7904e74..d539b90 100644
--- a/screensaver.xml.in
+++ b/screensaver.xml.in
@@ -34,6 +34,10 @@
<max>1</max>
<desc>
<value>0</value>
+ <name>Flying windows</name>
+ </desc>
+ <desc>
+ <value>1</value>
<name>Rotating cube</name>
</desc>
</option>
diff --git a/src/effect.cpp b/src/effect.cpp
new file mode 100644
index 0000000..cd18e32
--- /dev/null
+++ b/src/effect.cpp
@@ -0,0 +1,67 @@
+#include "screensaver.h"
+#include <cmath>
+
+
+#define sigmoid(x) (1.0f/(1.0f+exp(-5.5f*2*((x)-0.5))))
+#define sigmoidProgress(x) ((sigmoid(x) - sigmoid(0)) / \
+ (sigmoid(1) - sigmoid(0)))
+
+
+void
+ScreenEffect::handleEvent (XEvent *event)
+{
+ ScreenWrapper::handleEvent (event);
+}
+
+void
+ScreenEffect::cubeGetRotation (float &x, float &v, float &progress)
+{
+ ScreenWrapper::cubeGetRotation (x, v, progress);
+}
+
+bool ScreenEffect::enable()
+{
+ progress = 0.0;
+ return true;
+}
+
+void ScreenEffect::preparePaint (int msSinceLastPaint )
+{
+ if( ss->mState.running )
+ {
+ if( ss->mState.fadingIn )
+ {
+ float fadeDuration = ss->optionGetFadeInDuration ()*1000.0;
+ progress = sigmoidProgress(((float)ss->mTime)/fadeDuration);
+ ss->mTime += msSinceLastPaint;
+ if( ss->mTime >= fadeDuration )
+ {
+ if( ss->optionGetStartAutomatically() )
+ XActivateScreenSaver(screen->dpy ());
+ ss->mState.fadingIn = FALSE;
+ ss->mTime = 0;
+ }
+ }
+
+ else if( ss->mState.fadingOut )
+ {
+ float fadeDuration = ss->optionGetFadeOutDuration()*1000.0;
+ progress = sigmoidProgress( ((float)ss->mTime)/fadeDuration );
+ ss->mTime += msSinceLastPaint;
+ if( ss->mTime >= fadeDuration )
+ {
+ clean();
+ ss->mEffect->cleanEffect = true;
+ ss->mState.running = FALSE;
+ ss->cScreen->damageScreen();
+ }
+ }
+
+ else
+ {
+ progress = 1.0;
+ }
+ }
+
+ ScreenWrapper::preparePaint ( msSinceLastPaint );
+}
diff --git a/src/effect.h b/src/effect.h
new file mode 100644
index 0000000..602572b
--- /dev/null
+++ b/src/effect.h
@@ -0,0 +1,6 @@
+#ifndef EFFECT_H
+#define EFFECT_H
+
+#include "screensaver_internal.h"
+
+#endif
diff --git a/src/flyingwindows.cpp b/src/flyingwindows.cpp
new file mode 100644
index 0000000..019a9fe
--- /dev/null
+++ b/src/flyingwindows.cpp
@@ -0,0 +1,381 @@
+#include "flyingwindows.h"
+
+
+#define NE 0
+#define NO 1
+#define SE 2
+#define SO 3
+#define C 4
+
+void ScreenFlyingWindows::handleEvent( XEvent *event )
+{
+ ScreenEffect::handleEvent( event );
+ if( event->type == MapNotify )
+ {
+ CompWindow* w = screen->findWindow (event->xmap.window );
+ if(w)
+ WindowFlyingWindows::getInstance(w).initWindow();
+ }
+}
+
+bool ScreenFlyingWindows::enable()
+{
+ ss->mAngleCam = 0.0;
+ ss->mScreenCenter = Vector( 0.0, ss->optionGetBounce() ? 0.2 : 0.0,\
+ -ss->optionGetAttractionDepth() );
+ ss->mCamera = Matrix::identity;
+ ss->mDesktopOpacity = OPAQUE;
+
+ foreach (CompWindow *w, screen->windows ())
+ WindowFlyingWindows::getInstance(w).initWindow();
+
+ return ScreenEffect::enable();
+}
+
+void ScreenFlyingWindows::disable()
+{
+ foreach (CompWindow *w, screen->windows ())
+ {
+ WindowFlyingWindows& sw = WindowFlyingWindows::getInstance(w);
+ if( sw.active )
+ sw.transformFadeOut = ss->mCameraMat * sw.transform;
+
+ else sw.opacityFadeOut = sw.opacity;
+ }
+ ss->mCameraMat = Matrix::identity;
+ ScreenEffect::disable();
+}
+
+void ScreenFlyingWindows::addForce( const Point& p1, const Point& p2, const Point& center, Vector& resultante, Vector& couple, float w, bool attract )
+{
+ Vector u = p2 - p1;
+ float d = u.norm();
+ u.normalize();
+
+ if( d < 1e-5 ) d = 1e-5;
+
+ Vector force = attract ? w*u*d*d : -w*u/(d*d);
+ resultante += force;
+
+ couple += ( center - p1 ) ^ force;
+}
+
+void ScreenFlyingWindows::preparePaint( int msSinceLastPaint )
+{
+ ScreenEffect::preparePaint ( msSinceLastPaint );
+
+ float ratio = ss->optionGetAttractionRepulsionRatio()/100.0;
+ float wAt = ratio;
+ float wRt = 1-ratio;
+
+ if( ss->mState.fadingIn )
+ {
+ wAt *= getProgress();
+ wRt *= getProgress();
+
+ ss->mDesktopOpacity = (GLushort)( OPAQUE * ( 1.0 - getProgress() ));
+ }
+
+ if( ss->mState.fadingOut )
+ {
+ ss->mDesktopOpacity = (GLushort)(OPAQUE * getProgress());
+ }
+
+ if( !ss->mState.fadingOut )
+ {
+ ss->mAngleCam += ((float)msSinceLastPaint)/100000.0;
+ if( ss->mAngleCam > 0.03 ) ss->mAngleCam=0.03;
+
+ ss->mCamera.rotate( ss->mAngleCam*msSinceLastPaint, 0.0, 1.0, 0.0 );
+
+ Matrix centerTrans = Matrix::identity;
+ Matrix centerTransInv = Matrix::identity;
+
+ Vector screenCenterTranslated = ss->mScreenCenter.toCoordsSpace();
+ screenCenterTranslated[z] *= screen->width ();
+
+ centerTrans.scale( 1.0, 1.0, 1.0 / screen->width ());
+ centerTrans.translate( screenCenterTranslated );
+ centerTransInv.translate( -screenCenterTranslated );
+ centerTransInv.scale( 1.0, 1.0, 1.0 * screen->width ());
+
+ ss->mCameraMat = centerTrans * ss->mCamera * centerTransInv;
+ }
+
+ foreach (CompWindow *w, screen->windows ())
+ {
+ WindowFlyingWindows& sw = WindowFlyingWindows::getInstance(w);
+
+ if( sw.active )
+ {
+ if( ss->mState.fadingOut )
+ sw.transform = interpolate( sw.transformFadeOut, Matrix::identity, getProgress() );
+
+ else
+ {
+ int collisionVertex = -1;
+ int collisionIteration = 1;
+ Vector a, p, o, omega;
+ do
+ {
+ Vector resultante, couple, resultanteA, coupleA;
+ resultante = couple = resultanteA = coupleA = Vector::null;
+ Vector windowcenter = sw.vertex[C];
+ float mass = sqrt(((float)(WIN_W(w)*WIN_H(w)))/(screen->width () * screen->height ()));
+
+ float wR = 1e-8/mass*wRt;
+ float wA = 1e-8/mass*wAt;
+
+ int numPoint = 0;
+ for( int i = 0; i<5; i++)
+ {
+ foreach (CompWindow *w2, screen->windows ())
+ {
+ WindowFlyingWindows& sw2 = WindowFlyingWindows::getInstance(w2);
+ if( w2 != w && sw2.active )
+ {
+ numPoint++;
+ for( int j = 0; j<5; j++)
+ addForce( sw.vertex[i], sw2.vertex[j], windowcenter, resultante, couple, wR, FALSE );
+ }
+ }
+ addForce( sw.vertex[i], ss->mScreenCenter, windowcenter, resultanteA, coupleA, wA, TRUE );
+ }
+
+ if( numPoint < 1 )
+ numPoint = 1;
+
+ resultante += resultanteA*numPoint;
+ couple += coupleA*numPoint;
+
+ if( collisionVertex != -1 )
+ {
+ float wb = sw.vertex[collisionVertex][y]/msSinceLastPaint*5e-4;
+ resultante[y] = -wb;
+ float tmp = couple[z];
+ couple = (sw.vertex[collisionVertex]-windowcenter) ^ Vector( 0.0, -wb, 0.0 );
+ couple[z] = tmp;
+ sw.speed[y] = 0;
+ }
+
+ a = resultante - 5e-4*mass*sw.speed;
+ omega = couple*1000 - 5e-3*mass*sw.speedrot;
+
+ p = msSinceLastPaint*msSinceLastPaint*a+msSinceLastPaint*sw.speed;
+ sw.speed += msSinceLastPaint*a;
+
+ o = msSinceLastPaint*msSinceLastPaint*omega+msSinceLastPaint*sw.speedrot;
+ sw.speedrot += msSinceLastPaint*omega;
+
+ sw.transformTrans.translate( p[x]*screen->width (), -p[y]*screen->height (), p[z] );
+ sw.transformRot.rotate( o.norm(), o );
+
+ sw.transform = sw.transformTrans * sw.centerTrans * sw.transformRot * sw.centerTransInv;
+
+ sw.recalcVertices();
+
+ if ( ss->optionGetBounce () )
+ {
+ for( int i = 0; i < 4; i++ )
+ if( sw.vertex[i][y] < -0.5 )
+ collisionVertex = i;
+ }
+
+ } while ( collisionVertex != -1 && collisionIteration-- );
+ }
+ }
+ else
+ {
+ if( ss->mState.fadingOut )
+ {
+ sw.opacity = (GLushort)( sw.opacityOld*getProgress() + sw.opacityFadeOut*(1-getProgress()) );
+ }
+ else
+ sw.steps = (int)( (msSinceLastPaint * OPAQUE) / (ss->optionGetFadeInDuration()*1000.0) );
+ }
+ }
+}
+
+void ScreenFlyingWindows::donePaint ()
+{
+ ss->cScreen->damageScreen();
+ ScreenEffect::donePaint ();
+}
+
+void ScreenFlyingWindows::paint (CompOutput::ptrList &outputs,
+ unsigned int mask)
+{
+ CompOutput::ptrList newOutputs;
+ newOutputs.push_back (&screen->fullscreenOutput ());
+
+ ScreenEffect::paint (newOutputs, mask);
+}
+
+bool
+ScreenFlyingWindows::glPaintOutput(const GLScreenPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ CompOutput *output,
+ unsigned int mask)
+{
+ ss->gScreen->clearTargetOutput (GL_COLOR_BUFFER_BIT);
+ return ScreenEffect::glPaintOutput( attrib, transform, region, output, mask | PAINT_SCREEN_TRANSFORMED_MASK );
+}
+
+void
+ScreenFlyingWindows::glPaintTransformedOutput (const GLScreenPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ CompOutput *output,
+ unsigned int mask)
+{
+ bool wasCulled = glIsEnabled (GL_CULL_FACE);
+ if (wasCulled)
+ glDisable (GL_CULL_FACE);
+
+ GLenum oldFilter = ss->gScreen->textureFilter ();
+ if( ss->optionGetMipmaps() )
+ ss->gScreen->setTextureFilter (GL_LINEAR_MIPMAP_LINEAR);
+
+
+ mask &= ~PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
+
+ GLboolean bTwoSite;
+ glGetBooleanv(GL_LIGHT_MODEL_TWO_SIDE, &bTwoSite );
+ glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, ss->gScreen->lighting ());
+
+ ScreenEffect::glPaintTransformedOutput (attrib, transform, region, output, mask);
+
+ glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, bTwoSite);
+
+ ss->gScreen->setFilter (SCREEN_TRANS_FILTER, GLTexture::Good);
+ ss->gScreen->setTextureFilter (oldFilter);
+
+ if (wasCulled)
+ glEnable (GL_CULL_FACE);
+}
+
+WindowFlyingWindows::WindowFlyingWindows( CompWindow* w ) :
+ WindowEffect(w),
+ active( FALSE ),
+ opacity( GLWindow::get (w)->paintAttrib ().opacity ),
+ opacityFadeOut( 0 ),
+ opacityOld( 0 ),
+ steps(0)
+{
+
+}
+
+// Returns true if w is a flying window
+bool WindowFlyingWindows::isActiveWin()
+{
+ return !w->overrideRedirect () && \
+ w->mapNum () && \
+ w->isViewable () && \
+ !( w->wmType () & ( CompWindowTypeDockMask | CompWindowTypeDesktopMask )) && \
+ /* !( w->state & ( CompWindowStateSkipPagerMask | CompWindowStateShadedMask )) && \*/
+ ScreenSaverScreen::get (screen)->optionGetWindowMatch ().evaluate (w);
+}
+
+// Initialize window transformation matrices and vertices
+void WindowFlyingWindows::initWindow()
+{
+ active = isActiveWin();
+ if( active )
+ {
+ float x = WIN_X(this->w);
+ float y = WIN_Y(this->w);
+ float w = WIN_W(this->w);
+ float h = WIN_H(this->w);
+
+ transform = transformRot = transformTrans = Matrix::identity;
+ centerTrans = centerTransInv = Matrix::identity;
+
+ centerTrans.scale( 1.0, 1.0, 1.0/screen->width () );
+ centerTrans.translate( x + w/2.0, y + h/2.0, 0.0 );
+ centerTransInv.translate( -(x + w/2.0), -(y + h/2.0), 0.0);
+ centerTransInv.scale( 1.0f, 1.0f, 1.0f*screen->width () );
+
+ recalcVertices();
+ speed = speedrot = Vector::null;
+ }
+ else opacityOld = opacity;
+}
+
+// Update window vertices
+void WindowFlyingWindows::recalcVertices()
+{
+ float x = WIN_X(this->w);
+ float y = WIN_Y(this->w);
+ float w = WIN_W(this->w);
+ float h = WIN_H(this->w);
+
+ vertex[NO] = Point( x, y, 0.0 );
+ vertex[NE] = Point( x + w, y, 0.0 );
+ vertex[SO] = Point( x, y + h, 0.0 );
+ vertex[SE] = Point( x + w, y + h, 0.0 );
+ vertex[C] = Point( x + w/2.0, y + h/2.0, 0.0 );
+
+ // Apply the window transformation and normalize
+ for( int i = 0; i < 5; i++ )
+ vertex[i] = ( transform * vertex[i] ).toScreenSpace();
+}
+
+bool WindowFlyingWindows::glPaint (const GLWindowPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ unsigned int mask)
+{
+ GLWindowPaintAttrib sAttrib (attrib);
+ Matrix wTransform;
+
+ if( !active )
+ {
+ SCREENSAVER_SCREEN (screen);
+
+ if( opacity && steps && !ss->mState.fadingOut )
+ {
+ if( opacity < steps )
+ opacity = 0;
+ else opacity -= steps;
+ steps = 0;
+ }
+
+ sAttrib.opacity = opacity;
+ wTransform = transform;
+ }
+ else
+ {
+ SCREENSAVER_SCREEN (screen);
+ wTransform = transform * ss->mCameraMat * this->transform;
+ mask |= PAINT_WINDOW_TRANSFORMED_MASK;
+
+ if( w->state () & CompWindowStateSkipPagerMask )
+ return WindowEffect::glPaint (sAttrib, wTransform.m, region, mask );
+ }
+
+ if (w->alpha () || sAttrib.opacity != OPAQUE)
+ mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
+
+ // from paint.cpp
+ if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
+ {
+ if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
+ return FALSE;
+ if (mask & PAINT_WINDOW_NO_CORE_INSTANCE_MASK)
+ return FALSE;
+ if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
+ return FALSE;
+ if (w->shaded ())
+ return FALSE;
+ return TRUE;
+ }
+
+ GLFragment::Attrib fragment (sAttrib);
+
+ glPushMatrix();
+ glLoadMatrixf( wTransform.m );
+ bool status = sw->gWindow->glDraw (wTransform.m, fragment, region, mask);
+ glPopMatrix();
+ return status;
+}
diff --git a/src/flyingwindows.h b/src/flyingwindows.h
new file mode 100644
index 0000000..fa67187
--- /dev/null
+++ b/src/flyingwindows.h
@@ -0,0 +1,83 @@
+#ifndef FLYINGWINDOWS_H
+#define FLYINGWINDOWS_H
+
+#include "screensaver.h"
+
+class ScreenFlyingWindows : public ScreenEffect
+{
+public:
+ ScreenFlyingWindows() : ScreenEffect() {}
+ virtual ~ScreenFlyingWindows() {}
+
+ virtual void handleEvent (XEvent *event);
+ virtual bool enable();
+ virtual void disable();
+ virtual void preparePaint (int);
+ virtual void donePaint ();
+ virtual void glPaintTransformedOutput (const GLScreenPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ CompOutput *,
+ unsigned int );
+ virtual bool glPaintOutput (const GLScreenPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ CompOutput *,
+ unsigned int );
+ virtual void paint (CompOutput::ptrList &,
+ unsigned int );
+private:
+ void initWindow( CompWindow* _w );
+ void recalcVertices( CompWindow* _w );
+ void addForce( const Point& p1, const Point& p2, const Point& center, Vector& resultante, Vector& couple, float w, bool attract );
+};
+
+class WindowFlyingWindows : public WindowEffect
+{
+ friend class ScreenFlyingWindows;
+
+public:
+ WindowFlyingWindows( CompWindow* w );
+ virtual ~WindowFlyingWindows() {}
+ void initWindow();
+ virtual bool glPaint (const GLWindowPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ unsigned int );
+ void recalcVertices();
+
+ static WindowFlyingWindows& getInstance( CompWindow* w ) { return (WindowFlyingWindows& )*ScreenSaverWindow::get (w)->mEffect; }
+
+private:
+ bool isActiveWin();
+
+ // isScreenSaverWin()
+ bool active;
+
+ // used for non-active window like the desktop
+ GLushort opacity;
+ GLushort opacityFadeOut;
+ GLushort opacityOld;
+ int steps;
+
+ // used for active window
+ // translate matrix
+ Matrix transformTrans;
+
+ // rotation matrix
+ Matrix centerTrans, transformRot, centerTransInv;
+
+ // precomputed transform matrix
+ Matrix transform;
+
+ Matrix transformFadeOut;
+
+ // 5 normalized vertices are stored, the four corners and the center
+ Point vertex[5];
+
+ // normalized speed vectors
+ Vector speed;
+ Vector speedrot;
+};
+
+#endif
diff --git a/src/matrix.cpp b/src/matrix.cpp
new file mode 100644
index 0000000..c33ea0b
--- /dev/null
+++ b/src/matrix.cpp
@@ -0,0 +1,57 @@
+#include "screensaver.h"
+
+static const float _identity[16] = {
+ 1.0, 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0
+};
+
+const Matrix Matrix::identity = _identity;
+
+Matrix operator*( const Matrix& lhs, const Matrix& rhs )
+{
+ Matrix res;
+ res[0] = lhs[0] * rhs[0] + lhs[4] * rhs[1] + lhs[8] * rhs[2] + lhs[12] * rhs[3];
+ res[1] = lhs[1] * rhs[0] + lhs[5] * rhs[1] + lhs[9] * rhs[2] + lhs[13] * rhs[3];
+ res[2] = lhs[2] * rhs[0] + lhs[6] * rhs[1] + lhs[10] * rhs[2] + lhs[14] * rhs[3];
+ res[3] = lhs[3] * rhs[0] + lhs[7] * rhs[1] + lhs[11] * rhs[2] + lhs[15] * rhs[3];
+ res[4] = lhs[0] * rhs[4] + lhs[4] * rhs[5] + lhs[8] * rhs[6] + lhs[12] * rhs[7];
+ res[5] = lhs[1] * rhs[4] + lhs[5] * rhs[5] + lhs[9] * rhs[6] + lhs[13] * rhs[7];
+ res[6] = lhs[2] * rhs[4] + lhs[6] * rhs[5] + lhs[10] * rhs[6] + lhs[14] * rhs[7];
+ res[7] = lhs[3] * rhs[4] + lhs[7] * rhs[5] + lhs[11] * rhs[6] + lhs[15] * rhs[7];
+ res[8] = lhs[0] * rhs[8] + lhs[4] * rhs[9] + lhs[8] * rhs[10] + lhs[12] * rhs[11];
+ res[9] = lhs[1] * rhs[8] + lhs[5] * rhs[9] + lhs[9] * rhs[10] + lhs[13] * rhs[11];
+ res[10] = lhs[2] * rhs[8] + lhs[6] * rhs[9] + lhs[10] * rhs[10] + lhs[14] * rhs[11];
+ res[11] = lhs[3] * rhs[8] + lhs[7] * rhs[9] + lhs[11] * rhs[10] + lhs[15] * rhs[11];
+ res[12] = lhs[0] * rhs[12] + lhs[4] * rhs[13] + lhs[8] * rhs[14] + lhs[12] * rhs[15];
+ res[13] = lhs[1] * rhs[12] + lhs[5] * rhs[13] + lhs[9] * rhs[14] + lhs[13] * rhs[15];
+ res[14] = lhs[2] * rhs[12] + lhs[6] * rhs[13] + lhs[10] * rhs[14] + lhs[14] * rhs[15];
+ res[15] = lhs[3] * rhs[12] + lhs[7] * rhs[13] + lhs[11] * rhs[14] + lhs[15] * rhs[15];
+
+ return res;
+}
+
+Vector operator*( const Matrix& mat, const Vector& vect )
+{
+ Vector res;
+
+ res[0] = mat[0] * vect[0] + mat[4] * vect[1] + mat[8] * vect[2] + mat[12];
+ res[1] = mat[1] * vect[0] + mat[5] * vect[1] + mat[9] * vect[2] + mat[13];
+ res[2] = mat[2] * vect[0] + mat[6] * vect[1] + mat[10] * vect[2] + mat[14];
+ float w = mat[3] * vect[0] + mat[7] * vect[1] + mat[11] * vect[2] + mat[15];
+
+ res[0] /= w;
+ res[1] /= w;
+ res[2] /= w;
+
+ return res;
+}
+
+Matrix interpolate( const Matrix& from, const Matrix& to, float position )
+{
+ Matrix res;
+ for( int i = 0; i < 16; i++ )
+ res[i] = from[i] * (1 - position) + to[i] * position;
+ return res;
+}
diff --git a/src/matrix.h b/src/matrix.h
new file mode 100644
index 0000000..5dd5e9f
--- /dev/null
+++ b/src/matrix.h
@@ -0,0 +1,66 @@
+#ifndef MATRIX_H
+#define MATRIX_H
+
+#include <core/core.h>
+#include <opengl/opengl.h>
+#include <cmath>
+#include "vector.h"
+
+class Matrix
+{
+public:
+ static const Matrix identity;
+
+ Matrix() {
+ for (int i=0; i<16;i++) {
+ m[i] = 0;
+ }
+ }
+
+ Matrix( const GLMatrix &mat ) { memcpy( m, mat.getMatrix (), sizeof(m) ); }
+ Matrix( const Matrix& mat ) { memcpy( m, mat.m, sizeof(m) ); }
+ Matrix( const float* mat ) { memcpy( m, mat, sizeof(m) ); }
+
+ const float& operator[]( int i ) const { return m[i]; }
+ float& operator[]( int i ) { return m[i]; }
+
+ Matrix& operator*=( const Matrix& rhs ) { Matrix res; *this = *this * rhs; return *this; }
+ friend Matrix operator*( const Matrix& lhs, const Matrix& rhs );
+ friend Vector operator*( const Matrix& mat, const Vector& vect );
+
+ friend Matrix interpolate( const Matrix& from, const Matrix& to, float position );
+
+ Matrix& rotate( float angle, float x, float y, float z )
+ {
+ GLMatrix t (m);
+ t.rotate (angle, x, y, z );
+ memcpy ((void *)m, (const void *) t.getMatrix (), sizeof (float) * 16);
+ return *this;
+ }
+
+ Matrix& rotate( float angle, const Vector& vect ) { return rotate( angle, vect[x], vect[y], vect[z] ); }
+
+ Matrix& scale( float x, float y, float z )
+ {
+ GLMatrix t (m);
+ t.scale (x, y, z );
+ memcpy ((void *)m, (const void *) t.getMatrix (), sizeof (float) * 16);
+ return *this;
+ }
+
+ Matrix& scale( const Vector& vect ) { return scale( vect[x], vect[y], vect[z] ); }
+
+ Matrix& translate( float x, float y, float z )
+ {
+ GLMatrix t (m);
+ t.translate (x, y, z);
+ memcpy ((void *)m, (const void *) t.getMatrix (), sizeof (float) * 16);
+ return *this;
+ }
+
+ Matrix& translate( const Vector& vect ) { return translate( vect[x], vect[y], vect[z] ); }
+
+ float m[16];
+};
+
+#endif
diff --git a/src/rotatingcube.cpp b/src/rotatingcube.cpp
new file mode 100644
index 0000000..4b04c2b
--- /dev/null
+++ b/src/rotatingcube.cpp
@@ -0,0 +1,101 @@
+#include "rotatingcube.h"
+
+bool ScreenRotatingCube::loadCubePlugin()
+{
+ if (!CompPlugin::checkPluginABI ("cube", COMPIZ_CUBE_ABI))
+ return false;
+
+ return true;
+}
+
+bool ScreenRotatingCube::enable()
+{
+ if( !loadCubePlugin() )
+ return false;
+
+ CubeScreen *cs = ss->cubeScreen;
+
+ ss->mZCamera = 0.0;
+ ss->mCubeRotX = 0.0;
+ ss->mCubeRotV = 0.0;
+ cs->rotationState (CubeScreen::RotationManual);
+
+ ss->cubeScreen->cubeGetRotationSetEnabled (ss, true);
+
+ return ScreenEffect::enable();
+}
+
+void ScreenRotatingCube::disable()
+{
+ ss->mZCameraFadeOut = ss->mZCamera;
+ ss->mCubeRotXFadeOut = ss->mCubeRotX;
+ ss->mCubeRotVFadeOut = ss->mCubeRotV;
+
+ ss->cubeScreen->cubeGetRotationSetEnabled (ss, false);
+
+ ScreenEffect::disable();
+}
+
+void ScreenRotatingCube::clean()
+{
+ ss->cubeScreen->rotationState (CubeScreen::RotationNone);
+}
+
+void ScreenRotatingCube::cubeGetRotation( float& x, float& v, float &progress )
+{
+ ScreenEffect::cubeGetRotation( x, v, progress );
+
+ x += ss->mCubeRotX;
+ v += ss->mCubeRotV;
+ progress = MAX (progress, ss->mCubeProgress);
+}
+
+void ScreenRotatingCube::preparePaint (int msSinceLastPaint )
+{
+ ScreenEffect::preparePaint ( msSinceLastPaint );
+
+ float rotX = ss->optionGetCubeRotationSpeed ()/100.0;
+ float rotV = 0.0;
+
+ if( ss->mState.fadingIn )
+ {
+ rotX *= getProgress();
+ ss->mZCamera = -ss->optionGetCubeZoom() * getProgress();
+ ss->mCubeProgress = getProgress();
+ }
+ else if( ss->mState.fadingOut )
+ {
+ ss->mZCamera = ss->mZCameraFadeOut * (1-getProgress());
+ ss->mCubeRotX = ss->mCubeRotXFadeOut * (1-getProgress());
+ ss->mCubeRotV = ss->mCubeRotVFadeOut * (1-getProgress());
+ ss->mCubeProgress = 1 - getProgress();
+ }
+
+ if( !ss->mState.fadingOut )
+ {
+ ss->mCubeRotX += rotX * msSinceLastPaint;
+ ss->mCubeRotV += rotV * msSinceLastPaint;
+ }
+ if( ss->mCubeRotX > 180.0 ) ss->mCubeRotX -= 360.0;
+ if( ss->mCubeRotX < -180.0 ) ss->mCubeRotX += 360.0;
+}
+
+void ScreenRotatingCube::donePaint()
+{
+ ss->cScreen->damageScreen();
+ ScreenEffect::donePaint();
+}
+
+bool ScreenRotatingCube::glPaintOutput (const GLScreenPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ CompOutput *output,
+ unsigned int mask)
+{
+ GLScreenPaintAttrib sA (attrib);
+ sA.zCamera += ss->mZCamera;
+
+ mask &= ~PAINT_SCREEN_REGION_MASK;
+ mask |= PAINT_SCREEN_TRANSFORMED_MASK;
+ return ScreenEffect::glPaintOutput( sA, transform, region, output, mask );
+}
diff --git a/src/rotatingcube.h b/src/rotatingcube.h
new file mode 100644
index 0000000..d6ec85d
--- /dev/null
+++ b/src/rotatingcube.h
@@ -0,0 +1,29 @@
+#ifndef ROTATINGCUBE_H
+#define ROTATINGCUBE_H
+
+#include "screensaver.h"
+
+class ScreenRotatingCube : public ScreenEffect
+{
+public:
+ ScreenRotatingCube() : ScreenEffect() {}
+ virtual ~ScreenRotatingCube() {}
+
+ virtual bool enable();
+ virtual void disable();
+ virtual void cubeGetRotation( float& x, float& v, float &progress );
+ virtual void preparePaint( int msSinceLastPaint );
+ virtual void donePaint();
+ virtual bool glPaintOutput (const GLScreenPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ CompOutput *,
+ unsigned int );
+protected:
+ virtual void clean();
+
+private:
+ bool loadCubePlugin();
+};
+
+#endif
diff --git a/src/screensaver.cpp b/src/screensaver.cpp
new file mode 100644
index 0000000..3a38224
--- /dev/null
+++ b/src/screensaver.cpp
@@ -0,0 +1,312 @@
+/**
+ *
+ * Compiz screensaver plugin
+ *
+ * screensaver.cpp
+ *
+ * Copyright (c) 2007 Nicolas Viennot <nicolas@viennot.biz>
+ *
+ * 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.
+ *
+ **/
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "screensaver.h"
+#include "rotatingcube.h"
+#include "flyingwindows.h"
+
+COMPIZ_PLUGIN_20090315 (screensaver, ScreenSaverPluginVTable);
+
+template< typename _ScreenEffect, typename _WindowEffect >
+static void screenSaverEffectInstance ()
+{
+ SCREENSAVER_SCREEN (screen);
+ delete ss->mEffect;
+ ss->mEffect = new _ScreenEffect ();
+
+ foreach (CompWindow *w, screen->windows ())
+ {
+ SCREENSAVER_WINDOW(w);
+ delete sw->mEffect;
+ sw->mEffect = new _WindowEffect(w);
+ }
+}
+
+void
+ScreenSaverScreen::enableEffect ()
+{
+ enum ScreensaverOptions::Mode mode = (enum ScreensaverOptions::Mode) optionGetMode ();
+
+ if(mode == ModeFlyingWindows)
+ screenSaverEffectInstance<ScreenFlyingWindows, WindowFlyingWindows> ();
+
+ if (mode == ScreensaverOptions::ModeRotatingCube)
+ screenSaverEffectInstance <ScreenRotatingCube, WindowEffect> ();
+
+ mTime = 0;
+
+ if (!mEffect->enable ())
+ {
+ fprintf (stderr, "Fail\n");
+ screenSaverEffectInstance <ScreenEffect, WindowEffect> ();
+ return;
+ }
+
+ mState.fadingOut = false;
+ mState.fadingIn = true;
+ mState.running = true;
+}
+
+void
+ScreenSaverScreen::disableEffect ()
+{
+ mEffect->disable ();
+ mTime = 0;
+
+ mState.fadingOut = true;
+ mState.fadingIn = false;
+}
+
+void
+ScreenSaverScreen::cleanEffect ()
+{
+ screenSaverEffectInstance <ScreenEffect, WindowEffect> ();
+}
+
+void
+ScreenSaverScreen::setState (bool enable)
+{
+ if (!mState.running && enable)
+ mEffect->loadEffect = true;
+ if (mState.running && !enable && !mState.fadingOut)
+ disableEffect ();
+}
+
+bool
+ScreenSaverScreen::initiate (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options)
+{
+
+ setState (!mState.running);
+ return true;
+}
+
+void
+ScreenSaverScreen::cubeGetRotation (float &x, float &v, float &progress)
+{
+ mEffect->cubeGetRotation (x, v, progress);
+}
+
+bool
+ScreenSaverWindow::glPaint (const GLWindowPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ unsigned int mask)
+{
+ return mEffect->glPaint (attrib, transform, region, mask);
+}
+
+bool
+ScreenSaverScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ CompOutput *output,
+ unsigned int mask)
+{
+ return mEffect->glPaintOutput (attrib, transform, region, output, mask);
+}
+
+void
+ScreenSaverScreen::preparePaint (int ms)
+{
+ mEffect->preparePaint (ms);
+}
+
+void
+ScreenSaverScreen::glPaintTransformedOutput (const GLScreenPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ CompOutput *output,
+ unsigned int mask)
+{
+ mEffect->glPaintTransformedOutput (attrib, transform, region, output, mask);
+}
+
+void
+ScreenSaverScreen::donePaint ()
+{
+ mEffect->donePaint ();
+}
+
+void
+ScreenSaverScreen::handleEvent (XEvent *event)
+{
+ XScreenSaverNotifyEvent *xssEvent;
+
+ mEffect->handleEvent (event);
+
+ switch ((event->type & 0x7F) - mXSSContext.first_event)
+ {
+ case ScreenSaverNotify:
+ xssEvent = (XScreenSaverNotifyEvent *) event;
+ setState (xssEvent->state);
+ break;
+ default:
+ break;
+ }
+
+ if (mEffect->loadEffect)
+ {
+ mEffect->loadEffect = false;
+ enableEffect ();
+ }
+ else if (mEffect->cleanEffect)
+ {
+ mEffect->cleanEffect = false;
+ cleanEffect ();
+ }
+}
+
+void
+ScreenSaverScreen::paint (CompOutput::ptrList &outputs,
+ unsigned int mask)
+{
+ mEffect->paint (outputs, mask);
+}
+
+void
+ScreenSaverScreen::setXScreenSaver (bool enabled)
+{
+ Window root = screen->root ();
+
+ if (enabled && mXSSContext.init)
+ {
+ int dummy;
+ long unsigned int mask = 0;
+ XSetWindowAttributes attr;
+
+ if (!XScreenSaverQueryExtension (screen->dpy (), &mXSSContext.first_event, &dummy))
+ {
+ compLogMessage ("screensaver", CompLogLevelWarn,
+ "XScreenSaver Extension not available, cannot integrate with "\
+ "desktop settings!");
+ return;
+ }
+
+ mXSSContext.init = true;
+
+ XGetScreenSaver (screen->dpy (), &mXSSContext.timeout, &mXSSContext.interval,
+ &mXSSContext.prefer_blanking, &mXSSContext.allow_exposures);
+ XSetScreenSaver (screen->dpy (), (int) (optionGetAfter () * 60.0), mXSSContext.interval, 0, AllowExposures);
+
+ XScreenSaverSetAttributes (screen->dpy (), root, -100, -100, 1, 1, 0,
+ CopyFromParent, CopyFromParent, DefaultVisual (screen->dpy (), screen->screenNum ()), mask, &attr);
+
+ XScreenSaverSelectInput (screen->dpy (), root, ScreenSaverNotifyMask);
+
+ }
+ if (!enabled && mXSSContext.init )
+ {
+ mXSSContext.init = false;
+
+ XSetScreenSaver (screen->dpy (), mXSSContext.timeout, mXSSContext.interval,
+ mXSSContext.prefer_blanking, mXSSContext.allow_exposures);
+
+ XScreenSaverSelectInput (screen->dpy (), root, 0);
+ XScreenSaverUnsetAttributes (screen->dpy (), root);
+ }
+}
+
+void
+ScreenSaverScreen::optionChanged (CompOption *opt,
+ ScreensaverOptions::Options num)
+{
+ setXScreenSaver (false);
+ setXScreenSaver (optionGetStartAutomatically ());
+}
+
+ScreenSaverWindow::ScreenSaverWindow (CompWindow *w) :
+ PluginClassHandler <ScreenSaverWindow, CompWindow> (w),
+ mEffect (NULL),
+ window (w),
+ cWindow (CompositeWindow::get (w)),
+ gWindow (GLWindow::get (w))
+{
+ ScreenSaverScreen *ss = ScreenSaverScreen::get (screen);
+
+ if(ss->mState.running && (enum ScreensaverOptions::Mode) ss->optionGetMode() == ScreensaverOptions::ModeFlyingWindows)
+ mEffect = new WindowFlyingWindows (w);
+ else
+ mEffect = new WindowEffect (w);
+
+
+ GLWindowInterface::setHandler (gWindow);
+}
+
+ScreenSaverWindow::~ScreenSaverWindow ()
+{
+ delete mEffect;
+}
+
+ScreenSaverScreen::ScreenSaverScreen (CompScreen *s) :
+ PluginClassHandler <ScreenSaverScreen, CompScreen> (s),
+ cScreen (CompositeScreen::get (screen)),
+ gScreen (GLScreen::get (screen)),
+ cubeScreen (CubeScreen::get (screen)),
+ mEffect (new ScreenEffect ()),
+ mDesktopOpacity (OPAQUE)
+{
+ ScreenInterface::setHandler (screen);
+ GLScreenInterface::setHandler (gScreen);
+ CompositeScreenInterface::setHandler (cScreen);
+ CubeScreenInterface::setHandler (cubeScreen);
+
+ mState.running = false;
+ mState.fadingOut = false;
+ mState.fadingIn = false;
+
+ optionSetInitiateKeyInitiate (boost::bind (&ScreenSaverScreen::initiate, this, _1, _2, _3));
+ optionSetInitiateButtonInitiate (boost::bind (&ScreenSaverScreen::initiate, this, _1, _2, _3));
+ optionSetInitiateEdgeInitiate (boost::bind (&ScreenSaverScreen::initiate, this, _1, _2, _3));
+
+ optionSetStartAutomaticallyNotify (boost::bind (&ScreenSaverScreen::optionChanged, this, _1, _2));
+ optionSetAfterNotify (boost::bind (&ScreenSaverScreen::optionChanged, this, _1, _2));
+
+ mXSSContext.init = false;
+
+ mEffect->loadEffect = false;
+ mEffect->cleanEffect = false;
+
+ setXScreenSaver (optionGetStartAutomatically ());
+}
+
+ScreenSaverScreen::~ScreenSaverScreen ()
+{
+ delete mEffect;
+}
+
+
+bool
+ScreenSaverPluginVTable::init ()
+{
+ if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
+ !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
+ !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI) ||
+ !CompPlugin::checkPluginABI ("cube", COMPIZ_CUBE_ABI))
+ return false;
+
+ return true;
+}
diff --git a/src/screensaver.h b/src/screensaver.h
new file mode 100644
index 0000000..4737fec
--- /dev/null
+++ b/src/screensaver.h
@@ -0,0 +1,238 @@
+#ifndef SCREENSAVER_INTERNAL_H
+#define SCREENSAVER_INTERNAL_H
+
+#include <core/core.h>
+#include <composite/composite.h>
+#include <opengl/opengl.h>
+#include <cube/cube.h>
+
+#include <X11/extensions/scrnsaver.h>
+
+#include "screensaver_options.h"
+#include "matrix.h"
+#include "vector.h"
+
+#define WIN_X(w) ((w)->x () - (w)->input ().left )
+#define WIN_Y(w) ((w)->y () - (w)->input ().top )
+#define WIN_W(w) ((w)->width () + (w)->input ().left + (w)->input ().right )
+#define WIN_H(w) ((w)->height () + (w)->input ().top + (w)->input ().bottom )
+
+extern int displayPrivateIndex;
+
+class ScreenSaverScreen;
+class ScreenSaverWindow;
+
+class ScreenWrapper
+{
+public:
+ ScreenWrapper();
+ ~ScreenWrapper() {}
+
+ virtual void cubeGetRotation( float& x, float& v, float &progress );
+ virtual void handleEvent (XEvent *);
+ virtual void preparePaint (int);
+ virtual void donePaint ();
+ virtual void glPaintTransformedOutput (const GLScreenPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ CompOutput *,
+ unsigned int );
+ virtual bool glPaintOutput (const GLScreenPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ CompOutput *,
+ unsigned int );
+ virtual void paint (CompOutput::ptrList &,
+ unsigned int );
+
+protected:
+ CompScreen* s;
+ ScreenSaverScreen* ss;
+};
+
+class WindowWrapper
+{
+public:
+ WindowWrapper( CompWindow* w );
+ virtual ~WindowWrapper() {}
+ virtual bool glPaint (const GLWindowPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ unsigned int );
+protected:
+ CompWindow* w;
+ ScreenSaverWindow* sw;
+};
+
+
+class ScreenEffect : public ScreenWrapper
+{
+public:
+ ScreenEffect() : ScreenWrapper(), progress(0) {}
+ virtual ~ScreenEffect() {}
+ float getProgress() { return progress; }
+ virtual void handleEvent (XEvent *event);
+
+ virtual bool enable();
+ virtual void disable() {}
+ virtual void preparePaint( int msSinceLastPaint );
+ virtual void cubeGetRotation (float &, float &, float &); // TODO: get rid of this!
+
+ bool cleanEffect;
+ bool loadEffect;
+
+protected:
+ virtual void clean() {}
+
+private:
+ float progress;
+};
+
+class WindowEffect : public WindowWrapper
+{
+public:
+ WindowEffect( CompWindow* w ) : WindowWrapper(w) {}
+ virtual ~WindowEffect() {}
+};
+
+class ScreenSaver
+{
+ public:
+
+ class State
+ {
+ public:
+ // when the screensaver is enabled, running and fadingIn are set to true
+ // then, after fadingInDuration, fadingIn is set to false
+ // when the screensaver is requested to stop, fadingOut is set to true
+ // after fadingOutDuration, running is set to false
+ bool running;
+ bool fadingOut;
+ bool fadingIn;
+ };
+
+ class XSSContext
+ {
+ public:
+ int timeout, interval, prefer_blanking, allow_exposures;
+ int first_event;
+ bool init;
+ };
+};
+
+class ScreenSaverScreen :
+ public PluginClassHandler <ScreenSaverScreen, CompScreen>,
+ public ScreenInterface,
+ public CompositeScreenInterface,
+ public GLScreenInterface,
+ public CubeScreenInterface,
+ public ScreensaverOptions
+{
+ public:
+
+ ScreenSaverScreen (CompScreen *s);
+ ~ScreenSaverScreen ();
+
+ public:
+
+ CompositeScreen *cScreen;
+ GLScreen *gScreen;
+ CubeScreen *cubeScreen;
+
+ ScreenSaver::State mState;
+ ScreenSaver::XSSContext mXSSContext;
+
+ ScreenEffect *mEffect;
+
+ void
+ cubeGetRotation (float &x, float &v, float &progress);
+
+ void
+ handleEvent (XEvent *);
+
+ void
+ preparePaint (int);
+
+ void
+ donePaint ();
+
+ void
+ glPaintTransformedOutput (const GLScreenPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ CompOutput *,
+ unsigned int );
+
+
+ bool glPaintOutput (const GLScreenPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ CompOutput *,
+ unsigned int );
+
+ void
+ paint (CompOutput::ptrList &outputs,
+ unsigned int mask);
+
+ void enableEffect ();
+
+ void disableEffect ();
+
+ void cleanEffect ();
+
+ void setState (bool);
+
+ bool initiate (CompAction *, CompAction::State, CompOption::Vector);
+
+ void setXScreenSaver (bool);
+ void optionChanged (CompOption *, ScreensaverOptions::Options);
+
+ int mTime;
+ float mCubeRotX, mCubeRotV, mCubeProgress, mZCamera;
+ float mCubeRotXFadeOut, mCubeRotVFadeOut, mZCameraFadeOut;
+
+ Point mScreenCenter;
+ Matrix mCamera, mCameraMat;
+
+ float mAngleCam;
+ GLushort mDesktopOpacity;
+};
+
+class ScreenSaverWindow :
+ public PluginClassHandler <ScreenSaverWindow, CompWindow>,
+ public GLWindowInterface
+{
+ public:
+
+ ScreenSaverWindow (CompWindow *w);
+ ~ScreenSaverWindow ();
+
+ WindowEffect *mEffect;
+
+ bool
+ glPaint (const GLWindowPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ unsigned int );
+
+ CompWindow *window;
+ CompositeWindow *cWindow;
+ GLWindow *gWindow;
+
+};
+
+#define SCREENSAVER_SCREEN(s) \
+ ScreenSaverScreen *ss = ScreenSaverScreen::get (s);
+
+#define SCREENSAVER_WINDOW(w) \
+ ScreenSaverWindow *sw = ScreenSaverWindow::get (w);
+
+class ScreenSaverPluginVTable :
+ public CompPlugin::VTableForScreenAndWindow <ScreenSaverScreen, ScreenSaverWindow>
+{
+ public:
+
+ bool init ();
+};
+
+#endif
diff --git a/src/vector.cpp b/src/vector.cpp
new file mode 100644
index 0000000..d1bed04
--- /dev/null
+++ b/src/vector.cpp
@@ -0,0 +1,14 @@
+#include "vector.h"
+
+const Vector Vector::null( 0.0, 0.0, 0.0 );
+
+Vector operator^( const Vector& lhs, const Vector& rhs )
+{
+ Vector res;
+
+ res[0] = lhs[1]*rhs[2] - lhs[2]*rhs[1];
+ res[1] = lhs[2]*rhs[0] - lhs[0]*rhs[2];
+ res[2] = lhs[0]*rhs[1] - lhs[1]*rhs[0];
+
+ return res;
+}
diff --git a/src/vector.h b/src/vector.h
new file mode 100644
index 0000000..9a99986
--- /dev/null
+++ b/src/vector.h
@@ -0,0 +1,160 @@
+#ifndef VECTOR_H
+#define VECTOR_H
+
+#include <core/core.h>
+#include <opengl/opengl.h>
+#include <cmath>
+
+typedef enum
+{
+ x,
+ y,
+ z
+} VectorCoordsEnum;
+
+class Vector
+{
+public:
+ static const Vector null;
+
+ Vector()
+ {
+ for(int i = 0; i<3; i++) {
+ v[i] = 0;
+ }
+ }
+ Vector( float x, float y, float z ) { v[0] = x; v[1] = y; v[2] = z; }
+ Vector( const float* vect ) { v[0] = vect[0]; v[1] = vect[1]; v[2] = vect[2]; }
+ Vector( const Vector& vect ) { v[0] = vect[0]; v[1] = vect[1]; v[2] = vect[2]; }
+
+ float norm() { return sqrt( (*this) * (*this) ); }
+ Vector& normalize()
+ {
+ float n = norm();
+ if( n == 0.0 )
+ v[x] = v[y] = v[z] = 1.0;
+ else *this /= n;
+ return *this;
+ }
+
+ Vector toScreenSpace () const
+ {
+ Vector res;
+ res[0] = v[0]/screen->width () - 0.5;
+ res[1] = 0.5 - v[1]/screen->height ();
+ res[2] = v[2];
+ return res;
+ }
+
+ Vector toCoordsSpace () const
+ {
+ Vector res;
+ res[0] = ( v[0] + 0.5 )*screen->width ();
+ res[1] = ( 0.5 - v[1] )*screen->height ();
+ res[2] = v[2];
+ return res;
+ }
+
+ float& operator[]( int i ) { return v[i]; }
+ const float& operator[]( int i ) const { return v[i]; }
+ float& operator[]( VectorCoordsEnum c ) { return v[(int)c]; }
+ const float& operator[]( VectorCoordsEnum c ) const { return v[(int)c]; }
+
+ Vector& operator+=( const Vector& rhs )
+ {
+ v[0] += rhs[0];
+ v[1] += rhs[1];
+ v[2] += rhs[2];
+ return *this;
+ }
+
+ friend Vector operator+( const Vector& lhs, const Vector& rhs )
+ {
+ Vector res;
+ res[0] = lhs[0] + rhs[0];
+ res[1] = lhs[1] + rhs[1];
+ res[2] = lhs[2] + rhs[2];
+ return res;
+ }
+
+ Vector& operator-=( const Vector& rhs )
+ {
+ v[0] -= rhs[0];
+ v[1] -= rhs[1];
+ v[2] -= rhs[2];
+ return *this;
+ }
+
+ friend Vector operator-( const Vector& lhs, const Vector& rhs )
+ {
+ Vector res;
+ res[0] = lhs[0] - rhs[0];
+ res[1] = lhs[1] - rhs[1];
+ res[2] = lhs[2] - rhs[2];
+ return res;
+ }
+
+ friend Vector operator-( const Vector& vect )
+ {
+ Vector res;
+ res[0] = -vect[0];
+ res[1] = -vect[1];
+ res[2] = -vect[2];
+ return res;
+ }
+
+ Vector& operator*=( const float k )
+ {
+ v[0] *= k;
+ v[1] *= k;
+ v[2] *= k;
+ return *this;
+ }
+
+ friend float operator*( const Vector& lhs, const Vector& rhs )
+ {
+ return lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2];
+ }
+
+ friend Vector operator*( const float k, const Vector& vect )
+ {
+ Vector res;
+ res[0] = k * vect[0];
+ res[1] = k * vect[1];
+ res[2] = k * vect[2];
+ return res;
+ }
+
+ friend Vector operator*( const Vector& v, const float k ) { return k*v; }
+
+ Vector& operator/=( const float k )
+ {
+ v[0] /= k;
+ v[1] /= k;
+ v[2] /= k;
+ return *this;
+ }
+
+ friend Vector operator/( const Vector& vect, const float k )
+ {
+ Vector res;
+ res[0] = vect[0] / k;
+ res[1] = vect[1] / k;
+ res[2] = vect[2] / k;
+ return res;
+ }
+
+ Vector& operator^=( const Vector& vect )
+ {
+ *this = *this ^ vect;
+ return *this;
+ }
+
+ friend Vector operator^( const Vector& lhs, const Vector& rhs );
+
+ float v[3];
+};
+
+typedef Vector Point;
+
+#endif
diff --git a/src/wrapper.cpp b/src/wrapper.cpp
new file mode 100644
index 0000000..ac81720
--- /dev/null
+++ b/src/wrapper.cpp
@@ -0,0 +1,68 @@
+#include "screensaver.h"
+
+void ScreenWrapper::handleEvent( XEvent *event )
+{
+ screen->handleEvent (event);
+}
+
+ScreenWrapper::ScreenWrapper ()
+{
+ SCREENSAVER_SCREEN(screen);
+ this->s = screen;
+ this->ss = ss;
+}
+
+void ScreenWrapper::cubeGetRotation( float& x, float& v, float &progress )
+{
+ ss->cubeScreen->cubeGetRotation (x, v, progress);
+}
+
+void ScreenWrapper::preparePaint (int msSinceLastPaint )
+{
+ ss->cScreen->preparePaint (msSinceLastPaint);
+}
+
+void ScreenWrapper::donePaint ()
+{
+ ss->cScreen->donePaint ();
+}
+
+void ScreenWrapper::glPaintTransformedOutput (const GLScreenPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ CompOutput *output,
+ unsigned int mask)
+{
+ ss->gScreen->glPaintTransformedOutput (attrib, transform, region, output, mask);
+}
+
+bool ScreenWrapper::glPaintOutput (const GLScreenPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ CompOutput *output,
+ unsigned int mask)
+{
+ return ss->gScreen->glPaintOutput (attrib, transform, region, output, mask);
+}
+
+void ScreenWrapper::paint (CompOutput::ptrList &outputs,
+ unsigned int mask)
+{
+ ss->cScreen->paint (outputs, mask);
+}
+
+
+WindowWrapper::WindowWrapper( CompWindow* w )
+{
+ SCREENSAVER_WINDOW(w);
+ this->w = w;
+ this->sw = sw;
+}
+
+bool WindowWrapper::glPaint (const GLWindowPaintAttrib &attrib,
+ const GLMatrix &transform,
+ const CompRegion &region,
+ unsigned int mask)
+{
+ return sw->gWindow->glPaint (attrib, transform, region, mask);
+}
diff --git a/src/wrapper.h b/src/wrapper.h
new file mode 100644
index 0000000..6f7eae4
--- /dev/null
+++ b/src/wrapper.h
@@ -0,0 +1,5 @@
+#ifndef WRAPPER_H
+#define WRAPPER_H
+
+
+#endif