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 
22 #include "applet-config.h"
23 #include "applet-struct.h"
24 #include "applet-notifications.h"
25 #include "applet-fire.h"
26 #include "applet-star.h"
27 #include "applet-rain.h"
28 #include "applet-snow.h"
29 #include "applet-storm.h"
30 #include "applet-firework.h"
31 #include "applet-init.h"
32 
33 
34 CD_APPLET_DEFINE_BEGIN (N_("icon effects"),
35 	2, 0, 0,
36 	CAIRO_DOCK_CATEGORY_THEME,
37 	N_("This plugin adds many special effects to your icons."),
38 	"Fabounet (Fabrice Rey)")
39 	if (! g_bUseOpenGL)
40 		return FALSE;
41 	CD_APPLET_DEFINE_COMMON_APPLET_INTERFACE;
42 	CD_APPLET_SET_CONTAINER_TYPE (CAIRO_DOCK_MODULE_IS_PLUGIN);
43 CD_APPLET_DEFINE_END
44 
_set_effects_duration(void)45 static inline void _set_effects_duration (void)
46 {
47 	myData.pEffects[CD_ICON_EFFECT_FIRE].iDuration = myConfig.iFireDuration;
48 	myData.pEffects[CD_ICON_EFFECT_FIRE].bRepeat = myConfig.bContinueFire;
49 
50 	myData.pEffects[CD_ICON_EFFECT_STARS].iDuration = myConfig.iStarDuration;
51 	myData.pEffects[CD_ICON_EFFECT_STARS].bRepeat = myConfig.bContinueStar;
52 
53 	myData.pEffects[CD_ICON_EFFECT_RAIN].iDuration = myConfig.iRainDuration;
54 	myData.pEffects[CD_ICON_EFFECT_RAIN].bRepeat = myConfig.bContinueRain;
55 
56 	myData.pEffects[CD_ICON_EFFECT_SNOW].iDuration = myConfig.iSnowDuration;
57 	myData.pEffects[CD_ICON_EFFECT_SNOW].bRepeat = myConfig.bContinueSnow;
58 
59 	myData.pEffects[CD_ICON_EFFECT_SAND].iDuration = myConfig.iStormDuration;
60 	myData.pEffects[CD_ICON_EFFECT_SAND].bRepeat = myConfig.bContinueStorm;
61 
62 	myData.pEffects[CD_ICON_EFFECT_FIREWORK].iDuration = myConfig.iFireworkDuration;
63 	myData.pEffects[CD_ICON_EFFECT_FIREWORK].bRepeat = myConfig.bContinueFirework;
64 }
65 
66 //\___________ Here is where you initiate your applet. myConfig is already set at this point, and also myIcon, myContainer, myDock, myDesklet (and myDrawContext if you're in dock mode). The macro CD_APPLET_MY_CONF_FILE and CD_APPLET_MY_KEY_FILE can give you access to the applet's conf-file and its corresponding key-file (also available during reload). If you're in desklet mode, myDrawContext is still NULL, and myIcon's buffers has not been filled, because you may not need them then (idem when reloading).
67 CD_APPLET_INIT_BEGIN
68 	if (! g_bUseOpenGL || ! CD_APPLET_RESERVE_DATA_SLOT ())
69 		return;
70 
71 	gldi_object_register_notification (&myContainerObjectMgr,
72 		NOTIFICATION_ENTER_ICON,
73 		(GldiNotificationFunc) cd_icon_effect_on_enter,
74 		GLDI_RUN_AFTER, NULL);
75 	gldi_object_register_notification (&myContainerObjectMgr,
76 		NOTIFICATION_CLICK_ICON,
77 		(GldiNotificationFunc) cd_icon_effect_on_click,
78 		GLDI_RUN_FIRST, NULL);
79 	gldi_object_register_notification (&myIconObjectMgr,
80 		NOTIFICATION_REQUEST_ICON_ANIMATION,
81 		(GldiNotificationFunc) cd_icon_effect_on_request,
82 		GLDI_RUN_FIRST, NULL);
83 	gldi_object_register_notification (&myIconObjectMgr,
84 		NOTIFICATION_UPDATE_ICON,
85 		(GldiNotificationFunc) cd_icon_effect_update_icon,
86 		GLDI_RUN_AFTER, NULL);
87 	gldi_object_register_notification (&myIconObjectMgr,
88 		NOTIFICATION_PRE_RENDER_ICON,
89 		(GldiNotificationFunc) cd_icon_effect_pre_render_icon,
90 		GLDI_RUN_AFTER, NULL);
91 	gldi_object_register_notification (&myIconObjectMgr,
92 		NOTIFICATION_RENDER_ICON,
93 		(GldiNotificationFunc) cd_icon_effect_render_icon,
94 		GLDI_RUN_AFTER, NULL);
95 	gldi_object_register_notification (&myIconObjectMgr,
96 		NOTIFICATION_STOP_ICON,
97 		(GldiNotificationFunc) cd_icon_effect_free_data,
98 		GLDI_RUN_AFTER, NULL);
99 
100 	cd_icon_effect_register_fire (&myData.pEffects[CD_ICON_EFFECT_FIRE]);
101 	myData.iAnimationID[CD_ICON_EFFECT_FIRE] = cairo_dock_register_animation ("fire", D_("Fire"), TRUE);
102 
103 	cd_icon_effect_register_stars (&myData.pEffects[CD_ICON_EFFECT_STARS]);
104 	myData.iAnimationID[CD_ICON_EFFECT_STARS] = cairo_dock_register_animation ("stars", D_("Stars"), TRUE);
105 
106 	cd_icon_effect_register_rain (&myData.pEffects[CD_ICON_EFFECT_RAIN]);
107 	myData.iAnimationID[CD_ICON_EFFECT_RAIN] = cairo_dock_register_animation ("rain", D_("Rain"), TRUE);
108 
109 	cd_icon_effect_register_snow (&myData.pEffects[CD_ICON_EFFECT_SNOW]);
110 	myData.iAnimationID[CD_ICON_EFFECT_SNOW] = cairo_dock_register_animation ("snow", D_("Snow"), TRUE);
111 
112 	cd_icon_effect_register_storm (&myData.pEffects[CD_ICON_EFFECT_SAND]);
113 	myData.iAnimationID[CD_ICON_EFFECT_SAND] = cairo_dock_register_animation ("storm", D_("Storm"), TRUE);
114 
115 	cd_icon_effect_register_firework (&myData.pEffects[CD_ICON_EFFECT_FIREWORK]);
116 	myData.iAnimationID[CD_ICON_EFFECT_FIREWORK] = cairo_dock_register_animation ("firework", D_("Firework"), TRUE);
117 
118 	_set_effects_duration ();
119 CD_APPLET_INIT_END
120 
121 
_free_data_on_icon(Icon * pIcon,G_GNUC_UNUSED gpointer data)122 static void _free_data_on_icon (Icon *pIcon, G_GNUC_UNUSED gpointer data)
123 {
124 	cd_icon_effect_free_data (NULL, pIcon);
125 }
126 //\___________ Here is where you stop your applet. myConfig and myData are still valid, but will be reseted to 0 at the end of the function. In the end, your applet will go back to its original state, as if it had never been activated.
127 CD_APPLET_STOP_BEGIN
128 	gldi_object_remove_notification (&myContainerObjectMgr,
129 		NOTIFICATION_ENTER_ICON,
130 		(GldiNotificationFunc) cd_icon_effect_on_enter, NULL);
131 	gldi_object_remove_notification (&myContainerObjectMgr,
132 		NOTIFICATION_CLICK_ICON,
133 		(GldiNotificationFunc) cd_icon_effect_on_click, NULL);
134 	gldi_object_remove_notification (&myIconObjectMgr,
135 		NOTIFICATION_REQUEST_ICON_ANIMATION,
136 		(GldiNotificationFunc) cd_icon_effect_on_request, NULL);
137 	gldi_object_remove_notification (&myIconObjectMgr,
138 		NOTIFICATION_UPDATE_ICON,
139 		(GldiNotificationFunc) cd_icon_effect_update_icon, NULL);
140 	gldi_object_remove_notification (&myIconObjectMgr,
141 		NOTIFICATION_PRE_RENDER_ICON,
142 		(GldiNotificationFunc) cd_icon_effect_pre_render_icon, NULL);
143 	gldi_object_remove_notification (&myIconObjectMgr,
144 		NOTIFICATION_RENDER_ICON,
145 		(GldiNotificationFunc) cd_icon_effect_render_icon, NULL);
146 	gldi_object_remove_notification (&myIconObjectMgr,
147 		NOTIFICATION_STOP_ICON,
148 		(GldiNotificationFunc) cd_icon_effect_free_data, NULL);
149 
150 	cairo_dock_unregister_animation ("fire");
151 	cairo_dock_unregister_animation ("stars");
152 	cairo_dock_unregister_animation ("rain");
153 	cairo_dock_unregister_animation ("snow");
154 	cairo_dock_unregister_animation ("storm");
155 	cairo_dock_unregister_animation ("firework");
156 
157 	gldi_icons_foreach ((GldiIconFunc)_free_data_on_icon, NULL);
158 CD_APPLET_STOP_END
159 
160 
161 //\___________ The reload occurs in 2 occasions : when the user changes the applet's config, and when the user reload the cairo-dock's config or modify the desklet's size. The macro CD_APPLET_MY_CONFIG_CHANGED can tell you this. myConfig has already been reloaded at this point if you're in the first case, myData is untouched. You also have the macro CD_APPLET_MY_CONTAINER_TYPE_CHANGED that can tell you if you switched from dock/desklet to desklet/dock mode.
_effect_is_used_in_table(CDIconEffectsEnum iEffect,CDIconEffectsEnum * pEffectList)162 static gboolean _effect_is_used_in_table (CDIconEffectsEnum iEffect, CDIconEffectsEnum *pEffectList)
163 {
164 	int i;
165 	for (i = 0; i < CD_ICON_EFFECT_NB_EFFECTS; i ++)
166 	{
167 		if (pEffectList[i] == iEffect)
168 			return TRUE;
169 		else if (myConfig.iEffectsUsed[i] >= CD_ICON_EFFECT_NB_EFFECTS)
170 			break ;
171 	}
172 	return FALSE;
173 }
_effect_is_used(CDIconEffectsEnum iEffect)174 static gboolean _effect_is_used (CDIconEffectsEnum iEffect)
175 {
176 	gboolean bUsed;
177 	bUsed = _effect_is_used_in_table (iEffect, myConfig.iEffectsUsed);
178 	if (bUsed)
179 		return TRUE;
180 	bUsed = _effect_is_used_in_table (iEffect, myConfig.iEffectsOnClick[CAIRO_DOCK_LAUNCHER]);
181 	if (bUsed)
182 		return TRUE;
183 	bUsed = _effect_is_used_in_table (iEffect, myConfig.iEffectsOnClick[CAIRO_DOCK_APPLI]);
184 	return bUsed;
185 }
186 CD_APPLET_RELOAD_BEGIN
187 	if (CD_APPLET_MY_CONFIG_CHANGED)
188 	{
189 		if (myData.iFireTexture != 0 && ! _effect_is_used (CD_ICON_EFFECT_FIRE) && ! _effect_is_used (CD_ICON_EFFECT_SAND) && ! _effect_is_used (CD_ICON_EFFECT_FIREWORK))
190 		{
191 			glDeleteTextures (1, &myData.iFireTexture);
192 			myData.iFireTexture = 0;
193 		}
194 		if (myData.iStarTexture != 0 && ! _effect_is_used (CD_ICON_EFFECT_STARS))
195 		{
196 			glDeleteTextures (1, &myData.iStarTexture);
197 			myData.iStarTexture = 0;
198 		}
199 		if (myData.iSnowTexture != 0 && ! _effect_is_used (CD_ICON_EFFECT_SNOW))
200 		{
201 			glDeleteTextures (1, &myData.iSnowTexture);
202 			myData.iSnowTexture = 0;
203 		}
204 		if (myData.iRainTexture != 0 && ! _effect_is_used (CD_ICON_EFFECT_RAIN))
205 		{
206 			glDeleteTextures (1, &myData.iRainTexture);
207 			myData.iRainTexture = 0;
208 		}
209 
210 		_set_effects_duration ();
211 	}
212 CD_APPLET_RELOAD_END
213