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/>.
25
#include "applet-impulse.h"
28
#define IM_TAB_SIZE 256
30
extern CairoDockHidingEffect *g_pHidingBackend; // cairo_dock_is_hidden
32
////////////////// IMPULSE \\\\\\\\\\\\\\\\\\\\
36
cd_debug ("Impulse: start im");
42
cd_debug ("Impulse: stop im");
43
//im_stop(); // FIXME => if stopped, the client is not stopped and im_getSnapshot(IM_FFT) give always the same thing...
46
void cd_impulse_im_setSourceIndex (gint iSourceIndex)
48
cd_debug ("Impulse: iSourceIndex = %d", iSourceIndex);
49
im_setSourceIndex (iSourceIndex);
52
////////////////// USEFUL FUNCTIONS \\\\\\\\\\\\\\\\\\\\
54
static void _get_icons_list_without_separators (CDSharedMemory *pSharedMemory)
56
if (pSharedMemory->pDock == NULL)
58
pSharedMemory->pIconsList = NULL;
62
pSharedMemory->bIsUpdatingIconsList = TRUE;
64
pSharedMemory->pIconsList = NULL;
67
for (ic = pSharedMemory->pDock->icons; ic != NULL; ic = ic->next)
70
// cd_debug ("Impulse: icon name=%s", pIcon->cName);
71
if (! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon))
72
pSharedMemory->pIconsList = g_list_append (pSharedMemory->pIconsList, pIcon);
75
pSharedMemory->bIsUpdatingIconsList = FALSE;
76
cd_debug ("Impulse: updated icons list: %d", g_list_length(pSharedMemory->pIconsList));
79
//static gboolean _animate_the_dock (CDSharedMemory *pSharedMemory)
80
static gboolean _animate_the_dock (gpointer data)
83
// cd_debug ("Impulse: in");
84
if (myData.pSharedMemory->bIsUpdatingIconsList
85
|| cairo_dock_is_hidden (myData.pSharedMemory->pDock)) // not needed for the animations but not for pulse.
86
CD_APPLET_LEAVE (TRUE);
88
if (myData.pSharedMemory->pIconsList == NULL)
90
cd_impulse_stop_animations ();
91
CD_APPLET_LEAVE (FALSE);
94
guint iIcons = IM_TAB_SIZE / g_list_length (myData.pSharedMemory->pIconsList); // number of icons (without separators)
96
double *array = im_getSnapshot(IM_FFT);
98
// we check if there is a signal (most of the time, all values are > 0)
100
{ // is it really null?
102
for (j = 1; j < IM_TAB_SIZE; j++)
105
break; // there is a signal
108
cd_debug ("Impulse: No Signal? %d", j);
109
if (j == IM_TAB_SIZE)
110
CD_APPLET_LEAVE (TRUE);
112
* if null, increase the time of the loop?
113
* Maybe use: PA_SUBSCRIPTION_EVENT_CLIENT?
114
* or something else in pulse?
118
// Computing and animations
121
GList *ic = myData.pSharedMemory->pIconsList;
123
gboolean bHasNotBeenAnimated = TRUE;
124
for (i = 0; ic != NULL; i++) // i < 256
126
l += array[i]; // a sum for the average
127
if (i != 0 && (i % iIcons) == 0)
130
// cd_debug ("Impulse: Average: i=%d, l=%f ; I=%d ; l/I=%f ; %s", i, l, iIcons, l/iIcons, pIcon->cName);
131
if ((l/iIcons) > myData.pSharedMemory->fMinValueToAnim) // animation
133
//cd_debug ("Impulse: animation on this icon=%s", pIcon->cName);
134
cairo_dock_request_icon_animation (pIcon,
135
myData.pSharedMemory->pDock,
136
myData.pSharedMemory->cIconAnimation,
137
myData.pSharedMemory->iNbAnimations);
138
bHasNotBeenAnimated = FALSE;
139
myData.pSharedMemory->bNeedRefreshIfNotAnimated = TRUE;
141
else if (myData.pSharedMemory->bStopAnimations)
142
cairo_dock_stop_icon_animation (pIcon);
147
if (bHasNotBeenAnimated && myData.pSharedMemory->bStopAnimations && myData.pSharedMemory->bNeedRefreshIfNotAnimated)
149
cd_debug ("Impulse: refresh container");
150
cairo_dock_redraw_container (CAIRO_CONTAINER (myData.pSharedMemory->pDock));
151
myData.pSharedMemory->bNeedRefreshIfNotAnimated = FALSE; // no need of refresh until the next animation and if bHasNotBeenAnimated
154
//cd_debug ("Impulse: out");
156
CD_APPLET_LEAVE (TRUE);
159
static gboolean _impulse_check_pulse_status (void)
161
myData.iSidCheckStatus = 0;
163
cd_debug ("Impulse: checking PulseAudio Context status");
165
if (! myData.bHasBeenStarted && im_context_state () == IM_FAILED)
167
cd_impulse_stop_animations ();
168
cd_debug ("Impulse: starting failed");
169
cairo_dock_remove_dialog_if_any (myIcon);
170
cairo_dock_show_temporary_dialog_with_icon (D_("There is something wrong with PulseAudio.\nCan you check its status (installed? running? version?) and report this bug (if any) to forum.glx-dock.org"),
174
MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE);
175
CD_APPLET_SET_USER_IMAGE_ON_MY_ICON (myConfig.cIconImpulseERROR, "impulse-error.svg");
181
////////////////// NOTIFICATIONS \\\\\\\\\\\\\\\\\\\\
183
/*void cd_impulse_start_animations (void)
185
myData.iSidAnimate = g_timeout_add (myConfig.iLoopTime, (GSourceFunc) _animate_the_dock, NULL);
188
void _remove_notifications (void)
190
cairo_dock_remove_notification_func_on_object (&myDocksMgr,
191
NOTIFICATION_ICON_MOVED,
192
(CairoDockNotificationFunc) cd_impulse_on_icon_changed, NULL);
193
cairo_dock_remove_notification_func_on_object (&myDocksMgr,
194
NOTIFICATION_INSERT_ICON,
195
(CairoDockNotificationFunc) cd_impulse_on_icon_changed, NULL);
196
cairo_dock_remove_notification_func_on_object (&myDocksMgr,
197
NOTIFICATION_REMOVE_ICON,
198
(CairoDockNotificationFunc) cd_impulse_on_icon_changed, NULL);
201
void _register_notifications (void)
203
cairo_dock_register_notification_on_object (&myDocksMgr,
204
NOTIFICATION_ICON_MOVED,
205
(CairoDockNotificationFunc) cd_impulse_on_icon_changed,
206
CAIRO_DOCK_RUN_FIRST, NULL);
207
cairo_dock_register_notification_on_object (&myDocksMgr,
208
NOTIFICATION_INSERT_ICON,
209
(CairoDockNotificationFunc) cd_impulse_on_icon_changed,
210
CAIRO_DOCK_RUN_FIRST, NULL);
211
cairo_dock_register_notification_on_object (&myDocksMgr,
212
NOTIFICATION_REMOVE_ICON,
213
(CairoDockNotificationFunc) cd_impulse_on_icon_changed,
214
CAIRO_DOCK_RUN_FIRST, NULL);
217
////////////////// GENERAL FUNCTIONS \\\\\\\\\\\\\\\\\\\\
219
void cd_impulse_stop_animations (void)
221
//if (myData.pTask != NULL)
222
if (myData.iSidAnimate != 0)
224
/*cairo_dock_discard_task (myData.pTask);
225
myData.pTask = NULL;*/
226
g_source_remove (myData.iSidAnimate);
227
myData.iSidAnimate = 0;
228
// _free_shared_memory (myData.pSharedMemory);
229
_remove_notifications ();
231
if (myData.bPulseLaunched)
233
cd_impulse_draw_current_state ();
234
// myData.bPulseLaunched = FALSE; //FIXME => if already started and stopped, it will crash... because not correctly stopped...
237
void cd_impulse_launch_task (void) //(CairoDockModuleInstance *myApplet)
239
// if a task is already launching
240
/*if (myData.pTask != NULL)
242
cairo_dock_discard_task (myData.pTask);
245
if (myData.iSidAnimate != 0)
246
cd_impulse_stop_animations ();
249
if (! myData.bPulseLaunched)
251
_im_start (); // FIXME => if already started and stopped, it will crash... because not correctly stopped...
252
myData.bPulseLaunched = TRUE;
255
/*myData.pTask = cairo_dock_new_task_full (1,// (SECOND) myConfig.iLoopTime,
256
// (CairoDockGetDataAsyncFunc) _get_icons_list_without_separators,
258
(CairoDockUpdateSyncFunc) _animate_the_dock,
259
(GFreeFunc) _free_shared_memory,
260
myData.pSharedMemory);
261
_get_icons_list_without_separators (myData.pSharedMemory);
262
cairo_dock_launch_task (myData.pTask);*/
264
_get_icons_list_without_separators (myData.pSharedMemory);
265
_register_notifications();
267
myData.iSidAnimate = g_timeout_add (myConfig.iLoopTime, (GSourceFunc) _animate_the_dock, NULL); // or into a thread + time?
268
cd_debug ("Impulse: animations started (checking status: %d)", myData.iSidCheckStatus);
269
cd_impulse_draw_current_state ();
271
if (myData.iSidCheckStatus == 0)
272
myData.iSidCheckStatus = g_timeout_add_seconds (1, (GSourceFunc) _impulse_check_pulse_status, NULL);
275
gboolean cd_impulse_on_icon_changed (gpointer pUserData, Icon *pIcon, CairoDock *pDock)
277
// launched and something has changed in the right dock
278
//cd_debug ("Impulse: update needed? %d | %d", pDock, myConfig.pDock);
279
if (myData.iSidAnimate != 0 && pDock == myConfig.pDock)
281
_get_icons_list_without_separators (myData.pSharedMemory);
283
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
286
void cd_impulse_draw_current_state (void)
288
if (myData.iSidAnimate != 0)
289
CD_APPLET_SET_USER_IMAGE_ON_MY_ICON (myConfig.cIconImpulseON, "impulse-running.svg");
291
CD_APPLET_SET_USER_IMAGE_ON_MY_ICON (myConfig.cIconImpulseOFF, "impulse-stopped.svg");
294
////////////////// DELAY \\\\\\\\\\\\\\\\\\\\
296
static gboolean _impulse_restart_delayed (void)
298
myData.iSidRestartDelayed = 0;
300
if (! myData.bHasBeenStarted)
302
myData.bHasBeenStarted = TRUE;
303
cd_message ("Impulse has been started");
305
if (myConfig.bFree) // It's maybe a hack but Cairo-Penguin does that :)
307
cairo_dock_detach_icon_from_dock (myIcon, myDock, myIconsParam.iSeparateIcons);
308
cairo_dock_update_dock_size (myDock);
311
cairo_dock_insert_icon_in_dock (myIcon, myDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, CAIRO_DOCK_ANIMATE_ICON);
313
cd_impulse_launch_task (); // launched the animations
319
void cd_impulse_start_animating_with_delay (void)
321
if (myData.iSidRestartDelayed != 0)
324
if (cairo_dock_is_loading ())
325
myData.iSidRestartDelayed = g_timeout_add_seconds (2, (GSourceFunc) _impulse_restart_delayed, NULL); // priority to the loading of the dock
327
myData.iSidRestartDelayed = g_timeout_add_seconds (1, (GSourceFunc) _impulse_restart_delayed, NULL); // if we have to detach the icon