Implement buffer.release event
[profile/ivi/weston.git] / compositor / compositor.c
1 /*
2  * Copyright © 2008 Kristian Høgsberg
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18
19 #define _GNU_SOURCE
20
21 #include "config.h"
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <stdint.h>
27 #include <limits.h>
28 #include <stdarg.h>
29 #include <sys/ioctl.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <math.h>
33 #include <linux/input.h>
34 #include <dlfcn.h>
35 #include <getopt.h>
36 #include <signal.h>
37
38 #include "wayland-server.h"
39 #include "compositor.h"
40
41 /* The plan here is to generate a random anonymous socket name and
42  * advertise that through a service on the session dbus.
43  */
44 static const char *option_socket_name = NULL;
45 static const char *option_background = "background.jpg";
46 static int option_idle_time = 300;
47
48 WL_EXPORT void
49 wlsc_matrix_init(struct wlsc_matrix *matrix)
50 {
51         static const struct wlsc_matrix identity = {
52                 { 1, 0, 0, 0,  0, 1, 0, 0,  0, 0, 1, 0,  0, 0, 0, 1 }
53         };
54
55         memcpy(matrix, &identity, sizeof identity);
56 }
57
58 static void
59 wlsc_matrix_multiply(struct wlsc_matrix *m, const struct wlsc_matrix *n)
60 {
61         struct wlsc_matrix tmp;
62         const GLfloat *row, *column;
63         div_t d;
64         int i, j;
65
66         for (i = 0; i < 16; i++) {
67                 tmp.d[i] = 0;
68                 d = div(i, 4);
69                 row = m->d + d.quot * 4;
70                 column = n->d + d.rem;
71                 for (j = 0; j < 4; j++)
72                         tmp.d[i] += row[j] * column[j * 4];
73         }
74         memcpy(m, &tmp, sizeof tmp);
75 }
76
77 WL_EXPORT void
78 wlsc_matrix_translate(struct wlsc_matrix *matrix, GLfloat x, GLfloat y, GLfloat z)
79 {
80         struct wlsc_matrix translate = {
81                 { 1, 0, 0, 0,  0, 1, 0, 0,  0, 0, 1, 0,  x, y, z, 1 }
82         };
83
84         wlsc_matrix_multiply(matrix, &translate);
85 }
86
87 WL_EXPORT void
88 wlsc_matrix_scale(struct wlsc_matrix *matrix, GLfloat x, GLfloat y, GLfloat z)
89 {
90         struct wlsc_matrix scale = {
91                 { x, 0, 0, 0,  0, y, 0, 0,  0, 0, z, 0,  0, 0, 0, 1 }
92         };
93
94         wlsc_matrix_multiply(matrix, &scale);
95 }
96
97 static void
98 wlsc_matrix_transform(struct wlsc_matrix *matrix, struct wlsc_vector *v)
99 {
100         int i, j;
101         struct wlsc_vector t;
102
103         for (i = 0; i < 4; i++) {
104                 t.f[i] = 0;
105                 for (j = 0; j < 4; j++)
106                         t.f[i] += v->f[j] * matrix->d[i + j * 4];
107         }
108
109         *v = t;
110 }
111
112 WL_EXPORT void
113 wlsc_spring_init(struct wlsc_spring *spring,
114                  double k, double current, double target)
115 {
116         spring->k = k;
117         spring->friction = 100.0;
118         spring->current = current;
119         spring->previous = current;
120         spring->target = target;
121 }
122
123 WL_EXPORT void
124 wlsc_spring_update(struct wlsc_spring *spring, uint32_t msec)
125 {
126         double force, v, current, step;
127
128         step = (msec - spring->timestamp) / 300.0;
129         spring->timestamp = msec;
130
131         current = spring->current;
132         v = current - spring->previous;
133         force = spring->k * (spring->target - current) / 10.0 +
134                 (spring->previous - current) - v * spring->friction;
135
136         spring->current =
137                 current + (current - spring->previous) + force * step * step;
138         spring->previous = current;
139
140 #if 0
141         if (spring->current >= 1.0) {
142 #ifdef TWEENER_BOUNCE
143                 spring->current = 2.0 - spring->current;
144                 spring->previous = 2.0 - spring->previous;
145 #else
146                 spring->current = 1.0;
147                 spring->previous = 1.0;
148 #endif
149         }
150
151         if (spring->current <= 0.0) {
152                 spring->current = 0.0;
153                 spring->previous = 0.0;
154         }
155 #endif
156 }
157
158 WL_EXPORT int
159 wlsc_spring_done(struct wlsc_spring *spring)
160 {
161         return fabs(spring->previous - spring->target) < 0.0002 &&
162                 fabs(spring->current - spring->target) < 0.0002;
163 }
164
165 static void
166 surface_handle_buffer_destroy(struct wl_listener *listener,
167                               struct wl_resource *resource, uint32_t time)
168 {
169         struct wlsc_surface *es = container_of(listener, struct wlsc_surface,
170                                                buffer_destroy_listener);
171         struct wl_buffer *buffer = (struct wl_buffer *) resource;
172
173         if (es->buffer == buffer)
174                 es->buffer = NULL;
175 }
176
177 static void
178 output_handle_scanout_buffer_destroy(struct wl_listener *listener,
179                                      struct wl_resource *resource,
180                                      uint32_t time)
181 {
182         struct wlsc_output *output =
183                 container_of(listener, struct wlsc_output,
184                              scanout_buffer_destroy_listener);
185         struct wl_buffer *buffer = (struct wl_buffer *) resource;
186
187         if (output->scanout_buffer == buffer)
188                 output->scanout_buffer = NULL;
189 }
190
191 WL_EXPORT struct wlsc_surface *
192 wlsc_surface_create(struct wlsc_compositor *compositor,
193                     int32_t x, int32_t y, int32_t width, int32_t height)
194 {
195         struct wlsc_surface *surface;
196
197         surface = malloc(sizeof *surface);
198         if (surface == NULL)
199                 return NULL;
200
201         wl_list_init(&surface->link);
202         wl_list_init(&surface->buffer_link);
203         surface->map_type = WLSC_SURFACE_MAP_UNMAPPED;
204
205         glGenTextures(1, &surface->texture);
206         glBindTexture(GL_TEXTURE_2D, surface->texture);
207         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
208         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
209         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
210         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
211
212         surface->compositor = compositor;
213         surface->visual = NULL;
214         surface->image = EGL_NO_IMAGE_KHR;
215         surface->saved_texture = 0;
216         surface->x = x;
217         surface->y = y;
218         surface->width = width;
219         surface->height = height;
220
221         surface->buffer = NULL;
222
223         surface->buffer_destroy_listener.func = surface_handle_buffer_destroy;
224         wl_list_init(&surface->buffer_destroy_listener.link);
225
226         surface->transform = NULL;
227
228         return surface;
229 }
230
231 WL_EXPORT void
232 wlsc_surface_damage_rectangle(struct wlsc_surface *surface,
233                               int32_t x, int32_t y,
234                               int32_t width, int32_t height)
235 {
236         struct wlsc_compositor *compositor = surface->compositor;
237
238         pixman_region32_union_rect(&compositor->damage_region,
239                                    &compositor->damage_region,
240                                    surface->x + x, surface->y + y,
241                                    width, height);
242         wlsc_compositor_schedule_repaint(compositor);
243 }
244
245 WL_EXPORT void
246 wlsc_surface_damage(struct wlsc_surface *surface)
247 {
248         wlsc_surface_damage_rectangle(surface, 0, 0,
249                                       surface->width, surface->height);
250 }
251
252 WL_EXPORT uint32_t
253 wlsc_compositor_get_time(void)
254 {
255         struct timeval tv;
256
257         gettimeofday(&tv, NULL);
258
259         return tv.tv_sec * 1000 + tv.tv_usec / 1000;
260 }
261
262 static void
263 destroy_surface(struct wl_resource *resource, struct wl_client *client)
264 {
265         struct wlsc_surface *surface =
266                 container_of(resource, struct wlsc_surface, surface.resource);
267         struct wlsc_compositor *compositor = surface->compositor;
268
269         wlsc_surface_damage(surface);
270
271         wl_list_remove(&surface->link);
272         if (surface->saved_texture == 0)
273                 glDeleteTextures(1, &surface->texture);
274         else
275                 glDeleteTextures(1, &surface->saved_texture);
276
277         if (surface->buffer)
278                 wl_list_remove(&surface->buffer_destroy_listener.link);
279
280         if (surface->image != EGL_NO_IMAGE_KHR)
281                 compositor->destroy_image(compositor->display,
282                                           surface->image);
283
284         wl_list_remove(&surface->buffer_link);
285
286         free(surface);
287 }
288
289 static void
290 wlsc_buffer_attach(struct wl_buffer *buffer, struct wl_surface *surface)
291 {
292         struct wlsc_surface *es = (struct wlsc_surface *) surface;
293         struct wlsc_compositor *ec = es->compositor;
294         struct wl_list *surfaces_attached_to;
295
296         if (es->saved_texture != 0)
297                 es->texture = es->saved_texture;
298
299         glBindTexture(GL_TEXTURE_2D, es->texture);
300
301         if (wl_buffer_is_shm(buffer)) {
302                 /* Unbind any EGLImage texture that may be bound, so we don't
303                  * overwrite it.*/
304                 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
305                              0, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
306                 es->pitch = wl_shm_buffer_get_stride(buffer) / 4;
307                 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
308                              es->pitch, buffer->height, 0,
309                              GL_BGRA_EXT, GL_UNSIGNED_BYTE,
310                              wl_shm_buffer_get_data(buffer));
311                 es->visual = buffer->visual;
312
313                 surfaces_attached_to = buffer->user_data;
314
315                 wl_list_remove(&es->buffer_link);
316                 wl_list_insert(surfaces_attached_to, &es->buffer_link);
317         } else {
318                 if (es->image != EGL_NO_IMAGE_KHR)
319                         ec->destroy_image(ec->display, es->image);
320                 es->image = ec->create_image(ec->display, NULL,
321                                              EGL_WAYLAND_BUFFER_WL,
322                                              buffer, NULL);
323                 
324                 ec->image_target_texture_2d(GL_TEXTURE_2D, es->image);
325                 es->visual = buffer->visual;
326                 es->pitch = es->width;
327         }
328 }
329
330 static void
331 wlsc_sprite_attach(struct wlsc_sprite *sprite, struct wl_surface *surface)
332 {
333         struct wlsc_surface *es = (struct wlsc_surface *) surface;
334         struct wlsc_compositor *ec = es->compositor;
335
336         es->pitch = es->width;
337         es->image = sprite->image;
338         if (sprite->image != EGL_NO_IMAGE_KHR) {
339                 glBindTexture(GL_TEXTURE_2D, es->texture);
340                 ec->image_target_texture_2d(GL_TEXTURE_2D, es->image);
341         } else {
342                 if (es->saved_texture == 0)
343                         es->saved_texture = es->texture;
344                 es->texture = sprite->texture;
345         }
346
347         es->visual = sprite->visual;
348
349         if (es->buffer)
350                 es->buffer = NULL;
351 }
352
353 enum sprite_usage {
354         SPRITE_USE_CURSOR = (1 << 0),
355 };
356
357 static struct wlsc_sprite *
358 create_sprite_from_png(struct wlsc_compositor *ec,
359                        const char *filename, uint32_t usage)
360 {
361         uint32_t *pixels;
362         struct wlsc_sprite *sprite;
363         int32_t width, height;
364         uint32_t stride;
365
366         pixels = wlsc_load_image(filename, &width, &height, &stride);
367         if (pixels == NULL)
368                 return NULL;
369
370         sprite = malloc(sizeof *sprite);
371         if (sprite == NULL) {
372                 free(pixels);
373                 return NULL;
374         }
375
376         sprite->visual = &ec->compositor.premultiplied_argb_visual;
377         sprite->width = width;
378         sprite->height = height;
379         sprite->image = EGL_NO_IMAGE_KHR;
380
381         if (usage & SPRITE_USE_CURSOR && ec->create_cursor_image != NULL)
382                 sprite->image = ec->create_cursor_image(ec, width, height);
383
384         glGenTextures(1, &sprite->texture);
385         glBindTexture(GL_TEXTURE_2D, sprite->texture);
386         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
387         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
388         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
389         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
390
391         if (sprite->image != EGL_NO_IMAGE_KHR) {
392                 ec->image_target_texture_2d(GL_TEXTURE_2D, sprite->image);
393                 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
394                                 GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
395         } else {
396                 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, width, height, 0,
397                              GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
398         }
399
400         free(pixels);
401
402         return sprite;
403 }
404
405 static const struct {
406         const char *filename;
407         int hotspot_x, hotspot_y;
408 } pointer_images[] = {
409         { DATADIR "/wayland/bottom_left_corner.png",     6, 30 },
410         { DATADIR "/wayland/bottom_right_corner.png",   28, 28 },
411         { DATADIR "/wayland/bottom_side.png",           16, 20 },
412         { DATADIR "/wayland/grabbing.png",              20, 17 },
413         { DATADIR "/wayland/left_ptr.png",              10,  5 },
414         { DATADIR "/wayland/left_side.png",             10, 20 },
415         { DATADIR "/wayland/right_side.png",            30, 19 },
416         { DATADIR "/wayland/top_left_corner.png",        8,  8 },
417         { DATADIR "/wayland/top_right_corner.png",      26,  8 },
418         { DATADIR "/wayland/top_side.png",              18,  8 },
419         { DATADIR "/wayland/xterm.png",                 15, 15 }
420 };
421
422 static void
423 create_pointer_images(struct wlsc_compositor *ec)
424 {
425         int i, count;
426
427         count = ARRAY_LENGTH(pointer_images);
428         ec->pointer_sprites = malloc(count * sizeof *ec->pointer_sprites);
429         for (i = 0; i < count; i++) {
430                 ec->pointer_sprites[i] =
431                         create_sprite_from_png(ec,
432                                                pointer_images[i].filename,
433                                                SPRITE_USE_CURSOR);
434         }
435 }
436
437 static struct wlsc_surface *
438 background_create(struct wlsc_output *output, const char *filename)
439 {
440         struct wlsc_surface *background;
441         struct wlsc_sprite *sprite;
442
443         background = wlsc_surface_create(output->compositor,
444                                          output->x, output->y,
445                                          output->width, output->height);
446         if (background == NULL)
447                 return NULL;
448
449         sprite = create_sprite_from_png(output->compositor, filename, 0);
450         if (sprite == NULL) {
451                 free(background);
452                 return NULL;
453         }
454
455         wlsc_sprite_attach(sprite, &background->surface);
456
457         return background;
458 }
459
460 static int
461 texture_region(struct wlsc_surface *es, pixman_region32_t *region)
462 {
463         struct wlsc_compositor *ec = es->compositor;
464         GLfloat *v, inv_width, inv_height;
465         pixman_box32_t *rectangles;
466         unsigned int *p;
467         int i, n;
468
469         rectangles = pixman_region32_rectangles(region, &n);
470         v = wl_array_add(&ec->vertices, n * 16 * sizeof *v);
471         p = wl_array_add(&ec->indices, n * 6 * sizeof *p);
472         inv_width = 1.0 / es->pitch;
473         inv_height = 1.0 / es->height;
474
475         for (i = 0; i < n; i++, v += 16, p += 6) {
476                 v[ 0] = rectangles[i].x1;
477                 v[ 1] = rectangles[i].y1;
478                 v[ 2] = (GLfloat) (rectangles[i].x1 - es->x) * inv_width;
479                 v[ 3] = (GLfloat) (rectangles[i].y1 - es->y) * inv_height;
480
481                 v[ 4] = rectangles[i].x1;
482                 v[ 5] = rectangles[i].y2;
483                 v[ 6] = v[ 2];
484                 v[ 7] = (GLfloat) (rectangles[i].y2 - es->y) * inv_height;
485
486                 v[ 8] = rectangles[i].x2;
487                 v[ 9] = rectangles[i].y1;
488                 v[10] = (GLfloat) (rectangles[i].x2 - es->x) * inv_width;
489                 v[11] = v[ 3];
490
491                 v[12] = rectangles[i].x2;
492                 v[13] = rectangles[i].y2;
493                 v[14] = v[10];
494                 v[15] = v[ 7];
495
496                 p[0] = i * 4 + 0;
497                 p[1] = i * 4 + 1;
498                 p[2] = i * 4 + 2;
499                 p[3] = i * 4 + 2;
500                 p[4] = i * 4 + 1;
501                 p[5] = i * 4 + 3;
502         }
503
504         return n;
505 }
506
507 static void
508 transform_vertex(struct wlsc_surface *surface,
509                  GLfloat x, GLfloat y, GLfloat u, GLfloat v, GLfloat *r)
510 {
511         struct wlsc_vector t;
512
513         t.f[0] = x;
514         t.f[1] = y;
515         t.f[2] = 0.0;
516         t.f[3] = 1.0;
517
518         wlsc_matrix_transform(&surface->transform->matrix, &t);
519
520         r[ 0] = t.f[0];
521         r[ 1] = t.f[1];
522         r[ 2] = u;
523         r[ 3] = v;
524 }
525
526 static int
527 texture_transformed_surface(struct wlsc_surface *es)
528 {
529         struct wlsc_compositor *ec = es->compositor;
530         GLfloat *v;
531         unsigned int *p;
532
533         v = wl_array_add(&ec->vertices, 16 * sizeof *v);
534         p = wl_array_add(&ec->indices, 6 * sizeof *p);
535
536         transform_vertex(es, es->x, es->y, 0.0, 0.0, &v[0]);
537         transform_vertex(es, es->x, es->y + es->height, 0.0, 1.0, &v[4]);
538         transform_vertex(es, es->x + es->width, es->y, 1.0, 0.0, &v[8]);
539         transform_vertex(es, es->x + es->width, es->y + es->height,
540                          1.0, 1.0, &v[12]);
541
542         p[0] = 0;
543         p[1] = 1;
544         p[2] = 2;
545         p[3] = 2;
546         p[4] = 1;
547         p[5] = 3;
548
549         return 1;
550 }
551
552 static void
553 wlsc_surface_draw(struct wlsc_surface *es,
554                   struct wlsc_output *output, pixman_region32_t *clip)
555 {
556         struct wlsc_compositor *ec = es->compositor;
557         GLfloat *v;
558         pixman_region32_t repaint;
559         int n;
560
561         pixman_region32_init_rect(&repaint,
562                                   es->x, es->y, es->width, es->height);
563         pixman_region32_intersect(&repaint, &repaint, clip);
564         if (!pixman_region32_not_empty(&repaint))
565                 return;
566
567         if (es->visual == &ec->compositor.argb_visual) {
568                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
569                 glEnable(GL_BLEND);
570         } else if (es->visual == &ec->compositor.premultiplied_argb_visual) {
571                 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
572                 glEnable(GL_BLEND);
573         } else {
574                 glDisable(GL_BLEND);
575         }
576
577         if (es->transform == NULL)
578                 n = texture_region(es, &repaint);
579         else
580                 n = texture_transformed_surface(es);
581
582         glBindTexture(GL_TEXTURE_2D, es->texture);
583         v = ec->vertices.data;
584         glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof *v, &v[0]);
585         glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof *v, &v[2]);
586         glEnableVertexAttribArray(0);
587         glEnableVertexAttribArray(1);
588         glDrawElements(GL_TRIANGLES, n * 6, GL_UNSIGNED_INT, ec->indices.data);
589
590         ec->vertices.size = 0;
591         ec->indices.size = 0;
592         pixman_region32_fini(&repaint);
593 }
594
595 static void
596 wlsc_surface_raise(struct wlsc_surface *surface)
597 {
598         struct wlsc_compositor *compositor = surface->compositor;
599
600         wl_list_remove(&surface->link);
601         wl_list_insert(&compositor->surface_list, &surface->link);
602 }
603
604 WL_EXPORT void
605 wlsc_compositor_damage_all(struct wlsc_compositor *compositor)
606 {
607         struct wlsc_output *output;
608
609         wl_list_for_each(output, &compositor->output_list, link)
610                 wlsc_output_damage(output);
611 }
612
613 static inline void
614 wlsc_buffer_post_release(struct wl_buffer *buffer)
615 {
616         if (buffer->client == NULL) {
617                 fprintf(stderr, "buffer.release warning: buffer.client: %p\n",
618                         buffer->client);
619                 return;
620         }
621
622         wl_client_post_event(buffer->client,
623                              &buffer->resource.object,
624                              WL_BUFFER_RELEASE);
625 }
626
627 WL_EXPORT void
628 wlsc_output_finish_frame(struct wlsc_output *output, int msecs)
629 {
630         struct wlsc_compositor *compositor = output->compositor;
631         struct wlsc_animation *animation, *next;
632
633         if (output->scanout_buffer) {
634                 if (--output->scanout_buffer->busy_count == 0)
635                         wlsc_buffer_post_release(output->scanout_buffer);
636
637                 output->scanout_buffer = NULL;
638         }
639
640         output->finished = 1;
641
642         wl_event_source_timer_update(compositor->timer_source, 5);
643         compositor->repaint_on_timeout = 1;
644
645         wl_list_for_each_safe(animation, next,
646                               &compositor->animation_list, link)
647                 animation->frame(animation, output, msecs);
648 }
649
650 static void
651 wlsc_output_finish_redraw(struct wlsc_output *output, int msecs)
652 {
653         struct wlsc_compositor *compositor = output->compositor;
654         struct wlsc_surface *es;
655
656         wl_list_for_each(es, &compositor->surface_list, link) {
657                 if (es->output == output) {
658                         wl_display_post_frame(compositor->wl_display,
659                                               &es->surface, msecs);
660                 }
661         }
662 }
663
664 WL_EXPORT void
665 wlsc_output_damage(struct wlsc_output *output)
666 {
667         struct wlsc_compositor *compositor = output->compositor;
668
669         pixman_region32_union_rect(&compositor->damage_region,
670                                    &compositor->damage_region,
671                                    output->x, output->y,
672                                    output->width, output->height);
673         wlsc_compositor_schedule_repaint(compositor);
674 }
675
676 static void
677 fade_frame(struct wlsc_animation *animation,
678            struct wlsc_output *output, uint32_t msecs)
679 {
680         struct wlsc_compositor *compositor =
681                 container_of(animation,
682                              struct wlsc_compositor, fade.animation);
683
684         wlsc_spring_update(&compositor->fade.spring, msecs);
685         if (wlsc_spring_done(&compositor->fade.spring)) {
686                 if (compositor->fade.spring.current > 0.999) {
687                         compositor->state = WLSC_COMPOSITOR_SLEEPING;
688                         compositor->shell->lock(compositor->shell);
689                 }
690                 compositor->fade.spring.current =
691                         compositor->fade.spring.target;
692                 wl_list_remove(&animation->link);
693                 wl_list_init(&animation->link);
694         }
695
696         wlsc_output_damage(output);
697 }
698
699 static void
700 fade_output(struct wlsc_output *output,
701             GLfloat tint, pixman_region32_t *region)
702 {
703         struct wlsc_compositor *compositor = output->compositor;
704         struct wlsc_surface surface;
705         GLfloat color[4] = { 0.0, 0.0, 0.0, tint };
706
707         surface.compositor = compositor;
708         surface.x = output->x;
709         surface.y = output->y;
710         surface.width = output->width;
711         surface.height = output->height;
712         surface.texture = GL_NONE;
713         surface.transform = NULL;
714
715         if (tint <= 1.0)
716                 surface.visual =
717                         &compositor->compositor.premultiplied_argb_visual;
718         else
719                 surface.visual = &compositor->compositor.rgb_visual;
720
721         glUseProgram(compositor->solid_shader.program);
722         glUniformMatrix4fv(compositor->solid_shader.proj_uniform,
723                            1, GL_FALSE, output->matrix.d);
724         glUniform4fv(compositor->solid_shader.color_uniform, 1, color);
725         wlsc_surface_draw(&surface, output, region);
726 }
727  
728 static void
729 wlsc_output_repaint(struct wlsc_output *output)
730 {
731         struct wlsc_compositor *ec = output->compositor;
732         struct wlsc_surface *es;
733         struct wlsc_input_device *eid, *hw_cursor;
734         pixman_region32_t new_damage, total_damage;
735
736         output->prepare_render(output);
737
738         glViewport(0, 0, output->width, output->height);
739
740         glUseProgram(ec->texture_shader.program);
741         glUniformMatrix4fv(ec->texture_shader.proj_uniform,
742                            1, GL_FALSE, output->matrix.d);
743         glUniform1i(ec->texture_shader.tex_uniform, 0);
744
745         pixman_region32_init(&new_damage);
746         pixman_region32_init(&total_damage);
747         pixman_region32_intersect_rect(&new_damage,
748                                        &ec->damage_region,
749                                        output->x, output->y,
750                                        output->width, output->height);
751         pixman_region32_subtract(&ec->damage_region,
752                                  &ec->damage_region, &new_damage);
753         pixman_region32_union(&total_damage, &new_damage,
754                               &output->previous_damage_region);
755         pixman_region32_copy(&output->previous_damage_region, &new_damage);
756
757         hw_cursor = NULL;
758         if (ec->focus && ec->fade.spring.current < 0.001) {
759                 hw_cursor = (struct wlsc_input_device *) ec->input_device;
760                 if (output->set_hardware_cursor(output, hw_cursor) < 0)
761                         hw_cursor = NULL;
762         } else {
763                 output->set_hardware_cursor(output, NULL);
764         }
765
766         es = container_of(ec->surface_list.next, struct wlsc_surface, link);
767
768         if (es->visual == &ec->compositor.rgb_visual && hw_cursor) {
769                 if (output->prepare_scanout_surface(output, es) == 0) {
770                         /* We're drawing nothing now,
771                          * draw the damaged regions later. */
772                         pixman_region32_union(&ec->damage_region,
773                                               &ec->damage_region,
774                                               &total_damage);
775
776                         output->scanout_buffer = es->buffer;
777                         output->scanout_buffer->busy_count++;
778
779                         wl_list_remove(&output->scanout_buffer_destroy_listener.link);
780                         wl_list_insert(output->scanout_buffer->resource.destroy_listener_list.prev,
781                                        &output->scanout_buffer_destroy_listener.link);
782
783                         wlsc_output_finish_redraw(output,
784                                                   wlsc_compositor_get_time());
785                         return;
786                 }
787         }
788
789         if (es->fullscreen_output == output) {
790                 if (es->width < output->width ||
791                     es->height < output->height)
792                         glClear(GL_COLOR_BUFFER_BIT);
793                 wlsc_surface_draw(es, output, &total_damage);
794         } else {
795                 if (output->background)
796                         wlsc_surface_draw(output->background,
797                                           output, &total_damage);
798                 else
799                         fade_output(output, 1.0, &total_damage);
800
801                 glUseProgram(ec->texture_shader.program);
802                 wl_list_for_each_reverse(es, &ec->surface_list, link) {
803                         if (ec->overlay == es)
804                                 continue;
805
806                         wlsc_surface_draw(es, output, &total_damage);
807                 }
808         }
809
810         if (ec->overlay)
811                 wlsc_surface_draw(ec->overlay, output, &total_damage);
812
813         if (ec->focus)
814                 wl_list_for_each(eid, &ec->input_device_list, link) {
815                         if (&eid->input_device != ec->input_device ||
816                             eid != hw_cursor)
817                                 wlsc_surface_draw(eid->sprite, output,
818                                                   &total_damage);
819                 }
820
821         if (ec->fade.spring.current > 0.001)
822                 fade_output(output, ec->fade.spring.current, &total_damage);
823
824         wlsc_output_finish_redraw(output, wlsc_compositor_get_time());
825 }
826
827 static int
828 repaint(void *data)
829 {
830         struct wlsc_compositor *ec = data;
831         struct wlsc_output *output;
832         int repainted_all_outputs = 1;
833
834         wl_list_for_each(output, &ec->output_list, link) {
835                 if (!output->repaint_needed)
836                         continue;
837
838                 if (!output->finished) {
839                         repainted_all_outputs = 0;
840                         continue;
841                 }
842
843                 wlsc_output_repaint(output);
844                 output->finished = 0;
845                 output->repaint_needed = 0;
846                 output->present(output);
847         }
848
849         if (repainted_all_outputs)
850                 ec->repaint_on_timeout = 0;
851         else
852                 wl_event_source_timer_update(ec->timer_source, 1);
853
854         return 1;
855 }
856
857 WL_EXPORT void
858 wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor)
859 {
860         struct wlsc_output *output;
861
862         if (compositor->state == WLSC_COMPOSITOR_SLEEPING)
863                 return;
864
865         wl_list_for_each(output, &compositor->output_list, link)
866                 output->repaint_needed = 1;
867
868         if (compositor->repaint_on_timeout)
869                 return;
870
871         wl_event_source_timer_update(compositor->timer_source, 1);
872         compositor->repaint_on_timeout = 1;
873 }
874
875 WL_EXPORT void
876 wlsc_compositor_fade(struct wlsc_compositor *compositor, float tint)
877 {
878         int done;
879
880         done = wlsc_spring_done(&compositor->fade.spring);
881         compositor->fade.spring.target = tint;
882         if (wlsc_spring_done(&compositor->fade.spring))
883                 return;
884
885         if (done)
886                 compositor->fade.spring.timestamp =
887                         wlsc_compositor_get_time();
888
889         wlsc_compositor_damage_all(compositor);
890         if (wl_list_empty(&compositor->fade.animation.link))
891                 wl_list_insert(compositor->animation_list.prev,
892                                &compositor->fade.animation.link);
893 }
894
895 static void
896 surface_destroy(struct wl_client *client,
897                 struct wl_surface *surface)
898 {
899         wl_resource_destroy(&surface->resource, client,
900                             wlsc_compositor_get_time());
901 }
902
903 WL_EXPORT void
904 wlsc_surface_assign_output(struct wlsc_surface *es)
905 {
906         struct wlsc_compositor *ec = es->compositor;
907         struct wlsc_output *output;
908
909         struct wlsc_output *tmp = es->output;
910         es->output = NULL;
911
912         wl_list_for_each(output, &ec->output_list, link) {
913                 if (output->x < es->x && es->x < output->x + output->width &&
914                     output->y < es->y && es->y < output->y + output->height) {
915                         if (output != tmp)
916                                 printf("assiging surface %p to output %p\n",
917                                        es, output);
918                         es->output = output;
919                 }
920         }
921         
922         if (es->output == NULL) {
923                 printf("no output found\n");
924                 es->output = container_of(ec->output_list.next,
925                                           struct wlsc_output, link);
926         }
927 }
928
929 static void
930 surface_attach(struct wl_client *client,
931                struct wl_surface *surface, struct wl_buffer *buffer,
932                int32_t x, int32_t y)
933 {
934         struct wlsc_surface *es = (struct wlsc_surface *) surface;
935
936         buffer->busy_count++;
937
938         if (es->buffer && es->buffer->busy_count > 0)
939                 if (--es->buffer->busy_count == 0)
940                         wlsc_buffer_post_release(es->buffer);
941
942         es->buffer = buffer;
943         wl_list_remove(&es->buffer_destroy_listener.link);
944         wl_list_insert(es->buffer->resource.destroy_listener_list.prev,
945                        &es->buffer_destroy_listener.link);
946
947         es->x += x;
948         es->y += y;
949         es->width = buffer->width;
950         es->height = buffer->height;
951         if (x != 0 || y != 0)
952                 wlsc_surface_assign_output(es);
953         if (es->visual == NULL)
954                 wl_list_insert(&es->compositor->surface_list, &es->link);
955
956         wlsc_buffer_attach(buffer, surface);
957
958         /* FIXME: This damages the entire old surface, but we should
959          * really just damage the part that's no longer covered by the
960          * surface.  Anything covered by the new surface will be
961          * damaged by the client. */
962         wlsc_surface_damage(es);
963
964         es->compositor->shell->attach(es->compositor->shell, es);
965 }
966
967 static void
968 surface_damage(struct wl_client *client,
969                struct wl_surface *surface,
970                int32_t x, int32_t y, int32_t width, int32_t height)
971 {
972         struct wlsc_surface *es = (struct wlsc_surface *) surface;
973
974         wlsc_surface_damage_rectangle(es, x, y, width, height);
975 }
976
977 const static struct wl_surface_interface surface_interface = {
978         surface_destroy,
979         surface_attach,
980         surface_damage
981 };
982
983 static void
984 wlsc_input_device_attach(struct wlsc_input_device *device,
985                          int x, int y, int width, int height)
986 {
987         wlsc_surface_damage(device->sprite);
988
989         device->hotspot_x = x;
990         device->hotspot_y = y;
991
992         device->sprite->x = device->input_device.x - device->hotspot_x;
993         device->sprite->y = device->input_device.y - device->hotspot_y;
994         device->sprite->width = width;
995         device->sprite->height = height;
996
997         wlsc_surface_damage(device->sprite);
998 }
999
1000 static void
1001 wlsc_input_device_attach_buffer(struct wlsc_input_device *device,
1002                                 struct wl_buffer *buffer, int x, int y)
1003 {
1004         wlsc_buffer_attach(buffer, &device->sprite->surface);
1005         wlsc_input_device_attach(device, x, y, buffer->width, buffer->height);
1006 }
1007
1008 static void
1009 wlsc_input_device_attach_sprite(struct wlsc_input_device *device,
1010                                 struct wlsc_sprite *sprite, int x, int y)
1011 {
1012         wlsc_sprite_attach(sprite, &device->sprite->surface);
1013         wlsc_input_device_attach(device, x, y, sprite->width, sprite->height);
1014 }
1015
1016 WL_EXPORT void
1017 wlsc_input_device_set_pointer_image(struct wlsc_input_device *device,
1018                                     enum wlsc_pointer_type type)
1019 {
1020         struct wlsc_compositor *compositor =
1021                 (struct wlsc_compositor *) device->input_device.compositor;
1022
1023         wlsc_input_device_attach_sprite(device,
1024                                         compositor->pointer_sprites[type],
1025                                         pointer_images[type].hotspot_x,
1026                                         pointer_images[type].hotspot_y);
1027 }
1028
1029 static void
1030 compositor_create_surface(struct wl_client *client,
1031                           struct wl_compositor *compositor, uint32_t id)
1032 {
1033         struct wlsc_compositor *ec = (struct wlsc_compositor *) compositor;
1034         struct wlsc_surface *surface;
1035
1036         surface = wlsc_surface_create(ec, 0, 0, 0, 0);
1037         if (surface == NULL) {
1038                 wl_client_post_no_memory(client);
1039                 return;
1040         }
1041
1042         surface->surface.resource.destroy = destroy_surface;
1043
1044         surface->surface.resource.object.id = id;
1045         surface->surface.resource.object.interface = &wl_surface_interface;
1046         surface->surface.resource.object.implementation =
1047                 (void (**)(void)) &surface_interface;
1048         surface->surface.client = client;
1049
1050         wl_client_add_resource(client, &surface->surface.resource);
1051 }
1052
1053 const static struct wl_compositor_interface compositor_interface = {
1054         compositor_create_surface,
1055 };
1056
1057 static void
1058 wlsc_surface_transform(struct wlsc_surface *surface,
1059                        int32_t x, int32_t y, int32_t *sx, int32_t *sy)
1060 {
1061         *sx = x - surface->x;
1062         *sy = y - surface->y;
1063 }
1064
1065 WL_EXPORT struct wlsc_surface *
1066 pick_surface(struct wl_input_device *device, int32_t *sx, int32_t *sy)
1067 {
1068         struct wlsc_compositor *ec =
1069                 (struct wlsc_compositor *) device->compositor;
1070         struct wlsc_surface *es;
1071
1072         wl_list_for_each(es, &ec->surface_list, link) {
1073                 wlsc_surface_transform(es, device->x, device->y, sx, sy);
1074                 if (0 <= *sx && *sx < es->width &&
1075                     0 <= *sy && *sy < es->height)
1076                         return es;
1077         }
1078
1079         return NULL;
1080 }
1081
1082
1083 static void
1084 motion_grab_motion(struct wl_grab *grab,
1085                    uint32_t time, int32_t x, int32_t y)
1086 {
1087         struct wlsc_input_device *device =
1088                 (struct wlsc_input_device *) grab->input_device;
1089         struct wlsc_surface *es =
1090                 (struct wlsc_surface *) device->input_device.pointer_focus;
1091         int32_t sx, sy;
1092
1093         wlsc_surface_transform(es, x, y, &sx, &sy);
1094         wl_client_post_event(es->surface.client,
1095                              &device->input_device.object,
1096                              WL_INPUT_DEVICE_MOTION,
1097                              time, x, y, sx, sy);
1098 }
1099
1100 static void
1101 motion_grab_button(struct wl_grab *grab,
1102                    uint32_t time, int32_t button, int32_t state)
1103 {
1104         wl_client_post_event(grab->input_device->pointer_focus->client,
1105                              &grab->input_device->object,
1106                              WL_INPUT_DEVICE_BUTTON,
1107                              time, button, state);
1108 }
1109
1110 static void
1111 motion_grab_end(struct wl_grab *grab, uint32_t time)
1112 {
1113 }
1114
1115 static const struct wl_grab_interface motion_grab_interface = {
1116         motion_grab_motion,
1117         motion_grab_button,
1118         motion_grab_end
1119 };
1120
1121 WL_EXPORT void
1122 wlsc_compositor_wake(struct wlsc_compositor *compositor)
1123 {
1124         if (compositor->idle_inhibit)
1125                 return;
1126
1127         wlsc_compositor_fade(compositor, 0.0);
1128         compositor->state = WLSC_COMPOSITOR_ACTIVE;
1129
1130         wl_event_source_timer_update(compositor->idle_source,
1131                                      option_idle_time * 1000);
1132 }
1133
1134 static void
1135 wlsc_compositor_idle_inhibit(struct wlsc_compositor *compositor)
1136 {
1137         wlsc_compositor_wake(compositor);
1138         compositor->idle_inhibit++;
1139 }
1140
1141 static void
1142 wlsc_compositor_idle_release(struct wlsc_compositor *compositor)
1143 {
1144         compositor->idle_inhibit--;
1145         wlsc_compositor_wake(compositor);
1146 }
1147
1148 static int
1149 idle_handler(void *data)
1150 {
1151         struct wlsc_compositor *compositor = data;
1152
1153         if (compositor->idle_inhibit)
1154                 return 1;
1155
1156         wlsc_compositor_fade(compositor, 1.0);
1157
1158         return 1;
1159 }
1160
1161 WL_EXPORT void
1162 notify_motion(struct wl_input_device *device, uint32_t time, int x, int y)
1163 {
1164         struct wlsc_surface *es;
1165         struct wlsc_compositor *ec =
1166                 (struct wlsc_compositor *) device->compositor;
1167         struct wlsc_output *output;
1168         const struct wl_grab_interface *interface;
1169         struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
1170         int32_t sx, sy;
1171         int x_valid = 0, y_valid = 0;
1172         int min_x = INT_MAX, min_y = INT_MAX, max_x = INT_MIN, max_y = INT_MIN;
1173
1174         wlsc_compositor_wake(ec);
1175
1176         wl_list_for_each(output, &ec->output_list, link) {
1177                 if (output->x <= x && x <= output->x + output->width)
1178                         x_valid = 1;
1179
1180                 if (output->y <= y && y <= output->y + output->height)
1181                         y_valid = 1;
1182
1183                 /* FIXME: calculate this only on output addition/deletion */
1184                 if (output->x < min_x)
1185                         min_x = output->x;
1186                 if (output->y < min_y)
1187                         min_y = output->y;
1188
1189                 if (output->x + output->width > max_x)
1190                         max_x = output->x + output->width;
1191                 if (output->y + output->height > max_y)
1192                         max_y = output->y + output->height;
1193         }
1194         
1195         if (!x_valid) {
1196                 if (x < min_x)
1197                         x = min_x;
1198                 else if (x >= max_x)
1199                         x = max_x;
1200         }
1201         if (!y_valid) {
1202                 if (y < min_y)
1203                         y = min_y;
1204                 else  if (y >= max_y)
1205                         y = max_y;
1206         }
1207
1208         device->x = x;
1209         device->y = y;
1210
1211         if (device->grab) {
1212                 interface = device->grab->interface;
1213                 interface->motion(device->grab, time, x, y);
1214         } else {
1215                 es = pick_surface(device, &sx, &sy);
1216                 wl_input_device_set_pointer_focus(device,
1217                                                   &es->surface,
1218                                                   time, x, y, sx, sy);
1219                 if (es)
1220                         wl_client_post_event(es->surface.client,
1221                                              &device->object,
1222                                              WL_INPUT_DEVICE_MOTION,
1223                                              time, x, y, sx, sy);
1224         }
1225
1226         wlsc_surface_damage(wd->sprite);
1227
1228         wd->sprite->x = device->x - wd->hotspot_x;
1229         wd->sprite->y = device->y - wd->hotspot_y;
1230
1231         wlsc_surface_damage(wd->sprite);
1232 }
1233
1234 WL_EXPORT void
1235 wlsc_surface_activate(struct wlsc_surface *surface,
1236                       struct wlsc_input_device *device, uint32_t time)
1237 {
1238         struct wlsc_shell *shell = surface->compositor->shell;
1239
1240         wlsc_surface_raise(surface);
1241         if (device->selection)
1242                 shell->set_selection_focus(shell,
1243                                            device->selection,
1244                                            &surface->surface, time);
1245
1246         wl_input_device_set_keyboard_focus(&device->input_device,
1247                                            &surface->surface,
1248                                            time);
1249 }
1250
1251 struct wlsc_binding {
1252         uint32_t key;
1253         uint32_t button;
1254         uint32_t modifier;
1255         wlsc_binding_handler_t handler;
1256         void *data;
1257         struct wl_list link;
1258 };
1259
1260 WL_EXPORT void
1261 notify_button(struct wl_input_device *device,
1262               uint32_t time, int32_t button, int32_t state)
1263 {
1264         struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
1265         struct wlsc_compositor *compositor =
1266                 (struct wlsc_compositor *) device->compositor;
1267         struct wlsc_binding *b;
1268         struct wlsc_surface *surface =
1269                 (struct wlsc_surface *) device->pointer_focus;
1270
1271         if (state)
1272                 wlsc_compositor_idle_inhibit(compositor);
1273         else
1274                 wlsc_compositor_idle_release(compositor);
1275
1276         if (state && surface && device->grab == NULL) {
1277                 wlsc_surface_activate(surface, wd, time);
1278                 wl_input_device_start_grab(device,
1279                                            &device->motion_grab,
1280                                            button, time);
1281         }
1282
1283         wl_list_for_each(b, &compositor->binding_list, link) {
1284                 if (b->button == button &&
1285                     b->modifier == wd->modifier_state && state) {
1286                         b->handler(&wd->input_device,
1287                                    time, 0, button, state, b->data);
1288                         break;
1289                 }
1290         }
1291
1292         if (device->grab)
1293                 device->grab->interface->button(device->grab, time,
1294                                                 button, state);
1295
1296         if (!state && device->grab && device->grab_button == button)
1297                 wl_input_device_end_grab(device, time);
1298 }
1299
1300 static void
1301 terminate_binding(struct wl_input_device *device, uint32_t time,
1302                   uint32_t key, uint32_t button, uint32_t state, void *data)
1303 {
1304         struct wlsc_compositor *compositor = data;
1305
1306         if (state)
1307                 wl_display_terminate(compositor->wl_display);
1308 }
1309
1310 WL_EXPORT struct wlsc_binding *
1311 wlsc_compositor_add_binding(struct wlsc_compositor *compositor,
1312                             uint32_t key, uint32_t button, uint32_t modifier,
1313                             wlsc_binding_handler_t handler, void *data)
1314 {
1315         struct wlsc_binding *binding;
1316
1317         binding = malloc(sizeof *binding);
1318         if (binding == NULL)
1319                 return NULL;
1320
1321         binding->key = key;
1322         binding->button = button;
1323         binding->modifier = modifier;
1324         binding->handler = handler;
1325         binding->data = data;
1326         wl_list_insert(compositor->binding_list.prev, &binding->link);
1327
1328         return binding;
1329 }
1330
1331 WL_EXPORT void
1332 wlsc_binding_destroy(struct wlsc_binding *binding)
1333 {
1334         wl_list_remove(&binding->link);
1335         free(binding);
1336 }
1337
1338 static void
1339 update_modifier_state(struct wlsc_input_device *device,
1340                       uint32_t key, uint32_t state)
1341 {
1342         uint32_t modifier;
1343
1344         switch (key) {
1345         case KEY_LEFTCTRL:
1346         case KEY_RIGHTCTRL:
1347                 modifier = MODIFIER_CTRL;
1348                 break;
1349
1350         case KEY_LEFTALT:
1351         case KEY_RIGHTALT:
1352                 modifier = MODIFIER_ALT;
1353                 break;
1354
1355         case KEY_LEFTMETA:
1356         case KEY_RIGHTMETA:
1357                 modifier = MODIFIER_SUPER;
1358                 break;
1359
1360         default:
1361                 modifier = 0;
1362                 break;
1363         }
1364
1365         if (state)
1366                 device->modifier_state |= modifier;
1367         else
1368                 device->modifier_state &= ~modifier;
1369 }
1370
1371 WL_EXPORT void
1372 notify_key(struct wl_input_device *device,
1373            uint32_t time, uint32_t key, uint32_t state)
1374 {
1375         struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
1376         struct wlsc_compositor *compositor =
1377                 (struct wlsc_compositor *) device->compositor;
1378         uint32_t *k, *end;
1379         struct wlsc_binding *b;
1380
1381         if (state)
1382                 wlsc_compositor_idle_inhibit(compositor);
1383         else
1384                 wlsc_compositor_idle_release(compositor);
1385
1386         wl_list_for_each(b, &compositor->binding_list, link) {
1387                 if (b->key == key &&
1388                     b->modifier == wd->modifier_state) {
1389                         b->handler(&wd->input_device,
1390                                    time, key, 0, state, b->data);
1391                         break;
1392                 }
1393         }
1394
1395         update_modifier_state(wd, key, state);
1396         end = device->keys.data + device->keys.size;
1397         for (k = device->keys.data; k < end; k++) {
1398                 if (*k == key)
1399                         *k = *--end;
1400         }
1401         device->keys.size = (void *) end - device->keys.data;
1402         if (state) {
1403                 k = wl_array_add(&device->keys, sizeof *k);
1404                 *k = key;
1405         }
1406
1407         if (device->keyboard_focus != NULL)
1408                 wl_client_post_event(device->keyboard_focus->client,
1409                                      &device->object,
1410                                      WL_INPUT_DEVICE_KEY, time, key, state);
1411 }
1412
1413 WL_EXPORT void
1414 notify_pointer_focus(struct wl_input_device *device,
1415                      uint32_t time, struct wlsc_output *output,
1416                      int32_t x, int32_t y)
1417 {
1418         struct wlsc_input_device *wd = (struct wlsc_input_device *) device;
1419         struct wlsc_compositor *compositor =
1420                 (struct wlsc_compositor *) device->compositor;
1421         struct wlsc_surface *es;
1422         int32_t sx, sy;
1423
1424         if (output) {
1425                 device->x = x;
1426                 device->y = y;
1427                 es = pick_surface(device, &sx, &sy);
1428                 wl_input_device_set_pointer_focus(device,
1429                                                   &es->surface,
1430                                                   time, x, y, sx, sy);
1431
1432                 compositor->focus = 1;
1433
1434                 wd->sprite->x = device->x - wd->hotspot_x;
1435                 wd->sprite->y = device->y - wd->hotspot_y;
1436         } else {
1437                 wl_input_device_set_pointer_focus(device, NULL,
1438                                                   time, 0, 0, 0, 0);
1439                 compositor->focus = 0;
1440         }
1441
1442         wlsc_surface_damage(wd->sprite);
1443 }
1444
1445 WL_EXPORT void
1446 notify_keyboard_focus(struct wl_input_device *device,
1447                       uint32_t time, struct wlsc_output *output,
1448                       struct wl_array *keys)
1449 {
1450         struct wlsc_input_device *wd =
1451                 (struct wlsc_input_device *) device;
1452         struct wlsc_compositor *compositor =
1453                 (struct wlsc_compositor *) device->compositor;
1454         struct wlsc_surface *es;
1455         uint32_t *k, *end;
1456
1457         if (!wl_list_empty(&compositor->surface_list))
1458                 es = container_of(compositor->surface_list.next,
1459                                   struct wlsc_surface, link);
1460         else
1461                 es = NULL;
1462
1463         if (output) {
1464                 wl_array_copy(&wd->input_device.keys, keys);
1465                 wd->modifier_state = 0;
1466                 end = device->keys.data + device->keys.size;
1467                 for (k = device->keys.data; k < end; k++) {
1468                         wlsc_compositor_idle_inhibit(compositor);
1469                         update_modifier_state(wd, *k, 1);
1470                 }
1471
1472                 wl_input_device_set_keyboard_focus(&wd->input_device,
1473                                                    &es->surface, time);
1474         } else {
1475                 end = device->keys.data + device->keys.size;
1476                 for (k = device->keys.data; k < end; k++)
1477                         wlsc_compositor_idle_release(compositor);
1478
1479                 wd->modifier_state = 0;
1480                 wl_input_device_set_keyboard_focus(&wd->input_device,
1481                                                    NULL, time);
1482         }
1483 }
1484
1485
1486 static void
1487 input_device_attach(struct wl_client *client,
1488                     struct wl_input_device *device_base,
1489                     uint32_t time,
1490                     struct wl_buffer *buffer, int32_t x, int32_t y)
1491 {
1492         struct wlsc_input_device *device =
1493                 (struct wlsc_input_device *) device_base;
1494
1495         if (time < device->input_device.pointer_focus_time)
1496                 return;
1497         if (device->input_device.pointer_focus == NULL)
1498                 return;
1499         if (device->input_device.pointer_focus->client != client)
1500                 return;
1501
1502         if (buffer == NULL) {
1503                 wlsc_input_device_set_pointer_image(device,
1504                                                     WLSC_POINTER_LEFT_PTR);
1505                 return;
1506         }
1507
1508         wlsc_input_device_attach_buffer(device, buffer, x, y);
1509 }
1510
1511 const static struct wl_input_device_interface input_device_interface = {
1512         input_device_attach,
1513 };
1514
1515 WL_EXPORT void
1516 wlsc_input_device_init(struct wlsc_input_device *device,
1517                        struct wlsc_compositor *ec)
1518 {
1519         wl_input_device_init(&device->input_device, &ec->compositor);
1520
1521         device->input_device.object.interface = &wl_input_device_interface;
1522         device->input_device.object.implementation =
1523                 (void (**)(void)) &input_device_interface;
1524         wl_display_add_object(ec->wl_display, &device->input_device.object);
1525         wl_display_add_global(ec->wl_display, &device->input_device.object, NULL);
1526
1527         device->sprite = wlsc_surface_create(ec,
1528                                              device->input_device.x,
1529                                              device->input_device.y, 32, 32);
1530         device->hotspot_x = 16;
1531         device->hotspot_y = 16;
1532         device->modifier_state = 0;
1533
1534         device->input_device.motion_grab.interface = &motion_grab_interface;
1535
1536         wl_list_insert(ec->input_device_list.prev, &device->link);
1537
1538         wlsc_input_device_set_pointer_image(device, WLSC_POINTER_LEFT_PTR);
1539 }
1540
1541 static void
1542 wlsc_output_post_geometry(struct wl_client *client,
1543                           struct wl_object *global, uint32_t version)
1544 {
1545         struct wlsc_output *output =
1546                 container_of(global, struct wlsc_output, object);
1547
1548         wl_client_post_event(client, global,
1549                              WL_OUTPUT_GEOMETRY,
1550                              output->x, output->y,
1551                              output->width, output->height);
1552 }
1553
1554 static const char vertex_shader[] =
1555         "uniform mat4 proj;\n"
1556         "attribute vec2 position;\n"
1557         "attribute vec2 texcoord;\n"
1558         "varying vec2 v_texcoord;\n"
1559         "void main()\n"
1560         "{\n"
1561         "   gl_Position = proj * vec4(position, 0.0, 1.0);\n"
1562         "   v_texcoord = texcoord;\n"
1563         "}\n";
1564
1565 static const char texture_fragment_shader[] =
1566         "precision mediump float;\n"
1567         "varying vec2 v_texcoord;\n"
1568         "uniform sampler2D tex;\n"
1569         "void main()\n"
1570         "{\n"
1571         "   gl_FragColor = texture2D(tex, v_texcoord)\n;"
1572         "}\n";
1573
1574 static const char solid_fragment_shader[] =
1575         "precision mediump float;\n"
1576         "uniform vec4 color;\n"
1577         "void main()\n"
1578         "{\n"
1579         "   gl_FragColor = color\n;"
1580         "}\n";
1581
1582 static int
1583 compile_shader(GLenum type, const char *source)
1584 {
1585         GLuint s;
1586         char msg[512];
1587         GLint status;
1588
1589         s = glCreateShader(type);
1590         glShaderSource(s, 1, &source, NULL);
1591         glCompileShader(s);
1592         glGetShaderiv(s, GL_COMPILE_STATUS, &status);
1593         if (!status) {
1594                 glGetShaderInfoLog(s, sizeof msg, NULL, msg);
1595                 fprintf(stderr, "shader info: %s\n", msg);
1596                 return GL_NONE;
1597         }
1598
1599         return s;
1600 }
1601
1602 static int
1603 wlsc_shader_init(struct wlsc_shader *shader,
1604                  const char *vertex_source, const char *fragment_source)
1605 {
1606         char msg[512];
1607         GLint status;
1608
1609         shader->vertex_shader =
1610                 compile_shader(GL_VERTEX_SHADER, vertex_source);
1611         shader->fragment_shader =
1612                 compile_shader(GL_FRAGMENT_SHADER, fragment_source);
1613
1614         shader->program = glCreateProgram();
1615         glAttachShader(shader->program, shader->vertex_shader);
1616         glAttachShader(shader->program, shader->fragment_shader);
1617         glBindAttribLocation(shader->program, 0, "position");
1618         glBindAttribLocation(shader->program, 1, "texcoord");
1619
1620         glLinkProgram(shader->program);
1621         glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
1622         if (!status) {
1623                 glGetProgramInfoLog(shader->program, sizeof msg, NULL, msg);
1624                 fprintf(stderr, "link info: %s\n", msg);
1625                 return -1;
1626         }
1627
1628         shader->proj_uniform = glGetUniformLocation(shader->program, "proj");
1629         shader->tex_uniform = glGetUniformLocation(shader->program, "tex");
1630
1631         return 0;
1632 }
1633
1634 static int
1635 init_solid_shader(struct wlsc_shader *shader,
1636                   GLuint vertex_shader, const char *fragment_source)
1637 {
1638         GLint status;
1639         char msg[512];
1640
1641         shader->vertex_shader = vertex_shader;
1642         shader->fragment_shader =
1643                 compile_shader(GL_FRAGMENT_SHADER, fragment_source);
1644
1645         shader->program = glCreateProgram();
1646         glAttachShader(shader->program, shader->vertex_shader);
1647         glAttachShader(shader->program, shader->fragment_shader);
1648         glBindAttribLocation(shader->program, 0, "position");
1649         glBindAttribLocation(shader->program, 1, "texcoord");
1650
1651         glLinkProgram(shader->program);
1652         glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
1653         if (!status) {
1654                 glGetProgramInfoLog(shader->program, sizeof msg, NULL, msg);
1655                 fprintf(stderr, "link info: %s\n", msg);
1656                 return -1;
1657         }
1658  
1659         shader->proj_uniform = glGetUniformLocation(shader->program, "proj");
1660         shader->color_uniform = glGetUniformLocation(shader->program, "color");
1661
1662         return 0;
1663 }
1664
1665 WL_EXPORT void
1666 wlsc_output_destroy(struct wlsc_output *output)
1667 {
1668         destroy_surface(&output->background->surface.resource, NULL);
1669 }
1670
1671 WL_EXPORT void
1672 wlsc_output_move(struct wlsc_output *output, int x, int y)
1673 {
1674         struct wlsc_compositor *c = output->compositor;
1675         int flip;
1676
1677         output->x = x;
1678         output->y = y;
1679
1680         if (output->background) {
1681                 output->background->x = x;
1682                 output->background->y = y;
1683         }
1684
1685         pixman_region32_init(&output->previous_damage_region);
1686
1687         wlsc_matrix_init(&output->matrix);
1688         wlsc_matrix_translate(&output->matrix,
1689                               -output->x - output->width / 2.0,
1690                               -output->y - output->height / 2.0, 0);
1691
1692         flip = (output->flags & WL_OUTPUT_FLIPPED) ? -1 : 1;
1693         wlsc_matrix_scale(&output->matrix,
1694                           2.0 / output->width,
1695                           flip * 2.0 / output->height, 1);
1696
1697         pixman_region32_union_rect(&c->damage_region,
1698                                    &c->damage_region,
1699                                    x, y, output->width, output->height);
1700 }
1701
1702 WL_EXPORT void
1703 wlsc_output_init(struct wlsc_output *output, struct wlsc_compositor *c,
1704                  int x, int y, int width, int height, uint32_t flags)
1705 {
1706         output->compositor = c;
1707         output->x = x;
1708         output->y = y;
1709         output->width = width;
1710         output->height = height;
1711
1712         output->background =
1713                 background_create(output, option_background);
1714
1715         output->flags = flags;
1716         output->finished = 1;
1717         wlsc_output_move(output, x, y);
1718
1719         output->scanout_buffer_destroy_listener.func =
1720                 output_handle_scanout_buffer_destroy;
1721         wl_list_init(&output->scanout_buffer_destroy_listener.link);
1722
1723         output->object.interface = &wl_output_interface;
1724         wl_display_add_object(c->wl_display, &output->object);
1725         wl_display_add_global(c->wl_display, &output->object,
1726                               wlsc_output_post_geometry);
1727 }
1728
1729 static void
1730 shm_buffer_created(struct wl_buffer *buffer)
1731 {
1732         struct wl_list *surfaces_attached_to;
1733
1734         surfaces_attached_to = malloc(sizeof *surfaces_attached_to);
1735         if (!surfaces_attached_to) {
1736                 buffer->user_data = NULL;
1737                 return;
1738         }
1739
1740         wl_list_init(surfaces_attached_to);
1741
1742         buffer->user_data = surfaces_attached_to;
1743 }
1744
1745 static void
1746 shm_buffer_damaged(struct wl_buffer *buffer,
1747                    int32_t x, int32_t y, int32_t width, int32_t height)
1748 {
1749         struct wl_list *surfaces_attached_to = buffer->user_data;
1750         struct wlsc_surface *es;
1751         GLsizei tex_width = wl_shm_buffer_get_stride(buffer) / 4;
1752
1753         wl_list_for_each(es, surfaces_attached_to, buffer_link) {
1754                 glBindTexture(GL_TEXTURE_2D, es->texture);
1755                 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
1756                              tex_width, buffer->height, 0,
1757                              GL_BGRA_EXT, GL_UNSIGNED_BYTE,
1758                              wl_shm_buffer_get_data(buffer));
1759                 /* Hmm, should use glTexSubImage2D() here but GLES2 doesn't
1760                  * support any unpack attributes except GL_UNPACK_ALIGNMENT. */
1761         }
1762 }
1763
1764 static void
1765 shm_buffer_destroyed(struct wl_buffer *buffer)
1766 {
1767         struct wl_list *surfaces_attached_to = buffer->user_data;
1768         struct wlsc_surface *es, *next;
1769
1770         wl_list_for_each_safe(es, next, surfaces_attached_to, buffer_link) {
1771                 wl_list_remove(&es->buffer_link);
1772                 wl_list_init(&es->buffer_link);
1773         }
1774
1775         free(surfaces_attached_to);
1776 }
1777
1778 const static struct wl_shm_callbacks shm_callbacks = {
1779         shm_buffer_created,
1780         shm_buffer_damaged,
1781         shm_buffer_destroyed
1782 };
1783
1784 WL_EXPORT int
1785 wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display)
1786 {
1787         struct wl_event_loop *loop;
1788         const char *extensions;
1789
1790         ec->wl_display = display;
1791
1792         wl_compositor_init(&ec->compositor, &compositor_interface, display);
1793
1794         ec->shm = wl_shm_init(display, &shm_callbacks);
1795
1796         ec->image_target_texture_2d =
1797                 (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
1798         ec->image_target_renderbuffer_storage = (void *)
1799                 eglGetProcAddress("glEGLImageTargetRenderbufferStorageOES");
1800         ec->create_image = (void *) eglGetProcAddress("eglCreateImageKHR");
1801         ec->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
1802         ec->bind_display =
1803                 (void *) eglGetProcAddress("eglBindWaylandDisplayWL");
1804         ec->unbind_display =
1805                 (void *) eglGetProcAddress("eglUnbindWaylandDisplayWL");
1806
1807         extensions = (const char *) glGetString(GL_EXTENSIONS);
1808         if (!strstr(extensions, "GL_EXT_texture_format_BGRA8888")) {
1809                 fprintf(stderr,
1810                         "GL_EXT_texture_format_BGRA8888 not available\n");
1811                 return -1;
1812         }
1813
1814         extensions =
1815                 (const char *) eglQueryString(ec->display, EGL_EXTENSIONS);
1816         if (strstr(extensions, "EGL_WL_bind_wayland_display"))
1817                 ec->has_bind_display = 1;
1818         if (ec->has_bind_display)
1819                 ec->bind_display(ec->display, ec->wl_display);
1820
1821         wl_list_init(&ec->surface_list);
1822         wl_list_init(&ec->input_device_list);
1823         wl_list_init(&ec->output_list);
1824         wl_list_init(&ec->binding_list);
1825         wl_list_init(&ec->animation_list);
1826         wlsc_spring_init(&ec->fade.spring, 0.8, 0.0, 0.0);
1827         ec->fade.animation.frame = fade_frame;
1828         wl_list_init(&ec->fade.animation.link);
1829
1830         wlsc_compositor_add_binding(ec, KEY_BACKSPACE, 0,
1831                                     MODIFIER_CTRL | MODIFIER_ALT,
1832                                     terminate_binding, ec);
1833
1834         create_pointer_images(ec);
1835
1836         screenshooter_create(ec);
1837
1838         glActiveTexture(GL_TEXTURE0);
1839
1840         if (wlsc_shader_init(&ec->texture_shader,
1841                              vertex_shader, texture_fragment_shader) < 0)
1842                 return -1;
1843         if (init_solid_shader(&ec->solid_shader,
1844                               ec->texture_shader.vertex_shader,
1845                               solid_fragment_shader) < 0)
1846                 return -1;
1847
1848         loop = wl_display_get_event_loop(ec->wl_display);
1849         ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
1850         wl_event_source_timer_update(ec->idle_source, option_idle_time * 1000);
1851
1852         ec->timer_source = wl_event_loop_add_timer(loop, repaint, ec);
1853         pixman_region32_init(&ec->damage_region);
1854         wlsc_compositor_schedule_repaint(ec);
1855
1856         return 0;
1857 }
1858
1859 static int on_term_signal(int signal_number, void *data)
1860 {
1861         struct wlsc_compositor *ec = data;
1862
1863         wl_display_terminate(ec->wl_display);
1864
1865         return 1;
1866 }
1867
1868 static void *
1869 load_module(const char *name, const char *entrypoint, void **handle)
1870 {
1871         char path[PATH_MAX];
1872         void *module, *init;
1873
1874         if (name[0] != '/')
1875                 snprintf(path, sizeof path, MODULEDIR "/%s", name);
1876         else
1877                 snprintf(path, sizeof path, "%s", name);
1878
1879         module = dlopen(path, RTLD_LAZY);
1880         if (!module) {
1881                 fprintf(stderr,
1882                         "failed to load module: %s\n", dlerror());
1883                 return NULL;
1884         }
1885
1886         init = dlsym(module, entrypoint);
1887         if (!init) {
1888                 fprintf(stderr,
1889                         "failed to lookup init function: %s\n", dlerror());
1890                 return NULL;
1891         }
1892
1893         return init;
1894 }
1895
1896 int main(int argc, char *argv[])
1897 {
1898         struct wl_display *display;
1899         struct wlsc_compositor *ec;
1900         struct wl_event_loop *loop;
1901         int o;
1902         void *shell_module, *backend_module;
1903         int (*shell_init)(struct wlsc_compositor *ec);
1904         struct wlsc_compositor
1905                 *(*backend_init)(struct wl_display *display, char *options);
1906         char *backend = NULL;
1907         char *backend_options = "";
1908         char *shell = NULL;
1909         char *p;
1910
1911         static const char opts[] = "B:b:o:S:i:s:";
1912         static const struct option longopts[ ] = {
1913                 { "backend", 1, NULL, 'B' },
1914                 { "backend-options", 1, NULL, 'o' },
1915                 { "background", 1, NULL, 'b' },
1916                 { "socket", 1, NULL, 'S' },
1917                 { "idle-time", 1, NULL, 'i' },
1918                 { "shell", 1, NULL, 's' },
1919                 { NULL, }
1920         };
1921
1922         while (o = getopt_long(argc, argv, opts, longopts, &o), o > 0) {
1923                 switch (o) {
1924                 case 'b':
1925                         option_background = optarg;
1926                         break;
1927                 case 'B':
1928                         backend = optarg;
1929                         break;
1930                 case 'o':
1931                         backend_options = optarg;
1932                         break;
1933                 case 'S':
1934                         option_socket_name = optarg;
1935                         break;
1936                 case 'i':
1937                         option_idle_time = strtol(optarg, &p, 0);
1938                         if (*p != '\0') {
1939                                 fprintf(stderr,
1940                                         "invalid idle time option: %s\n",
1941                                         optarg);
1942                                 exit(EXIT_FAILURE);
1943                         }
1944                         break;
1945                 case 's':
1946                         shell = optarg;
1947                         break;
1948                 }
1949         }
1950
1951         display = wl_display_create();
1952
1953         ec = NULL;
1954
1955         if (!backend) {
1956                 if (getenv("WAYLAND_DISPLAY"))
1957                         backend = "wayland-backend.so";
1958                 else if (getenv("DISPLAY"))
1959                         backend = "x11-backend.so";
1960                 else if (getenv("OPENWFD"))
1961                         backend = "openwfd-backend.so";
1962                 else
1963                         backend = "drm-backend.so";
1964         }
1965
1966         if (!shell)
1967                 shell = "desktop-shell.so";
1968
1969         backend_init = load_module(backend, "backend_init", &backend_module);
1970         if (!backend_init)
1971                 exit(EXIT_FAILURE);
1972
1973         shell_init = load_module(shell, "shell_init", &shell_module);
1974         if (!shell_init)
1975                 exit(EXIT_FAILURE);
1976
1977         ec = backend_init(display, backend_options);
1978         if (ec == NULL) {
1979                 fprintf(stderr, "failed to create compositor\n");
1980                 exit(EXIT_FAILURE);
1981         }
1982
1983         if (shell_init(ec) < 0)
1984                 exit(EXIT_FAILURE);
1985
1986         if (wl_display_add_socket(display, option_socket_name)) {
1987                 fprintf(stderr, "failed to add socket: %m\n");
1988                 exit(EXIT_FAILURE);
1989         }
1990
1991         loop = wl_display_get_event_loop(ec->wl_display);
1992         wl_event_loop_add_signal(loop, SIGTERM, on_term_signal, ec);
1993         wl_event_loop_add_signal(loop, SIGINT, on_term_signal, ec);
1994
1995         wl_display_run(display);
1996
1997         if (ec->has_bind_display)
1998                 ec->unbind_display(ec->display, display);
1999         wl_display_destroy(display);
2000
2001         ec->destroy(ec);
2002
2003         return 0;
2004 }