13 #include <xcb/render.h>
17 #define WINDOW_TYPE_FADE(t) (t != DC_WINDOW_TYPE_DESKTOP)
20 void (*window_show)(d_window_t *w);
21 void (*window_hide)(d_window_t *w);
24 // unsigned int fade_step_size;
25 unsigned int fade_step_time;
26 unsigned int fade_total_time;
28 struct timeval next_timeout;
35 uint16_t current_alpha;
36 struct timeval start_time;
37 struct timeval end_time;
40 static void fade_window_show(d_window_t *w);
41 static void fade_window_hide(d_window_t *w);
42 static void start_fade(d_window_t *w, uint16_t start_alpha, uint16_t end_alpha,
46 fade_init(d_screen_t *sc, int id)
50 data_t *d = malloc(sizeof(data_t));
51 d->window_show = sc->window_show;
52 d->window_hide = sc->window_hide;
53 screen_add_plugin_data(sc, plugin_id, d);
55 sc->window_show = fade_window_show;
56 sc->window_hide = fade_window_hide;
58 d->fades = list_new();
59 d->fade_step_time = 15000; /* 15 milliseconds */
60 d->fade_total_time = 180000; /* 0.18 seconds */
64 fade_free(d_screen_t *sc)
69 d = screen_find_plugin_data(sc, plugin_id);
70 screen_remove_plugin_data(sc, plugin_id);
72 for (it = list_top(d->fades); it; it = it->next) {
73 fade_t *fade = it->data;
74 window_set_opacity(fade->w, 0xffff);
75 window_zombie_unref(fade->w);
76 window_unref(fade->w);
84 fade_window_show(d_window_t *w)
89 d = screen_find_plugin_data(w->sc, plugin_id);
91 /* kill the zombies off cuz a new copy is being shown */
92 for (it = list_top(d->fades); it; it = it->next) {
93 fade_t *fade = it->data;
95 window_zombie_unref(w);
103 if (!window_is_input_only(w) && dcompmgr_running()) {
104 d_window_type_t type = window_get_type(w);
105 if (WINDOW_TYPE_FADE(type))
106 start_fade(w, 0x2000, 0xffff, TRUE);
111 fade_window_hide(d_window_t *w)
115 if (!window_is_input_only(w) && dcompmgr_running()) {
116 d_window_type_t type = window_get_type(w);
117 if (WINDOW_TYPE_FADE(type))
118 start_fade(w, 0xffff, 0x0002, FALSE);
121 d = screen_find_plugin_data(w->sc, plugin_id);
126 start_fade(d_window_t *w, uint16_t start_alpha, uint16_t end_alpha,
135 d = screen_find_plugin_data(w->sc, plugin_id);
136 gettimeofday(&now, NULL);
138 if (list_length(d->fades) == 0) {
139 d->next_timeout = now;
140 time_add(&d->next_timeout, d->fade_step_time);
143 /* look for an existing one */
145 for (it = list_top(d->fades); it; it = it->next) {
147 if (fade->w == w) break;
150 fade = malloc(sizeof(fade_t));
152 list_append(d->fades, fade);
158 fade->start_alpha = start_alpha;
159 fade->end_alpha = end_alpha;
162 fade->start_time = now;
163 fade->end_time = now;
164 time_add(&fade->end_time, d->fade_total_time);
165 fade->current_alpha = start_alpha;
167 window_set_opacity(w, fade->current_alpha);
170 /* figure out how far we have to go to finish the fade from where
171 we are from the previous fade */
175 total = ABS(fade->end_alpha - fade->start_alpha);
176 remain = ABS(fade->current_alpha - fade->end_alpha);
177 percent = (double)remain / total;
179 //printf("start %d end %d current %d\n", fade->start, fade->end,
181 //printf("remain %lu total %lu percent %f\n", remain, total, percent);
183 fade->start_time = now;
184 time_add(&fade->start_time, -(1-percent)*d->fade_total_time);
185 fade->end_time = now;
186 time_add(&fade->end_time, percent*d->fade_total_time);
188 if (newfade || refalways) {
189 window_zombie_ref(w);
195 fade_next_timeout(struct d_screen *sc, struct timeval *tv)
199 d = screen_find_plugin_data(sc, plugin_id);
201 if (list_length(d->fades) == 0)
204 *tv = d->next_timeout;
210 fade_timeout(struct d_screen *sc, const struct timeval *now)
213 d_list_it_t *it, *next;
215 d = screen_find_plugin_data(sc, plugin_id);
217 for (it = list_top(d->fades); it; it = next) {
218 fade_t *fade = it->data;
222 if (time_compare(&fade->end_time, now) <= 0) {
224 fade->current_alpha = fade->end_alpha;
227 struct timeval total_time, time_left;
228 unsigned long remain, total;
231 time_difference(&fade->end_time, now, &time_left);
232 time_difference(&fade->end_time, &fade->start_time, &total_time);
235 /* count milliseconds */
236 remain = time_left.tv_sec * 1000 + time_left.tv_usec / 1000;
237 total = total_time.tv_sec * 1000 + total_time.tv_usec / 1000;
238 percent = (double)remain / total;
240 //printf("done %lu total %lu percent %f\n", done, total, percent);
242 if (fade->end_alpha > fade->start_alpha)
244 fade->current_alpha = fade->end_alpha -
245 (fade->end_alpha - fade->start_alpha) * percent;
248 fade->current_alpha = fade->end_alpha +
249 (fade->start_alpha - fade->end_alpha) * percent;
252 window_set_opacity(fade->w, fade->current_alpha);
254 if (fade->current_alpha == fade->end_alpha) {
255 list_delete_link(d->fades, it);
256 window_zombie_unref(fade->w);
257 window_unref(fade->w);
262 d->next_timeout = *now;
263 time_add(&d->next_timeout, d->fade_step_time);