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