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