[beryl-commits] r1489 - branches trunk/beryl-plugins/po trunk/beryl-plugins/src

guillaume at server.beryl-project.org guillaume at server.beryl-project.org
Sat Dec 2 00:22:56 CET 2006


Author: guillaume
Date: 2006-12-02 00:22:55 +0100 (Sat, 02 Dec 2006)
New Revision: 1489

Added:
   trunk/beryl-plugins/src/3d.c
Removed:
   branches/beryl-3d-plugin/
Modified:
   trunk/beryl-plugins/po/POTFILES.in
   trunk/beryl-plugins/src/Makefile.am
Log:
beryl-plugins: Merge 3d plugin to trunk (roico)


Modified: trunk/beryl-plugins/po/POTFILES.in
===================================================================
--- trunk/beryl-plugins/po/POTFILES.in	2006-12-01 21:32:33 UTC (rev 1488)
+++ trunk/beryl-plugins/po/POTFILES.in	2006-12-01 23:22:55 UTC (rev 1489)
@@ -1,3 +1,4 @@
+src/3d.c
 src/animation.c
 src/annotate.c
 src/bench.c

Added: trunk/beryl-plugins/src/3d.c
===================================================================
--- trunk/beryl-plugins/src/3d.c	                        (rev 0)
+++ trunk/beryl-plugins/src/3d.c	2006-12-01 23:22:55 UTC (rev 1489)
@@ -0,0 +1,1042 @@
+/**
+ *
+ * Beryl 3d plugin
+ *
+ * 3d.c
+ *
+ * Copyright : (C) 2006 by Roi Cohen
+ * E-mail    : roico12 at gmail.com
+ *
+ *
+ * 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.
+ *
+ **/
+
+/**
+TODO:
+        1. Add 3d shadows / projections.
+        2. Add width to windows.
+        3. Add an option to select z-order of windows not only by viewports but also by screens.
+        4. Fix 3d for inside cube and planed / unfolded cube.
+        5. Find a better solution for blur cache + 3d.
+        6. Fix bugs with 3d + animations / wobbly.
+        	- Wobbly will draw the window twice if its in 2 different viewports.
+        	- Many Bugs with animations, some are solvable by changing the load order, but it will result with clipping when animations are done.
+*/
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <math.h>
+
+#include <beryl.h>
+#include <beryl_helpers.h>
+
+#define PI 3.14159265359f
+
+#define TD_SPACE_DEFAULT    0.04f
+#define TD_SPACE_MIN        0.0f
+#define TD_SPACE_MAX        1.0f
+#define TD_SPACE_PRECISION  0.01f
+
+#define TD_SPEED_DEFAULT    0.005f
+#define TD_SPEED_MIN        0.0f
+#define TD_SPEED_MAX        1.0f
+#define TD_SPEED_PRECISION  0.001f
+
+#define TD_CREATE_MIPMAPS_DEFAULT TRUE
+
+#define TD_DISABLE_BACKFACE_CULLING_DEFAULT TRUE
+
+#define TD_DISABLE_CAPS_IN_INSIDE_CUBE_DEFAULT TRUE
+
+#define TD_SCREEN_OPTION_SPACE         			0
+#define TD_SCREEN_OPTION_SPEED         			1
+#define TD_SCREEN_OPTION_CREATE_MIPMAPS			2
+#define TD_SCREEN_OPTION_DISABLE_BACKFACE_CULLING	3
+#define TD_SCREEN_OPTION_DISABLE_CAPS_IN_INSIDE_CUBE	4
+#define TD_SCREEN_OPTION_NUM				5
+
+#define SPEED (tds->opt[TD_SCREEN_OPTION_SPEED].value.f)
+#define SPACE (tds->opt[TD_SCREEN_OPTION_SPACE].value.f)
+#define CREATE_MIPMAPS (tds->opt[TD_SCREEN_OPTION_CREATE_MIPMAPS].value.b)
+#define DISABLE_BACKFACE_CULLING (tds->opt[TD_SCREEN_OPTION_DISABLE_BACKFACE_CULLING].value.b)
+#define DISABLE_CAPS (tds->opt[TD_SCREEN_OPTION_DISABLE_CAPS_IN_INSIDE_CUBE].value.b)
+
+
+static int displayPrivateIndex;
+
+typedef struct _revertReorder
+{
+        struct _revertReorder* next;
+        struct _revertReorder* prev;
+
+        CompWindow* window;
+
+        CompWindow* nextWindow;
+        CompWindow* prevWindow;
+} RevertReorder;
+
+
+typedef enum _MultiMonitorMode
+{
+	Automatic,
+    Multiscreen,
+    Multiple,
+	OneBig,
+} MultiMonitorMode;
+
+
+typedef struct _tdDisplay {
+        int screenPrivateIndex;
+} tdDisplay;
+
+
+
+typedef struct _tdScreen {
+
+        int windowPrivateIndex;
+        CompOption opt[TD_SCREEN_OPTION_NUM];
+
+        Bool tdWindowExists;
+        //Bool reorder;
+
+        PreparePaintScreenProc preparePaintScreen;
+
+        PaintTransformedScreenProc paintTransformedScreen;
+        PaintScreenProc paintScreen;
+
+        DonePaintScreenProc donePaintScreen;
+
+        PaintWindowProc paintWindow;
+
+        RevertReorder* revertReorder;
+	
+	float maxZ;
+	
+        int currentViewportNum;
+        float xMove;
+        
+        int mmModeAtom;
+        MultiMonitorMode currentMmMode;
+        
+        int insideAtom;
+        
+        Bool currentDifferentResolutions;
+        
+        int currentScreenNum;
+        
+        float mvm[16];	//ModelView Matrix.
+        float pm[16];	//Projection Matrix.
+        float pmvm[16];	//Projection * ModelView matrix.
+        
+        Bool reorderWindowPainting;
+        int tmpOutput;
+} tdScreen;
+
+typedef struct _tdWindow {
+        float z;
+        float currentZ;
+} tdWindow;
+
+
+#define GET_TD_DISPLAY(d)       \
+        ((tdDisplay *) (d)->privates[displayPrivateIndex].ptr)
+
+#define TD_DISPLAY(d)   \
+        tdDisplay *tdd = GET_TD_DISPLAY (d)
+
+#define GET_TD_SCREEN(s, tdd)   \
+        ((tdScreen *) (s)->privates[(tdd)->screenPrivateIndex].ptr)
+
+#define TD_SCREEN(s)    \
+        tdScreen *tds = GET_TD_SCREEN (s, GET_TD_DISPLAY (s->display))
+
+#define GET_TD_WINDOW(w, tds)                                     \
+        ((tdWindow *) (w)->privates[(tds)->windowPrivateIndex].ptr)
+
+#define TD_WINDOW(w)    \
+        tdWindow *tdw = GET_TD_WINDOW  (w,                     \
+                GET_TD_SCREEN  (w->screen,             \
+                        GET_TD_DISPLAY (w->screen->display)))
+
+
+
+#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))
+
+static Bool
+windowIs3D(CompWindow* w)
+{
+        if(w->attrib.override_redirect)
+                return FALSE;
+
+        if(!(w->shaded || w->attrib.map_state == IsViewable))
+                return FALSE;
+
+        switch(w->type)
+        {
+                case CompWindowTypeDialogMask:
+                case CompWindowTypeModalDialogMask:
+                case CompWindowTypeUtilMask:
+                case CompWindowTypeNormalMask:
+                        return TRUE;
+        }
+
+        return FALSE;
+}
+
+static Bool
+differentResolutions(CompScreen* s)
+{
+	//This code is taken from cube plugin... thanks for whoever wrote it (davidr i guess).
+
+	BoxPtr pBox0, pBox1;
+	int    i, j, k;
+
+	k = 0;
+
+	for (i = 0; i < s->nOutputDev; i++)
+	{
+		/* dimensions must match first output */
+		if (s->outputDev[i].width  != s->outputDev[0].width ||
+		    s->outputDev[i].height != s->outputDev[0].height)
+			continue;
+
+		pBox0 = &s->outputDev[0].region.extents;
+        	pBox1 = &s->outputDev[i].region.extents;
+
+		/* top and bottom line must match first output */
+		if (pBox0->y1 != pBox1->y1 || pBox0->y2 != pBox1->y2)
+			continue;
+
+		k++;
+
+		for (j = 0; j < s->nOutputDev; j++)
+		{
+			pBox0 = &s->outputDev[j].region.extents;
+
+			/* must not intersect other output region */
+			if (i != j && pBox0->x2 > pBox1->x1 && pBox0->x1 < pBox1->x2)
+			{
+				k--;
+ 				break;
+			}
+		}
+	}
+	
+	if( k != s->nOutputDev)
+		return TRUE;
+	
+	return FALSE;
+}
+
+#define REAL_POSITION(x, s) ( (x >= 0)? x: x + (s)->hsize * (s)->width )
+
+#define VIEWPORT(x, s) ( ( REAL_POSITION(x, s) / (s)->width ) % (s)->hsize )
+#define SCREEN(x, s)   ( ( REAL_POSITION(x, s) % (s)->width ) / (s)->outputDev[0].width )
+
+#define RIGHT_VIEWPORT(w) VIEWPORT( (w)->attrib.x + (w)->attrib.width -1, (w)->screen)
+#define LEFT_VIEWPORT(w) VIEWPORT( (w)->attrib.x + 1, (w)->screen)
+
+#define RIGHT_SCREEN(w) SCREEN( (w)->attrib.x + (w)->attrib.width -1, (w)->screen)
+#define LEFT_SCREEN(w) SCREEN( (w)->attrib.x + 1, (w)->screen)
+
+#define IS_IN_VIEWPORT(w, i) ( ( LEFT_VIEWPORT(w) > RIGHT_VIEWPORT(w) && !(LEFT_VIEWPORT(w) > i && i > RIGHT_VIEWPORT(w)) ) \
+                                || ( LEFT_VIEWPORT(w) <= i && i <= RIGHT_VIEWPORT(w) ) )
+
+#define DO_3D(d) (compDisplayGetRequestFlagForAny (d, "ENABLE_3D"))
+
+#define MULTISCREENCUBE_MODE  ( (tds->currentMmMode == Automatic && !tds->currentDifferentResolutions) \
+                    || tds->currentMmMode == Multiscreen )
+
+static void
+reorder(CompScreen* screen)
+{
+        CompWindow* firstReordered = NULL;
+        CompWindow* next;
+        CompWindow* w;
+
+        TD_SCREEN(screen);
+
+        for( w = screen->windows; w && w != firstReordered; w = next )
+        {
+                next = w->next;
+
+                if(!windowIs3D(w))
+                        continue;
+
+                if(!firstReordered)
+                        firstReordered = w;
+
+                if(tds->revertReorder)
+                {
+                        tds->revertReorder->next = (RevertReorder*) malloc(sizeof(RevertReorder));
+                        tds->revertReorder->next->prev = tds->revertReorder;
+
+                        tds->revertReorder = tds->revertReorder->next;
+                }
+
+                else
+                {
+                        tds->revertReorder = (RevertReorder*) malloc(sizeof(RevertReorder));
+                        tds->revertReorder->prev = NULL;
+                }
+
+                tds->revertReorder->next = NULL;
+
+                tds->revertReorder->window = w;
+                tds->revertReorder->nextWindow = w->next;
+                tds->revertReorder->prevWindow = w->prev;
+
+                unhookWindowFromScreen (screen, w);
+
+                /*This is a faster replacement to insertWindowIntoScreen (screen, w, screen->reverseWindows->id)
+                  The original function will go through all the windows until it finds screen->reverseWindows->id
+                  But we already know where that window is, so it's unnecessary to go through all the windows.*/
+                if(screen->windows)
+                {
+                        screen->reverseWindows->next = w;
+                        w->next = NULL;
+                        w->prev = screen->reverseWindows;
+                        screen->reverseWindows = w;
+                }
+
+                else
+                {
+                        screen->reverseWindows = screen->windows = w;
+                        w->prev = w->next = NULL;
+                }
+        }
+}
+
+static void
+revertReorder(CompScreen* screen)
+{
+        TD_SCREEN(screen);
+
+        while(tds->revertReorder)
+        {
+                unhookWindowFromScreen(screen, tds->revertReorder->window);
+
+                tds->revertReorder->window->next = tds->revertReorder->nextWindow;
+                tds->revertReorder->window->prev = tds->revertReorder->prevWindow;
+
+                if(tds->revertReorder->nextWindow)
+                        tds->revertReorder->nextWindow->prev = tds->revertReorder->window;
+                else
+                        screen->reverseWindows = tds->revertReorder->window;
+
+                if(tds->revertReorder->prevWindow)
+                        tds->revertReorder->prevWindow->next = tds->revertReorder->window;
+                else
+                        screen->windows = tds->revertReorder->window;
+
+                if(tds->revertReorder->prev)
+                {
+                        tds->revertReorder = tds->revertReorder->prev;
+
+                        free(tds->revertReorder->next);
+                        tds->revertReorder->next = NULL;
+                }
+
+                else
+                {
+                        free(tds->revertReorder);
+                        tds->revertReorder = NULL;
+                }
+        }
+}
+
+static void
+tdPreparePaintScreen(CompScreen *screen, int msSinceLastPaint)
+{
+        tdWindow** lastInViewport;
+
+        CompWindow* w;
+
+        tdWindow* tdw;
+
+        int i;
+
+        float maxZoom;
+
+        TD_SCREEN(screen);
+
+        if( tds->currentMmMode != IPCS_GetInt (IPCS_OBJECT(screen), tds->mmModeAtom)
+        	|| tds->currentViewportNum != screen->hsize
+        	|| tds->currentScreenNum != screen->nOutputDev
+        	|| tds->currentDifferentResolutions != differentResolutions(screen))
+        {
+                tds->currentViewportNum = screen->hsize;
+                tds->currentMmMode = IPCS_GetInt (IPCS_OBJECT(screen), tds->mmModeAtom);
+                tds->currentScreenNum = screen->nOutputDev;
+                tds->currentDifferentResolutions = differentResolutions(screen); 
+                
+                
+                if( MULTISCREENCUBE_MODE )
+                	tds->currentViewportNum *= tds->currentScreenNum;
+
+
+                if(tds->currentViewportNum > 2
+                   && (tds->currentMmMode != Multiple || screen->nOutputDev == 1)
+                   && !(MULTISCREENCUBE_MODE && tds->currentDifferentResolutions))
+                        tds->xMove = 1.0f / (tan( PI * (tds->currentViewportNum - 2.0f) / (2.0f * tds->currentViewportNum) ));
+                else
+                        tds->xMove = 0.0f;
+                
+                   
+                if( MULTISCREENCUBE_MODE )
+                	tds->currentViewportNum /= tds->currentScreenNum;
+        }
+
+        if(!DO_3D(screen->display))
+        {
+                //tds->reorder = TRUE;
+
+                if(tds->tdWindowExists)
+                        reorder(screen);
+
+                UNWRAP(tds, screen, preparePaintScreen);
+                (*screen->preparePaintScreen) (screen, msSinceLastPaint);
+                WRAP(tds, screen, preparePaintScreen, tdPreparePaintScreen);
+
+                return;
+        }
+	
+	compDisplaySetRequestFlagForPlugin (screen->display, "3d", "DRAW_ALL_FACES");
+	
+        lastInViewport = (tdWindow**) malloc(sizeof(tdWindow*) * screen->hsize);
+
+        for(i=0; i<screen->hsize; i++)
+                lastInViewport[i] = NULL;
+	
+	tds->maxZ = 0.0f;
+	
+        for(w = screen->windows; w; w = w->next)
+        {
+                if(!windowIs3D(w))
+                        continue;
+
+                tdw = GET_TD_WINDOW(w, tds);
+                maxZoom = 0.0f;
+
+                for(i=0; i<screen->hsize; i++)
+                {
+                        if( IS_IN_VIEWPORT(w, i) )
+                        {
+                                if( lastInViewport[i] && lastInViewport[i]->z > maxZoom )
+                                        maxZoom = lastInViewport[i]->z;
+
+                                lastInViewport[i] = tdw;
+                        }
+                }
+
+                tdw->z = maxZoom + SPACE;
+                
+                if(tdw->z > tds->maxZ)
+                	tds->maxZ = tdw->z;
+        }
+        
+        if( tds->maxZ > 0.0f && IPCS_GetBool (IPCS_OBJECT(screen), tds->insideAtom) && DISABLE_CAPS)
+		compDisplaySetRequestFlagForPlugin (screen->display, "3d", "NO_CUBE_CAPS");
+
+        reorder(screen);
+
+        //tds->reorder = FALSE;
+
+        free(lastInViewport);
+
+        UNWRAP(tds, screen, preparePaintScreen);
+        (*screen->preparePaintScreen) (screen, msSinceLastPaint);
+        WRAP(tds, screen, preparePaintScreen, tdPreparePaintScreen);
+}
+
+static Bool
+tdPaintWindow (CompWindow * w,
+                   const WindowPaintAttrib * attrib,
+                   Region region, unsigned int mask)
+{
+        Bool status;
+        Bool disabledCull = FALSE;
+ 
+        TD_SCREEN(w->screen);
+        TD_WINDOW(w);
+        
+        int output = tds->tmpOutput;
+        int width;
+        
+        if( output < w->screen->nOutputDev && MULTISCREENCUBE_MODE)
+        	width = w->screen->outputDev[output].width;
+        else
+       		width = w->screen->width;
+
+	if(DO_3D(w->screen->display) && tds->reorderWindowPainting)
+	{
+		//Window painting is done twice, once in reverse mode and one in normal.
+		//We should paint it only in the needed mode.
+		
+		float pntA[4] = {w->screen->outputDev[output].region.extents.x1,
+			w->screen->outputDev[output].region.extents.y1, tdw->currentZ, 1};
+		
+		float pntB[4] = {w->screen->outputDev[output].region.extents.x2,
+			w->screen->outputDev[output].region.extents.y1, tdw->currentZ, 1};
+		
+		float pntC[4] = {w->screen->outputDev[output].region.extents.x1 +
+			w->screen->outputDev[output].width / 2.0f,
+			w->screen->outputDev[output].region.extents.y1 +
+			w->screen->outputDev[output].height / 2.0f, tdw->currentZ, 1};
+		
+		MULTMV(tds->pmvm, pntA);
+		DIVV(pntA);
+		
+		MULTMV(tds->pmvm, pntB);
+		DIVV(pntB);
+		
+		MULTMV(tds->pmvm, pntC);
+		DIVV(pntC);
+
+		float vecA[3] = {pntC[0] - pntA[0], pntC[1] - pntA[1], pntC[2] - pntA[2]};
+		float vecB[3] = {pntC[0] - pntB[0], pntC[1] - pntB[1], pntC[2] - pntB[2]};
+		
+		float ortho[3] = {vecA[1]*vecB[2] - vecA[2]*vecB[1],
+					vecA[2]*vecB[0] - vecA[0]*vecB[2],
+					vecA[0]*vecB[1] - vecA[1]*vecB[0]};
+		
+		if(ortho[2] > 0.0f)	//The window is reversed, should be painted front to back.
+		{
+			if(mask & PAINT_WINDOW_BACK_TO_FRONT_MASK)
+				return TRUE;
+		}
+		
+		else
+		{
+			if(mask & PAINT_WINDOW_FRONT_TO_BACK_MASK)
+				return TRUE;
+		}
+	}
+	
+        glPushMatrix();
+ 
+        if(tdw->currentZ != 0.0f)
+        {
+                if(glIsEnabled(GL_CULL_FACE) && DISABLE_BACKFACE_CULLING)
+                {
+                        disabledCull = TRUE;
+                        glDisable(GL_CULL_FACE);
+                }
+ 
+		glTranslatef(0.0f, 0.0f, tdw->currentZ);
+ 
+                if (!IS_IN_VIEWPORT(w,0))
+                {
+                        float angle = 360 / tds->currentViewportNum;
+                        
+                        glScalef(1.0f, 1.0f, 1.0f / width);
+                        
+                        if (RIGHT_VIEWPORT(w) == w->screen->hsize - 1)
+                        {
+                                glTranslatef(-width * tdw->currentZ * tds->xMove, 0.0f, 0.0f);
+				glRotatef(-angle, 0.0f, 1.0f, 0.0f);
+				glTranslatef(-width * tdw->currentZ * tds->xMove, 0.0f, 0.0f);
+                        }
+                        
+                        else if(LEFT_VIEWPORT(w) == 1)
+                        {
+				glTranslatef(width + width * tdw->currentZ * tds->xMove, 0.0f, 0.0f);
+				glRotatef(angle, 0.0f, 1.0f, 0.0f);
+				glTranslatef(width * tdw->currentZ * tds->xMove - width, 0.0f, 0.0f);
+                        }
+                }
+                
+                if( LEFT_VIEWPORT(w) != RIGHT_VIEWPORT(w)
+                       || ( LEFT_SCREEN(w) != RIGHT_SCREEN(w) && MULTISCREENCUBE_MODE ) )
+                {
+                        if(LEFT_VIEWPORT(w) == 0 && ( LEFT_SCREEN(w) == output || !MULTISCREENCUBE_MODE ) )
+                                glTranslatef(width * tdw->currentZ * tds->xMove, 0.0f, 0.0f);
+ 
+                        else if(RIGHT_VIEWPORT(w) == 0 && ( RIGHT_SCREEN(w) == output || !MULTISCREENCUBE_MODE ))
+                                glTranslatef(-width * tdw->currentZ * tds->xMove, 0.0f, 0.0f);
+                }
+ 
+                /*glBegin(GL_QUADS);
+                        glVertex3f(w->serverX, w->serverY,  0.0f);
+                        glVertex3f(w->serverX, w->serverY,  -SPACE/2);
+                        glVertex3f(w->serverX, w->serverY + w->height,  -SPACE/2);
+                        glVertex3f(w->serverX, w->serverY + w->height,  0.0f);
+ 
+                        glVertex3f(w->serverX + w->width, w->serverY,  0.0f);
+                        glVertex3f(w->serverX + w->width, w->serverY,  -SPACE/2);
+                        glVertex3f(w->serverX + w->width, w->serverY + w->height,  -SPACE/2);
+                        glVertex3f(w->serverX + w->width, w->serverY + w->height,  0.0f);
+ 
+                        glVertex3f(w->serverX, w->serverY, 0.0f);
+                        glVertex3f(w->serverX + w->width, w->serverY, 0.0f);
+                        glVertex3f(w->serverX + w->width, w->serverY, -SPACE/2);
+                        glVertex3f(w->serverX, w->serverY, -SPACE/2);
+ 
+                        glVertex3f(w->serverX, w->serverY, 0.0f);
+                        glVertex3f(w->serverX + w->width, w->serverY, 0.0f);
+                        glVertex3f(w->serverX + w->width, w->serverY, -SPACE/2);
+                        glVertex3f(w->serverX, w->serverY, -SPACE/2);
+ 
+                        glVertex3f(w->serverX, w->serverY + w->height, 0.0f);
+                        glVertex3f(w->serverX + w->width, w->serverY + w->height, 0.0f);
+                        glVertex3f(w->serverX + w->width, w->serverY + w->height, -SPACE/2);
+                        glVertex3f(w->serverX, w->serverY + w->height, -SPACE/2);
+                glEnd();*/
+	}
+		
+	UNWRAP (tds, w->screen, paintWindow);
+        status = (*w->screen->paintWindow) (w, attrib, region, mask);
+        WRAP (tds, w->screen, paintWindow, tdPaintWindow);
+ 
+        if(disabledCull)
+        	glEnable(GL_CULL_FACE);
+ 
+        glPopMatrix();
+ 
+        return status;
+}
+
+static void
+tdPaintTransformedScreen (CompScreen * s,
+                          const ScreenPaintAttrib * sAttrib,
+                          Region region,
+                          int output,
+                          unsigned int mask)
+{
+        TD_SCREEN(s);
+	
+	tds->reorderWindowPainting = FALSE;
+	
+	tds->tmpOutput = output;
+	
+        if(DO_3D(s->display))
+        {
+        	if(CREATE_MIPMAPS)
+                	s->display->textureFilter = GL_LINEAR_MIPMAP_LINEAR;
+		
+		/*Front to back should always be done.
+		  If FTB is already in mask, then the viewport is reversed, and all windows should be reversed.
+		  If BTF is in mask, the viewport isn't reversed, but some of the windows there might be, so we set FTB in addition to BTF, and check for each window what mode it should use...*/
+		
+		if((mask & PAINT_SCREEN_ORDER_BACK_TO_FRONT_MASK) && !IPCS_GetBool (IPCS_OBJECT(s), tds->insideAtom))
+		{		
+			tds->reorderWindowPainting = TRUE;
+			mask |= PAINT_SCREEN_ORDER_FRONT_TO_BACK_MASK;
+			
+			glPushMatrix();	//Get the matrices.
+			
+				(s->applyScreenTransform) (s, sAttrib, output);
+				prepareXCoords (s, output, -sAttrib->zTranslate);
+			
+				glGetFloatv(GL_MODELVIEW_MATRIX, tds->mvm);
+				glGetFloatv(GL_PROJECTION_MATRIX, tds->pm);
+				
+				MULTM(tds->pm, tds->mvm, tds->pmvm);
+			
+			glPopMatrix();
+		}
+	}
+		
+        UNWRAP (tds, s, paintTransformedScreen);
+        (*s->paintTransformedScreen) (s, sAttrib, region, output, mask);
+        WRAP (tds, s, paintTransformedScreen, tdPaintTransformedScreen);
+}
+
+static Bool
+tdPaintScreen (CompScreen * s,
+                const ScreenPaintAttrib * sAttrib,
+                Region region, int output, unsigned int mask)
+{
+        Bool status;
+
+        TD_SCREEN(s);
+
+        if((DO_3D(s->display)) || tds->tdWindowExists)
+        {
+                mask |= PAINT_SCREEN_TRANSFORMED_MASK;
+		mask &= ~PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
+	}
+	
+        UNWRAP (tds, s, paintScreen);
+        status = (*s->paintScreen) (s, sAttrib, region, output, mask);
+        WRAP (tds, s, paintScreen, tdPaintScreen);
+
+        return status;
+}
+
+static void
+tdDonePaintScreen (CompScreen * s)
+{
+        CompWindow *w;
+        tdWindow *tdw;
+
+        TD_SCREEN (s);
+	
+	compDisplayClearRequestFlagForPlugin (s->display, "3d", "DRAW_ALL_FACES");
+	compDisplayClearRequestFlagForPlugin (s->display, "3d", "NO_CUBE_CAPS");
+	
+        if( DO_3D(s->display) || tds->tdWindowExists)
+        {
+                float aim = 0.0f;
+                       
+		damageScreen(s);
+		
+		tds->tdWindowExists = FALSE;
+                
+                for(w = s->windows; w; w = w->next)
+                {
+                        tdw = GET_TD_WINDOW  (w, GET_TD_SCREEN  (w->screen, GET_TD_DISPLAY (w->screen->display)));
+                        
+                        if ( DO_3D(s->display) )
+                        {
+                        	if( IPCS_GetBool (IPCS_OBJECT(s), tds->insideAtom) )
+                        		aim = tdw->z - tds->maxZ;
+                        	
+                        	else
+                        		aim = tdw->z; 
+                        }
+                                
+                        if( fabs( tdw->currentZ - aim )  < SPEED)
+                                tdw->currentZ = aim;
+                                
+                        else if(tdw->currentZ < aim)
+                                tdw->currentZ += SPEED;
+                                
+                        else if(tdw->currentZ > aim)
+                                tdw->currentZ -= SPEED;
+                                
+                        if(tdw->currentZ)
+                                tds->tdWindowExists = TRUE;
+                }
+        }
+        
+        revertReorder(s);
+
+        UNWRAP (tds, s, donePaintScreen);
+        (*s->donePaintScreen) (s);
+        WRAP (tds, s, donePaintScreen, tdDonePaintScreen);
+}
+
+static void
+tdScreenInitOptions (tdScreen *tds)
+{
+        CompOption *o;
+
+        o = &tds->opt[TD_SCREEN_OPTION_SPACE];
+        o->name                 = "space";
+        o->shortDesc        = "Space between windows";
+        o->group                = N_("");
+        o->subGroup             = N_("");
+        o->displayHints         = "";
+        o->longDesc             = "Change the space between the windows.";
+        o->type                 = CompOptionTypeFloat;
+        o->value.f              = TD_SPACE_DEFAULT;
+        o->rest.f.min       = TD_SPACE_MIN;
+        o->rest.f.max       = TD_SPACE_MAX;
+    o->rest.f.precision = TD_SPACE_PRECISION;
+
+        o = &tds->opt[TD_SCREEN_OPTION_SPEED];
+        o->name                 = "speed";
+        o->shortDesc        = "3D animation speed";
+        o->group                = N_("");
+        o->subGroup             = N_("");
+        o->displayHints         = "";
+        o->longDesc             = "Change the speed of the 3D animation.";
+        o->type                 = CompOptionTypeFloat;
+        o->value.f              = TD_SPEED_DEFAULT;
+        o->rest.f.min       = TD_SPEED_MIN;
+        o->rest.f.max       = TD_SPEED_MAX;
+    o->rest.f.precision = TD_SPEED_PRECISION;
+
+    o = &tds->opt[TD_SCREEN_OPTION_CREATE_MIPMAPS];
+        o->name                 = "mipmaps";
+        o->shortDesc        = "create mipmaps";
+        o->group                = N_("");
+        o->subGroup             = N_("");
+        o->displayHints         = "";
+        o->longDesc             = "Create mipmaps.";
+        o->type                 = CompOptionTypeBool;
+        o->value.f              = TD_CREATE_MIPMAPS_DEFAULT;
+
+    o = &tds->opt[TD_SCREEN_OPTION_DISABLE_BACKFACE_CULLING];
+        o->name                 = "noculling";
+        o->shortDesc        = "Disable Backface Culling";
+        o->group                = N_("");
+        o->subGroup             = N_("");
+        o->displayHints         = "";
+        o->longDesc             = "Disable Backface Culling.";
+        o->type                 = CompOptionTypeBool;
+        o->value.f              = TD_DISABLE_BACKFACE_CULLING_DEFAULT;
+        
+    o = &tds->opt[TD_SCREEN_OPTION_DISABLE_CAPS_IN_INSIDE_CUBE];
+        o->name                 = "nocaps";
+        o->shortDesc        = "Disable caps in inside cube";
+        o->group                = N_("");
+        o->subGroup             = N_("");
+        o->displayHints         = "";
+        o->longDesc             = "Disable cube caps when inside cube mode is used.";
+        o->type                 = CompOptionTypeBool;
+        o->value.f              = TD_DISABLE_CAPS_IN_INSIDE_CUBE_DEFAULT;
+}
+
+static CompOption *
+tdGetScreenOptions (CompScreen *s, int *count)
+{
+        if(s)
+        {
+                TD_SCREEN(s);
+
+                *count = NUM_OPTIONS(tds);
+
+                return tds->opt;
+        }
+
+        else
+        {
+                tdScreen * tds = malloc(sizeof(tdScreen));
+
+                tdScreenInitOptions(tds);
+                *count = NUM_OPTIONS (tds);
+
+                return tds->opt;
+        }
+}
+
+static Bool
+tdSetScreenOption (CompScreen * screen,
+                        char *name, CompOptionValue * value)
+{
+        CompOption *o;
+        int index;
+
+        TD_SCREEN (screen);
+
+        o = compFindOption (tds->opt, NUM_OPTIONS (tds), name, &index);
+        if (!o)
+                return FALSE;
+
+        switch (index)
+        {
+                case TD_SCREEN_OPTION_SPACE:
+                case TD_SCREEN_OPTION_SPEED:
+                        if(compSetFloatOption(o, value))
+                                return TRUE;
+                        break;
+
+                case TD_SCREEN_OPTION_CREATE_MIPMAPS:
+                        if(compSetBoolOption(o, value))
+                                return TRUE;
+                        break;
+		
+		case TD_SCREEN_OPTION_DISABLE_BACKFACE_CULLING:
+		case TD_SCREEN_OPTION_DISABLE_CAPS_IN_INSIDE_CUBE:
+			if(compSetBoolOption(o, value))
+				return TRUE;
+			break;
+ 
+		
+                default:
+                        break;
+        }
+
+        return FALSE;
+}
+
+static Bool
+tdInitDisplay (CompPlugin  *p,
+                 CompDisplay *d)
+{
+        tdDisplay *tdd;
+
+        tdd = malloc (sizeof (tdDisplay));
+        if (!tdd)
+                return FALSE;
+
+        tdd->screenPrivateIndex = allocateScreenPrivateIndex (d);
+        if (tdd->screenPrivateIndex < 0)
+        {
+                free (tdd);
+                return FALSE;
+        }
+
+        d->privates[displayPrivateIndex].ptr = tdd;
+
+        return TRUE;
+}
+
+static void
+tdFiniDisplay (CompPlugin *p,
+                 CompDisplay *d)
+{
+        TD_DISPLAY (d);
+
+        freeScreenPrivateIndex (d, tdd->screenPrivateIndex);
+
+        free (tdd);
+}
+
+static Bool
+tdInitScreen (CompPlugin  *p,
+                 CompScreen *s)
+{
+        TD_DISPLAY(s->display);
+
+        tdScreen *tds;
+
+        tds = malloc (sizeof (tdScreen));
+        if (!tds)
+                return FALSE;
+
+        tds->windowPrivateIndex = allocateWindowPrivateIndex (s);
+        if (tds->windowPrivateIndex < 0)
+        {
+                free (tds);
+                free (tdd);
+                return FALSE;
+        }
+
+        tdScreenInitOptions (tds);
+
+        tds->tdWindowExists = FALSE;
+        //tds->reorder = TRUE;
+        tds->revertReorder = NULL;
+        
+        tds->mmModeAtom = IPCS_GetAtom (IPCS_OBJECT (s), IPCS_INT,
+                                             "MM_MODE", TRUE);
+        
+        tds->insideAtom = IPCS_GetAtom (IPCS_OBJECT (s), IPCS_BOOL, 
+ 	                                     "INSIDE", TRUE); 
+        
+        tds->currentViewportNum = s->hsize;
+        tds->currentMmMode = IPCS_GetInt (IPCS_OBJECT(s), tds->mmModeAtom);
+        tds->currentScreenNum = s->nOutputDev;
+        tds->currentDifferentResolutions = differentResolutions(s);
+
+        if( MULTISCREENCUBE_MODE )
+                tds->currentViewportNum *= tds->currentScreenNum;
+
+
+        if(tds->currentViewportNum > 2 && tds->currentMmMode != Multiple)
+                tds->xMove = 1.0f / (tan( PI * (tds->currentViewportNum - 2.0f) / (2.0f * tds->currentViewportNum) ));
+        else
+                tds->xMove = 0.0f;
+                
+                   
+        if( MULTISCREENCUBE_MODE )
+              	tds->currentViewportNum /= tds->currentScreenNum;
+
+        WRAP(tds, s, paintTransformedScreen, tdPaintTransformedScreen);
+        WRAP(tds, s, paintWindow, tdPaintWindow);
+        WRAP(tds, s, paintScreen, tdPaintScreen);
+        WRAP(tds, s, donePaintScreen, tdDonePaintScreen);
+        WRAP(tds, s, preparePaintScreen, tdPreparePaintScreen);
+
+        s->privates[tdd->screenPrivateIndex].ptr = tds;
+
+        return TRUE;
+}
+
+static void
+tdFiniScreen (CompPlugin *p,
+                 CompScreen *s)
+{
+        TD_SCREEN (s);
+
+        freeWindowPrivateIndex (s, tds->windowPrivateIndex);
+
+        UNWRAP(tds, s, paintTransformedScreen);
+        UNWRAP(tds, s, paintWindow);
+        UNWRAP(tds, s, paintScreen);
+        UNWRAP(tds, s, donePaintScreen);
+        UNWRAP(tds, s, preparePaintScreen);
+
+        free (tds);
+}
+
+static Bool
+tdInitWindow (CompPlugin * p, CompWindow * w)
+{
+        tdWindow *tdw;
+
+        TD_SCREEN (w->screen);
+
+        tdw = malloc (sizeof (tdWindow));
+        if (!tdw)
+                return FALSE;
+
+        tdw->z=0.0f;
+        tdw->currentZ=0.0f;
+
+        w->privates[tds->windowPrivateIndex].ptr = tdw;
+
+        return TRUE;
+}
+
+static void
+tdFiniWindow (CompPlugin * p, CompWindow * w)
+{
+        TD_WINDOW (w);
+
+        free (tdw);
+}
+
+static Bool
+tdInit (CompPlugin *p)
+{
+        displayPrivateIndex = allocateDisplayPrivateIndex ();
+        if (displayPrivateIndex < 0)
+                return FALSE;
+
+        return TRUE;
+}
+
+static void
+tdFini (CompPlugin *p)
+{
+        if (displayPrivateIndex >= 0)
+                freeDisplayPrivateIndex (displayPrivateIndex);
+}
+
+CompPluginDep tdDeps[] = {
+    {CompPluginRuleAfter, "decoration"},
+};
+
+static CompPluginVTable tdVTable = {
+        "3d",
+        "A 3D world",
+        "Windows live in a 3D world.",
+        tdInit,
+        tdFini,
+        tdInitDisplay,
+        tdFiniDisplay,
+        tdInitScreen,
+        tdFiniScreen,
+        tdInitWindow,
+        tdFiniWindow,
+        /*tdGetDisplayOptions*/ 0,
+        /*tdSetDisplayOption*/ 0,
+        tdGetScreenOptions,
+        tdSetScreenOption,
+        tdDeps,
+        sizeof (tdDeps) / sizeof (tdDeps[0]),
+        0,
+        0,
+        BERYL_ABI_INFO,
+        "beryl plugins"
+};
+
+CompPluginVTable *
+getCompPluginInfo (void)
+{
+        return &tdVTable;
+}

Modified: trunk/beryl-plugins/src/Makefile.am
===================================================================
--- trunk/beryl-plugins/src/Makefile.am	2006-12-01 21:32:33 UTC (rev 1488)
+++ trunk/beryl-plugins/src/Makefile.am	2006-12-01 23:22:55 UTC (rev 1489)
@@ -120,6 +120,9 @@
 libplace_la_LIBADD = @BERYL_LIBS@ @GLIB_LIBS@ @BERYLSETTINGS_LIBS@
 libplace_la_SOURCES = place.c
 
+lib3d_la_LDFLAGS = $(PFLAGS)
+lib3d_la_LIBADD = @BERYL_LIBS@ @BERYLSETTINGS_LIBS@
+lib3d_la_SOURCES = 3d.c
 
 INCLUDES =                              \
 	@BERYL_CFLAGS@                      \
@@ -165,4 +168,5 @@
 	libbench.la         \
 	libgroup.la			\
 	libclone.la			\
+	lib3d.la	    \
 	$(libannotate_module)	




More information about the commits mailing list