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_show_listing (void)
{
	if (myData.pListing == NULL)
	{
		myData.pListing = cd_do_create_listing ();
		
		cairo_dock_register_notification_on_container (CAIRO_CONTAINER (myData.pListing),
			CAIRO_DOCK_UPDATE_DEFAULT_CONTAINER,
			(CairoDockNotificationFunc) cd_do_update_listing_notification,
			CAIRO_DOCK_RUN_AFTER,
			NULL);
		cairo_dock_register_notification_on_container (CAIRO_CONTAINER (myData.pListing),
			CAIRO_DOCK_RENDER_DEFAULT_CONTAINER,
			(CairoDockNotificationFunc) cd_do_render_listing_notification,
			CAIRO_DOCK_RUN_AFTER,
			NULL);
		if (myData.pScoobySurface == NULL)
		{
			cairo_t* pSourceContext = cairo_dock_create_context_from_container (CAIRO_CONTAINER (g_pMainDock));
			myData.pScoobySurface = cairo_dock_create_surface_from_image_simple (MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE,
				pSourceContext,
				2 * (myDialogs.dialogTextDescription.iSize + 2),
				2 * (myDialogs.dialogTextDescription.iSize + 2));
			cairo_destroy (pSourceContext);
		}
		if (myData.pActiveButtonSurface == NULL)
		{
			g_print ("load button : %dx%d\n", myDialogs.dialogTextDescription.iSize + 2, myData.pListing->container.iWidth);
			cairo_t* pSourceContext = cairo_dock_create_context_from_container (CAIRO_CONTAINER (g_pMainDock));
			myData.pActiveButtonSurface = cairo_dock_create_surface_from_image_simple (MY_APPLET_SHARE_DATA_DIR"/active-button.svg",
				pSourceContext,
				(myData.pListing->container.iWidth - (myDialogs.dialogTextDescription.iSize + 2) * 3) / 3,
				myDialogs.dialogTextDescription.iSize + 2);
			myData.pInactiveButtonSurface = cairo_dock_create_surface_from_image_simple (MY_APPLET_SHARE_DATA_DIR"/inactive-button.svg",
				pSourceContext,
				(myData.pListing->container.iWidth - (myDialogs.dialogTextDescription.iSize + 2) * 3) / 3,
				myDialogs.dialogTextDescription.iSize + 2);
			cairo_destroy (pSourceContext);
		}
	}
	else
	{
		gtk_widget_show (myData.pListing->container.pWidget);
		
		int iWidth = _listing_compute_width (pListing);
		int iHeight = _listing_compute_height (pListing);
		if (myData.pListing->container.iWidth != iWidth || myData.pListing->container.iHeight != iHeight)
		{
			gtk_window_resize (GTK_WINDOW (myData.pListing->container.pWidget),
				iWidth,
				iHeight);
		}
		_place_listing (myData.pListing);
		cairo_dock_redraw_container (CAIRO_CONTAINER (myData.pListing));
	}
}
static void _load_image (Icon *icon)
{
	int iWidth = cairo_dock_icon_get_allocated_width (icon);
	int iHeight = cairo_dock_icon_get_allocated_height (icon);
	cairo_surface_t *pSurface = NULL;
	
	if (icon->pSubDock != NULL && icon->iSubdockViewType != 0)  // a stack rendering is specified, we'll draw it when the sub-icons will be loaded
	{
		pSurface = cairo_dock_create_blank_surface (iWidth, iHeight);
		cairo_dock_trigger_redraw_subdock_content_on_icon (icon);  // now that the icon has a surface/texture, we can draw the sub-dock content on it.
	}
	else if (icon->cFileName)  // else simply draw the image
	{
		gchar *cIconPath = cairo_dock_search_icon_s_path (icon->cFileName, MAX (iWidth, iHeight));
		if (cIconPath != NULL && *cIconPath != '\0')
			pSurface = cairo_dock_create_surface_from_image_simple (cIconPath,
				iWidth,
				iHeight);
		g_free (cIconPath);
	}
	cairo_dock_load_image_buffer_from_surface (&icon->image, pSurface, iWidth, iHeight);
}
static void _load_appli (Icon *icon)
{
	if (cairo_dock_icon_is_being_removed (icon))
		return ;
	
	//\__________________ register the class to get its attributes, if it was not done yet.
	if (icon->cClass && !icon->pMimeTypes && !icon->cCommand)
	{
		gchar *cClass = cairo_dock_register_class_full (NULL, icon->cClass, icon->cWmClass);
		if (cClass != NULL)
		{
			g_free (cClass);
			icon->cCommand = g_strdup (cairo_dock_get_class_command (icon->cClass));
			icon->pMimeTypes = g_strdupv ((gchar**)cairo_dock_get_class_mimetypes (icon->cClass));
		}
	}
	
	//\__________________ then draw the icon
	int iWidth = cairo_dock_icon_get_allocated_width (icon);
	int iHeight = cairo_dock_icon_get_allocated_height (icon);
	cairo_surface_t *pPrevSurface = icon->image.pSurface;
	GLuint iPrevTexture = icon->image.iTexture;
	icon->image.pSurface = NULL;
	icon->image.iTexture = 0;
	
	// use the thumbnail in the case of a minimized window.
	if (myTaskbarParam.iMinimizedWindowRenderType == 1 && icon->pAppli->bIsHidden)
	{
		// create the thumbnail (window preview).
		if (g_bUseOpenGL)  // in OpenGL, we should be able to use the texture-from-pixmap mechanism
		{
			GLuint iTexture = gldi_window_get_texture (icon->pAppli);
			if (iTexture)
				cairo_dock_load_image_buffer_from_texture (&icon->image, iTexture, iWidth, iHeight);
		}
		if (icon->image.iTexture == 0)  // if not opengl or didn't work, get the content of the pixmap from the X server.
		{
			cairo_surface_t *pThumbnailSurface = gldi_window_get_thumbnail_surface (icon->pAppli, iWidth, iHeight);
			cairo_dock_load_image_buffer_from_surface (&icon->image, pThumbnailSurface, iWidth, iHeight);
		}
		// draw the previous image as an emblem.
		if (icon->image.iTexture != 0 && iPrevTexture != 0)
		{
			cairo_dock_print_overlay_on_icon_from_texture (icon, iPrevTexture, CAIRO_OVERLAY_LOWER_LEFT);
		}
		else if (icon->image.pSurface != NULL && pPrevSurface != NULL)
		{
			cairo_dock_print_overlay_on_icon_from_surface (icon, pPrevSurface, 0, 0, CAIRO_OVERLAY_LOWER_LEFT);
		}
	}
	
	// in other cases (or if the preview couldn't be used)
	if (icon->image.iTexture == 0 && icon->image.pSurface == NULL)
	{
		cairo_surface_t *pSurface = NULL;
		// or use the class icon
		if (myTaskbarParam.bOverWriteXIcons && ! cairo_dock_class_is_using_xicon (icon->cClass))
			pSurface = cairo_dock_create_surface_from_class (icon->cClass, iWidth, iHeight);
		// or use the X icon
		if (pSurface == NULL)
			pSurface = gldi_window_get_icon_surface (icon->pAppli, iWidth, iHeight);
		// or use a default image
		if (pSurface == NULL)  // some applis like xterm don't define any icon, set the default one.
		{
			cd_debug ("%s (%p) doesn't define any icon, we set the default one.", icon->cName, icon->pAppli);
			gchar *cIconPath = cairo_dock_search_image_s_path (CAIRO_DOCK_DEFAULT_APPLI_ICON_NAME);
			if (cIconPath == NULL)  // image non trouvee.
			{
				cIconPath = g_strdup (GLDI_SHARE_DATA_DIR"/icons/"CAIRO_DOCK_DEFAULT_APPLI_ICON_NAME);
			}
			pSurface = cairo_dock_create_surface_from_image_simple (cIconPath,
				iWidth,
				iHeight);
			g_free (cIconPath);
		}
		if (pSurface != NULL)
			cairo_dock_load_image_buffer_from_surface (&icon->image, pSurface, iWidth, iHeight);
	}
	
	// bent the icon in the case of a minimized window and if defined in the config.
	if (icon->pAppli->bIsHidden && myTaskbarParam.iMinimizedWindowRenderType == 2)
	{
		GldiContainer *pContainer = cairo_dock_get_icon_container (icon);
		if (pContainer)
			cairo_dock_draw_hidden_appli_icon (icon, pContainer, FALSE);
	}
}
void gldi_dialog_init_internals (CairoDialog *pDialog, CairoDialogAttr *pAttribute)
{
	pDialog->container.iface.animation_loop = _animation_loop;
	
	//\________________ set up the window
	GtkWidget *pWindow = pDialog->container.pWidget;
	gtk_window_set_title (GTK_WINDOW (pWindow), "cairo-dock-dialog");
	if (! pAttribute->pInteractiveWidget && ! pAttribute->pActionFunc)  // not an interactive dialog
		gtk_window_set_type_hint (GTK_WINDOW (pDialog->container.pWidget), GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);  // pour ne pas prendre le focus.
	
	gtk_widget_add_events (pWindow, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
	gtk_window_resize (GTK_WINDOW (pWindow), CAIRO_DIALOG_MIN_SIZE, CAIRO_DIALOG_MIN_SIZE);
	gtk_window_set_keep_above (GTK_WINDOW (pWindow), TRUE);
	
	pDialog->pIcon = pAttribute->pIcon;
	if (pAttribute->bForceAbove)  // try to force it above other windows (with most WM, it will still stay below fullscreen windows).
	{
		gtk_window_set_keep_above (GTK_WINDOW (pDialog->container.pWidget), TRUE);
		gtk_window_set_type_hint (GTK_WINDOW (pDialog->container.pWidget), GDK_WINDOW_TYPE_HINT_DOCK);  // should be called before the window becomes visible
	}
	
	//\________________ load the message
	if (pAttribute->cText != NULL)
	{
		pDialog->cText = g_strdup (pAttribute->cText);  // it may be a const string, so duplicate it
		pDialog->pTextBuffer = _cairo_dock_create_dialog_text_surface (pAttribute->cText,
			pAttribute->bUseMarkup,
			&pDialog->iTextWidth, &pDialog->iTextHeight);
		///pDialog->iTextTexture = cairo_dock_create_texture_from_surface (pDialog->pTextBuffer);
	}
	pDialog->bUseMarkup = pAttribute->bUseMarkup;  // remember this attribute, in case another text is set (with cairo_dock_set_dialog_message).

	//\________________ load the icon
	if (pAttribute->cImageFilePath != NULL)
	{
		pDialog->pIconBuffer = _cairo_dock_create_dialog_icon_surface (pAttribute->cImageFilePath, pAttribute->pIcon, pAttribute->iIconSize, &pDialog->iIconSize);
		///pDialog->iIconTexture = cairo_dock_create_texture_from_surface (pDialog->pIconBuffer);
	}

	//\________________ load the interactive widget
	if (pAttribute->pInteractiveWidget != NULL)
	{
		pDialog->pInteractiveWidget = pAttribute->pInteractiveWidget;
		
		GtkRequisition requisition;
		gtk_widget_get_preferred_size (pAttribute->pInteractiveWidget, &requisition, NULL);
		pDialog->iInteractiveWidth = requisition.width;
		pDialog->iInteractiveHeight = requisition.height;
	}
	
	//\________________ load the buttons
	pDialog->pUserData = pAttribute->pUserData;
	pDialog->pFreeUserDataFunc = pAttribute->pFreeDataFunc;
	if (pAttribute->cButtonsImage != NULL && pAttribute->pActionFunc != NULL)
	{
		int i;
		for (i = 0; pAttribute->cButtonsImage[i] != NULL; i++);
		
		pDialog->iNbButtons = i;
		pDialog->action_on_answer = pAttribute->pActionFunc;
		pDialog->pButtons = g_new0 (CairoDialogButton, pDialog->iNbButtons);
		const gchar *cButtonImage;
		for (i = 0; i < pDialog->iNbButtons; i++)
		{
			cButtonImage = pAttribute->cButtonsImage[i];
			if (strcmp (cButtonImage, "ok") == 0)
			{
				pDialog->pButtons[i].iDefaultType = 1;
			}
			else if (strcmp (cButtonImage, "cancel") == 0)
			{
				pDialog->pButtons[i].iDefaultType = 0;
			}
			else
			{
				gchar *cButtonPath;
				if (*cButtonImage != '/')
					cButtonPath = cairo_dock_search_icon_s_path (cButtonImage,
						MAX (myDialogsParam.iDialogButtonWidth, myDialogsParam.iDialogButtonHeight));
				else
					cButtonPath = (gchar*)cButtonImage;
				pDialog->pButtons[i].pSurface = cairo_dock_create_surface_from_image_simple (cButtonPath,
					myDialogsParam.iDialogButtonWidth,
					myDialogsParam.iDialogButtonHeight);
				if (cButtonPath != cButtonImage)
					g_free (cButtonPath);
				///pDialog->pButtons[i].iTexture = cairo_dock_create_texture_from_surface (pDialog->pButtons[i].pSurface);
			}
		}
	}
	else
	{
		pDialog->bNoInput = pAttribute->bNoInput;
	}
	
	//\________________ set a decorator.
	cairo_dock_set_dialog_decorator_by_name (pDialog, (pAttribute->cDecoratorName ? pAttribute->cDecoratorName : myDialogsParam.cDecoratorName));
	if (pDialog->pDecorator != NULL)
		pDialog->pDecorator->set_size (pDialog);
	
	//\________________ Maintenant qu'on connait tout, on calcule les tailles des divers elements.
	_compute_dialog_sizes (pDialog);
	pDialog->container.iWidth = pDialog->iBubbleWidth + pDialog->iLeftMargin + pDialog->iRightMargin;
	pDialog->container.iHeight = pDialog->iBubbleHeight + pDialog->iTopMargin + pDialog->iBottomMargin + pDialog->iMinBottomGap;
	
	//\________________ On reserve l'espace pour les decorations.
	GtkWidget *pMainHBox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
	gtk_container_add (GTK_CONTAINER (pDialog->container.pWidget), pMainHBox);
	pDialog->pLeftPaddingBox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
	g_object_set (pDialog->pLeftPaddingBox, "width-request", pDialog->iLeftMargin, NULL);
	gtk_box_pack_start (GTK_BOX (pMainHBox),
		pDialog->pLeftPaddingBox,
		FALSE,
		FALSE,
		0);

	pDialog->pWidgetLayout = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
	gtk_box_pack_start (GTK_BOX (pMainHBox),
		pDialog->pWidgetLayout,
		FALSE,
		FALSE,
		0);

	pDialog->pRightPaddingBox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
	g_object_set (pDialog->pRightPaddingBox, "width-request", pDialog->iRightMargin, NULL);
	gtk_box_pack_start (GTK_BOX (pMainHBox),
		pDialog->pRightPaddingBox,
		FALSE,
		FALSE,
		0);
	
	//\________________ On reserve l'espace pour les elements.
	if (pDialog->container.bDirectionUp)
		pDialog->pTopWidget = _cairo_dock_add_dialog_internal_box (pDialog, 0, pDialog->iTopMargin, FALSE);
	else
		pDialog->pTipWidget = _cairo_dock_add_dialog_internal_box (pDialog, 0, pDialog->iMinBottomGap + pDialog->iBottomMargin, TRUE);
	if (pDialog->iMessageWidth != 0 && pDialog->iMessageHeight != 0)
	{
		pDialog->pMessageWidget = _cairo_dock_add_dialog_internal_box (pDialog, pDialog->iMessageWidth, pDialog->iMessageHeight, FALSE);
	}
	if (pDialog->pInteractiveWidget != NULL)
	{
		gtk_box_pack_start (GTK_BOX (pDialog->pWidgetLayout),
			pDialog->pInteractiveWidget,
			FALSE,
			FALSE,
			0);
		gtk_window_present (GTK_WINDOW (pDialog->container.pWidget));
		gtk_widget_grab_focus (pDialog->pInteractiveWidget);
		
		// set a MenuItem style to the dialog, so that the interactive widget can use the style defined for menu-items (either from the GTK theme, or from our own .css), and therefore be well integrated into the dialog, as if it was inside a menu.
		GtkStyleContext *ctx = gtk_widget_get_style_context (pDialog->pWidgetLayout);
		gtk_style_context_add_class (ctx, myDialogsParam.bUseDefaultColors && myStyleParam.bUseSystemColors ? GTK_STYLE_CLASS_MENUITEM : "gldimenuitem");
	}
	if (pDialog->pButtons != NULL)
	{
		pDialog->pButtonsWidget = _cairo_dock_add_dialog_internal_box (pDialog, pDialog->iButtonsWidth, pDialog->iButtonsHeight, FALSE);
	}
	if (pDialog->container.bDirectionUp)
		pDialog->pTipWidget = _cairo_dock_add_dialog_internal_box (pDialog, 0, pDialog->iMinBottomGap + pDialog->iBottomMargin, TRUE);
	else
		pDialog->pTopWidget = _cairo_dock_add_dialog_internal_box (pDialog, 0, pDialog->iTopMargin, TRUE);
	
	gtk_widget_show_all (pDialog->container.pWidget);
	
	//\________________ load the input shape.
	if (pDialog->bNoInput)
	{
		_cairo_dock_set_dialog_input_shape (pDialog);
	}
	
	//\________________ connect the signals to the window
	g_signal_connect (G_OBJECT (pDialog->container.pWidget),
		"draw",
		G_CALLBACK (on_expose_dialog),
		pDialog);
	g_signal_connect_after (G_OBJECT (pDialog->container.pWidget),
		"draw",
		G_CALLBACK (on_expose_dialog_after),
		pDialog);
	g_signal_connect (G_OBJECT (pDialog->container.pWidget),
		"configure-event",
		G_CALLBACK (on_configure_dialog),
		pDialog);
	g_signal_connect (G_OBJECT (pDialog->container.pWidget),
		"unmap-event",
		G_CALLBACK (on_unmap_dialog),
		pDialog);  // prevent dialogs from being hidden (for instance by a 'show-desktop' event), because they might be modal
	g_signal_connect (G_OBJECT (pDialog->container.pWidget),
		"map-event",
		G_CALLBACK (on_map_dialog),
		pDialog);  // some WM (like GS) prevent the focus to be taken, so we have to force it whenever the dialog is shown (creation or unhide).
	if (pDialog->pInteractiveWidget != NULL && pDialog->pButtons == NULL)  // the dialog has no button to be closed, so it can be closed by clicking on it. But some widget (like the GTK calendar) let pass the click to their parent (= the dialog), which then close it. To prevent this, we memorize the last click on the widget.
		g_signal_connect (G_OBJECT (pDialog->pInteractiveWidget),
			"button-press-event",
			G_CALLBACK (on_button_press_widget),
			pDialog);
	
	cairo_dock_launch_animation (CAIRO_CONTAINER (pDialog));
}
void cairo_dock_load_icon_image (Icon *icon, G_GNUC_UNUSED GldiContainer *pContainer)
{
	if (icon->pContainer == NULL)
	{
		cd_warning ("/!\\ Icon %s is not inside a container !!!", icon->cName);  // it's ok if this happens, but it should be rare, and I'd like to know when, so be noisy.
		return;
	}
	GldiModuleInstance *pInstance = icon->pModuleInstance;  // this is the only function where we destroy/create the icon's surface, so we must handle the cairo-context here.
	if (pInstance && pInstance->pDrawContext != NULL)
	{
		cairo_destroy (pInstance->pDrawContext);
		pInstance->pDrawContext = NULL;
	}
	
	//g_print ("%s (%s, %dx%d)\n", __func__, icon->cName, (int)icon->fWidth, (int)icon->fHeight);
	// the renderer of the container must have set the size beforehand, when the icon has been inserted into the container.
	if (cairo_dock_icon_get_allocated_width (icon) <= 0 || cairo_dock_icon_get_allocated_height (icon) <= 0)  // we don't want a surface/texture.
	{
		cairo_dock_unload_image_buffer (&icon->image);
		return;
	}
	g_return_if_fail (icon->fWidth > 0); // should never happen; if it does, it's an error, so be noisy.
	
	//\______________ keep the current buffer on the icon so that the 'load' can use it (for instance, applis may draw emblems).
	cairo_surface_t *pPrevSurface = icon->image.pSurface;
	GLuint iPrevTexture = icon->image.iTexture;
	
	//\______________ load the image buffer (surface + texture).
	if (icon->iface.load_image)
		icon->iface.load_image (icon);
	
	//\______________ if nothing has changed or no image was loaded, set a default image.
	if ((icon->image.pSurface == pPrevSurface || icon->image.pSurface == NULL)
	&& (icon->image.iTexture == iPrevTexture || icon->image.iTexture == 0))
	{
		gchar *cIconPath = cairo_dock_search_image_s_path (CAIRO_DOCK_DEFAULT_ICON_NAME);
		if (cIconPath == NULL)  // fichier non trouve.
		{
			cIconPath = g_strdup (GLDI_SHARE_DATA_DIR"/icons/"CAIRO_DOCK_DEFAULT_ICON_NAME);
		}
		int w = cairo_dock_icon_get_allocated_width (icon);
		int h = cairo_dock_icon_get_allocated_height (icon);
		cairo_surface_t *pSurface = cairo_dock_create_surface_from_image_simple (cIconPath,
			w,
			h);
		cairo_dock_load_image_buffer_from_surface (&icon->image, pSurface, w, h);
		g_free (cIconPath);
	}
	
	//\_____________ set the background if needed.
	icon->bNeedApplyBackground = FALSE;
	if (g_pIconBackgroundBuffer.pSurface != NULL && ! GLDI_OBJECT_IS_SEPARATOR_ICON (icon))
	{
		if (icon->image.iTexture != 0 && g_pIconBackgroundBuffer.iTexture != 0)
		{
			if (! cairo_dock_apply_icon_background_opengl (icon))  // couldn't draw on the texture
			{
				icon->bDamaged = FALSE;  // it's not a big deal, since we can draw under the existing image easily; so we don't need to damage the icon (it's expensive especially if it's an applet).
				icon->bNeedApplyBackground = TRUE;  // just postpone it until drawing is possible.
			}
		}
		else if (icon->image.pSurface != NULL)
		{
			cairo_t *pCairoIconBGContext = cairo_create (icon->image.pSurface);
			cairo_set_operator (pCairoIconBGContext, CAIRO_OPERATOR_DEST_OVER);
			cairo_dock_apply_image_buffer_surface_at_size (&g_pIconBackgroundBuffer, pCairoIconBGContext,
				icon->image.iWidth, icon->image.iHeight,
				0, 0, 1);
			cairo_destroy (pCairoIconBGContext);
		}
	}
	
	//\______________ free the previous buffers.
	if (pPrevSurface != NULL)
		cairo_surface_destroy (pPrevSurface);
	if (iPrevTexture != 0)
		_cairo_dock_delete_texture (iPrevTexture);
	
	if (pInstance && icon->image.pSurface != NULL)
	{
		pInstance->pDrawContext = cairo_create (icon->image.pSurface);
		if (!pInstance->pDrawContext || cairo_status (pInstance->pDrawContext) != CAIRO_STATUS_SUCCESS)
		{
			cd_warning ("couldn't initialize drawing context, applet won't be able to draw itself !");
			pInstance->pDrawContext = NULL;
		}
	}
}
static void _cairo_dock_finish_load_data_renderer (CairoDataRenderer *pRenderer, gboolean bLoadTextures, Icon *pIcon)
{
	int iNbValues = cairo_data_renderer_get_nb_values (pRenderer);
	//\___________________ On charge les emblemes si l'implementation les a valides.
	if (pRenderer->pEmblems != NULL)
	{
		CairoDataRendererEmblem *pEmblem;
		cairo_surface_t *pSurface;
		int i;
		for (i = 0; i < iNbValues; i ++)
		{
			pEmblem = &pRenderer->pEmblems[i];
			if (pEmblem->pSurface != NULL)
			{
				cairo_surface_destroy (pEmblem->pSurface);
				pEmblem->pSurface = NULL;
			}
			if (pEmblem->iTexture != 0)
			{
				_cairo_dock_delete_texture (pEmblem->iTexture);
				pEmblem->iTexture = 0;
			}
			if (pEmblem->param.fWidth != 0 && pEmblem->param.fHeight != 0 && pEmblem->cImagePath != NULL)
			{
				pSurface = cairo_dock_create_surface_from_image_simple (pEmblem->cImagePath,
					pEmblem->param.fWidth * pRenderer->iWidth,
					pEmblem->param.fHeight * pRenderer->iHeight);
				if (bLoadTextures)
				{
					pEmblem->iTexture = cairo_dock_create_texture_from_surface (pSurface);
					cairo_surface_destroy (pSurface);
				}
				else
					pEmblem->pSurface = pSurface;
			}
		}
	}
	
	//\___________________ On charge les labels si l'implementation les a valides.
	if (pRenderer->pLabels != NULL)
	{
		GldiTextDescription textDescription;
		gldi_text_description_copy (&textDescription, &myIconsParam.quickInfoTextDescription);
		
		CairoDataRendererText *pLabel;
		cairo_surface_t *pSurface;
		int i;
		for (i = 0; i < iNbValues; i ++)
		{
			pLabel = &pRenderer->pLabels[i];
			if (pLabel->pSurface != NULL)
			{
				cairo_surface_destroy (pLabel->pSurface);
				pLabel->pSurface = NULL;
			}
			if (pLabel->iTexture != 0)
			{
				_cairo_dock_delete_texture (pLabel->iTexture);
				pLabel->iTexture = 0;
			}
			if (pLabel->param.fWidth != 0 && pLabel->param.fHeight != 0 && pLabel->cText != NULL)
			{
				textDescription.bNoDecorations = TRUE;
				textDescription.bUseDefaultColors = FALSE;
				textDescription.iMargin = 0;
				textDescription.bOutlined = TRUE;  /// tester avec et sans ...
				textDescription.fColorStart.rgba.red = pLabel->param.pColor[0];
				textDescription.fColorStart.rgba.green = pLabel->param.pColor[1];
				textDescription.fColorStart.rgba.blue = pLabel->param.pColor[2];
				textDescription.fColorStart.rgba.alpha = 1.;
				pSurface = cairo_dock_create_surface_from_text (pLabel->cText,
					&textDescription,
					&pLabel->iTextWidth, &pLabel->iTextHeight);
				if (bLoadTextures)
				{
					pLabel->iTexture = cairo_dock_create_texture_from_surface (pSurface);
					cairo_surface_destroy (pSurface);
				}
				else
					pLabel->pSurface = pSurface;
			}
		}
	}
	
	//\___________________ On regarde si le texte dessine sur l'icone sera suffisamment lisible.
	if (pRenderer->pValuesText != NULL)
	{
		CairoDataRendererTextParam *pText = &pRenderer->pValuesText[0];
		//g_print ("+++++++pText->fWidth * pRenderer->iWidth : %.2f\n", pText->fWidth * pRenderer->iWidth);
		pRenderer->bCanRenderValueAsText = (pText->fWidth * pRenderer->iWidth >= CD_MIN_TEXT_WITH);
	}
	
	if (pRenderer->bCanRenderValueAsText && pRenderer->bWriteValues)
		gldi_icon_set_quick_info (pIcon, NULL);
	
	//\___________________ Build an overlay if the renderer will use some.
	if (pRenderer->bUseOverlay)
	{
		//g_print ("+ overlay %dx%d\n", pRenderer->iWidth, pRenderer->iHeight);
		cairo_surface_t *pSurface = cairo_dock_create_blank_surface (pRenderer->iWidth, pRenderer->iHeight);
		pRenderer->pOverlay = cairo_dock_add_overlay_from_surface (pIcon, pSurface, pRenderer->iWidth, pRenderer->iHeight, pRenderer->iOverlayPosition, (gpointer)"data-renderer");  // this string is constant; any previous overlay will be removed.
		cairo_dock_set_overlay_scale (pRenderer->pOverlay, 0);  // keep the original size of the image
	}
}
static void _make_bar_surface (ProgressBar *pProgressBar)
{
	CairoDataRenderer *pRenderer = CAIRO_DATA_RENDERER (pProgressBar);
	int iWidth = pRenderer->iWidth;
	
	if (pProgressBar->cImageGradation != NULL)  // an image is provided
	{
		pProgressBar->pBarSurface = cairo_dock_create_surface_from_image_simple (
			pProgressBar->cImageGradation,
			iWidth,
			pProgressBar->iBarThickness);
	}
	
	if (pProgressBar->pBarSurface == NULL)  // no image was provided, or it was not valid.
	{
		// create a surface to bufferize the pattern.
		pProgressBar->pBarSurface = cairo_dock_create_blank_surface (iWidth, pProgressBar->iBarThickness);
		
		cairo_t *ctx = cairo_create (pProgressBar->pBarSurface);
		cairo_pattern_t *pGradationPattern = NULL;
		if (myIndicatorsParam.bBarUseDefaultColors)
		{
			gldi_style_colors_set_selected_bg_color (ctx);
		}
		else
		{
			// create the pattern.
			pGradationPattern = cairo_pattern_create_linear (0.,
				0.,
				iWidth,
				0.);  // de gauche a droite.
			g_return_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS);
			
			cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE);
			
			gdouble *fColorGradation = pProgressBar->fColorGradation;
			int iNbColors = 2;
			int i;
			for (i = 0; i < iNbColors; i ++)
			{
				cairo_pattern_add_color_stop_rgba (pGradationPattern,
					(double)i / (iNbColors-1),
					fColorGradation[4*i+0],
					fColorGradation[4*i+1],
					fColorGradation[4*i+2],
					fColorGradation[4*i+3]);
			}
			cairo_set_source (ctx, pGradationPattern);
		}
		
		// draw the pattern on the surface.
		cairo_set_operator (ctx, CAIRO_OPERATOR_OVER);
		
		cairo_set_line_width (ctx, pProgressBar->iBarThickness);
		
		double r = .5*pProgressBar->iBarThickness;  // radius
		cairo_move_to (ctx, 0, r);
		cairo_rel_line_to (ctx, iWidth, 0);
		
		cairo_stroke (ctx);
		
		if (pGradationPattern)
			cairo_pattern_destroy (pGradationPattern);
		cairo_destroy (ctx);
	}
	pProgressBar->iBarTexture = cairo_dock_create_texture_from_surface (pProgressBar->pBarSurface);
}