1 /**
2 * This file is a part of the Cairo-Dock project
3 *
4 * Copyright : (C) see the 'copyright' file.
5 * E-mail    : see the 'copyright' file.
6 *
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.
11 *
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/>.
18 */
19 
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "applet-struct.h"
24 #include "applet-musicplayer.h"
25 #include "applet-draw.h"
26 #include "applet-dbus.h"
27 #include "3dcover-draw.h"
28 #include "applet-cover.h"
29 #include "applet-notifications.h"
30 
31 static void _show_players_list_dialog (void);
32 
33 
_cd_musicplayer_prev(GtkMenuItem * menu_item,gpointer * data)34 static void _cd_musicplayer_prev (GtkMenuItem *menu_item, gpointer *data) {
35 	myData.pCurrentHandler->control (PLAYER_PREVIOUS, NULL);
36 }
_cd_musicplayer_pp(GtkMenuItem * menu_item,gpointer * data)37 static void _cd_musicplayer_pp (GtkMenuItem *menu_item, gpointer *data) {
38 	myData.pCurrentHandler->control (PLAYER_PLAY_PAUSE, NULL);
39 }
_cd_musicplayer_stop(GtkMenuItem * menu_item,gpointer * data)40 static void _cd_musicplayer_stop (GtkMenuItem *menu_item, gpointer *data) {
41 	myData.pCurrentHandler->control (PLAYER_STOP, NULL);
42 }
_cd_musicplayer_next(GtkMenuItem * menu_item,gpointer * data)43 static void _cd_musicplayer_next (GtkMenuItem *menu_item, gpointer *data) {
44 	myData.pCurrentHandler->control (PLAYER_NEXT, NULL);
45 }
_cd_musicplayer_show_from_systray(GtkMenuItem * menu_item,gpointer * data)46 static void _cd_musicplayer_show_from_systray (GtkMenuItem *menu_item, gpointer *data)
47 {
48 	gboolean bRaised = FALSE;
49 	if (myData.pCurrentHandler->raise)
50 		bRaised = myData.pCurrentHandler->raise ();
51 	if (! bRaised)
52 		cairo_dock_launch_command (myData.pCurrentHandler->launch);
53 }
_cd_musicplayer_quit(GtkMenuItem * menu_item,gpointer * data)54 static void _cd_musicplayer_quit (GtkMenuItem *menu_item, gpointer *data)
55 {
56 	gboolean bQuit = FALSE;
57 	if (myData.pCurrentHandler->quit)
58 		bQuit = myData.pCurrentHandler->quit ();
59 	if (! bQuit)
60 	{
61 		gchar *cmd = g_strdup_printf ("killall %s", myData.pCurrentHandler->launch);
62 		cairo_dock_launch_command (cmd);
63 		g_free (cmd);
64 	}
65 }
_cd_musicplayer_jumpbox(GtkMenuItem * menu_item,gpointer * data)66 static void _cd_musicplayer_jumpbox (GtkMenuItem *menu_item, gpointer *data) {
67 	myData.pCurrentHandler->control (PLAYER_JUMPBOX, NULL);
68 }
_cd_musicplayer_shuffle(GtkMenuItem * menu_item,gpointer * data)69 static void _cd_musicplayer_shuffle (GtkMenuItem *menu_item, gpointer *data) {
70 	myData.pCurrentHandler->control (PLAYER_SHUFFLE, NULL);
71 }
_cd_musicplayer_repeat(GtkMenuItem * menu_item,gpointer * data)72 static void _cd_musicplayer_repeat (GtkMenuItem *menu_item, gpointer *data) {
73 	myData.pCurrentHandler->control (PLAYER_REPEAT, NULL);
74 }
_cd_musicplayer_rate(GtkMenuItem * menu_item,gpointer * data)75 static void _cd_musicplayer_rate (GtkMenuItem *menu_item, gpointer *data) {
76 	/// trouver un moyen esthetique.
77 }
_cd_musicplayer_info(GtkMenuItem * menu_item,gpointer * data)78 static void _cd_musicplayer_info (GtkMenuItem *menu_item, gpointer *data)
79 {
80 	// the user wants to see this dialogue, it's maybe better to not remove it automatically
81 	cd_musicplayer_popup_info (0); // 0 = without any timeout
82 }
_cd_musicplayer_launch(GtkMenuItem * menu_item,gpointer * data)83 static void _cd_musicplayer_launch (GtkMenuItem *menu_item, gpointer *data)
84 {
85 	cairo_dock_launch_command (myData.pCurrentHandler->launch);
86 }
87 
_cd_musicplayer_choose_player(GtkMenuItem * menu_item,gpointer * data)88 static void _cd_musicplayer_choose_player (GtkMenuItem *menu_item, gpointer *data)
89 {
90 	CD_APPLET_ENTER;
91 	_show_players_list_dialog ();
92 	CD_APPLET_LEAVE ();
93 }
94 
_cd_musicplayer_find_player(GtkMenuItem * menu_item,gpointer * data)95 static void _cd_musicplayer_find_player (GtkMenuItem *menu_item, gpointer *data)
96 {
97 	CD_APPLET_ENTER;
98 	MusicPlayerHandler *pHandler = cd_musicplayer_dbus_find_opened_player ();
99 	if (pHandler == NULL)
100 	{
101 		gldi_dialog_show_temporary_with_icon (D_("Sorry, I couldn't detect any player.\nIf it is running, it is maybe because its version is too old and does not offer such service."),
102 			myIcon,
103 			myContainer,
104 			7000,
105 			MY_APPLET_SHARE_DATA_DIR"/"MY_APPLET_ICON_FILE);
106 	}
107 	else if (pHandler != myData.pCurrentHandler)
108 	{
109 		if (myData.pCurrentHandler != NULL)
110 		{
111 			cd_musicplayer_stop_current_handler (TRUE);
112 		}
113 
114 		// get the name of the running player.
115 		const gchar *cPlayerName;
116 		if (strcmp (pHandler->name, "Mpris2") == 0)  // generic MPRIS2 handler, use the program name.
117 			cPlayerName = pHandler->launch;
118 		else
119 			cPlayerName = pHandler->name;
120 		cd_debug ("found %s (%s)", pHandler->name, cPlayerName);
121 
122 		// write it down into our conf file
123 		cairo_dock_update_conf_file (CD_APPLET_MY_CONF_FILE,
124 			G_TYPE_STRING, "Configuration", "current-player", cPlayerName,
125 			G_TYPE_STRING, "Configuration", "desktop-entry", "",  // reset the desktop filename, we'll get the new one from the "DesktopEntry" property of the new player
126 			G_TYPE_INVALID);
127 		g_free (myConfig.cMusicPlayer);
128 		myConfig.cMusicPlayer = g_strdup (cPlayerName);
129 		g_free (myConfig.cLastKnownDesktopFile);
130 		myConfig.cLastKnownDesktopFile = NULL;
131 
132 		// set the handler with this value.
133 		cd_musicplayer_set_current_handler (myConfig.cMusicPlayer);
134 	}
135 	CD_APPLET_LEAVE ();
136 }
137 
138 
_choice_dialog_action(int iClickedButton,GtkWidget * pInteractiveWidget,gpointer data,CairoDialog * pDialog)139 static void _choice_dialog_action (int iClickedButton, GtkWidget *pInteractiveWidget, gpointer data, CairoDialog *pDialog)
140 {
141 	if (iClickedButton == 1 || iClickedButton == -2)  // click on "cancel", or Escape
142 		return;
143 	// get the value in the widget.
144 	GtkWidget *pEntry = gtk_bin_get_child (GTK_BIN (pInteractiveWidget));
145 	const gchar *cPlayerName = gtk_entry_get_text (GTK_ENTRY (pEntry));
146 	if (cPlayerName == NULL || *cPlayerName == '\0')
147 		return;
148 	// write it down into our conf file
149 	cairo_dock_update_conf_file (CD_APPLET_MY_CONF_FILE,
150 		G_TYPE_STRING, "Configuration", "current-player", cPlayerName,
151 		G_TYPE_STRING, "Configuration", "desktop-entry", "",  // reset the desktop filename, we'll get the new one from the "DesktopEntry" property of the new player
152 		G_TYPE_INVALID);
153 	g_free (myConfig.cMusicPlayer);
154 	myConfig.cMusicPlayer = g_strdup (cPlayerName);
155 	g_free (myConfig.cLastKnownDesktopFile);
156 	myConfig.cLastKnownDesktopFile = NULL;
157 	// set the handler with this value.
158 	cd_musicplayer_set_current_handler (myConfig.cMusicPlayer);
159 	// launch it, if it's already running, it's likely to have no effect
160 	cairo_dock_launch_command (myData.pCurrentHandler->launch);
161 }
_show_players_list_dialog(void)162 static void _show_players_list_dialog (void)
163 {
164 	// build a list of the available groups.
165 	GtkWidget *pComboBox = gtk_combo_box_text_new_with_entry ();
166 	GList *h;
167 	MusicPlayerHandler *handler;
168 	for (h = myData.pHandlers; h != NULL; h = h->next)
169 	{
170 		handler = h->data;
171 		if (handler->cMprisService != NULL)
172 			gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (pComboBox), handler->name);
173 	}
174 	GtkTreeModel *pModel = gtk_combo_box_get_model (GTK_COMBO_BOX (pComboBox));
175 	if (pModel)
176 		gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (pModel), CAIRO_DOCK_MODEL_NAME, GTK_SORT_ASCENDING);
177 	/// maybe try to set the dialog color (text and bg colors)...
178 
179 	// detect a running player and set it as the current choice.
180 	MusicPlayerHandler *pRunningHandler = cd_musicplayer_dbus_find_opened_player ();
181 	if (pRunningHandler != NULL)
182 	{
183 		GtkWidget *pEntry = gtk_bin_get_child (GTK_BIN (pComboBox));
184 		if (strcmp (pRunningHandler->name, "Mpris2") == 0)  // generic MPRIS2 handler, use the program name.
185 			gtk_entry_set_text (GTK_ENTRY (pEntry), pRunningHandler->launch);
186 		else
187 			gtk_entry_set_text (GTK_ENTRY (pEntry), pRunningHandler->name);
188 	}
189 
190 	// build the dialog.
191 	CairoDialogAttr attr;
192 	memset (&attr, 0, sizeof (CairoDialogAttr));
193 	attr.cText = D_("Choose a music player to control");
194 	attr.cImageFilePath = NULL;
195 	attr.pInteractiveWidget = pComboBox;
196 	attr.pActionFunc = (CairoDockActionOnAnswerFunc)_choice_dialog_action;
197 	attr.pUserData = NULL;
198 	attr.pFreeDataFunc = (GFreeFunc)NULL;
199 	const gchar *cButtons[] = {"ok", "cancel", NULL};
200 	attr.cButtonsImage = cButtons;
201 	attr.pIcon = myIcon;
202 	attr.pContainer = myContainer;
203 
204 	gldi_dialog_new (&attr);
205 }
206 
207 //\___________ Define here the action to be taken when the user left-clicks on your icon or on its subdock or your desklet. The icon and the container that were clicked are available through the macros CD_APPLET_CLICKED_ICON and CD_APPLET_CLICKED_CONTAINER. CD_APPLET_CLICKED_ICON may be NULL if the user clicked in the container but out of icons.
208 CD_APPLET_ON_CLICK_BEGIN
209 	if (myData.pCurrentHandler != NULL)
210 	{
211 		if (CD_APPLET_MY_CONTAINER_IS_OPENGL && myData.numberButtons != 0  && myConfig.bOpenglThemes && myDesklet)
212 		{
213 			// Actions au clic sur un bouton :
214 			if (myData.mouseOnButton1)
215 			{
216 				if(myData.bIsRunning)
217 				{
218 					_cd_musicplayer_pp (NULL, NULL);
219 				}
220 				else
221 				{
222 					if (myIcon->cClass != NULL)
223 						gldi_icon_launch_command (myIcon);
224 					else if (myData.pCurrentHandler->launch)
225 						cairo_dock_launch_command (myData.pCurrentHandler->launch);
226 				}
227 			}
228 			else if (myData.mouseOnButton2)
229 				_cd_musicplayer_prev (NULL, NULL);
230 			else if (myData.mouseOnButton3)
231 				_cd_musicplayer_next (NULL, NULL);
232 			else if (myData.mouseOnButton4)
233 			{
234 				if(myData.bIsRunning)
235 				{
236 					if (myData.pCurrentHandler->iPlayerControls & PLAYER_JUMPBOX)
237 						_cd_musicplayer_jumpbox (NULL, NULL);
238 					else if (myIcon->pAppli != NULL)
239 						gldi_window_show (myIcon->pAppli);
240 				}
241 				else if (myData.pCurrentHandler->launch != NULL)
242 					cairo_dock_launch_command (myData.pCurrentHandler->launch);
243 			}
244 			else
245 			{
246 				if(myData.bIsRunning)
247 					cd_musicplayer_popup_info (myConfig.iDialogDuration);
248 				else
249 				{
250 					if (myIcon->cClass != NULL)
251 						gldi_icon_launch_command (myIcon);
252 					else if (myData.pCurrentHandler->launch)
253 						cairo_dock_launch_command (myData.pCurrentHandler->launch);
254 				}
255 			}
256 		}
257 		else  // pas de boutons.
258 		{
259 			if(myData.bIsRunning)
260 			{
261 				if (myConfig.bPauseOnClick)
262 				{
263 					_cd_musicplayer_pp (NULL, NULL);
264 				}
265 				else if (myIcon->pAppli != NULL)
266 				{
267 					if (myIcon->pAppli == gldi_windows_get_active ())  // la fenetre du lecteur a le focus. en mode desklet ca ne marche pas car il aura pris le focus au moment du clic.
268 						gldi_window_minimize (myIcon->pAppli);
269 					else
270 						gldi_window_show (myIcon->pAppli);
271 				}
272 				else
273 				{
274 					_cd_musicplayer_show_from_systray (NULL, NULL);
275 				}
276 			}
277 			else
278 			{
279 				if (myIcon->cClass != NULL)
280 					gldi_icon_launch_command (myIcon);
281 				else if (myData.pCurrentHandler->launch)
282 					cairo_dock_launch_command (myData.pCurrentHandler->launch);
283 			}
284 		}
285 	}
286 	else
287 	{
288 		_show_players_list_dialog ();
289 	}
290 CD_APPLET_ON_CLICK_END
291 
292 
293 //\___________ Define here the entries you want to add to the menu when the user right-clicks on your icon or on its subdock or your desklet. The icon and the container that were clicked are available through the macros CD_APPLET_CLICKED_ICON and CD_APPLET_CLICKED_CONTAINER. CD_APPLET_CLICKED_ICON may be NULL if the user clicked in the container but out of icons. The menu where you can add your entries is available throught the macro CD_APPLET_MY_MENU; you can add sub-menu to it if you want.
294 CD_APPLET_ON_BUILD_MENU_BEGIN
295 	if (! myData.bIsRunning)
296 	{
297 		CD_APPLET_ADD_IN_MENU_WITH_STOCK (D_("Find opened player"), GLDI_ICON_NAME_FIND, _cd_musicplayer_find_player, CD_APPLET_MY_MENU);
298 		if (myData.pCurrentHandler != NULL)
299 			CD_APPLET_ADD_IN_MENU_WITH_STOCK (myData.pCurrentHandler->cDisplayedName?myData.pCurrentHandler->cDisplayedName:myData.pCurrentHandler->name, GLDI_ICON_NAME_MEDIA_PLAY, _cd_musicplayer_launch, CD_APPLET_MY_MENU);
300 		else
301 			CD_APPLET_ADD_IN_MENU_WITH_STOCK (D_("Choose a player"), GLDI_ICON_NAME_MEDIA_PLAY, _cd_musicplayer_choose_player, CD_APPLET_MY_MENU);
302 	}
303 	else
304 	{
305 		if (myData.pCurrentHandler->iPlayerControls & PLAYER_PREVIOUS)
306 		{
307 			gchar *cLabel = g_strdup_printf ("%s (%s)", D_("Previous"), D_("scroll-up"));
308 			CD_APPLET_ADD_IN_MENU_WITH_STOCK (cLabel, GLDI_ICON_NAME_MEDIA_PREVIOUS, _cd_musicplayer_prev, CD_APPLET_MY_MENU);
309 			g_free (cLabel);
310 		}
311 		if (myData.pCurrentHandler->iPlayerControls & PLAYER_PLAY_PAUSE)
312 		{
313 			gchar *cLabel = g_strdup_printf ("%s (%s)", D_("Play/Pause"), myConfig.bPauseOnClick ? D_("left-click") : D_("middle-click"));
314 			CD_APPLET_ADD_IN_MENU_WITH_STOCK (cLabel, (myData.iPlayingStatus != PLAYER_PLAYING ? GLDI_ICON_NAME_MEDIA_PLAY : GLDI_ICON_NAME_MEDIA_PAUSE), _cd_musicplayer_pp, CD_APPLET_MY_MENU);
315 			g_free (cLabel);
316 		}
317 		if (myData.pCurrentHandler->iPlayerControls & PLAYER_NEXT)
318 		{
319 			gchar *cLabel = g_strdup_printf ("%s (%s)", D_("Next"), D_("scroll-down"));
320 			CD_APPLET_ADD_IN_MENU_WITH_STOCK (cLabel, GLDI_ICON_NAME_MEDIA_NEXT, _cd_musicplayer_next, CD_APPLET_MY_MENU);
321 			g_free (cLabel);
322 		}
323 		if (myData.pCurrentHandler->iPlayerControls & PLAYER_STOP)
324 			CD_APPLET_ADD_IN_MENU_WITH_STOCK (D_("Stop"), GLDI_ICON_NAME_MEDIA_STOP, _cd_musicplayer_stop, CD_APPLET_MY_MENU);
325 
326 		CD_APPLET_ADD_SEPARATOR_IN_MENU (CD_APPLET_MY_MENU);  // on n'a jamais zero action, donc on met toujours un separateur.
327 
328 		CD_APPLET_ADD_IN_MENU_WITH_STOCK (D_("Information"), GLDI_ICON_NAME_INFO, _cd_musicplayer_info, CD_APPLET_MY_MENU);
329 
330 		CD_APPLET_ADD_SEPARATOR_IN_MENU (CD_APPLET_MY_MENU);
331 
332 		if (myData.pCurrentHandler->iPlayerControls & PLAYER_JUMPBOX)
333 			CD_APPLET_ADD_IN_MENU (D_("Show JumpBox"), _cd_musicplayer_jumpbox, CD_APPLET_MY_MENU);
334 		if (myData.pCurrentHandler->iPlayerControls & PLAYER_SHUFFLE)
335 		{
336 			pMenuItem = gtk_check_menu_item_new_with_label (D_("Shuffle"));
337 			gboolean bIsShuffle = (myData.pCurrentHandler->get_shuffle_status ? myData.pCurrentHandler->get_shuffle_status() : FALSE);
338 			gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (pMenuItem), bIsShuffle);
339 			gtk_menu_shell_append  (GTK_MENU_SHELL (CD_APPLET_MY_MENU), pMenuItem);
340 			g_signal_connect (G_OBJECT (pMenuItem), "toggled", G_CALLBACK (_cd_musicplayer_shuffle), NULL);
341 		}
342 		if (myData.pCurrentHandler->iPlayerControls & PLAYER_REPEAT)
343 		{
344 			pMenuItem = gtk_check_menu_item_new_with_label (D_("Repeat"));
345 			gboolean bIsLoop = (myData.pCurrentHandler->get_loop_status ? myData.pCurrentHandler->get_loop_status() : FALSE);
346 			gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (pMenuItem), bIsLoop);
347 			gtk_menu_shell_append  (GTK_MENU_SHELL (CD_APPLET_MY_MENU), pMenuItem);
348 			g_signal_connect (G_OBJECT (pMenuItem), "toggled", G_CALLBACK (_cd_musicplayer_repeat), NULL);
349 		}
350 
351 		if (myData.pCurrentHandler->iPlayerControls & PLAYER_RATE)
352 			CD_APPLET_ADD_IN_MENU (D_("Rate this song"), _cd_musicplayer_rate, CD_APPLET_MY_MENU);
353 
354 		if (myIcon->pAppli == NULL)  // player in the systray.
355 		{
356 			CD_APPLET_ADD_IN_MENU_WITH_STOCK (D_("Show"), GLDI_ICON_NAME_FIND, _cd_musicplayer_show_from_systray, CD_APPLET_MY_MENU);
357 			CD_APPLET_ADD_IN_MENU_WITH_STOCK (D_("Quit"), GLDI_ICON_NAME_CLOSE, _cd_musicplayer_quit, CD_APPLET_MY_MENU);  // GLDI_ICON_NAME_QUIT looks too much like the "quit" of the dock.
358 		}
359 	}
360 CD_APPLET_ON_BUILD_MENU_END
361 
362 
363 CD_APPLET_ON_MIDDLE_CLICK_BEGIN
364 	if (myData.pCurrentHandler != NULL)
365 	{
366 		if (myConfig.bPauseOnClick)
367 		{
368 			_cd_musicplayer_next (NULL, NULL);
369 		}
370 		else
371 		{
372 			_cd_musicplayer_pp (NULL, NULL);
373 		}
374 	}
375 	else
376 	{
377 		_show_players_list_dialog ();
378 	}
379 CD_APPLET_ON_MIDDLE_CLICK_END
380 
381 
382 CD_APPLET_ON_DROP_DATA_BEGIN
383 	cd_message (" %s --> nouvelle pochette ou chanson !", CD_APPLET_RECEIVED_DATA);
384 
385 	if (myData.pCurrentHandler != NULL)
386 	{
387 			gboolean isJpeg = g_str_has_suffix(CD_APPLET_RECEIVED_DATA,"jpg")
388 			|| g_str_has_suffix(CD_APPLET_RECEIVED_DATA,"JPG")
389 			|| g_str_has_suffix(CD_APPLET_RECEIVED_DATA,"jpeg")
390 			|| g_str_has_suffix(CD_APPLET_RECEIVED_DATA,"JPEG");
391 
392 		if (isJpeg)
393 		{
394 			if (myData.cArtist != NULL && myData.cAlbum != NULL/* && myData.pCurrentHandler->cCoverDir != NULL*/)
395 			{
396 				cd_debug ("MP - Le fichier est un JPEG");
397 				gchar *cDirPath = myData.pCurrentHandler->cCoverDir ? g_strdup (myData.pCurrentHandler->cCoverDir) : g_strdup_printf("%s/musicplayer", g_cCairoDockDataDir);
398 				gchar *cCommand, *cHost = NULL;
399 				gchar *cFilePath = (*CD_APPLET_RECEIVED_DATA == '/' ? g_strdup (CD_APPLET_RECEIVED_DATA) : g_filename_from_uri (CD_APPLET_RECEIVED_DATA, &cHost, NULL));
400 				if (cHost != NULL)  // fichier distant, on le telecharge dans le cache du lecteur.
401 				{
402 					cd_debug ("MP - Le fichier est distant (sur %s)", cHost);
403 					cCommand = g_strdup_printf ("wget -O \"%s/%s - %s.jpg\" '%s'",
404 						cDirPath,
405 						myData.cArtist,
406 						myData.cAlbum,
407 						CD_APPLET_RECEIVED_DATA);
408 				}
409 				else  // fichier local, on le copie juste dans le cache du lecteur.
410 				{
411 					cd_debug ("MP - Le fichier est local");
412 					cCommand = g_strdup_printf ("cp \"%s\" \"%s/%s - %s.jpg\"",
413 						cFilePath,
414 						cDirPath,
415 						myData.cArtist,
416 						myData.cAlbum);
417 				}
418 				cd_debug ("MP - on recupere la pochette par : '%s'", cCommand);
419 				cairo_dock_launch_command (cCommand);
420 				g_free (cCommand);
421 				g_free (cFilePath);
422 				g_free (cHost);
423 				g_free (cDirPath);
424 
425 				cd_musicplayer_set_cover_path (NULL);
426 				cd_musicplayer_update_icon ();
427 			}
428 		}
429 		else
430 		{
431 			cd_debug ("MP - on rajoute la chanson a la queue.");
432 			myData.pCurrentHandler->control (PLAYER_ENQUEUE, CD_APPLET_RECEIVED_DATA);
433 		}
434 	}
435 	else
436 	{
437 		_show_players_list_dialog ();
438 	}
439 CD_APPLET_ON_DROP_DATA_END
440 
441 
442 CD_APPLET_ON_SCROLL_BEGIN
443 	if (myData.pCurrentHandler != NULL)
444 	{
445 		if (myConfig.bNextPrevOnScroll)
446 		{
447 			if (CD_APPLET_SCROLL_DOWN)
448   				_cd_musicplayer_next (NULL, NULL);
449 			else if (CD_APPLET_SCROLL_UP)
450   				_cd_musicplayer_prev (NULL, NULL);
451 		}
452 		else if (myData.pCurrentHandler->iPlayerControls & PLAYER_VOLUME)
453 		{
454 			if (CD_APPLET_SCROLL_DOWN)
455 				myData.pCurrentHandler->control (PLAYER_VOLUME, "down");
456 			else if (CD_APPLET_SCROLL_UP)
457   				myData.pCurrentHandler->control (PLAYER_VOLUME, "up");
458 		}
459 		else
460 			cd_warning ("can't control the volume with the player '%s'", myData.pCurrentHandler->name);
461 	}
462 	else
463 	{
464 		_show_players_list_dialog ();
465 	}
466 CD_APPLET_ON_SCROLL_END
467 
468 
469 #define _update_button_count(on, count) \
470 	if (on) {\
471 		if (count < NB_TRANSITION_STEP) {\
472 			count ++;\
473 			bNeedsUpdate = TRUE; } }\
474 	else if (count != 0) {\
475 		count --;\
476 		bNeedsUpdate = TRUE; }
477 
478 CD_APPLET_ON_UPDATE_ICON_BEGIN
479 
480 	gboolean bNeedsUpdate = FALSE;
481 
482 	if (myData.iCoverTransition > 0)
483 	{
484 		myData.iCoverTransition --;
485 		bNeedsUpdate = TRUE;
486 	}
487 
488 	_update_button_count (myData.mouseOnButton1, myData.iButton1Count);
489 	_update_button_count (myData.mouseOnButton2, myData.iButton2Count);
490 	_update_button_count (myData.mouseOnButton3, myData.iButton3Count);
491 	_update_button_count (myData.mouseOnButton4, myData.iButton4Count);
492 
493 	if (! bNeedsUpdate)
494 		CD_APPLET_STOP_UPDATE_ICON;  // quit.
495 
496 	cd_opengl_render_to_texture (myApplet);
497 
498 	if ((myData.iCoverTransition == 0) &&
499 		(myData.iButton1Count == 0 || myData.iButton1Count == NB_TRANSITION_STEP) &&
500 		(myData.iButton2Count == 0 || myData.iButton2Count == NB_TRANSITION_STEP) &&
501 		(myData.iButton3Count == 0 || myData.iButton3Count == NB_TRANSITION_STEP) &&
502 		(myData.iButton4Count == 0 || myData.iButton4Count == NB_TRANSITION_STEP))
503 	{
504 		CD_APPLET_PAUSE_UPDATE_ICON;  // redraw and stop.
505 	}
506 
507 CD_APPLET_ON_UPDATE_ICON_END
508 
509 
cd_opengl_test_mouse_over_buttons(GldiModuleInstance * myApplet,GldiContainer * pContainer,gboolean * bStartAnimation)510 gboolean cd_opengl_test_mouse_over_buttons (GldiModuleInstance *myApplet, GldiContainer *pContainer, gboolean *bStartAnimation)
511 {
512 	CD_APPLET_ENTER;
513 	int iPrevButtonState = myData.iButtonState;
514 	myData.iButtonState = cd_opengl_check_buttons_state (myApplet);
515 
516 	if (iPrevButtonState != myData.iButtonState)
517 	{
518 		*bStartAnimation = TRUE;  // ca c'est pour faire une animation de transition...
519 	}
520 	CD_APPLET_LEAVE (GLDI_NOTIFICATION_LET_PASS);
521 }
522