static cairo_surface_t *_cairo_dock_create_dialog_icon_surface (const gchar *cImageFilePath, Icon *pIcon, int iDesiredSize, int *iIconSize)
{
	if (cImageFilePath == NULL)
		return NULL;
	if (iDesiredSize == 0)
		iDesiredSize = myDialogsParam.iDialogIconSize;
	cairo_surface_t *pIconBuffer = NULL;
	if (strcmp (cImageFilePath, "same icon") == 0)
	{
		if (pIcon && pIcon->image.pSurface)
		{
			int iWidth, iHeight;
			cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
			pIconBuffer = cairo_dock_duplicate_surface (pIcon->image.pSurface,
				iWidth, iHeight,
				iDesiredSize, iDesiredSize);
		}
		else if (pIcon && pIcon->cFileName)
		{
			pIconBuffer = cairo_dock_create_surface_from_image_simple (pIcon->cFileName,
				iDesiredSize,
				iDesiredSize);
		}
	}
	else
	{
		pIconBuffer = cairo_dock_create_surface_from_image_simple (cImageFilePath,
			iDesiredSize,
			iDesiredSize);
	}
	if (pIconBuffer != NULL)
		*iIconSize = iDesiredSize;
	return pIconBuffer;
}
void cd_do_select_previous_next_matching_icon (gboolean bNext)
{
	GList *pMatchingElement = myData.pCurrentMatchingElement;
	do
	{
		if (!bNext)
			myData.pCurrentMatchingElement = cairo_dock_get_previous_element (myData.pCurrentMatchingElement, myData.pMatchingIcons);
		else
			myData.pCurrentMatchingElement = cairo_dock_get_next_element (myData.pCurrentMatchingElement, myData.pMatchingIcons);
	} while (myData.pCurrentMatchingElement != pMatchingElement && ((Icon*)myData.pCurrentMatchingElement->data)->image.pSurface == NULL);
	
	if (myData.pCurrentMatchingElement != pMatchingElement)  // on complete le texte et on redessine.
	{
		Icon *pIcon = myData.pCurrentMatchingElement->data;
		if (pIcon->cCommand && *pIcon->cCommand != *myData.sCurrentText->str)  // cas d'une commande avec un tiret.
			myData.iNbValidCaracters = 0;
		cd_do_delete_invalid_caracters ();
		
		if (pIcon->cBaseURI != NULL)
		{
			gchar *cFile = g_path_get_basename (pIcon->cCommand);
			g_string_assign (myData.sCurrentText, cFile);
			g_free (cFile);
		}
		else
			g_string_assign (myData.sCurrentText, pIcon->cCommand);
		
		
		cd_do_load_pending_caracters ();
		
		// on arme l'animation de decalage.
		myData.iMatchingGlideCount = 10;  // on rembobine l'animation.
		myData.iPreviousMatchingOffset = myData.iCurrentMatchingOffset;  // on part du point courant.
		int iWidth, iHeight;
		cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
		if (iHeight != 0)
		{
			double fZoom = (double) g_pMainDock->container.iHeight/2 / iHeight;
			myData.iMatchingAimPoint += (bNext ? 1 : -1) * iWidth * fZoom;  // on cherche a atteindre le nouveau point.
		}
		
		// on repositionne les caracteres et on anime tout ca.
		cd_do_launch_appearance_animation ();
		cairo_dock_redraw_container (CAIRO_CONTAINER (g_pMainDock));
	}
}
void cd_indicator_set_icon (CDAppletIndicator *pIndicator, const gchar *cStatusIcon)
{
    GldiModuleInstance *myApplet = pIndicator->pApplet;
    if (cStatusIcon != pIndicator->cStatusIcon)
    {
        g_free (pIndicator->cStatusIcon);
        pIndicator->cStatusIcon = g_strdup (cStatusIcon);
    }
    if (cStatusIcon == NULL)
        return;

    int iWidth, iHeight;
    cairo_dock_get_icon_extent (myIcon, &iWidth, &iHeight);
    const gchar *cIconName = cStatusIcon;
    gchar *tmp_icon_name = NULL;
    gchar *cIconPath = cairo_dock_search_icon_s_path (cIconName, MAX (iWidth, iHeight));  // on regarde si l'icone sera trouvee.
    gchar *cIconPathFallback = NULL;
    if (cIconPath == NULL)  // l'icone ne sera pas trouvee, on regarde si ce n'est pas une icone en carton d'Ubuntu.
    {
        gchar *str = g_strstr_len (cIconName, -1, "-panel");
        if (str)
        {
            tmp_icon_name = g_strndup (cIconName, str - cIconName);
            cIconName = tmp_icon_name;
            cIconPath = cairo_dock_search_icon_s_path (cIconName, MAX (iWidth, iHeight));
        }
    }
    if (cIconPath == NULL)  // l'icone ne sera pas trouvee, on met une icone par defaut.
    {
        gboolean bAddSuffix = (!g_str_has_suffix (cIconName, ".png") && !g_str_has_suffix (cIconName, ".svg"));
        cIconPathFallback = g_strdup_printf ("%s/%s%s", myApplet->pModule->pVisitCard->cShareDataDir, cIconName, bAddSuffix ? ".svg" : "");
    }

    cd_debug ("set %s", cIconPathFallback ? cIconPathFallback : cIconName);
    //CD_APPLET_SET_IMAGE_ON_MY_ICON (cIconPathFallback ? cIconPathFallback : cIconName);
    cairo_dock_set_image_on_icon_with_default (myDrawContext,
            cIconPathFallback ? cIconPathFallback : cIconName,
            myIcon,
            myContainer,
            myApplet->pModule->pVisitCard->cIconFilePath);

    g_free (tmp_icon_name);
    g_free (cIconPath);
    g_free (cIconPathFallback);
}
static void _load_emblem (Icon *pIcon)
{
	const gchar *cImage = NULL;
	if (GLDI_OBJECT_IS_APPLET_ICON (pIcon))
	{
		cImage = GLDI_ICON_NAME_JUMP_TO;
	}
	else
	{
		cImage = GLDI_ICON_NAME_DELETE;
	}
	
	int iWidth, iHeight;
	cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
	gchar *cIcon = cairo_dock_search_icon_s_path (cImage, MAX (iWidth/2, iHeight/2));
	cairo_dock_free_image_buffer (s_pEmblem);
	s_pEmblem = cairo_dock_create_image_buffer (cIcon, iWidth/2, iHeight/2, 0);
	g_free (cIcon);
}
void cairo_dock_draw_subdock_content_on_icon (Icon *pIcon, CairoDock *pDock)
{
	g_return_if_fail (pIcon != NULL && pIcon->pSubDock != NULL && (pIcon->image.pSurface != NULL || pIcon->image.iTexture != 0));
	
	CairoIconContainerRenderer *pRenderer = cairo_dock_get_icon_container_renderer (pIcon->cClass != NULL ? "Stack" : s_cRendererNames[pIcon->iSubdockViewType]);
	if (pRenderer == NULL)
		return;
	cd_debug ("%s (%s)", __func__, pIcon->cName);
	
	int w, h;
	cairo_dock_get_icon_extent (pIcon, &w, &h);
	
	if (pIcon->image.iTexture != 0 && pRenderer->render_opengl)  // dessin opengl
	{
		//\______________ On efface le dessin existant.
		if (! cairo_dock_begin_draw_icon (pIcon, 0))  // 0 <=> erase the current texture.
			return ;
		
		_cairo_dock_set_blend_alpha ();
		_cairo_dock_set_alpha (1.);
		_cairo_dock_enable_texture ();
		
		//\______________ On dessine les 3 ou 4 premieres icones du sous-dock.
		pRenderer->render_opengl (pIcon, CAIRO_CONTAINER (pDock), w, h);
		
		//\______________ On finit le dessin.
		_cairo_dock_disable_texture ();
		cairo_dock_end_draw_icon (pIcon);
	}
	else if (pIcon->image.pSurface != NULL && pRenderer->render != NULL)  // dessin cairo
	{
		//\______________ On efface le dessin existant.
		cairo_t *pCairoContext = cairo_dock_begin_draw_icon_cairo (pIcon, 0, NULL);  // 0 <=> erase
		g_return_if_fail (pCairoContext != NULL);
		
		//\______________ On dessine les 3 ou 4 premieres icones du sous-dock.
		pRenderer->render (pIcon, CAIRO_CONTAINER (pDock), w, h, pCairoContext);
		
		//\______________ On finit le dessin.
		cairo_dock_end_draw_icon_cairo (pIcon);
		cairo_destroy (pCairoContext);
	}
}
void cd_tomboy_draw_content_on_icon (cairo_t *pIconContext, Icon *pIcon)
{
	if (pIcon->cClass == NULL || *pIcon->cClass == '\0')  // note vide => rien a afficher.
		return ;
	int w, h;
	cairo_dock_get_icon_extent (pIcon, CD_APPLET_MY_ICONS_LIST_CONTAINER, &w, &h);
	const int iNeedleOffset = 42./200*h;  // on laisse de la place pour l'aiguille de la punaise.
	gchar **cLines = g_strsplit (pIcon->cClass, "\n", -1);
	
	cairo_set_operator (pIconContext, CAIRO_OPERATOR_OVER);
	cairo_set_source_rgb (pIconContext, myConfig.fTextColor[0], myConfig.fTextColor[1], myConfig.fTextColor[2]);

	cairo_select_font_face (pIconContext,
		"sans",
		CAIRO_FONT_SLANT_NORMAL,
		CAIRO_FONT_WEIGHT_NORMAL);
	cairo_set_font_size (pIconContext, (myDock ? 14. : 12.));  // police 12 au zoom maximal.
	cairo_text_extents_t textExtents;
	cairo_text_extents (pIconContext, cLines[0], &textExtents);  // on recupere la hauteur d'une ligne.
	
	int i = 1, j = 1;
	while (cLines[i] != NULL && iNeedleOffset+j*textExtents.height < h)
	{
		if (*cLines[i] != '\0')  // on saute les lignes vides.
		{
			cairo_move_to (pIconContext,
				12./200*h,  // on laisse un peu de place pour ne pas deborder sur la gauche.
				iNeedleOffset+j*(textExtents.height+2));
			cairo_show_text (pIconContext, cLines[i]);
			j ++;
		}
		i ++;
	}
	g_strfreev (cLines);
	
	if (g_bUseOpenGL)
		cairo_dock_update_icon_texture (pIcon);
	else if (myDock)
		cairo_dock_add_reflection_to_icon (pIconContext, pIcon, CD_APPLET_MY_ICONS_LIST_CONTAINER);
}
void cairo_dock_load_icon_quickinfo (Icon *icon)
{
	if (icon->cQuickInfo == NULL)  // no more quick-info -> remove any previous one
	{
		cairo_dock_remove_overlay_at_position (icon, CAIRO_OVERLAY_BOTTOM, (gpointer)"quick-info");
	}
	else  // add an overlay at the bottom with the text surface; any previous "quick-info" overlay will be removed.
	{
		int iWidth, iHeight;
		cairo_dock_get_icon_extent (icon, &iWidth, &iHeight);
		double fMaxScale = cairo_dock_get_icon_max_scale (icon);
		if (iHeight / (myIconsParam.quickInfoTextDescription.iSize * fMaxScale) > 5)  // if the icon is very height (the text occupies less than 20% of the icon)
			fMaxScale = MIN ((double)iHeight / (myIconsParam.quickInfoTextDescription.iSize * 5), MAX (1., 16./myIconsParam.quickInfoTextDescription.iSize) * fMaxScale);  // let's make it use 20% of the icon's height, limited to 16px
		int w, h;
		cairo_surface_t *pSurface = cairo_dock_create_surface_from_text_full (icon->cQuickInfo,
			&myIconsParam.quickInfoTextDescription,
			fMaxScale,
			iWidth,  // limit the text to the width of the icon
			&w, &h);
		CairoOverlay *pOverlay = cairo_dock_add_overlay_from_surface (icon, pSurface, w, h, CAIRO_OVERLAY_BOTTOM, (gpointer)"quick-info");  // the constant string "quick-info" is used as a unique identifier for all quick-infos; the surface is taken by the overlay.
		if (pOverlay)
			cairo_dock_set_overlay_scale (pOverlay, 0);
	}
}
void cd_switcher_draw_main_icon_expanded_mode (void)
{
	// definition des parametres de dessin.
	int iWidth, iHeight;
	CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
	//double fRatio = (myDock ? myDock->fRatio : 1.);
	//double fMaxScale = cairo_dock_get_max_scale (myContainer); //coefficient Max icone Width
	myData.switcher.fOneViewportHeight = (iHeight - 2 * myConfig.iLineSize - (myData.switcher.iNbLines - 1) * myConfig.iInLineSize) / myData.switcher.iNbLines; //hauteur d'un bureau/viewport sans compter les lignes exterieures et interieures.
	myData.switcher.fOneViewportWidth = (iWidth - 2 * myConfig.iLineSize - (myData.switcher.iNbColumns - 1) * myConfig.iInLineSize) / myData.switcher.iNbColumns; //largeur d'un bureau/viewport sans compter les lignes exterieures et interieures.

	cairo_surface_t *pSurface = NULL;
	double fZoomX, fZoomY;
	if (myConfig.bMapWallpaper)
	{
		cairo_dock_erase_cairo_context (myDrawContext);
		
		pSurface = cairo_dock_get_desktop_bg_surface ();
		fZoomX = 1. * iWidth / g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
		fZoomY= 1. * iHeight / g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
		cairo_translate (myDrawContext,
			0.,
			0.);

		cairo_save (myDrawContext);
		cairo_scale (myDrawContext,
			fZoomX ,
			fZoomY );
		cairo_set_source_surface (myDrawContext,
			pSurface,
			0.,
			0.);
		cairo_paint(myDrawContext);
		cairo_restore (myDrawContext);
		
		if (CD_APPLET_MY_CONTAINER_IS_OPENGL)
			cairo_dock_update_icon_texture (myIcon);
		else
			CD_APPLET_UPDATE_REFLECT_ON_MY_ICON;
	}
	else
	{
		CD_APPLET_SET_LOCAL_IMAGE_ON_MY_ICON (MY_APPLET_ICON_FILE);
	}

	if (myConfig.bDrawWindows)
	{
		GList *pWindowList = cairo_dock_get_current_applis_list ();
		pWindowList = g_list_sort (pWindowList, (GCompareFunc) _compare_icons_stack_order);
		
		//fMaxScale = (myIcon->pSubDock != NULL ? cairo_dock_get_max_scale (myIcon->pSubDock) : 1);
		//fRatio = (myIcon->pSubDock != NULL ? myIcon->pSubDock->fRatio : 1);
		gint data[6];
		int iNumDesktop=0, iNumViewportX=0, iNumViewportY=0;
		cairo_t *pCairoContext;
		Icon *pIcon;
		CairoContainer *pContainer = CD_APPLET_MY_ICONS_LIST_CONTAINER;
		GList *pIconsList = CD_APPLET_MY_ICONS_LIST;
		GList *ic;
		for (ic = pIconsList; ic != NULL; ic = ic->next)
		{
			pIcon = ic->data;
			cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
			
			data[0] = iNumDesktop;
			data[1] = iNumViewportX;
			data[2] = iNumViewportY;
			data[3] = iWidth;
			data[4] = iHeight;
			pCairoContext = cairo_create (pIcon->pIconBuffer);
			data[5] = GPOINTER_TO_INT (pCairoContext);
			cairo_set_line_width (pCairoContext, 1.);
			cairo_set_source_rgba (pCairoContext, myConfig.RGBWLineColors[0], myConfig.RGBWLineColors[1], myConfig.RGBWLineColors[2], myConfig.RGBWLineColors[3]);
		
			g_list_foreach (pWindowList, (GFunc) _cd_switcher_draw_windows_on_viewport, data);
			
			iNumViewportX ++;
			if (iNumViewportX == g_iNbViewportX)
			{
				iNumViewportY ++;
				if (iNumViewportY == g_iNbViewportY)
					iNumDesktop ++;
			}
			cairo_destroy (pCairoContext);
		}
		g_list_free (pWindowList);  // le contenu appartient a la hash table, mais pas la liste.
	}
}
static void _cd_switcher_draw_windows_on_viewport (Icon *pIcon, gint *data)
{
	if (pIcon == NULL || pIcon->fPersonnalScale > 0)
		return ;
	if (pIcon->bIsHidden && ! myConfig.bDisplayHiddenWindows)
		return ;
	int iNumDesktop = data[0];
	int iNumViewportX = data[1];
	int iNumViewportY = data[2];
	int iOneViewportWidth = data[3];
	int iOneViewportHeight = data[4];
	cairo_t *pCairoContext = GINT_TO_POINTER (data[5]);
	
	// On calcule les coordonnees en repere absolu.
	int x = pIcon->windowGeometry.x;  // par rapport au viewport courant.
	x += myData.switcher.iCurrentViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];  // repere absolu
	if (x < 0)
		x += g_iNbViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
	int y = pIcon->windowGeometry.y;
	y += myData.switcher.iCurrentViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
	if (y < 0)
		y += g_iNbViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
	int w = pIcon->windowGeometry.width, h = pIcon->windowGeometry.height;
	
	// test d'intersection avec le viewport donne.
	//g_print (" %s : (%d;%d) %dx%d\n", pIcon->acName, x, y, w, h);
	if ((pIcon->iNumDesktop != -1 && pIcon->iNumDesktop != iNumDesktop) ||
		x + w <= iNumViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] ||
		x >= (iNumViewportX + 1) * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] ||
		y + h <= iNumViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] ||
		y >= (iNumViewportY + 1) * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL])
		return ;
	//g_print (" > on la dessine (%x)\n", pIcon->pIconBuffer);
	
	// on dessine ses traits.
	cairo_save (pCairoContext);
	
	cairo_set_source_rgba (pCairoContext, myConfig.RGBWLineColors[0], myConfig.RGBWLineColors[1], myConfig.RGBWLineColors[2], myConfig.RGBWLineColors[3]);
	cairo_rectangle (pCairoContext,
		(1.*x/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] - iNumViewportX)*iOneViewportWidth,
		(1.*y/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] - iNumViewportY)*iOneViewportHeight,
		1.*w/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL]*iOneViewportWidth,
		1.*h/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]*iOneViewportHeight);
	if (pIcon->Xid == cairo_dock_get_current_active_window ())
	{
		//g_print (" %s est la fenetre active\n", pIcon->acName);
		cairo_fill (pCairoContext);
	}
	else
	{
		cairo_stroke (pCairoContext);
	}
	
	if (pIcon->pIconBuffer != NULL)
	{
		CairoDock *pParentDock = NULL;
		pParentDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
		if (pParentDock == NULL)
			pParentDock = g_pMainDock;
		int iWidth, iHeight;
		cairo_dock_get_icon_extent (pIcon, CAIRO_CONTAINER (pParentDock), &iWidth, &iHeight);
		double fZoomX = (double) w/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL]*iOneViewportWidth / iWidth;
		double fZoomY = (double) h/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]*iOneViewportHeight / iHeight;
		double fZoom = MIN (fZoomX, fZoomY);  // on garde le ratio.
		
		cairo_translate (pCairoContext,
			(1.*x/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] - iNumViewportX)*iOneViewportWidth + (fZoomX - fZoom) * iWidth/2,
			(1.*y/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] - iNumViewportY)*iOneViewportHeight + (fZoomY - fZoom) * iHeight/2);
		cairo_scale (pCairoContext,
			fZoom,
			fZoom);
		cairo_set_source_surface (pCairoContext,
			pIcon->pIconBuffer,
			0.,
			0.);
		cairo_paint (pCairoContext);
	}
	
	cairo_restore (pCairoContext);
}
void gldi_gl_container_set_ortho_view_for_icon (Icon *pIcon)
{
	int w, h;
	cairo_dock_get_icon_extent (pIcon, &w, &h);
	_set_ortho_view (w, h);
}
void cd_switcher_draw_main_icon_expanded_mode (void)
{
	// apply the desktop bg or the user image on the main icon, in dock mode
	int iWidth, iHeight;
	
	if (myDock)
	{
		CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
		myData.switcher.fOneViewportHeight = (iHeight - 2 * myConfig.iLineSize - (myData.switcher.iNbLines - 1) * myConfig.iInLineSize) / myData.switcher.iNbLines; //hauteur d'un bureau/viewport sans compter les lignes exterieures et interieures.
		myData.switcher.fOneViewportWidth = (iWidth - 2 * myConfig.iLineSize - (myData.switcher.iNbColumns - 1) * myConfig.iInLineSize) / myData.switcher.iNbColumns; //largeur d'un bureau/viewport sans compter les lignes exterieures et interieures.

		cairo_surface_t *pSurface = NULL;
		double fZoomX, fZoomY;
		if (myConfig.iIconDrawing == SWICTHER_MAP_WALLPAPER)
		{
			cairo_dock_erase_cairo_context (myDrawContext);

			pSurface = myData.pDesktopBgMapSurface;
			fZoomX = 1. * iWidth / myData.iSurfaceWidth;
			fZoomY= 1. * iHeight / myData.iSurfaceHeight;
			cairo_translate (myDrawContext,
				0.,
				0.);

			cairo_save (myDrawContext);
			cairo_scale (myDrawContext,
				fZoomX ,
				fZoomY );
			cairo_set_source_surface (myDrawContext,
				pSurface,
				0.,
				0.);
			cairo_paint(myDrawContext);
			cairo_restore (myDrawContext);

			if (CD_APPLET_MY_CONTAINER_IS_OPENGL)
				cairo_dock_update_icon_texture (myIcon);
		}
		else
		{
			CD_APPLET_SET_IMAGE_ON_MY_ICON (MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE);
		}
	}
	
	if (myConfig.bDrawWindows)
	{
		GList *pWindowList = cairo_dock_get_current_applis_list ();
		pWindowList = g_list_sort (pWindowList, (GCompareFunc) _compare_icons_stack_order);
		
		CDSwitcherDesktop data;
		int iNumDesktop=0, iNumViewportX=0, iNumViewportY=0;
		cairo_t *pCairoContext;
		Icon *pIcon;
		GList *pIconsList = CD_APPLET_MY_ICONS_LIST;
		GList *ic;
		for (ic = pIconsList; ic != NULL; ic = ic->next)
		{
			pIcon = ic->data;
			cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
			
			pCairoContext = cairo_create (pIcon->image.pSurface);
			cairo_set_line_width (pCairoContext, 1.);
			if (myConfig.bUseDefaultColors)
				gldi_style_colors_set_line_color (myDrawContext);
			else
				cairo_set_source_rgba (pCairoContext, myConfig.RGBWLineColors[0], myConfig.RGBWLineColors[1], myConfig.RGBWLineColors[2], myConfig.RGBWLineColors[3]);
			
			data.iNumDesktop = iNumDesktop;
			data.iNumViewportX = iNumViewportX;
			data.iNumViewportY = iNumViewportY;
			data.iOneViewportWidth = iWidth;
			data.iOneViewportHeight = iHeight;
			data.pCairoContext = pCairoContext;
			g_list_foreach (pWindowList, (GFunc) _cd_switcher_draw_windows_on_viewport, &data);
			
			iNumViewportX ++;
			if (iNumViewportX == g_desktopGeometry.iNbViewportX)
			{
				iNumViewportY ++;
				if (iNumViewportY == g_desktopGeometry.iNbViewportY)
					iNumDesktop ++;
			}
			cairo_destroy (pCairoContext);
		}
		g_list_free (pWindowList);  // le contenu appartient a la hash table, mais pas la liste.
	}
}