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