2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 3
10
* of the License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24
#include "../config.h"
25
#include "cairo-dock-log.h"
26
#include "cairo-dock-backends-manager.h"
27
#include "cairo-dock-notifications.h"
28
#include "cairo-dock-draw-opengl.h"
29
#include "cairo-dock-opengl-font.h"
30
#include "cairo-dock-animations.h"
31
#include "cairo-dock-surface-factory.h"
32
#include "cairo-dock-draw.h"
33
#include "cairo-dock-container.h"
34
#include "cairo-dock-icons.h"
35
#include "cairo-dock-load.h"
36
#include "cairo-dock-config.h"
37
#include "cairo-dock-keyfile-utilities.h"
38
#include "cairo-dock-packages.h"
39
#include "cairo-dock-gauge.h"
40
#include "cairo-dock-graph.h"
41
#include "cairo-dock-data-renderer.h"
43
extern gboolean g_bUseOpenGL;
44
extern CairoContainer *g_pPrimaryContainer;
45
extern gchar *g_cExtrasDirPath;
47
#define cairo_dock_set_data_renderer_on_icon(pIcon, pRenderer) (pIcon)->pDataRenderer = pRenderer
48
#define cairo_dock_get_icon_data_renderer(pIcon) (pIcon)->pDataRenderer
51
static CairoDockGLFont *s_pFont = NULL;
53
#define _init_data_renderer_font(...) s_pFont = cairo_dock_load_textured_font ("Monospace Bold 12", 0, 184) // on va jusqu'a ø
55
CairoDockGLFont *cairo_dock_get_default_data_renderer_font (void)
58
_init_data_renderer_font ();
62
void cairo_dock_unload_default_data_renderer_font (void)
64
cairo_dock_free_gl_font (s_pFont);
69
CairoDataRenderer *cairo_dock_new_data_renderer (const gchar *cRendererName)
71
CairoDataRendererNewFunc init = cairo_dock_get_data_renderer_entry_point (cRendererName);
72
g_return_val_if_fail (init != NULL, NULL);
74
if (g_pPrimaryContainer && s_pFont == NULL)
76
_init_data_renderer_font ();
82
static void _cairo_dock_init_data_renderer (CairoDataRenderer *pRenderer, CairoContainer *pContainer, CairoDataRendererAttribute *pAttribute)
84
//\_______________ On alloue la structure des donnees.
85
pRenderer->data.iNbValues = MAX (1, pAttribute->iNbValues);
86
pRenderer->data.iMemorySize = MAX (2, pAttribute->iMemorySize); // au moins la derniere valeur et la nouvelle.
87
pRenderer->data.pValuesBuffer = g_new0 (gdouble, pRenderer->data.iNbValues * pRenderer->data.iMemorySize);
88
pRenderer->data.pTabValues = g_new (gdouble *, pRenderer->data.iMemorySize);
90
for (i = 0; i < pRenderer->data.iMemorySize; i ++)
92
pRenderer->data.pTabValues[i] = &pRenderer->data.pValuesBuffer[i*pRenderer->data.iNbValues];
94
pRenderer->data.iCurrentIndex = -1;
95
pRenderer->data.pMinMaxValues = g_new (gdouble, 2 * pRenderer->data.iNbValues);
96
if (pAttribute->pMinMaxValues != NULL)
98
memcpy (pRenderer->data.pMinMaxValues, pAttribute->pMinMaxValues, 2 * pRenderer->data.iNbValues * sizeof (gdouble));
102
if (pAttribute->bUpdateMinMax)
104
for (i = 0; i < pRenderer->data.iNbValues; i ++)
106
pRenderer->data.pMinMaxValues[2*i] = 1.e6;
107
pRenderer->data.pMinMaxValues[2*i+1] = -1.e6;
112
for (i = 0; i < pRenderer->data.iNbValues; i ++)
114
pRenderer->data.pMinMaxValues[2*i] = 0.;
115
pRenderer->data.pMinMaxValues[2*i+1] = 1.;
120
//\_______________ On charge les parametres generaux.
121
pRenderer->bUpdateMinMax = pAttribute->bUpdateMinMax;
122
pRenderer->bWriteValues = pAttribute->bWriteValues;
123
pRenderer->iLatencyTime = pAttribute->iLatencyTime;
124
pRenderer->iSmoothAnimationStep = 0;
125
pRenderer->format_value = pAttribute->format_value;
126
pRenderer->pFormatData = pAttribute->pFormatData;
127
pRenderer->cTitles = pAttribute->cTitles;
128
memcpy (pRenderer->fTextColor, pAttribute->fTextColor, sizeof (pRenderer->fTextColor));
129
pRenderer->cEmblems = pAttribute->cEmblems;
132
static void _cairo_dock_render_to_texture (CairoDataRenderer *pDataRenderer, Icon *pIcon, CairoContainer *pContainer)
134
if (! cairo_dock_begin_draw_icon (pIcon, pContainer, 0))
137
pDataRenderer->interface.render_opengl (pDataRenderer);
139
cairo_dock_end_draw_icon (pIcon, pContainer);
141
static void _cairo_dock_render_to_context (CairoDataRenderer *pDataRenderer, Icon *pIcon, CairoContainer *pContainer, cairo_t *pCairoContext)
143
//\________________ On efface tout.
144
cairo_set_source_rgba (pCairoContext, 0.0, 0.0, 0.0, 0.0);
145
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
146
cairo_paint (pCairoContext);
147
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_OVER);
149
//\________________ On dessine.
150
cairo_save (pCairoContext);
151
pDataRenderer->interface.render (pDataRenderer, pCairoContext);
152
cairo_restore (pCairoContext);
154
if (pContainer->bUseReflect)
156
cairo_dock_add_reflection_to_icon (pIcon, pContainer);
159
if (CAIRO_DOCK_CONTAINER_IS_OPENGL (pContainer))
160
cairo_dock_update_icon_texture (pIcon);
163
static gboolean cairo_dock_update_icon_data_renderer_notification (gpointer pUserData, Icon *pIcon, CairoContainer *pContainer, gboolean *bContinueAnimation)
165
CairoDataRenderer *pRenderer = cairo_dock_get_icon_data_renderer (pIcon);
166
if (pRenderer == NULL)
167
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
169
if (pRenderer->iSmoothAnimationStep > 0)
171
pRenderer->iSmoothAnimationStep --;
172
int iDeltaT = cairo_dock_get_slow_animation_delta_t (pContainer);
173
int iNbIterations = pRenderer->iLatencyTime / iDeltaT;
175
pRenderer->fLatency = (double) pRenderer->iSmoothAnimationStep / iNbIterations;
176
_cairo_dock_render_to_texture (pRenderer, pIcon, pContainer);
177
cairo_dock_redraw_icon (pIcon, pContainer);
179
if (pRenderer->iSmoothAnimationStep < iNbIterations)
180
*bContinueAnimation = TRUE;
183
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
186
void cairo_dock_add_new_data_renderer_on_icon (Icon *pIcon, CairoContainer *pContainer, CairoDataRendererAttribute *pAttribute)
188
CairoDataRenderer *pRenderer = cairo_dock_new_data_renderer (pAttribute->cModelName);
190
cairo_dock_set_data_renderer_on_icon (pIcon, pRenderer);
191
if (pRenderer == NULL)
194
_cairo_dock_init_data_renderer (pRenderer, pContainer, pAttribute);
196
cairo_dock_get_icon_extent (pIcon, pContainer, &pRenderer->iWidth, &pRenderer->iHeight);
197
if (pAttribute->cEmblems != NULL)
198
pRenderer->pEmblems = g_new0 (CairoDataRendererEmblem, pAttribute->iNbValues);
199
pRenderer->pTextZones = g_new0 (CairoDataRendererTextZone, pAttribute->iNbValues);
201
pRenderer->interface.load (pRenderer, pContainer, pAttribute);
203
gboolean bLoadTextures = FALSE;
204
if (CAIRO_DOCK_CONTAINER_IS_OPENGL (pContainer) && pRenderer->interface.render_opengl)
206
bLoadTextures = TRUE;
207
cairo_dock_register_notification_on_icon (pIcon, CAIRO_DOCK_UPDATE_ICON_SLOW,
208
(CairoDockNotificationFunc) cairo_dock_update_icon_data_renderer_notification,
209
CAIRO_DOCK_RUN_AFTER, NULL);
212
if (pRenderer->pEmblems != NULL)
214
CairoDataRendererEmblem *pEmblem;
215
cairo_surface_t *pSurface;
217
for (i = 0; i < pAttribute->iNbValues; i ++)
219
pEmblem = &pRenderer->pEmblems[i];
220
if (pEmblem->fWidth != 0 && pEmblem->fHeight != 0)
222
pSurface = cairo_dock_create_surface_from_image_simple (pAttribute->cEmblems[i],
223
pEmblem->fWidth * pRenderer->iWidth,
224
pEmblem->fHeight * pRenderer->iHeight);
227
pEmblem->iTexture = cairo_dock_create_texture_from_surface (pSurface);
228
cairo_surface_destroy (pSurface);
231
pEmblem->pSurface = pSurface;
240
void cairo_dock_render_new_data_on_icon (Icon *pIcon, CairoContainer *pContainer, cairo_t *pCairoContext, double *pNewValues)
242
CairoDataRenderer *pRenderer = cairo_dock_get_icon_data_renderer (pIcon);
243
g_return_if_fail (pRenderer != NULL);
245
//\___________________ On met a jour les valeurs du renderer.
246
CairoDataToRenderer *pData = cairo_data_renderer_get_data (pRenderer);
247
pData->iCurrentIndex ++;
248
if (pData->iCurrentIndex >= pData->iMemorySize)
249
pData->iCurrentIndex -= pData->iMemorySize;
252
for (i = 0; i < pData->iNbValues; i ++)
254
fNewValue = pNewValues[i];
255
if (pRenderer->bUpdateMinMax)
257
if (fNewValue < pData->pMinMaxValues[2*i])
258
pData->pMinMaxValues[2*i] = fNewValue;
259
if (fNewValue > pData->pMinMaxValues[2*i+1])
260
pData->pMinMaxValues[2*i+1] = fNewValue;
262
pData->pTabValues[pData->iCurrentIndex][i] = fNewValue;
265
//\___________________ On met a jour le dessin de l'icone.
266
if (CAIRO_DOCK_CONTAINER_IS_OPENGL (pContainer) && pRenderer->interface.render_opengl)
268
if (pRenderer->iLatencyTime > 0)
270
int iDeltaT = cairo_dock_get_slow_animation_delta_t (pContainer);
271
int iNbIterations = pRenderer->iLatencyTime / iDeltaT;
272
pRenderer->iSmoothAnimationStep = iNbIterations;
273
cairo_dock_launch_animation (pContainer);
277
pRenderer->fLatency = 0;
278
_cairo_dock_render_to_texture (pRenderer, pIcon, pContainer);
283
_cairo_dock_render_to_context (pRenderer, pIcon, pContainer, pCairoContext);
286
//\___________________ On met a jour l'info rapide si le renderer n'a pu ecrire les valeurs.
287
if (! pRenderer->bCanRenderValueAsText && pRenderer->bWriteValues) // on prend en charge l'ecriture des valeurs.
290
gchar *cBuffer = g_new0 (gchar, pData->iNbValues * (CAIRO_DOCK_DATA_FORMAT_MAX_LEN+1));
292
for (i = 0; i < pData->iNbValues; i ++)
294
fValue = cairo_data_renderer_get_normalized_current_value (pRenderer, i);
295
cairo_data_renderer_format_value_full (pRenderer, fValue, i, str);
297
if (i+1 < pData->iNbValues)
305
cairo_dock_set_quick_info (pIcon, pContainer, cBuffer);
309
cairo_dock_redraw_icon (pIcon, pContainer);
314
void cairo_dock_free_data_renderer (CairoDataRenderer *pRenderer)
316
if (pRenderer == NULL)
319
g_free (pRenderer->data.pValuesBuffer);
320
g_free (pRenderer->data.pTabValues);
321
g_free (pRenderer->data.pMinMaxValues);
323
if (pRenderer->pEmblems != NULL)
325
CairoDataRendererEmblem *pEmblem;
327
for (i = 0; i < pRenderer->data.iNbValues; i ++)
329
pEmblem = &pRenderer->pEmblems[i];
330
if (pEmblem->pSurface != NULL)
331
cairo_surface_destroy (pEmblem->pSurface);
332
if (pEmblem->iTexture != 0)
333
_cairo_dock_delete_texture (pEmblem->iTexture);
335
g_free (pRenderer->pEmblems);
338
if (pRenderer->pTextZones != NULL)
339
g_free (pRenderer->pTextZones);
341
pRenderer->interface.free (pRenderer);
344
void cairo_dock_remove_data_renderer_on_icon (Icon *pIcon)
346
CairoDataRenderer *pRenderer = cairo_dock_get_icon_data_renderer (pIcon);
348
cairo_dock_remove_notification_func_on_icon (pIcon, CAIRO_DOCK_UPDATE_ICON_SLOW, (CairoDockNotificationFunc) cairo_dock_update_icon_data_renderer_notification, NULL);
350
cairo_dock_free_data_renderer (pRenderer);
351
cairo_dock_set_data_renderer_on_icon (pIcon, NULL);
356
void cairo_dock_reload_data_renderer_on_icon (Icon *pIcon, CairoContainer *pContainer, CairoDataRendererAttribute *pAttribute)
358
//\_____________ On recupere les donnees de l'actuel renderer.
359
CairoDataToRenderer *pData = NULL;
360
CairoDataRenderer *pOldRenderer = cairo_dock_get_icon_data_renderer (pIcon);
361
g_return_if_fail (pOldRenderer != NULL || pAttribute != NULL);
363
if (pAttribute == NULL) // rien ne change dans les parametres du data-renderer, on se contente de le recharger a la taille de l'icone.
365
g_return_if_fail (pOldRenderer->interface.reload != NULL);
366
cairo_dock_get_icon_extent (pIcon, pContainer, &pOldRenderer->iWidth, &pOldRenderer->iHeight);
367
pOldRenderer->interface.reload (pOldRenderer);
369
else // on recree le data-renderer avec les nouveaux attributs.
371
pAttribute->iNbValues = MAX (1, pAttribute->iNbValues);
372
//\_____________ On recupere les donnees courantes.
373
if (pOldRenderer && pOldRenderer->data.iNbValues == pAttribute->iNbValues)
375
pData = g_memdup (&pOldRenderer->data, sizeof (CairoDataToRenderer));
376
memset (&pOldRenderer->data, 0, sizeof (CairoDataToRenderer));
378
pAttribute->iMemorySize = MAX (2, pAttribute->iMemorySize);
379
if (pData->iMemorySize != pAttribute->iMemorySize) // on redimensionne le tampon des valeurs.
381
int iOldMemorySize = pData->iMemorySize;
382
pData->iMemorySize = pAttribute->iMemorySize;
383
pData->pValuesBuffer = g_realloc (pData->pValuesBuffer, pData->iMemorySize * pData->iNbValues * sizeof (gdouble));
384
if (pData->iMemorySize > iOldMemorySize)
386
memset (&pData->pValuesBuffer[iOldMemorySize * pData->iNbValues], 0, (pData->iMemorySize - iOldMemorySize) * pData->iNbValues * sizeof (gdouble));
389
g_free (pData->pTabValues);
390
pData->pTabValues = g_new (gdouble *, pData->iMemorySize);
392
for (i = 0; i < pData->iMemorySize; i ++)
394
pData->pTabValues[i] = &pData->pValuesBuffer[i*pData->iNbValues];
396
if (pData->iCurrentIndex >= pData->iMemorySize)
397
pData->iCurrentIndex = pData->iMemorySize - 1;
401
//\_____________ On supprime l'ancien.
402
cairo_dock_remove_data_renderer_on_icon (pIcon);
404
//\_____________ On en cree un nouveau.
405
cairo_dock_add_new_data_renderer_on_icon (pIcon, pContainer, pAttribute);
407
//\_____________ On lui remet les valeurs actuelles.
408
CairoDataRenderer *pNewRenderer = cairo_dock_get_icon_data_renderer (pIcon);
409
if (pNewRenderer != NULL && pData != NULL)
410
memcpy (&pNewRenderer->data, pData, sizeof (CairoDataToRenderer));
416
void cairo_dock_resize_data_renderer_history (Icon *pIcon, int iNewMemorySize)
418
CairoDataRenderer *pRenderer = cairo_dock_get_icon_data_renderer (pIcon);
419
g_return_if_fail (pRenderer != NULL);
420
CairoDataToRenderer *pData = cairo_data_renderer_get_data (pRenderer);
422
iNewMemorySize = MAX (2, iNewMemorySize);
423
//g_print ("iMemorySize : %d -> %d\n", pData->iMemorySize, iNewMemorySize);
424
if (pData->iMemorySize == iNewMemorySize)
427
int iOldMemorySize = pData->iMemorySize;
428
pData->iMemorySize = iNewMemorySize;
429
pData->pValuesBuffer = g_realloc (pData->pValuesBuffer, pData->iMemorySize * pData->iNbValues * sizeof (gdouble));
430
if (iNewMemorySize > iOldMemorySize)
432
memset (&pData->pValuesBuffer[iOldMemorySize * pData->iNbValues], 0, (iNewMemorySize - iOldMemorySize) * pData->iNbValues * sizeof (gdouble));
435
g_free (pData->pTabValues);
436
pData->pTabValues = g_new (gdouble *, pData->iMemorySize);
438
for (i = 0; i < pData->iMemorySize; i ++)
440
pData->pTabValues[i] = &pData->pValuesBuffer[i*pData->iNbValues];
442
if (pData->iCurrentIndex >= pData->iMemorySize)
443
pData->iCurrentIndex = pData->iMemorySize - 1;
446
void cairo_dock_refresh_data_renderer (Icon *pIcon, CairoContainer *pContainer, cairo_t *pCairoContext)
448
CairoDataRenderer *pRenderer = cairo_dock_get_icon_data_renderer (pIcon);
449
g_return_if_fail (pRenderer != NULL);
451
if (CAIRO_DOCK_CONTAINER_IS_OPENGL (pContainer) && pRenderer->interface.render_opengl)
453
_cairo_dock_render_to_texture (pRenderer, pIcon, pContainer);
457
_cairo_dock_render_to_context (pRenderer, pIcon, pContainer, pCairoContext);
463
/////////////////////////////////////////////////
464
/////////////// LIST OF THEMES /////////////////
465
/////////////////////////////////////////////////
466
GHashTable *cairo_dock_list_available_themes_for_data_renderer (const gchar *cRendererName)
468
CairoDockDataRendererRecord *pRecord = cairo_dock_get_data_renderer_record (cRendererName);
469
g_return_val_if_fail (pRecord != NULL, NULL);
471
if (pRecord->cThemeDirName == NULL)
473
gchar *cGaugeShareDir = g_strdup_printf ("%s/%s", CAIRO_DOCK_SHARE_DATA_DIR, pRecord->cThemeDirName);
474
gchar *cGaugeUserDir = g_strdup_printf ("%s/%s", g_cExtrasDirPath, pRecord->cThemeDirName);
475
GHashTable *pGaugeTable = cairo_dock_list_packages (cGaugeShareDir, cGaugeUserDir, pRecord->cThemeDirName);
477
g_free (cGaugeShareDir);
478
g_free (cGaugeUserDir);
483
gchar *cairo_dock_get_data_renderer_theme_path (const gchar *cRendererName, const gchar *cThemeName, CairoDockPackageType iType) // utile pour DBus aussi.
485
CairoDockDataRendererRecord *pRecord = cairo_dock_get_data_renderer_record (cRendererName);
486
g_return_val_if_fail (pRecord != NULL, NULL);
488
if (pRecord->cThemeDirName == NULL)
491
const gchar *cGaugeShareDir = g_strdup_printf ("%s/%s", CAIRO_DOCK_SHARE_DATA_DIR, pRecord->cThemeDirName);
492
gchar *cGaugeUserDir = g_strdup_printf ("%s/%s", g_cExtrasDirPath, pRecord->cThemeDirName);
493
gchar *cGaugePath = cairo_dock_get_package_path (cThemeName, cGaugeShareDir, cGaugeUserDir, pRecord->cThemeDirName, iType);
494
g_free (cGaugeUserDir);
498
gchar *cairo_dock_get_package_path_for_data_renderer (const gchar *cRendererName, const gchar *cAppletConfFilePath, GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, const gchar *cDefaultThemeName)
500
CairoDockDataRendererRecord *pRecord = cairo_dock_get_data_renderer_record (cRendererName);
501
g_return_val_if_fail (pRecord != NULL, NULL);
503
gchar *cChosenThemeName = cairo_dock_get_string_key_value (pKeyFile, cGroupName, cKeyName, bFlushConfFileNeeded, cDefaultThemeName, NULL, NULL);
504
if (cChosenThemeName == NULL)
505
cChosenThemeName = g_strdup (pRecord->cDefaultTheme);
507
CairoDockPackageType iType = cairo_dock_extract_package_type_from_name (cChosenThemeName);
508
gchar *cGaugePath = cairo_dock_get_data_renderer_theme_path (cRendererName, cChosenThemeName, iType);
510
if (cGaugePath == NULL) // theme introuvable.
511
cGaugePath = g_strdup_printf ("%s/%s", CAIRO_DOCK_SHARE_DATA_DIR, pRecord->cThemeDirName, pRecord->cDefaultTheme);
513
if (iType != CAIRO_DOCK_ANY_PACKAGE)
515
g_key_file_set_string (pKeyFile, cGroupName, cKeyName, cChosenThemeName);
516
cairo_dock_write_keys_to_file (pKeyFile, cAppletConfFilePath);
518
cd_debug ("Theme de la jauge : %s", cGaugePath);
519
g_free (cChosenThemeName);
524
void cairo_dock_register_built_in_data_renderers (void)
526
cairo_dock_register_data_renderer_entry_point ("gauge", (CairoDataRendererNewFunc) cairo_dock_new_gauge, "gauges", "Turbo-night-fuel");
527
cairo_dock_register_data_renderer_entry_point ("graph", (CairoDataRendererNewFunc) cairo_dock_new_graph, NULL, NULL);