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);
73 for (it = list_top(d->fades); it; it = it->next) {
74 fade_t *fade = it->data;
75 window_set_opacity(fade->w, 0xffff);
76 window_zombie_unref(fade->w);
77 window_unref(fade->w);
86 fade_window_show(d_window_t *w)
91 d = screen_find_plugin_data(w->sc, plugin_id);
93 /* kill the zombies off cuz a new copy is being shown */
94 for (it = list_top(d->fades); it; it = it->next) {
95 fade_t *fade = it->data;
97 window_zombie_unref(w);
105 if (!window_is_input_only(w) && dcompmgr_running()) {
106 d_window_type_t type = window_get_type(w);
107 if (WINDOW_TYPE_FADE(type))
108 start_fade(w, 0x2000, 0xffff, TRUE);
113 fade_window_hide(d_window_t *w)
117 if (!window_is_input_only(w) && dcompmgr_running()) {
118 d_window_type_t type = window_get_type(w);
119 if (WINDOW_TYPE_FADE(type))
120 start_fade(w, 0xffff, 0x0002, FALSE);
123 d = screen_find_plugin_data(w->sc, plugin_id);
128 start_fade(d_window_t *w, uint16_t start_alpha, uint16_t end_alpha,
137 d = screen_find_plugin_data(w->sc, plugin_id);
138 gettimeofday(&now, NULL);
140 if (list_length(d->fades) == 0) {
141 d->next_timeout = now;
142 time_add(&d->next_timeout, d->fade_step_time);
145 /* look for an existing one */
147 for (it = list_top(d->fades); it; it = it->next) {
149 if (fade->w == w) break;
152 fade = malloc(sizeof(fade_t));
154 list_append(d->fades, fade);
160 fade->start_alpha = start_alpha;
161 fade->end_alpha = end_alpha;
164 fade->start_time = now;
165 fade->end_time = now;
166 time_add(&fade->end_time, d->fade_total_time);
167 fade->current_alpha = start_alpha;
169 window_set_opacity(w, fade->current_alpha);
172 /* figure out how far we have to go to finish the fade from where
173 we are from the previous fade */
177 total = ABS(fade->end_alpha - fade->start_alpha);
178 remain = ABS(fade->current_alpha - fade->end_alpha);
179 percent = (double)remain / total;
181 //printf("start %d end %d current %d\n", fade->start, fade->end,
183 //printf("remain %lu total %lu percent %f\n", remain, total, percent);
185 fade->start_time = now;
186 time_add(&fade->start_time, -(1-percent)*d->fade_total_time);
187 fade->end_time = now;
188 time_add(&fade->end_time, percent*d->fade_total_time);
190 if (newfade || refalways) {
191 window_zombie_ref(w);
197 fade_next_timeout(struct d_screen *sc, struct timeval *tv)
201 d = screen_find_plugin_data(sc, plugin_id);
203 if (!d || list_length(d->fades) == 0)
206 *tv = d->next_timeout;
212 fade_timeout(struct d_screen *sc, const struct timeval *now)
215 d_list_it_t *it, *next;
217 d = screen_find_plugin_data(sc, plugin_id);
219 for (it = list_top(d->fades); it; it = next) {
220 fade_t *fade = it->data;
224 if (time_compare(&fade->end_time, now) <= 0) {
226 fade->current_alpha = fade->end_alpha;
229 struct timeval total_time, time_left;
230 unsigned long remain, total;
233 time_difference(&fade->end_time, now, &time_left);
234 time_difference(&fade->end_time, &fade->start_time, &total_time);
237 /* count milliseconds */
238 remain = time_left.tv_sec * 1000 + time_left.tv_usec / 1000;
239 total = total_time.tv_sec * 1000 + total_time.tv_usec / 1000;
240 percent = (double)remain / total;
242 //printf("done %lu total %lu percent %f\n", done, total, percent);
244 if (fade->end_alpha > fade->start_alpha)
246 fade->current_alpha = fade->end_alpha -
247 (fade->end_alpha - fade->start_alpha) * percent;
250 fade->current_alpha = fade->end_alpha +
251 (fade->start_alpha - fade->end_alpha) * percent;
254 window_set_opacity(fade->w, fade->current_alpha);
256 if (fade->current_alpha == fade->end_alpha) {
257 list_delete_link(d->fades, it);
258 window_zombie_unref(fade->w);
259 window_unref(fade->w);
264 d->next_timeout = *now;
265 time_add(&d->next_timeout, d->fade_step_time);