12 #include <xcb/render.h>
17 void (*window_show)(d_window_t *w);
18 void (*window_hide)(d_window_t *w);
21 // unsigned int fade_step_size;
22 unsigned int fade_step_time;
23 unsigned int fade_total_time;
25 struct timeval next_timeout;
32 uint16_t current_alpha;
33 struct timeval start_time;
34 struct timeval end_time;
37 static void fade_window_show(d_window_t *w);
38 static void fade_window_hide(d_window_t *w);
39 static void start_fade(d_window_t *w, uint16_t start, uint16_t end);
42 fade_init(d_screen_t *sc, int id)
46 data_t *d = malloc(sizeof(data_t));
47 d->window_show = sc->window_show;
48 d->window_hide = sc->window_hide;
49 screen_add_plugin_data(sc, plugin_id, d);
51 sc->window_show = fade_window_show;
52 sc->window_hide = fade_window_hide;
54 d->fades = list_new();
55 d->fade_step_time = 5000; /* 5 milliseconds */
56 d->fade_total_time = 166000; /* 0.15 seconds */
60 fade_free(d_screen_t *sc)
65 d = screen_find_plugin_data(sc, plugin_id);
66 screen_remove_plugin_data(sc, plugin_id);
68 for (it = list_top(d->fades); it; it = it->next) {
69 fade_t *fade = it->data;
70 window_set_opacity(fade->w, 0xffff);
71 window_zombie_unref(fade->w);
72 window_unref(fade->w);
80 fade_window_show(d_window_t *w)
84 if (!window_is_input_only(w))
85 start_fade(w, 0x0000, 0xffff);
87 d = screen_find_plugin_data(w->sc, plugin_id);
92 fade_window_hide(d_window_t *w)
96 if (!window_is_input_only(w))
97 start_fade(w, 0xffff, 0x0000);
99 d = screen_find_plugin_data(w->sc, plugin_id);
104 start_fade(d_window_t *w, uint16_t start_alpha, uint16_t end_alpha)
112 d = screen_find_plugin_data(w->sc, plugin_id);
113 gettimeofday(&now, NULL);
115 if (list_length(d->fades) == 0) {
116 d->next_timeout = now;
117 time_add(&d->next_timeout, d->fade_step_time);
120 /* look for an existing one */
122 for (it = list_top(d->fades); it; it = it->next) {
124 if (fade->w == w) break;
127 fade = malloc(sizeof(fade_t));
129 list_append(d->fades, fade);
135 fade->start_alpha = start_alpha;
136 fade->end_alpha = end_alpha;
139 fade->start_time = now;
140 fade->end_time = now;
141 time_add(&fade->end_time, d->fade_total_time);
142 fade->current_alpha = start_alpha;
144 window_set_opacity(w, fade->current_alpha);
147 window_zombie_ref(w);
150 /* figure out how far we have to go to finish the fade from where
151 we are from the previous fade */
155 total = ABS(fade->end_alpha - fade->start_alpha);
156 remain = ABS(fade->current_alpha - fade->end_alpha);
157 percent = (double)remain / total;
159 //printf("start %d end %d current %d\n", fade->start, fade->end,
161 //printf("remain %lu total %lu percent %f\n", remain, total, percent);
163 fade->start_time = now;
164 time_add(&fade->start_time, -(1-percent)*d->fade_total_time);
165 fade->end_time = now;
166 time_add(&fade->end_time, percent*d->fade_total_time);
171 fade_next_timeout(struct d_screen *sc, struct timeval *tv)
175 d = screen_find_plugin_data(sc, plugin_id);
177 if (list_length(d->fades) == 0)
180 *tv = d->next_timeout;
186 fade_timeout(struct d_screen *sc, const struct timeval *now)
189 d_list_it_t *it, *next;
191 d = screen_find_plugin_data(sc, plugin_id);
193 for (it = list_top(d->fades); it; it = next) {
194 fade_t *fade = it->data;
198 if (time_compare(&fade->end_time, now) <= 0) {
200 fade->current_alpha = fade->end_alpha;
203 struct timeval total_time, time_left;
204 unsigned long remain, total;
207 time_difference(&fade->end_time, now, &time_left);
208 time_difference(&fade->end_time, &fade->start_time, &total_time);
211 /* count milliseconds */
212 remain = time_left.tv_sec * 1000 + time_left.tv_usec / 1000;
213 total = total_time.tv_sec * 1000 + total_time.tv_usec / 1000;
214 percent = (double)remain / total;
216 //printf("done %lu total %lu percent %f\n", done, total, percent);
218 if (fade->end_alpha > fade->start_alpha)
220 fade->current_alpha = fade->end_alpha -
221 (fade->end_alpha - fade->start_alpha) * percent;
224 fade->current_alpha = fade->end_alpha +
225 (fade->start_alpha - fade->end_alpha) * percent;
228 window_set_opacity(fade->w, fade->current_alpha);
230 if (fade->current_alpha == fade->end_alpha) {
231 list_delete_link(d->fades, it);
232 window_zombie_unref(fade->w);
233 window_unref(fade->w);
238 d->next_timeout = *now;
239 time_add(&d->next_timeout, d->fade_step_time);