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