compositor: refactor surface_attach()
[profile/ivi/weston-ivi-shell.git] / src / compositor.c
1 /*
2  * Copyright © 2010-2011 Intel Corporation
3  * Copyright © 2008-2011 Kristian Høgsberg
4  * Copyright © 2012 Collabora, Ltd.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and
7  * its documentation for any purpose is hereby granted without fee, provided
8  * that the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of the copyright holders not be used in
11  * advertising or publicity pertaining to distribution of the software
12  * without specific, written prior permission.  The copyright holders make
13  * no representations about the suitability of this software for any
14  * purpose.  It is provided "as is" without express or implied warranty.
15  *
16  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
21  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  */
24
25 #define _GNU_SOURCE
26
27 #include "config.h"
28
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <stdint.h>
33 #include <limits.h>
34 #include <stdarg.h>
35 #include <assert.h>
36 #include <sys/ioctl.h>
37 #include <sys/wait.h>
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <fcntl.h>
41 #include <unistd.h>
42 #include <math.h>
43 #include <linux/input.h>
44 #include <dlfcn.h>
45 #include <signal.h>
46 #include <setjmp.h>
47 #include <execinfo.h>
48
49 #include <wayland-server.h>
50 #include "compositor.h"
51
52 static struct wl_list child_process_list;
53 static jmp_buf segv_jmp_buf;
54
55 static int
56 sigchld_handler(int signal_number, void *data)
57 {
58         struct weston_process *p;
59         int status;
60         pid_t pid;
61
62         pid = waitpid(-1, &status, WNOHANG);
63         if (!pid)
64                 return 1;
65
66         wl_list_for_each(p, &child_process_list, link) {
67                 if (p->pid == pid)
68                         break;
69         }
70
71         if (&p->link == &child_process_list) {
72                 fprintf(stderr, "unknown child process exited\n");
73                 return 1;
74         }
75
76         wl_list_remove(&p->link);
77         p->cleanup(p, status);
78
79         return 1;
80 }
81
82 WL_EXPORT void
83 weston_watch_process(struct weston_process *process)
84 {
85         wl_list_insert(&child_process_list, &process->link);
86 }
87
88 static void
89 child_client_exec(int sockfd, const char *path)
90 {
91         int clientfd;
92         char s[32];
93         sigset_t allsigs;
94
95         /* do not give our signal mask to the new process */
96         sigfillset(&allsigs);
97         sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
98
99         /* Launch clients as the user. */
100         seteuid(getuid());
101
102         /* SOCK_CLOEXEC closes both ends, so we dup the fd to get a
103          * non-CLOEXEC fd to pass through exec. */
104         clientfd = dup(sockfd);
105         if (clientfd == -1) {
106                 fprintf(stderr, "compositor: dup failed: %m\n");
107                 return;
108         }
109
110         snprintf(s, sizeof s, "%d", clientfd);
111         setenv("WAYLAND_SOCKET", s, 1);
112
113         if (execl(path, path, NULL) < 0)
114                 fprintf(stderr, "compositor: executing '%s' failed: %m\n",
115                         path);
116 }
117
118 WL_EXPORT struct wl_client *
119 weston_client_launch(struct weston_compositor *compositor,
120                      struct weston_process *proc,
121                      const char *path,
122                      weston_process_cleanup_func_t cleanup)
123 {
124         int sv[2];
125         pid_t pid;
126         struct wl_client *client;
127
128         if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
129                 fprintf(stderr, "weston_client_launch: "
130                         "socketpair failed while launching '%s': %m\n",
131                         path);
132                 return NULL;
133         }
134
135         pid = fork();
136         if (pid == -1) {
137                 close(sv[0]);
138                 close(sv[1]);
139                 fprintf(stderr,  "weston_client_launch: "
140                         "fork failed while launching '%s': %m\n", path);
141                 return NULL;
142         }
143
144         if (pid == 0) {
145                 child_client_exec(sv[1], path);
146                 exit(-1);
147         }
148
149         close(sv[1]);
150
151         client = wl_client_create(compositor->wl_display, sv[0]);
152         if (!client) {
153                 close(sv[0]);
154                 fprintf(stderr, "weston_client_launch: "
155                         "wl_client_create failed while launching '%s'.\n",
156                         path);
157                 return NULL;
158         }
159
160         proc->pid = pid;
161         proc->cleanup = cleanup;
162         weston_watch_process(proc);
163
164         return client;
165 }
166
167 static void
168 surface_handle_buffer_destroy(struct wl_listener *listener,
169                               struct wl_resource *resource, uint32_t time)
170 {
171         struct weston_surface *es =
172                 container_of(listener, struct weston_surface, 
173                              buffer_destroy_listener);
174
175         es->buffer = NULL;
176 }
177
178 static const pixman_region32_data_t undef_region_data;
179
180 static void
181 undef_region(pixman_region32_t *region)
182 {
183         pixman_region32_fini(region);
184         region->data = (pixman_region32_data_t *) &undef_region_data;
185 }
186
187 static int
188 region_is_undefined(pixman_region32_t *region)
189 {
190         return region->data == &undef_region_data;
191 }
192
193 static void
194 empty_region(pixman_region32_t *region)
195 {
196         if (!region_is_undefined(region))
197                 pixman_region32_fini(region);
198
199         pixman_region32_init(region);
200 }
201
202 WL_EXPORT struct weston_surface *
203 weston_surface_create(struct weston_compositor *compositor)
204 {
205         struct weston_surface *surface;
206
207         surface = calloc(1, sizeof *surface);
208         if (surface == NULL)
209                 return NULL;
210
211         wl_list_init(&surface->surface.resource.destroy_listener_list);
212
213         wl_list_init(&surface->link);
214         wl_list_init(&surface->layer_link);
215
216         surface->surface.resource.client = NULL;
217
218         surface->compositor = compositor;
219         surface->image = EGL_NO_IMAGE_KHR;
220         surface->alpha = 255;
221         surface->pitch = 1;
222
223         surface->buffer = NULL;
224         surface->output = NULL;
225         surface->force_configure = 0;
226
227         pixman_region32_init(&surface->damage);
228         pixman_region32_init(&surface->opaque);
229         pixman_region32_init(&surface->clip);
230         undef_region(&surface->input);
231         pixman_region32_init(&surface->transform.opaque);
232         wl_list_init(&surface->frame_callback_list);
233
234         surface->buffer_destroy_listener.func = surface_handle_buffer_destroy;
235
236         wl_list_init(&surface->geometry.transformation_list);
237         wl_list_insert(&surface->geometry.transformation_list,
238                        &surface->transform.position.link);
239         weston_matrix_init(&surface->transform.position.matrix);
240         pixman_region32_init(&surface->transform.boundingbox);
241         surface->geometry.dirty = 1;
242
243         return surface;
244 }
245
246 WL_EXPORT void
247 weston_surface_set_color(struct weston_surface *surface,
248                  GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
249 {
250         surface->color[0] = red;
251         surface->color[1] = green;
252         surface->color[2] = blue;
253         surface->color[3] = alpha;
254         surface->shader = &surface->compositor->solid_shader;
255 }
256
257 static void
258 surface_to_global_float(struct weston_surface *surface,
259                         int32_t sx, int32_t sy, GLfloat *x, GLfloat *y)
260 {
261         if (surface->transform.enabled) {
262                 struct weston_vector v = { { sx, sy, 0.0f, 1.0f } };
263
264                 weston_matrix_transform(&surface->transform.matrix, &v);
265
266                 if (fabsf(v.f[3]) < 1e-6) {
267                         fprintf(stderr, "warning: numerical instability in "
268                                 "weston_surface_to_global(), divisor = %g\n",
269                                 v.f[3]);
270                         *x = 0;
271                         *y = 0;
272                         return;
273                 }
274
275                 *x = v.f[0] / v.f[3];
276                 *y = v.f[1] / v.f[3];
277         } else {
278                 *x = sx + surface->geometry.x;
279                 *y = sy + surface->geometry.y;
280         }
281 }
282
283 WL_EXPORT void
284 weston_surface_damage_below(struct weston_surface *surface)
285 {
286         struct weston_compositor *compositor = surface->compositor;
287         pixman_region32_t damage;
288
289         pixman_region32_init(&damage);
290         pixman_region32_subtract(&damage, &surface->transform.boundingbox,
291                                  &surface->clip);
292         pixman_region32_union(&compositor->damage,
293                               &compositor->damage, &damage);
294         pixman_region32_fini(&damage);
295 }
296
297 static void
298 surface_compute_bbox(struct weston_surface *surface, int32_t sx, int32_t sy,
299                      int32_t width, int32_t height,
300                      pixman_region32_t *bbox)
301 {
302         GLfloat min_x = HUGE_VALF,  min_y = HUGE_VALF;
303         GLfloat max_x = -HUGE_VALF, max_y = -HUGE_VALF;
304         int32_t s[4][2] = {
305                 { sx,         sy },
306                 { sx,         sy + height },
307                 { sx + width, sy },
308                 { sx + width, sy + height }
309         };
310         GLfloat int_x, int_y;
311         int i;
312
313         for (i = 0; i < 4; ++i) {
314                 GLfloat x, y;
315                 surface_to_global_float(surface, s[i][0], s[i][1], &x, &y);
316                 if (x < min_x)
317                         min_x = x;
318                 if (x > max_x)
319                         max_x = x;
320                 if (y < min_y)
321                         min_y = y;
322                 if (y > max_y)
323                         max_y = y;
324         }
325
326         int_x = floorf(min_x);
327         int_y = floorf(min_y);
328         pixman_region32_init_rect(bbox, int_x, int_y,
329                                   ceilf(max_x) - int_x, ceilf(max_y) - int_y);
330 }
331
332 static void
333 weston_surface_update_transform_disable(struct weston_surface *surface)
334 {
335         surface->transform.enabled = 0;
336
337         /* round off fractions when not transformed */
338         surface->geometry.x = roundf(surface->geometry.x);
339         surface->geometry.y = roundf(surface->geometry.y);
340
341         pixman_region32_init_rect(&surface->transform.boundingbox,
342                                   surface->geometry.x,
343                                   surface->geometry.y,
344                                   surface->geometry.width,
345                                   surface->geometry.height);
346
347         if (surface->alpha == 255) {
348                 pixman_region32_copy(&surface->transform.opaque,
349                                      &surface->opaque);
350                 pixman_region32_translate(&surface->transform.opaque,
351                                           surface->geometry.x,
352                                           surface->geometry.y);
353         }
354 }
355
356 static int
357 weston_surface_update_transform_enable(struct weston_surface *surface)
358 {
359         struct weston_matrix *matrix = &surface->transform.matrix;
360         struct weston_matrix *inverse = &surface->transform.inverse;
361         struct weston_transform *tform;
362
363         surface->transform.enabled = 1;
364
365         /* Otherwise identity matrix, but with x and y translation. */
366         surface->transform.position.matrix.d[12] = surface->geometry.x;
367         surface->transform.position.matrix.d[13] = surface->geometry.y;
368
369         weston_matrix_init(matrix);
370         wl_list_for_each(tform, &surface->geometry.transformation_list, link)
371                 weston_matrix_multiply(matrix, &tform->matrix);
372
373         if (weston_matrix_invert(inverse, matrix) < 0) {
374                 /* Oops, bad total transformation, not invertible */
375                 fprintf(stderr, "error: weston_surface %p"
376                         " transformation not invertible.\n", surface);
377                 return -1;
378         }
379
380         surface_compute_bbox(surface, 0, 0, surface->geometry.width,
381                              surface->geometry.height,
382                              &surface->transform.boundingbox);
383
384         return 0;
385 }
386
387 WL_EXPORT void
388 weston_surface_update_transform(struct weston_surface *surface)
389 {
390         if (!surface->geometry.dirty)
391                 return;
392
393         surface->geometry.dirty = 0;
394
395         weston_surface_damage_below(surface);
396
397         pixman_region32_fini(&surface->transform.boundingbox);
398         pixman_region32_fini(&surface->transform.opaque);
399         pixman_region32_init(&surface->transform.opaque);
400
401         if (region_is_undefined(&surface->input))
402                 pixman_region32_init_rect(&surface->input, 0, 0, 
403                                           surface->geometry.width,
404                                           surface->geometry.height);
405
406         /* transform.position is always in transformation_list */
407         if (surface->geometry.transformation_list.next ==
408             &surface->transform.position.link &&
409             surface->geometry.transformation_list.prev ==
410             &surface->transform.position.link) {
411                 weston_surface_update_transform_disable(surface);
412         } else {
413                 if (weston_surface_update_transform_enable(surface) < 0)
414                         weston_surface_update_transform_disable(surface);
415         }
416
417         /* weston_surface_damage() without update */
418         pixman_region32_union(&surface->damage, &surface->damage,
419                               &surface->transform.boundingbox);
420
421         if (weston_surface_is_mapped(surface))
422                 weston_surface_assign_output(surface);
423
424         weston_compositor_schedule_repaint(surface->compositor);
425 }
426
427 WL_EXPORT void
428 weston_surface_to_global_float(struct weston_surface *surface,
429                                int32_t sx, int32_t sy, GLfloat *x, GLfloat *y)
430 {
431         weston_surface_update_transform(surface);
432
433         surface_to_global_float(surface, sx, sy, x, y);
434 }
435
436 WL_EXPORT void
437 weston_surface_to_global(struct weston_surface *surface,
438                          int32_t sx, int32_t sy, int32_t *x, int32_t *y)
439 {
440         GLfloat xf, yf;
441
442         weston_surface_to_global_float(surface, sx, sy, &xf, &yf);
443         *x = floorf(xf);
444         *y = floorf(yf);
445 }
446
447 static void
448 surface_from_global_float(struct weston_surface *surface,
449                           int32_t x, int32_t y, GLfloat *sx, GLfloat *sy)
450 {
451         if (surface->transform.enabled) {
452                 struct weston_vector v = { { x, y, 0.0f, 1.0f } };
453
454                 weston_matrix_transform(&surface->transform.inverse, &v);
455
456                 if (fabsf(v.f[3]) < 1e-6) {
457                         fprintf(stderr, "warning: numerical instability in "
458                                 "weston_surface_from_global(), divisor = %g\n",
459                                 v.f[3]);
460                         *sx = 0;
461                         *sy = 0;
462                         return;
463                 }
464
465                 *sx = v.f[0] / v.f[3];
466                 *sy = v.f[1] / v.f[3];
467         } else {
468                 *sx = x - surface->geometry.x;
469                 *sy = y - surface->geometry.y;
470         }
471 }
472
473 WL_EXPORT void
474 weston_surface_from_global(struct weston_surface *surface,
475                            int32_t x, int32_t y, int32_t *sx, int32_t *sy)
476 {
477         GLfloat sxf, syf;
478
479         weston_surface_update_transform(surface);
480
481         surface_from_global_float(surface, x, y, &sxf, &syf);
482         *sx = floorf(sxf);
483         *sy = floorf(syf);
484 }
485
486 static void
487 weston_surface_damage_rectangle(struct weston_surface *surface,
488                                 int32_t sx, int32_t sy,
489                                 int32_t width, int32_t height)
490 {
491         weston_surface_update_transform(surface);
492
493         if (surface->transform.enabled) {
494                 pixman_region32_t box;
495                 surface_compute_bbox(surface, sx, sy, width, height, &box);
496                 pixman_region32_union(&surface->damage, &surface->damage,
497                                       &box);
498                 pixman_region32_fini(&box);
499         } else {
500                 pixman_region32_union_rect(&surface->damage, &surface->damage,
501                                            surface->geometry.x + sx,
502                                            surface->geometry.y + sy,
503                                            width, height);
504         }
505
506         weston_compositor_schedule_repaint(surface->compositor);
507 }
508
509 WL_EXPORT void
510 weston_surface_damage(struct weston_surface *surface)
511 {
512         weston_surface_update_transform(surface);
513
514         pixman_region32_union(&surface->damage, &surface->damage,
515                               &surface->transform.boundingbox);
516
517         weston_compositor_schedule_repaint(surface->compositor);
518 }
519
520 WL_EXPORT void
521 weston_surface_configure(struct weston_surface *surface,
522                          GLfloat x, GLfloat y, int width, int height)
523 {
524         surface->geometry.x = x;
525         surface->geometry.y = y;
526         surface->geometry.width = width;
527         surface->geometry.height = height;
528         surface->geometry.dirty = 1;
529 }
530
531 WL_EXPORT void
532 weston_surface_set_position(struct weston_surface *surface,
533                             GLfloat x, GLfloat y)
534 {
535         surface->geometry.x = x;
536         surface->geometry.y = y;
537         surface->geometry.dirty = 1;
538 }
539
540 WL_EXPORT int
541 weston_surface_is_mapped(struct weston_surface *surface)
542 {
543         if (surface->output)
544                 return 1;
545         else
546                 return 0;
547 }
548
549 WL_EXPORT uint32_t
550 weston_compositor_get_time(void)
551 {
552         struct timeval tv;
553
554         gettimeofday(&tv, NULL);
555
556         return tv.tv_sec * 1000 + tv.tv_usec / 1000;
557 }
558
559 static struct weston_surface *
560 weston_compositor_pick_surface(struct weston_compositor *compositor,
561                                int32_t x, int32_t y, int32_t *sx, int32_t *sy)
562 {
563         struct weston_surface *surface;
564
565         wl_list_for_each(surface, &compositor->surface_list, link) {
566                 weston_surface_from_global(surface, x, y, sx, sy);
567                 if (pixman_region32_contains_point(&surface->input,
568                                                    *sx, *sy, NULL))
569                         return surface;
570         }
571
572         return NULL;
573 }
574
575 static void
576 weston_device_repick(struct wl_input_device *device, uint32_t time)
577 {
578         struct weston_input_device *wd = (struct weston_input_device *) device;
579         const struct wl_pointer_grab_interface *interface;
580         struct weston_surface *surface, *focus;
581
582         surface = weston_compositor_pick_surface(wd->compositor,
583                                                  device->x, device->y,
584                                                  &device->current_x,
585                                                  &device->current_y);
586
587         if (&surface->surface != device->current) {
588                 interface = device->pointer_grab->interface;
589                 interface->focus(device->pointer_grab, time, &surface->surface,
590                                  device->current_x, device->current_y);
591                 device->current = &surface->surface;
592         }
593
594         focus = (struct weston_surface *) device->pointer_grab->focus;
595         if (focus)
596                 weston_surface_from_global(focus, device->x, device->y,
597                                            &device->pointer_grab->x, &device->pointer_grab->y);
598 }
599
600 WL_EXPORT void
601 weston_compositor_repick(struct weston_compositor *compositor)
602 {
603         struct weston_input_device *device;
604         uint32_t time;
605
606         if (!compositor->focus)
607                 return;
608
609         time = weston_compositor_get_time();
610         wl_list_for_each(device, &compositor->input_device_list, link)
611                 weston_device_repick(&device->input_device, time);
612 }
613
614 static void
615 weston_surface_unmap(struct weston_surface *surface)
616 {
617         struct wl_input_device *device = surface->compositor->input_device;
618
619         weston_surface_damage_below(surface);
620         surface->output = NULL;
621         wl_list_remove(&surface->link);
622         wl_list_remove(&surface->layer_link);
623
624         if (device->keyboard_focus == &surface->surface)
625                 wl_input_device_set_keyboard_focus(device, NULL,
626                                                    weston_compositor_get_time());
627         if (device->pointer_focus == &surface->surface)
628                 wl_input_device_set_pointer_focus(device, NULL, 0, 0,
629                                                   weston_compositor_get_time());
630
631         weston_compositor_schedule_repaint(surface->compositor);
632 }
633
634 static void
635 destroy_surface(struct wl_resource *resource)
636 {
637         struct weston_surface *surface =
638                 container_of(resource,
639                              struct weston_surface, surface.resource);
640         struct weston_compositor *compositor = surface->compositor;
641
642         if (weston_surface_is_mapped(surface))
643                 weston_surface_unmap(surface);
644
645         if (surface->texture)
646                 glDeleteTextures(1, &surface->texture);
647
648         if (surface->buffer)
649                 wl_list_remove(&surface->buffer_destroy_listener.link);
650
651         if (surface->image != EGL_NO_IMAGE_KHR)
652                 compositor->destroy_image(compositor->display,
653                                           surface->image);
654
655         pixman_region32_fini(&surface->transform.boundingbox);
656         pixman_region32_fini(&surface->damage);
657         pixman_region32_fini(&surface->opaque);
658         pixman_region32_fini(&surface->clip);
659         if (!region_is_undefined(&surface->input))
660                 pixman_region32_fini(&surface->input);
661
662         free(surface);
663 }
664
665 WL_EXPORT void
666 weston_surface_destroy(struct weston_surface *surface)
667 {
668         /* Not a valid way to destroy a client surface */
669         assert(surface->surface.resource.client == NULL);
670
671         destroy_surface(&surface->surface.resource);
672 }
673
674 static void
675 weston_buffer_attach(struct wl_buffer *buffer, struct wl_surface *surface)
676 {
677         struct weston_surface *es = (struct weston_surface *) surface;
678         struct weston_compositor *ec = es->compositor;
679
680         if (es->buffer) {
681                 weston_buffer_post_release(es->buffer);
682                 wl_list_remove(&es->buffer_destroy_listener.link);
683         }
684
685         es->buffer = buffer;
686
687         if (!buffer) {
688                 if (weston_surface_is_mapped(es))
689                         weston_surface_unmap(es);
690                 return;
691         }
692
693         buffer->busy_count++;
694         wl_list_insert(es->buffer->resource.destroy_listener_list.prev,
695                        &es->buffer_destroy_listener.link);
696
697         if (es->geometry.width != buffer->width ||
698             es->geometry.height != buffer->height) {
699                 undef_region(&es->input);
700                 pixman_region32_fini(&es->opaque);
701                 pixman_region32_init(&es->opaque);
702         }
703
704         if (!es->texture) {
705                 glGenTextures(1, &es->texture);
706                 glBindTexture(GL_TEXTURE_2D, es->texture);
707                 glTexParameteri(GL_TEXTURE_2D,
708                                 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
709                 glTexParameteri(GL_TEXTURE_2D,
710                                 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
711                 es->shader = &ec->texture_shader;
712         } else {
713                 glBindTexture(GL_TEXTURE_2D, es->texture);
714         }
715
716         if (wl_buffer_is_shm(buffer)) {
717                 es->pitch = wl_shm_buffer_get_stride(buffer) / 4;
718         } else {
719                 if (es->image != EGL_NO_IMAGE_KHR)
720                         ec->destroy_image(ec->display, es->image);
721                 es->image = ec->create_image(ec->display, NULL,
722                                              EGL_WAYLAND_BUFFER_WL,
723                                              buffer, NULL);
724
725                 ec->image_target_texture_2d(GL_TEXTURE_2D, es->image);
726
727                 es->pitch = buffer->width;
728         }
729 }
730
731 static int
732 texture_region(struct weston_surface *es, pixman_region32_t *region)
733 {
734         struct weston_compositor *ec = es->compositor;
735         GLfloat *v, inv_width, inv_height;
736         GLfloat sx, sy;
737         pixman_box32_t *rectangles;
738         unsigned int *p;
739         int i, n;
740
741         rectangles = pixman_region32_rectangles(region, &n);
742         v = wl_array_add(&ec->vertices, n * 16 * sizeof *v);
743         p = wl_array_add(&ec->indices, n * 6 * sizeof *p);
744         inv_width = 1.0 / es->pitch;
745         inv_height = 1.0 / es->geometry.height;
746
747         for (i = 0; i < n; i++, v += 16, p += 6) {
748                 surface_from_global_float(es, rectangles[i].x1,
749                                           rectangles[i].y1, &sx, &sy);
750                 v[ 0] = rectangles[i].x1;
751                 v[ 1] = rectangles[i].y1;
752                 v[ 2] = sx * inv_width;
753                 v[ 3] = sy * inv_height;
754
755                 surface_from_global_float(es, rectangles[i].x1,
756                                           rectangles[i].y2, &sx, &sy);
757                 v[ 4] = rectangles[i].x1;
758                 v[ 5] = rectangles[i].y2;
759                 v[ 6] = sx * inv_width;
760                 v[ 7] = sy * inv_height;
761
762                 surface_from_global_float(es, rectangles[i].x2,
763                                           rectangles[i].y1, &sx, &sy);
764                 v[ 8] = rectangles[i].x2;
765                 v[ 9] = rectangles[i].y1;
766                 v[10] = sx * inv_width;
767                 v[11] = sy * inv_height;
768
769                 surface_from_global_float(es, rectangles[i].x2,
770                                           rectangles[i].y2, &sx, &sy);
771                 v[12] = rectangles[i].x2;
772                 v[13] = rectangles[i].y2;
773                 v[14] = sx * inv_width;
774                 v[15] = sy * inv_height;
775
776                 p[0] = i * 4 + 0;
777                 p[1] = i * 4 + 1;
778                 p[2] = i * 4 + 2;
779                 p[3] = i * 4 + 2;
780                 p[4] = i * 4 + 1;
781                 p[5] = i * 4 + 3;
782         }
783
784         return n;
785 }
786
787 WL_EXPORT void
788 weston_surface_draw(struct weston_surface *es, struct weston_output *output,
789                     pixman_region32_t *damage)
790 {
791         struct weston_compositor *ec = es->compositor;
792         GLfloat *v;
793         pixman_region32_t repaint;
794         GLint filter;
795         int n;
796
797         pixman_region32_init(&repaint);
798         pixman_region32_intersect(&repaint,
799                                   &es->transform.boundingbox, damage);
800         pixman_region32_subtract(&repaint, &repaint, &es->clip);
801
802         if (!pixman_region32_not_empty(&repaint))
803                 goto out;
804
805         glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
806         glEnable(GL_BLEND);
807
808         if (ec->current_shader != es->shader) {
809                 glUseProgram(es->shader->program);
810                 ec->current_shader = es->shader;
811         }
812
813         glUniformMatrix4fv(es->shader->proj_uniform,
814                            1, GL_FALSE, output->matrix.d);
815         glUniform1i(es->shader->tex_uniform, 0);
816         glUniform4fv(es->shader->color_uniform, 1, es->color);
817         glUniform1f(es->shader->alpha_uniform, es->alpha / 255.0);
818         glUniform1f(es->shader->texwidth_uniform,
819                     (GLfloat)es->geometry.width / es->pitch);
820
821         if (es->transform.enabled || output->zoom.active)
822                 filter = GL_LINEAR;
823         else
824                 filter = GL_NEAREST;
825
826         n = texture_region(es, &repaint);
827
828         glBindTexture(GL_TEXTURE_2D, es->texture);
829         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
830         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
831
832         v = ec->vertices.data;
833         glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof *v, &v[0]);
834         glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof *v, &v[2]);
835         glEnableVertexAttribArray(0);
836         glEnableVertexAttribArray(1);
837
838         glDrawElements(GL_TRIANGLES, n * 6, GL_UNSIGNED_INT, ec->indices.data);
839
840         glDisableVertexAttribArray(1);
841         glDisableVertexAttribArray(0);
842
843         ec->vertices.size = 0;
844         ec->indices.size = 0;
845
846 out:
847         pixman_region32_fini(&repaint);
848 }
849
850 WL_EXPORT void
851 weston_surface_restack(struct weston_surface *surface, struct wl_list *below)
852 {
853         wl_list_remove(&surface->layer_link);
854         wl_list_insert(below, &surface->layer_link);
855         weston_surface_damage_below(surface);
856         weston_surface_damage(surface);
857 }
858
859 WL_EXPORT void
860 weston_compositor_damage_all(struct weston_compositor *compositor)
861 {
862         struct weston_output *output;
863
864         wl_list_for_each(output, &compositor->output_list, link)
865                 weston_output_damage(output);
866 }
867
868 WL_EXPORT void
869 weston_buffer_post_release(struct wl_buffer *buffer)
870 {
871         if (--buffer->busy_count > 0)
872                 return;
873
874         assert(buffer->resource.client != NULL);
875         wl_resource_queue_event(&buffer->resource, WL_BUFFER_RELEASE);
876 }
877
878 WL_EXPORT void
879 weston_output_damage(struct weston_output *output)
880 {
881         struct weston_compositor *compositor = output->compositor;
882
883         pixman_region32_union(&compositor->damage,
884                               &compositor->damage, &output->region);
885         weston_compositor_schedule_repaint(compositor);
886 }
887
888 static void
889 fade_frame(struct weston_animation *animation,
890            struct weston_output *output, uint32_t msecs)
891 {
892         struct weston_compositor *compositor =
893                 container_of(animation,
894                              struct weston_compositor, fade.animation);
895         struct weston_surface *surface;
896
897         surface = compositor->fade.surface;
898         weston_spring_update(&compositor->fade.spring, msecs);
899         weston_surface_set_color(surface, 0.0, 0.0, 0.0,
900                                  compositor->fade.spring.current);
901         weston_surface_damage(surface);
902
903         if (weston_spring_done(&compositor->fade.spring)) {
904                 compositor->fade.spring.current =
905                         compositor->fade.spring.target;
906                 wl_list_remove(&animation->link);
907                 wl_list_init(&animation->link);
908
909                 if (compositor->fade.spring.current < 0.001) {
910                         destroy_surface(&surface->surface.resource);
911                         compositor->fade.surface = NULL;
912                 } else if (compositor->fade.spring.current > 0.999) {
913                         compositor->state = WESTON_COMPOSITOR_SLEEPING;
914                         compositor->shell->lock(compositor->shell);
915                 }
916         }
917 }
918
919 struct weston_frame_callback {
920         struct wl_resource resource;
921         struct wl_list link;
922 };
923
924 static void
925 weston_output_repaint(struct weston_output *output, int msecs)
926 {
927         struct weston_compositor *ec = output->compositor;
928         struct weston_surface *es;
929         struct weston_layer *layer;
930         struct weston_animation *animation, *next;
931         struct weston_frame_callback *cb, *cnext;
932         pixman_region32_t opaque, new_damage, output_damage;
933         int32_t width, height;
934
935         weston_compositor_update_drag_surfaces(ec);
936
937         width = output->current->width +
938                 output->border.left + output->border.right;
939         height = output->current->height +
940                 output->border.top + output->border.bottom;
941         glViewport(0, 0, width, height);
942
943         /* Rebuild the surface list and update surface transforms up front. */
944         wl_list_init(&ec->surface_list);
945         wl_list_for_each(layer, &ec->layer_list, link) {
946                 wl_list_for_each(es, &layer->surface_list, layer_link) {
947                         weston_surface_update_transform(es);
948                         wl_list_insert(ec->surface_list.prev, &es->link);
949                 }
950         }
951
952         if (output->assign_planes)
953                 /*
954                  * This will queue flips for the fbs and sprites where
955                  * applicable and clear the damage for those surfaces.
956                  * The repaint loop below will repaint everything
957                  * else.
958                  */
959                 output->assign_planes(output);
960
961         pixman_region32_init(&new_damage);
962         pixman_region32_init(&opaque);
963
964         wl_list_for_each(es, &ec->surface_list, link) {
965                 pixman_region32_subtract(&es->damage, &es->damage, &opaque);
966                 pixman_region32_union(&new_damage, &new_damage, &es->damage);
967                 empty_region(&es->damage);
968                 pixman_region32_copy(&es->clip, &opaque);
969                 pixman_region32_union(&opaque, &opaque, &es->transform.opaque);
970         }
971
972         pixman_region32_union(&ec->damage, &ec->damage, &new_damage);
973
974         pixman_region32_init(&output_damage);
975         pixman_region32_union(&output_damage,
976                               &ec->damage, &output->previous_damage);
977         pixman_region32_copy(&output->previous_damage, &ec->damage);
978         pixman_region32_intersect(&output_damage,
979                                   &output_damage, &output->region);
980         pixman_region32_subtract(&ec->damage, &ec->damage, &output->region);
981
982         pixman_region32_fini(&opaque);
983         pixman_region32_fini(&new_damage);
984
985         if (output->dirty)
986                 weston_output_update_matrix(output);
987
988         output->repaint(output, &output_damage);
989
990         pixman_region32_fini(&output_damage);
991
992         output->repaint_needed = 0;
993
994         weston_compositor_repick(ec);
995         wl_event_loop_dispatch(ec->input_loop, 0);
996
997         wl_list_for_each_safe(cb, cnext, &output->frame_callback_list, link) {
998                 wl_callback_send_done(&cb->resource, msecs);
999                 wl_resource_destroy(&cb->resource, 0);
1000         }
1001
1002         wl_list_for_each_safe(animation, next, &ec->animation_list, link)
1003                 animation->frame(animation, output, msecs);
1004 }
1005
1006 static int
1007 weston_compositor_read_input(int fd, uint32_t mask, void *data)
1008 {
1009         struct weston_compositor *compositor = data;
1010
1011         wl_event_loop_dispatch(compositor->input_loop, 0);
1012
1013         return 1;
1014 }
1015
1016 WL_EXPORT void
1017 weston_output_finish_frame(struct weston_output *output, int msecs)
1018 {
1019         struct weston_compositor *compositor = output->compositor;
1020         struct wl_event_loop *loop =
1021                 wl_display_get_event_loop(compositor->wl_display);
1022         int fd;
1023
1024         if (output->repaint_needed) {
1025                 weston_output_repaint(output, msecs);
1026                 return;
1027         }
1028
1029         output->repaint_scheduled = 0;
1030         if (compositor->input_loop_source)
1031                 return;
1032
1033         fd = wl_event_loop_get_fd(compositor->input_loop);
1034         compositor->input_loop_source =
1035                 wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
1036                                      weston_compositor_read_input, compositor);
1037 }
1038
1039 static void
1040 idle_repaint(void *data)
1041 {
1042         struct weston_output *output = data;
1043
1044         weston_output_finish_frame(output, weston_compositor_get_time());
1045 }
1046
1047 WL_EXPORT void
1048 weston_layer_init(struct weston_layer *layer, struct wl_list *below)
1049 {
1050         wl_list_init(&layer->surface_list);
1051         wl_list_insert(below, &layer->link);
1052 }
1053
1054 WL_EXPORT void
1055 weston_compositor_schedule_repaint(struct weston_compositor *compositor)
1056 {
1057         struct weston_output *output;
1058         struct wl_event_loop *loop;
1059
1060         if (compositor->state == WESTON_COMPOSITOR_SLEEPING)
1061                 return;
1062
1063         loop = wl_display_get_event_loop(compositor->wl_display);
1064         wl_list_for_each(output, &compositor->output_list, link) {
1065                 output->repaint_needed = 1;
1066                 if (output->repaint_scheduled)
1067                         continue;
1068
1069                 wl_event_loop_add_idle(loop, idle_repaint, output);
1070                 output->repaint_scheduled = 1;
1071         }
1072
1073         if (compositor->input_loop_source) {
1074                 wl_event_source_remove(compositor->input_loop_source);
1075                 compositor->input_loop_source = NULL;
1076         }
1077 }
1078
1079 WL_EXPORT void
1080 weston_compositor_fade(struct weston_compositor *compositor, float tint)
1081 {
1082         struct weston_surface *surface;
1083         int done;
1084
1085         done = weston_spring_done(&compositor->fade.spring);
1086         compositor->fade.spring.target = tint;
1087         if (weston_spring_done(&compositor->fade.spring))
1088                 return;
1089
1090         if (done)
1091                 compositor->fade.spring.timestamp =
1092                         weston_compositor_get_time();
1093
1094         if (compositor->fade.surface == NULL) {
1095                 surface = weston_surface_create(compositor);
1096                 weston_surface_configure(surface, 0, 0, 8192, 8192);
1097                 weston_surface_set_color(surface, 0.0, 0.0, 0.0, 0.0);
1098                 wl_list_insert(&compositor->fade_layer.surface_list,
1099                                &surface->layer_link);
1100                 weston_surface_assign_output(surface);
1101                 compositor->fade.surface = surface;
1102                 pixman_region32_init(&surface->input);
1103         }
1104
1105         weston_surface_damage(compositor->fade.surface);
1106         if (wl_list_empty(&compositor->fade.animation.link))
1107                 wl_list_insert(compositor->animation_list.prev,
1108                                &compositor->fade.animation.link);
1109 }
1110
1111 static void
1112 surface_destroy(struct wl_client *client, struct wl_resource *resource)
1113 {
1114         wl_resource_destroy(resource, weston_compositor_get_time());
1115 }
1116
1117 WL_EXPORT void
1118 weston_surface_assign_output(struct weston_surface *es)
1119 {
1120         struct weston_compositor *ec = es->compositor;
1121         struct weston_output *output, *new_output;
1122         pixman_region32_t region;
1123         uint32_t max, area;
1124         pixman_box32_t *e;
1125
1126         weston_surface_update_transform(es);
1127
1128         new_output = NULL;
1129         max = 0;
1130         pixman_region32_init(&region);
1131         wl_list_for_each(output, &ec->output_list, link) {
1132                 pixman_region32_intersect(&region, &es->transform.boundingbox,
1133                                           &output->region);
1134
1135                 e = pixman_region32_extents(&region);
1136                 area = (e->x2 - e->x1) * (e->y2 - e->y1);
1137
1138                 if (area >= max) {
1139                         new_output = output;
1140                         max = area;
1141                 }
1142         }
1143         pixman_region32_fini(&region);
1144
1145         es->output = new_output;
1146         if (!wl_list_empty(&es->frame_callback_list)) {
1147                 wl_list_insert_list(new_output->frame_callback_list.prev,
1148                                     &es->frame_callback_list);
1149                 wl_list_init(&es->frame_callback_list);
1150         }
1151 }
1152
1153 static void
1154 surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
1155 {
1156         struct weston_shell *shell = es->compositor->shell;
1157
1158         if (!weston_surface_is_mapped(es)) {
1159                 shell->map(shell, es, es->buffer->width, es->buffer->height,
1160                            sx, sy);
1161         } else if (es->force_configure || sx != 0 || sy != 0 ||
1162                    es->geometry.width != es->buffer->width ||
1163                    es->geometry.height != es->buffer->height) {
1164                 GLfloat from_x, from_y;
1165                 GLfloat to_x, to_y;
1166
1167                 surface_to_global_float(es, 0, 0, &from_x, &from_y);
1168                 surface_to_global_float(es, sx, sy, &to_x, &to_y);
1169                 shell->configure(shell, es,
1170                                  es->geometry.x + to_x - from_x,
1171                                  es->geometry.y + to_y - from_y,
1172                                  es->buffer->width, es->buffer->height);
1173                 es->force_configure = 0;
1174         }
1175 }
1176
1177 static void
1178 surface_attach(struct wl_client *client,
1179                struct wl_resource *resource,
1180                struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
1181 {
1182         struct weston_surface *es = resource->data;
1183         struct wl_buffer *buffer = NULL;
1184
1185         if (buffer_resource)
1186                 buffer = buffer_resource->data;
1187
1188         weston_buffer_attach(buffer, &es->surface);
1189
1190         if (buffer)
1191                 surface_configure(es, sx, sy);
1192 }
1193
1194 static void
1195 surface_damage(struct wl_client *client,
1196                struct wl_resource *resource,
1197                int32_t x, int32_t y, int32_t width, int32_t height)
1198 {
1199         struct weston_surface *es = resource->data;
1200
1201         weston_surface_damage_rectangle(es, x, y, width, height);
1202
1203         if (es->buffer && wl_buffer_is_shm(es->buffer)) {
1204                 glBindTexture(GL_TEXTURE_2D, es->texture);
1205                 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
1206                              es->pitch, es->buffer->height, 0,
1207                              GL_BGRA_EXT, GL_UNSIGNED_BYTE,
1208                              wl_shm_buffer_get_data(es->buffer));
1209
1210                 /* Hmm, should use glTexSubImage2D() here but GLES2 doesn't
1211                  * support any unpack attributes except GL_UNPACK_ALIGNMENT. */
1212         }
1213 }
1214
1215 static void
1216 destroy_frame_callback(struct wl_resource *resource)
1217 {
1218         struct weston_frame_callback *cb = resource->data;
1219
1220         wl_list_remove(&cb->link);
1221         free(cb);
1222 }
1223
1224 static void
1225 surface_frame(struct wl_client *client,
1226               struct wl_resource *resource, uint32_t callback)
1227 {
1228         struct weston_frame_callback *cb;
1229         struct weston_surface *es = resource->data;
1230
1231         cb = malloc(sizeof *cb);
1232         if (cb == NULL) {
1233                 wl_resource_post_no_memory(resource);
1234                 return;
1235         }
1236                 
1237         cb->resource.object.interface = &wl_callback_interface;
1238         cb->resource.object.id = callback;
1239         cb->resource.destroy = destroy_frame_callback;
1240         cb->resource.client = client;
1241         cb->resource.data = cb;
1242
1243         wl_client_add_resource(client, &cb->resource);
1244
1245         if (es->output) {
1246                 wl_list_insert(es->output->frame_callback_list.prev,
1247                                &cb->link);
1248         } else {
1249                 wl_list_insert(es->frame_callback_list.prev, &cb->link);
1250         }
1251 }
1252
1253 static void
1254 surface_set_opaque_region(struct wl_client *client,
1255                           struct wl_resource *resource,
1256                           struct wl_resource *region_resource)
1257 {
1258         struct weston_surface *surface = resource->data;
1259         struct weston_region *region;
1260
1261         pixman_region32_fini(&surface->opaque);
1262
1263         if (region_resource) {
1264                 region = region_resource->data;
1265                 pixman_region32_init_rect(&surface->opaque, 0, 0,
1266                                           surface->geometry.width,
1267                                           surface->geometry.height);
1268                 pixman_region32_intersect(&surface->opaque,
1269                                           &surface->opaque, &region->region);
1270         } else {
1271                 pixman_region32_init(&surface->opaque);
1272         }
1273
1274         surface->geometry.dirty = 1;
1275 }
1276
1277 static void
1278 surface_set_input_region(struct wl_client *client,
1279                          struct wl_resource *resource,
1280                          struct wl_resource *region_resource)
1281 {
1282         struct weston_surface *surface = resource->data;
1283         struct weston_region *region;
1284
1285         if (region_resource) {
1286                 region = region_resource->data;
1287                 pixman_region32_init_rect(&surface->input, 0, 0,
1288                                           surface->geometry.width,
1289                                           surface->geometry.height);
1290                 pixman_region32_intersect(&surface->input,
1291                                           &surface->input, &region->region);
1292         } else {
1293                 pixman_region32_init_rect(&surface->input, 0, 0,
1294                                           surface->geometry.width,
1295                                           surface->geometry.height);
1296         }
1297
1298         weston_compositor_schedule_repaint(surface->compositor);
1299 }
1300
1301 const static struct wl_surface_interface surface_interface = {
1302         surface_destroy,
1303         surface_attach,
1304         surface_damage,
1305         surface_frame,
1306         surface_set_opaque_region,
1307         surface_set_input_region
1308 };
1309
1310 static void
1311 compositor_create_surface(struct wl_client *client,
1312                           struct wl_resource *resource, uint32_t id)
1313 {
1314         struct weston_compositor *ec = resource->data;
1315         struct weston_surface *surface;
1316
1317         surface = weston_surface_create(ec);
1318         if (surface == NULL) {
1319                 wl_resource_post_no_memory(resource);
1320                 return;
1321         }
1322
1323         surface->surface.resource.destroy = destroy_surface;
1324
1325         surface->surface.resource.object.id = id;
1326         surface->surface.resource.object.interface = &wl_surface_interface;
1327         surface->surface.resource.object.implementation =
1328                 (void (**)(void)) &surface_interface;
1329         surface->surface.resource.data = surface;
1330
1331         wl_client_add_resource(client, &surface->surface.resource);
1332 }
1333
1334 static void
1335 destroy_region(struct wl_resource *resource)
1336 {
1337         struct weston_region *region =
1338                 container_of(resource, struct weston_region, resource);
1339
1340         pixman_region32_fini(&region->region);
1341         free(region);
1342 }
1343
1344 static void
1345 region_destroy(struct wl_client *client, struct wl_resource *resource)
1346 {
1347         wl_resource_destroy(resource, weston_compositor_get_time());
1348 }
1349
1350 static void
1351 region_add(struct wl_client *client, struct wl_resource *resource,
1352            int32_t x, int32_t y, int32_t width, int32_t height)
1353 {
1354         struct weston_region *region = resource->data;
1355
1356         pixman_region32_union_rect(&region->region, &region->region,
1357                                    x, y, width, height);
1358 }
1359
1360 static void
1361 region_subtract(struct wl_client *client, struct wl_resource *resource,
1362                 int32_t x, int32_t y, int32_t width, int32_t height)
1363 {
1364         struct weston_region *region = resource->data;
1365         pixman_region32_t rect;
1366
1367         pixman_region32_init_rect(&rect, x, y, width, height);
1368         pixman_region32_subtract(&region->region, &region->region, &rect);
1369         pixman_region32_fini(&rect);
1370 }
1371
1372 static const struct wl_region_interface region_interface = {
1373         region_destroy,
1374         region_add,
1375         region_subtract
1376 };
1377
1378 static void
1379 compositor_create_region(struct wl_client *client,
1380                          struct wl_resource *resource, uint32_t id)
1381 {
1382         struct weston_region *region;
1383
1384         region = malloc(sizeof *region);
1385         if (region == NULL) {
1386                 wl_resource_post_no_memory(resource);
1387                 return;
1388         }
1389
1390         region->resource.destroy = destroy_region;
1391
1392         region->resource.object.id = id;
1393         region->resource.object.interface = &wl_region_interface;
1394         region->resource.object.implementation =
1395                 (void (**)(void)) &region_interface;
1396         region->resource.data = region;
1397
1398         pixman_region32_init(&region->region);
1399
1400         wl_client_add_resource(client, &region->resource);
1401 }
1402
1403 const static struct wl_compositor_interface compositor_interface = {
1404         compositor_create_surface,
1405         compositor_create_region
1406 };
1407
1408 WL_EXPORT void
1409 weston_compositor_wake(struct weston_compositor *compositor)
1410 {
1411         compositor->state = WESTON_COMPOSITOR_ACTIVE;
1412         weston_compositor_fade(compositor, 0.0);
1413
1414         wl_event_source_timer_update(compositor->idle_source,
1415                                      compositor->idle_time * 1000);
1416 }
1417
1418 static void
1419 weston_compositor_dpms_on(struct weston_compositor *compositor)
1420 {
1421         struct weston_output *output;
1422
1423         wl_list_for_each(output, &compositor->output_list, link)
1424                 if (output->set_dpms)
1425                         output->set_dpms(output, WESTON_DPMS_ON);
1426 }
1427
1428 WL_EXPORT void
1429 weston_compositor_activity(struct weston_compositor *compositor)
1430 {
1431         if (compositor->state == WESTON_COMPOSITOR_ACTIVE) {
1432                 weston_compositor_wake(compositor);
1433         } else {
1434                 weston_compositor_dpms_on(compositor);
1435                 compositor->shell->unlock(compositor->shell);
1436         }
1437 }
1438
1439 static void
1440 weston_compositor_idle_inhibit(struct weston_compositor *compositor)
1441 {
1442         weston_compositor_activity(compositor);
1443         compositor->idle_inhibit++;
1444 }
1445
1446 static void
1447 weston_compositor_idle_release(struct weston_compositor *compositor)
1448 {
1449         compositor->idle_inhibit--;
1450         weston_compositor_activity(compositor);
1451 }
1452
1453 static int
1454 idle_handler(void *data)
1455 {
1456         struct weston_compositor *compositor = data;
1457
1458         if (compositor->idle_inhibit)
1459                 return 1;
1460
1461         weston_compositor_fade(compositor, 1.0);
1462
1463         return 1;
1464 }
1465
1466 static  void
1467 weston_input_update_drag_surface(struct wl_input_device *input_device,
1468                                  int dx, int dy);
1469
1470 WL_EXPORT void
1471 notify_motion(struct wl_input_device *device, uint32_t time, int x, int y)
1472 {
1473         struct weston_output *output;
1474         const struct wl_pointer_grab_interface *interface;
1475         struct weston_input_device *wd = (struct weston_input_device *) device;
1476         struct weston_compositor *ec = wd->compositor;
1477         int x_valid = 0, y_valid = 0;
1478         int min_x = INT_MAX, min_y = INT_MAX, max_x = INT_MIN, max_y = INT_MIN;
1479
1480         weston_compositor_activity(ec);
1481
1482         wl_list_for_each(output, &ec->output_list, link) {
1483                 if (output->x <= x && x < output->x + output->current->width)
1484                         x_valid = 1;
1485
1486                 if (output->y <= y && y < output->y + output->current->height)
1487                         y_valid = 1;
1488
1489                 /* FIXME: calculate this only on output addition/deletion */
1490                 if (output->x < min_x)
1491                         min_x = output->x;
1492                 if (output->y < min_y)
1493                         min_y = output->y;
1494
1495                 if (output->x + output->current->width > max_x)
1496                         max_x = output->x + output->current->width - 1;
1497                 if (output->y + output->current->height > max_y)
1498                         max_y = output->y + output->current->height - 1;
1499         }
1500         
1501         if (!x_valid) {
1502                 if (x < min_x)
1503                         x = min_x;
1504                 else if (x >= max_x)
1505                         x = max_x;
1506         }
1507         if (!y_valid) {
1508                 if (y < min_y)
1509                         y = min_y;
1510                 else  if (y >= max_y)
1511                         y = max_y;
1512         }
1513
1514         weston_input_update_drag_surface(device,
1515                                          x - device->x, y - device->y);
1516
1517         device->x = x;
1518         device->y = y;
1519
1520         wl_list_for_each(output, &ec->output_list, link)
1521                 if (output->zoom.active &&
1522                     pixman_region32_contains_point(&output->region, x, y, NULL))
1523                         weston_output_update_zoom(output, x, y);
1524
1525         weston_device_repick(device, time);
1526         interface = device->pointer_grab->interface;
1527         interface->motion(device->pointer_grab, time,
1528                           device->pointer_grab->x, device->pointer_grab->y);
1529
1530         if (wd->sprite) {
1531                 weston_surface_set_position(wd->sprite,
1532                                             device->x - wd->hotspot_x,
1533                                             device->y - wd->hotspot_y);
1534
1535                 weston_compositor_schedule_repaint(ec);
1536         }
1537 }
1538
1539 WL_EXPORT void
1540 weston_surface_activate(struct weston_surface *surface,
1541                         struct weston_input_device *device, uint32_t time)
1542 {
1543         wl_input_device_set_keyboard_focus(&device->input_device,
1544                                            &surface->surface, time);
1545         wl_data_device_set_keyboard_focus(&device->input_device);
1546 }
1547
1548 WL_EXPORT void
1549 notify_button(struct wl_input_device *device,
1550               uint32_t time, int32_t button, int32_t state)
1551 {
1552         struct weston_input_device *wd = (struct weston_input_device *) device;
1553         struct weston_compositor *compositor = wd->compositor;
1554
1555         if (state) {
1556                 weston_compositor_idle_inhibit(compositor);
1557                 if (device->button_count == 0) {
1558                         device->grab_button = button;
1559                         device->grab_time = time;
1560                         device->grab_x = device->x;
1561                         device->grab_y = device->y;
1562                 }
1563                 device->button_count++;
1564         } else {
1565                 weston_compositor_idle_release(compositor);
1566                 device->button_count--;
1567         }
1568
1569         weston_compositor_run_binding(compositor, wd, time, 0, button, 0, state);
1570
1571         device->pointer_grab->interface->button(device->pointer_grab, time, button, state);
1572
1573 }
1574
1575 WL_EXPORT void
1576 notify_axis(struct wl_input_device *device,
1577               uint32_t time, uint32_t axis, int32_t value)
1578 {
1579         struct weston_input_device *wd = (struct weston_input_device *) device;
1580         struct weston_compositor *compositor = wd->compositor;
1581
1582         weston_compositor_activity(compositor);
1583
1584         if (value)
1585                 weston_compositor_run_binding(compositor, wd,
1586                                                 time, 0, 0, axis, value);
1587         else
1588                 return;
1589
1590         if (device->pointer_focus_resource)
1591                 wl_resource_post_event(device->pointer_focus_resource,
1592                                 WL_INPUT_DEVICE_AXIS, time, axis, value);
1593 }
1594
1595 static void
1596 update_modifier_state(struct weston_input_device *device,
1597                       uint32_t key, uint32_t state)
1598 {
1599         uint32_t modifier;
1600
1601         switch (key) {
1602         case KEY_LEFTCTRL:
1603         case KEY_RIGHTCTRL:
1604                 modifier = MODIFIER_CTRL;
1605                 break;
1606
1607         case KEY_LEFTALT:
1608         case KEY_RIGHTALT:
1609                 modifier = MODIFIER_ALT;
1610                 break;
1611
1612         case KEY_LEFTMETA:
1613         case KEY_RIGHTMETA:
1614                 modifier = MODIFIER_SUPER;
1615                 break;
1616
1617         default:
1618                 modifier = 0;
1619                 break;
1620         }
1621
1622         if (state)
1623                 device->modifier_state |= modifier;
1624         else
1625                 device->modifier_state &= ~modifier;
1626 }
1627
1628 WL_EXPORT void
1629 notify_key(struct wl_input_device *device,
1630            uint32_t time, uint32_t key, uint32_t state)
1631 {
1632         struct weston_input_device *wd = (struct weston_input_device *) device;
1633         struct weston_compositor *compositor = wd->compositor;
1634         uint32_t *k, *end;
1635
1636         if (state) {
1637                 weston_compositor_idle_inhibit(compositor);
1638                 device->grab_key = key;
1639                 device->grab_time = time;
1640         } else {
1641                 weston_compositor_idle_release(compositor);
1642         }
1643
1644         update_modifier_state(wd, key, state);
1645         end = device->keys.data + device->keys.size;
1646         for (k = device->keys.data; k < end; k++) {
1647                 if (*k == key)
1648                         *k = *--end;
1649         }
1650         device->keys.size = (void *) end - device->keys.data;
1651         if (state) {
1652                 k = wl_array_add(&device->keys, sizeof *k);
1653                 *k = key;
1654         }
1655
1656         if (device->keyboard_grab == &device->default_keyboard_grab)
1657                 weston_compositor_run_binding(compositor, wd,
1658                                               time, key, 0, 0, state);
1659
1660         device->keyboard_grab->interface->key(device->keyboard_grab,
1661                                               time, key, state);
1662 }
1663
1664 WL_EXPORT void
1665 notify_pointer_focus(struct wl_input_device *device,
1666                      uint32_t time, struct weston_output *output,
1667                      int32_t x, int32_t y)
1668 {
1669         struct weston_input_device *wd = (struct weston_input_device *) device;
1670         struct weston_compositor *compositor = wd->compositor;
1671
1672         if (output) {
1673                 weston_input_update_drag_surface(device, x - device->x,
1674                                                  y - device->y);
1675
1676                 device->x = x;
1677                 device->y = y;
1678                 compositor->focus = 1;
1679                 weston_compositor_repick(compositor);
1680         } else {
1681                 compositor->focus = 0;
1682                 weston_compositor_repick(compositor);
1683         }
1684 }
1685
1686 static void
1687 destroy_device_saved_kbd_focus(struct wl_listener *listener,
1688                                struct wl_resource *resource, uint32_t time)
1689 {
1690         struct weston_input_device *wd;
1691
1692         wd = container_of(listener, struct weston_input_device,
1693                           saved_kbd_focus_listener);
1694
1695         wd->saved_kbd_focus = NULL;
1696 }
1697
1698 WL_EXPORT void
1699 notify_keyboard_focus(struct wl_input_device *device,
1700                       uint32_t time, struct weston_output *output,
1701                       struct wl_array *keys)
1702 {
1703         struct weston_input_device *wd =
1704                 (struct weston_input_device *) device;
1705         struct weston_compositor *compositor = wd->compositor;
1706         struct wl_surface *surface;
1707         uint32_t *k;
1708
1709         if (output) {
1710                 wl_array_copy(&wd->input_device.keys, keys);
1711                 wd->modifier_state = 0;
1712                 wl_array_for_each(k, &device->keys) {
1713                         weston_compositor_idle_inhibit(compositor);
1714                         update_modifier_state(wd, *k, 1);
1715                 }
1716
1717                 surface = wd->saved_kbd_focus;
1718
1719                 if (surface) {
1720                         wl_list_remove(&wd->saved_kbd_focus_listener.link);
1721                         wl_input_device_set_keyboard_focus(&wd->input_device,
1722                                                            surface, time);
1723                         wd->saved_kbd_focus = NULL;
1724                 }
1725         } else {
1726                 wl_array_for_each(k, &device->keys)
1727                         weston_compositor_idle_release(compositor);
1728
1729                 wd->modifier_state = 0;
1730
1731                 surface = wd->input_device.keyboard_focus;
1732
1733                 if (surface) {
1734                         wd->saved_kbd_focus = surface;
1735                         wd->saved_kbd_focus_listener.func =
1736                                 destroy_device_saved_kbd_focus;
1737                         wl_list_insert(surface->resource.destroy_listener_list.prev,
1738                                        &wd->saved_kbd_focus_listener.link);
1739                 }
1740
1741                 wl_input_device_set_keyboard_focus(&wd->input_device,
1742                                                    NULL, time);
1743         }
1744 }
1745
1746 /* TODO: share this function with wayland-server.c */
1747 static struct wl_resource *
1748 find_resource_for_surface(struct wl_list *list, struct wl_surface *surface)
1749 {
1750         struct wl_resource *r;
1751
1752         if (!surface)
1753                 return NULL;
1754
1755         wl_list_for_each(r, list, link) {
1756                 if (r->client == surface->resource.client)
1757                         return r;
1758         }
1759
1760         return NULL;
1761 }
1762
1763 static void
1764 lose_touch_focus_resource(struct wl_listener *listener,
1765                           struct wl_resource *resource, uint32_t time)
1766 {
1767         struct weston_input_device *device =
1768                 container_of(listener, struct weston_input_device,
1769                              touch_focus_resource_listener);
1770
1771         device->touch_focus_resource = NULL;
1772 }
1773
1774 static void
1775 lose_touch_focus(struct wl_listener *listener,
1776                  struct wl_resource *resource, uint32_t time)
1777 {
1778         struct weston_input_device *device =
1779                 container_of(listener, struct weston_input_device,
1780                              touch_focus_listener);
1781
1782         device->touch_focus = NULL;
1783 }
1784
1785 static void
1786 touch_set_focus(struct weston_input_device *device,
1787                 struct wl_surface *surface, uint32_t time)
1788 {
1789         struct wl_input_device *input_device = &device->input_device;
1790         struct wl_resource *resource;
1791
1792         if (device->touch_focus == surface)
1793                 return;
1794
1795         if (surface) {
1796                 resource =
1797                         find_resource_for_surface(&input_device->resource_list,
1798                                                   surface);
1799                 if (!resource) {
1800                         fprintf(stderr, "couldn't find resource\n");
1801                         return;
1802                 }
1803
1804                 device->touch_focus_resource_listener.func =
1805                         lose_touch_focus_resource;
1806                 wl_list_insert(resource->destroy_listener_list.prev,
1807                                &device->touch_focus_resource_listener.link);
1808                 device->touch_focus_listener.func = lose_touch_focus;
1809                 wl_list_insert(surface->resource.destroy_listener_list.prev,
1810                                &device->touch_focus_listener.link);
1811
1812                 device->touch_focus = surface;
1813                 device->touch_focus_resource = resource;
1814         } else {
1815                 if (device->touch_focus)
1816                         wl_list_remove(&device->touch_focus_listener.link);
1817                 if (device->touch_focus_resource)
1818                         wl_list_remove(&device->touch_focus_resource_listener.link);
1819                 device->touch_focus = NULL;
1820                 device->touch_focus_resource = NULL;
1821         }
1822 }
1823
1824 /**
1825  * notify_touch - emulates button touches and notifies surfaces accordingly.
1826  *
1827  * It assumes always the correct cycle sequence until it gets here: touch_down
1828  * → touch_update → ... → touch_update → touch_end. The driver is responsible
1829  * for sending along such order.
1830  *
1831  */
1832 WL_EXPORT void
1833 notify_touch(struct wl_input_device *device, uint32_t time, int touch_id,
1834              int x, int y, int touch_type)
1835 {
1836         struct weston_input_device *wd = (struct weston_input_device *) device;
1837         struct weston_compositor *ec = wd->compositor;
1838         struct weston_surface *es;
1839         int32_t sx, sy;
1840
1841         switch (touch_type) {
1842         case WL_INPUT_DEVICE_TOUCH_DOWN:
1843                 weston_compositor_idle_inhibit(ec);
1844
1845                 wd->num_tp++;
1846
1847                 /* the first finger down picks the surface, and all further go
1848                  * to that surface for the remainder of the touch session i.e.
1849                  * until all touch points are up again. */
1850                 if (wd->num_tp == 1) {
1851                         es = weston_compositor_pick_surface(ec, x, y, &sx, &sy);
1852                         touch_set_focus(wd, &es->surface, time);
1853                 } else if (wd->touch_focus) {
1854                         es = (struct weston_surface *) wd->touch_focus;
1855                         weston_surface_from_global(es, x, y, &sx, &sy);
1856                 }
1857
1858                 if (wd->touch_focus_resource && wd->touch_focus)
1859                         wl_input_device_send_touch_down(wd->touch_focus_resource,
1860                                                         time, &wd->touch_focus->resource,
1861                                                         touch_id, sx, sy);
1862                 break;
1863         case WL_INPUT_DEVICE_TOUCH_MOTION:
1864                 es = (struct weston_surface *) wd->touch_focus;
1865                 if (!es)
1866                         break;
1867
1868                 weston_surface_from_global(es, x, y, &sx, &sy);
1869                 if (wd->touch_focus_resource)
1870                         wl_input_device_send_touch_motion(wd->touch_focus_resource,
1871                                                           time, touch_id, sx, sy);
1872                 break;
1873         case WL_INPUT_DEVICE_TOUCH_UP:
1874                 weston_compositor_idle_release(ec);
1875                 wd->num_tp--;
1876
1877                 if (wd->touch_focus_resource)
1878                         wl_input_device_send_touch_up(wd->touch_focus_resource,
1879                                                       time, touch_id);
1880                 if (wd->num_tp == 0)
1881                         touch_set_focus(wd, NULL, time);
1882                 break;
1883         }
1884 }
1885
1886 static void
1887 input_device_attach(struct wl_client *client,
1888                     struct wl_resource *resource,
1889                     uint32_t time,
1890                     struct wl_resource *buffer_resource, int32_t x, int32_t y)
1891 {
1892         struct weston_input_device *device = resource->data;
1893         struct weston_compositor *compositor = device->compositor;
1894         struct wl_buffer *buffer = NULL;
1895
1896         if (time < device->input_device.pointer_focus_time)
1897                 return;
1898         if (device->input_device.pointer_focus == NULL)
1899                 return;
1900         if (device->input_device.pointer_focus->resource.client != client)
1901                 return;
1902
1903         if (buffer_resource)
1904                 buffer = buffer_resource->data;
1905
1906         weston_buffer_attach(buffer, &device->sprite->surface);
1907
1908         if (!buffer)
1909                 return;
1910
1911         if (!weston_surface_is_mapped(device->sprite)) {
1912                 wl_list_insert(&compositor->cursor_layer.surface_list,
1913                                &device->sprite->layer_link);
1914                 weston_surface_assign_output(device->sprite);
1915         }
1916
1917
1918         device->hotspot_x = x;
1919         device->hotspot_y = y;
1920         weston_surface_configure(device->sprite,
1921                                  device->input_device.x - device->hotspot_x,
1922                                  device->input_device.y - device->hotspot_y,
1923                                  buffer->width, buffer->height);
1924
1925         surface_damage(NULL, &device->sprite->surface.resource,
1926                        0, 0, buffer->width, buffer->height);
1927 }
1928
1929 const static struct wl_input_device_interface input_device_interface = {
1930         input_device_attach,
1931 };
1932
1933 static void
1934 handle_drag_surface_destroy(struct wl_listener *listener,
1935                             struct wl_resource *resource, uint32_t time)
1936 {
1937         struct weston_input_device *device;
1938
1939         device = container_of(listener, struct weston_input_device,
1940                               drag_surface_destroy_listener);
1941
1942         device->drag_surface = NULL;
1943 }
1944
1945 static void unbind_input_device(struct wl_resource *resource)
1946 {
1947         wl_list_remove(&resource->link);
1948         free(resource);
1949 }
1950
1951 static void
1952 bind_input_device(struct wl_client *client,
1953                   void *data, uint32_t version, uint32_t id)
1954 {
1955         struct wl_input_device *device = data;
1956         struct wl_resource *resource;
1957
1958         resource = wl_client_add_object(client, &wl_input_device_interface,
1959                                         &input_device_interface, id, data);
1960         wl_list_insert(&device->resource_list, &resource->link);
1961         resource->destroy = unbind_input_device;
1962 }
1963
1964 static void
1965 device_handle_new_drag_icon(struct wl_listener *listener,
1966                             struct wl_resource *resource, uint32_t time)
1967 {
1968         struct weston_input_device *device;
1969
1970         device = container_of(listener, struct weston_input_device,
1971                               new_drag_icon_listener);
1972
1973         weston_input_update_drag_surface(&device->input_device, 0, 0);
1974 }
1975
1976 WL_EXPORT void
1977 weston_input_device_init(struct weston_input_device *device,
1978                          struct weston_compositor *ec)
1979 {
1980         wl_input_device_init(&device->input_device);
1981
1982         wl_display_add_global(ec->wl_display, &wl_input_device_interface,
1983                               device, bind_input_device);
1984
1985         device->sprite = weston_surface_create(ec);
1986         device->sprite->surface.resource.data = device->sprite;
1987
1988         device->compositor = ec;
1989         device->hotspot_x = 16;
1990         device->hotspot_y = 16;
1991         device->modifier_state = 0;
1992         device->num_tp = 0;
1993
1994         device->drag_surface_destroy_listener.func = handle_drag_surface_destroy;
1995
1996         wl_list_insert(ec->input_device_list.prev, &device->link);
1997
1998         device->new_drag_icon_listener.func = device_handle_new_drag_icon;
1999         wl_list_insert(device->input_device.drag_icon_listener_list.prev,
2000                        &device->new_drag_icon_listener.link);
2001 }
2002
2003 WL_EXPORT void
2004 weston_input_device_release(struct weston_input_device *device)
2005 {
2006         wl_list_remove(&device->link);
2007         /* The global object is destroyed at wl_display_destroy() time. */
2008
2009         if (device->sprite)
2010                 destroy_surface(&device->sprite->surface.resource);
2011
2012         wl_input_device_release(&device->input_device);
2013 }
2014
2015 static void
2016 device_setup_new_drag_surface(struct weston_input_device *device,
2017                               struct weston_surface *surface)
2018 {
2019         struct wl_input_device *input_device = &device->input_device;
2020
2021         device->drag_surface = surface;
2022
2023         weston_surface_set_position(device->drag_surface,
2024                                     input_device->x, input_device->y);
2025
2026         wl_list_insert(surface->surface.resource.destroy_listener_list.prev,
2027                        &device->drag_surface_destroy_listener.link);
2028 }
2029
2030 static void
2031 device_release_drag_surface(struct weston_input_device *device)
2032 {
2033         undef_region(&device->drag_surface->input);
2034         wl_list_remove(&device->drag_surface_destroy_listener.link);
2035         device->drag_surface = NULL;
2036 }
2037
2038 static void
2039 device_map_drag_surface(struct weston_input_device *device)
2040 {
2041         if (weston_surface_is_mapped(device->drag_surface) ||
2042             !device->drag_surface->buffer)
2043                 return;
2044
2045         wl_list_insert(&device->sprite->layer_link,
2046                        &device->drag_surface->layer_link);
2047         weston_surface_assign_output(device->drag_surface);
2048         empty_region(&device->drag_surface->input);
2049 }
2050
2051 static  void
2052 weston_input_update_drag_surface(struct wl_input_device *input_device,
2053                                  int dx, int dy)
2054 {
2055         int surface_changed = 0;
2056         struct weston_input_device *device = (struct weston_input_device *)
2057                 input_device;
2058
2059         if (!device->drag_surface && !input_device->drag_surface)
2060                 return;
2061
2062         if (device->drag_surface && input_device->drag_surface &&
2063             (&device->drag_surface->surface.resource !=
2064              &input_device->drag_surface->resource))
2065                 /* between calls to this funcion we got a new drag_surface */
2066                 surface_changed = 1;
2067
2068         if (!input_device->drag_surface || surface_changed) {
2069                 device_release_drag_surface(device);
2070                 if (!surface_changed)
2071                         return;
2072         }
2073
2074         if (!device->drag_surface || surface_changed) {
2075                 struct weston_surface *surface = (struct weston_surface *)
2076                         input_device->drag_surface;
2077                 device_setup_new_drag_surface(device, surface);
2078         }
2079
2080         /* the client may not have attached a buffer to the drag surface
2081          * when we setup it up, so check if map is needed on every update */
2082         device_map_drag_surface(device);
2083
2084         /* the client may have attached a buffer with a different size to
2085          * the drag surface, causing the input region to be reset */
2086         if (region_is_undefined(&device->drag_surface->input))
2087                 empty_region(&device->drag_surface->input);
2088
2089         if (!dx && !dy)
2090                 return;
2091
2092         weston_surface_set_position(device->drag_surface,
2093                                     device->drag_surface->geometry.x + dx,
2094                                     device->drag_surface->geometry.y + dy);
2095 }
2096
2097 WL_EXPORT void
2098 weston_compositor_update_drag_surfaces(struct weston_compositor *compositor)
2099 {
2100         weston_input_update_drag_surface(compositor->input_device, 0, 0);
2101 }
2102
2103 static void
2104 bind_output(struct wl_client *client,
2105             void *data, uint32_t version, uint32_t id)
2106 {
2107         struct weston_output *output = data;
2108         struct weston_mode *mode;
2109         struct wl_resource *resource;
2110
2111         resource = wl_client_add_object(client,
2112                                         &wl_output_interface, NULL, id, data);
2113
2114         wl_output_send_geometry(resource,
2115                                 output->x,
2116                                 output->y,
2117                                 output->mm_width,
2118                                 output->mm_height,
2119                                 output->subpixel,
2120                                 output->make, output->model);
2121
2122         wl_list_for_each (mode, &output->mode_list, link) {
2123                 wl_output_send_mode(resource,
2124                                     mode->flags,
2125                                     mode->width,
2126                                     mode->height,
2127                                     mode->refresh);
2128         }
2129 }
2130
2131 static const char vertex_shader[] =
2132         "uniform mat4 proj;\n"
2133         "attribute vec2 position;\n"
2134         "attribute vec2 texcoord;\n"
2135         "varying vec2 v_texcoord;\n"
2136         "void main()\n"
2137         "{\n"
2138         "   gl_Position = proj * vec4(position, 0.0, 1.0);\n"
2139         "   v_texcoord = texcoord;\n"
2140         "}\n";
2141
2142 static const char texture_fragment_shader[] =
2143         "precision mediump float;\n"
2144         "varying vec2 v_texcoord;\n"
2145         "uniform sampler2D tex;\n"
2146         "uniform float alpha;\n"
2147         "uniform float texwidth;\n"
2148         "void main()\n"
2149         "{\n"
2150         "   if (v_texcoord.x < 0.0 || v_texcoord.x > texwidth ||\n"
2151         "       v_texcoord.y < 0.0 || v_texcoord.y > 1.0)\n"
2152         "      discard;\n"
2153         "   gl_FragColor = texture2D(tex, v_texcoord)\n;"
2154         "   gl_FragColor = alpha * gl_FragColor;\n"
2155         "}\n";
2156
2157 static const char solid_fragment_shader[] =
2158         "precision mediump float;\n"
2159         "uniform vec4 color;\n"
2160         "void main()\n"
2161         "{\n"
2162         "   gl_FragColor = color\n;"
2163         "}\n";
2164
2165 static int
2166 compile_shader(GLenum type, const char *source)
2167 {
2168         GLuint s;
2169         char msg[512];
2170         GLint status;
2171
2172         s = glCreateShader(type);
2173         glShaderSource(s, 1, &source, NULL);
2174         glCompileShader(s);
2175         glGetShaderiv(s, GL_COMPILE_STATUS, &status);
2176         if (!status) {
2177                 glGetShaderInfoLog(s, sizeof msg, NULL, msg);
2178                 fprintf(stderr, "shader info: %s\n", msg);
2179                 return GL_NONE;
2180         }
2181
2182         return s;
2183 }
2184
2185 static int
2186 weston_shader_init(struct weston_shader *shader,
2187                    const char *vertex_source, const char *fragment_source)
2188 {
2189         char msg[512];
2190         GLint status;
2191
2192         shader->vertex_shader =
2193                 compile_shader(GL_VERTEX_SHADER, vertex_source);
2194         shader->fragment_shader =
2195                 compile_shader(GL_FRAGMENT_SHADER, fragment_source);
2196
2197         shader->program = glCreateProgram();
2198         glAttachShader(shader->program, shader->vertex_shader);
2199         glAttachShader(shader->program, shader->fragment_shader);
2200         glBindAttribLocation(shader->program, 0, "position");
2201         glBindAttribLocation(shader->program, 1, "texcoord");
2202
2203         glLinkProgram(shader->program);
2204         glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
2205         if (!status) {
2206                 glGetProgramInfoLog(shader->program, sizeof msg, NULL, msg);
2207                 fprintf(stderr, "link info: %s\n", msg);
2208                 return -1;
2209         }
2210
2211         shader->proj_uniform = glGetUniformLocation(shader->program, "proj");
2212         shader->tex_uniform = glGetUniformLocation(shader->program, "tex");
2213         shader->alpha_uniform = glGetUniformLocation(shader->program, "alpha");
2214         shader->color_uniform = glGetUniformLocation(shader->program, "color");
2215         shader->texwidth_uniform = glGetUniformLocation(shader->program,
2216                                                         "texwidth");
2217
2218         return 0;
2219 }
2220
2221 WL_EXPORT void
2222 weston_output_destroy(struct weston_output *output)
2223 {
2224         pixman_region32_fini(&output->region);
2225         pixman_region32_fini(&output->previous_damage);
2226 }
2227
2228 WL_EXPORT void
2229 weston_output_update_zoom(struct weston_output *output, int x, int y)
2230 {
2231         float ratio;
2232
2233         if (output->zoom.level <= 0)
2234                 return;
2235
2236         output->zoom.magnification = 1 / output->zoom.level;
2237         ratio = 1 - (1 / output->zoom.magnification);
2238
2239         output->zoom.trans_x = (((float)(x - output->x) / output->current->width) * (ratio * 2)) - ratio;
2240         output->zoom.trans_y = (((float)(y - output->y) / output->current->height) * (ratio * 2)) - ratio;
2241
2242         output->dirty = 1;
2243         weston_output_damage(output);
2244 }
2245
2246 WL_EXPORT void
2247 weston_output_update_matrix(struct weston_output *output)
2248 {
2249         int flip;
2250         struct weston_matrix camera;
2251         struct weston_matrix modelview;
2252
2253         weston_matrix_init(&output->matrix);
2254         weston_matrix_translate(&output->matrix,
2255                                 -(output->x + (output->border.right + output->current->width - output->border.left) / 2.0),
2256                                 -(output->y + (output->border.bottom + output->current->height - output->border.top) / 2.0), 0);
2257
2258         flip = (output->flags & WL_OUTPUT_FLIPPED) ? -1 : 1;
2259         weston_matrix_scale(&output->matrix,
2260                             2.0 / (output->current->width + output->border.left + output->border.right),
2261                             flip * 2.0 / (output->current->height + output->border.top + output->border.bottom), 1);
2262         if (output->zoom.active) {
2263                 weston_matrix_init(&camera);
2264                 weston_matrix_init(&modelview);
2265                 weston_matrix_translate(&camera, output->zoom.trans_x, flip * output->zoom.trans_y, 0);
2266                 weston_matrix_invert(&modelview, &camera);
2267                 weston_matrix_scale(&modelview, output->zoom.magnification, output->zoom.magnification, 1.0);
2268                 weston_matrix_multiply(&output->matrix, &modelview);
2269         }
2270
2271         output->dirty = 0;
2272 }
2273
2274 WL_EXPORT void
2275 weston_output_move(struct weston_output *output, int x, int y)
2276 {
2277         output->x = x;
2278         output->y = y;
2279
2280         pixman_region32_init(&output->previous_damage);
2281         pixman_region32_init_rect(&output->region, x, y,
2282                                   output->current->width,
2283                                   output->current->height);
2284 }
2285
2286 WL_EXPORT void
2287 weston_output_init(struct weston_output *output, struct weston_compositor *c,
2288                    int x, int y, int width, int height, uint32_t flags)
2289 {
2290         output->compositor = c;
2291         output->x = x;
2292         output->y = y;
2293         output->border.top = 0;
2294         output->border.bottom = 0;
2295         output->border.left = 0;
2296         output->border.right = 0;
2297         output->mm_width = width;
2298         output->mm_height = height;
2299         output->dirty = 1;
2300
2301         output->zoom.active = 0;
2302         output->zoom.increment = 0.05;
2303         output->zoom.level = 1.0;
2304         output->zoom.magnification = 1.0;
2305         output->zoom.trans_x = 0.0;
2306         output->zoom.trans_y = 0.0;
2307
2308         output->flags = flags;
2309         weston_output_move(output, x, y);
2310
2311         wl_list_init(&output->frame_callback_list);
2312
2313         wl_display_add_global(c->wl_display,
2314                               &wl_output_interface, output, bind_output);
2315 }
2316
2317 static void
2318 compositor_bind(struct wl_client *client,
2319                 void *data, uint32_t version, uint32_t id)
2320 {
2321         struct weston_compositor *compositor = data;
2322
2323         wl_client_add_object(client, &wl_compositor_interface,
2324                              &compositor_interface, id, compositor);
2325 }
2326
2327 WL_EXPORT int
2328 weston_compositor_init(struct weston_compositor *ec, struct wl_display *display)
2329 {
2330         struct wl_event_loop *loop;
2331         const char *extensions;
2332
2333         ec->wl_display = display;
2334
2335         if (!wl_display_add_global(display, &wl_compositor_interface,
2336                                    ec, compositor_bind))
2337                 return -1;
2338
2339         wl_display_init_shm(display);
2340
2341         ec->image_target_texture_2d =
2342                 (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
2343         ec->image_target_renderbuffer_storage = (void *)
2344                 eglGetProcAddress("glEGLImageTargetRenderbufferStorageOES");
2345         ec->create_image = (void *) eglGetProcAddress("eglCreateImageKHR");
2346         ec->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
2347         ec->bind_display =
2348                 (void *) eglGetProcAddress("eglBindWaylandDisplayWL");
2349         ec->unbind_display =
2350                 (void *) eglGetProcAddress("eglUnbindWaylandDisplayWL");
2351
2352         extensions = (const char *) glGetString(GL_EXTENSIONS);
2353         if (!strstr(extensions, "GL_EXT_texture_format_BGRA8888")) {
2354                 fprintf(stderr,
2355                         "GL_EXT_texture_format_BGRA8888 not available\n");
2356                 return -1;
2357         }
2358
2359         if (!strstr(extensions, "GL_EXT_read_format_bgra")) {
2360                 fprintf(stderr, "GL_EXT_read_format_bgra not available\n");
2361                 return -1;
2362         }
2363
2364         extensions =
2365                 (const char *) eglQueryString(ec->display, EGL_EXTENSIONS);
2366         if (strstr(extensions, "EGL_WL_bind_wayland_display"))
2367                 ec->has_bind_display = 1;
2368         if (ec->has_bind_display)
2369                 ec->bind_display(ec->display, ec->wl_display);
2370
2371         wl_list_init(&ec->surface_list);
2372         wl_list_init(&ec->layer_list);
2373         wl_list_init(&ec->input_device_list);
2374         wl_list_init(&ec->output_list);
2375         wl_list_init(&ec->binding_list);
2376         wl_list_init(&ec->animation_list);
2377         weston_spring_init(&ec->fade.spring, 30.0, 1.0, 1.0);
2378         ec->fade.animation.frame = fade_frame;
2379         wl_list_init(&ec->fade.animation.link);
2380
2381         weston_layer_init(&ec->fade_layer, &ec->layer_list);
2382         weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
2383
2384         ec->screenshooter = screenshooter_create(ec);
2385
2386         wl_data_device_manager_init(ec->wl_display);
2387
2388         glActiveTexture(GL_TEXTURE0);
2389
2390         if (weston_shader_init(&ec->texture_shader,
2391                              vertex_shader, texture_fragment_shader) < 0)
2392                 return -1;
2393         if (weston_shader_init(&ec->solid_shader,
2394                              vertex_shader, solid_fragment_shader) < 0)
2395                 return -1;
2396
2397         loop = wl_display_get_event_loop(ec->wl_display);
2398         ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
2399         wl_event_source_timer_update(ec->idle_source, ec->idle_time * 1000);
2400
2401         ec->input_loop = wl_event_loop_create();
2402
2403         weston_compositor_schedule_repaint(ec);
2404
2405         return 0;
2406 }
2407
2408 WL_EXPORT void
2409 weston_compositor_shutdown(struct weston_compositor *ec)
2410 {
2411         struct weston_output *output, *next;
2412
2413         wl_event_source_remove(ec->idle_source);
2414
2415         if (ec->screenshooter)
2416                 screenshooter_destroy(ec->screenshooter);
2417
2418         /* Destroy all outputs associated with this compositor */
2419         wl_list_for_each_safe(output, next, &ec->output_list, link)
2420                 output->destroy(output);
2421
2422         weston_binding_list_destroy_all(&ec->binding_list);
2423
2424         wl_array_release(&ec->vertices);
2425         wl_array_release(&ec->indices);
2426 }
2427
2428 static int on_term_signal(int signal_number, void *data)
2429 {
2430         struct wl_display *display = data;
2431
2432         fprintf(stderr, "caught signal %d\n", signal_number);
2433         wl_display_terminate(display);
2434
2435         return 1;
2436 }
2437
2438 static void
2439 on_segv_signal(int s, siginfo_t *siginfo, void *context)
2440 {
2441         void *buffer[32];
2442         int i, count;
2443         Dl_info info;
2444
2445         fprintf(stderr, "caught segv\n");
2446
2447         count = backtrace(buffer, ARRAY_LENGTH(buffer));
2448         for (i = 0; i < count; i++) {
2449                 dladdr(buffer[i], &info);
2450                 fprintf(stderr, "  [%016lx]  %s  (%s)\n",
2451                         (long) buffer[i],
2452                         info.dli_sname ? info.dli_sname : "--",
2453                         info.dli_fname);
2454         }
2455
2456         longjmp(segv_jmp_buf, 1);
2457 }
2458
2459
2460 static void *
2461 load_module(const char *name, const char *entrypoint, void **handle)
2462 {
2463         char path[PATH_MAX];
2464         void *module, *init;
2465
2466         if (name[0] != '/')
2467                 snprintf(path, sizeof path, MODULEDIR "/%s", name);
2468         else
2469                 snprintf(path, sizeof path, "%s", name);
2470
2471         module = dlopen(path, RTLD_LAZY);
2472         if (!module) {
2473                 fprintf(stderr,
2474                         "failed to load module: %s\n", dlerror());
2475                 return NULL;
2476         }
2477
2478         init = dlsym(module, entrypoint);
2479         if (!init) {
2480                 fprintf(stderr,
2481                         "failed to lookup init function: %s\n", dlerror());
2482                 return NULL;
2483         }
2484
2485         return init;
2486 }
2487
2488 int main(int argc, char *argv[])
2489 {
2490         struct wl_display *display;
2491         struct weston_compositor *ec;
2492         struct wl_event_source *signals[4];
2493         struct wl_event_loop *loop;
2494         struct sigaction segv_action;
2495         void *shell_module, *backend_module;
2496         int (*shell_init)(struct weston_compositor *ec);
2497         struct weston_compositor
2498                 *(*backend_init)(struct wl_display *display,
2499                                  int argc, char *argv[]);
2500         int i;
2501         char *backend = NULL;
2502         char *shell = NULL;
2503         int32_t idle_time = 300;
2504         int32_t xserver;
2505         char *socket_name = NULL;
2506         char *config_file;
2507
2508         const const struct config_key shell_config_keys[] = {
2509                 { "type", CONFIG_KEY_STRING, &shell },
2510         };
2511
2512         const const struct config_section cs[] = {
2513                 { "shell",
2514                   shell_config_keys, ARRAY_LENGTH(shell_config_keys) },
2515         };
2516
2517         const struct weston_option core_options[] = {
2518                 { WESTON_OPTION_STRING, "backend", 'B', &backend },
2519                 { WESTON_OPTION_STRING, "socket", 'S', &socket_name },
2520                 { WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time },
2521                 { WESTON_OPTION_BOOLEAN, "xserver", 0, &xserver },
2522         };
2523
2524         argc = parse_options(core_options,
2525                              ARRAY_LENGTH(core_options), argc, argv);
2526
2527         display = wl_display_create();
2528
2529         loop = wl_display_get_event_loop(display);
2530         signals[0] = wl_event_loop_add_signal(loop, SIGTERM, on_term_signal,
2531                                               display);
2532         signals[1] = wl_event_loop_add_signal(loop, SIGINT, on_term_signal,
2533                                               display);
2534         signals[2] = wl_event_loop_add_signal(loop, SIGQUIT, on_term_signal,
2535                                               display);
2536
2537         wl_list_init(&child_process_list);
2538         signals[3] = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler,
2539                                               NULL);
2540
2541         segv_action.sa_flags = SA_SIGINFO | SA_RESETHAND;
2542         segv_action.sa_sigaction = on_segv_signal;
2543         sigemptyset(&segv_action.sa_mask);
2544         sigaction(SIGSEGV, &segv_action, NULL);
2545
2546         if (!backend) {
2547                 if (getenv("WAYLAND_DISPLAY"))
2548                         backend = "wayland-backend.so";
2549                 else if (getenv("DISPLAY"))
2550                         backend = "x11-backend.so";
2551                 else if (getenv("OPENWFD"))
2552                         backend = "openwfd-backend.so";
2553                 else
2554                         backend = "drm-backend.so";
2555         }
2556
2557         config_file = config_file_path("weston.ini");
2558         parse_config_file(config_file, cs, ARRAY_LENGTH(cs), shell);
2559         free(config_file);
2560
2561         if (!shell)
2562                 shell = "desktop-shell.so";
2563
2564         backend_init = load_module(backend, "backend_init", &backend_module);
2565         if (!backend_init)
2566                 exit(EXIT_FAILURE);
2567
2568         shell_init = load_module(shell, "shell_init", &shell_module);
2569         if (!shell_init)
2570                 exit(EXIT_FAILURE);
2571
2572         ec = backend_init(display, argc, argv);
2573         if (ec == NULL) {
2574                 fprintf(stderr, "failed to create compositor\n");
2575                 exit(EXIT_FAILURE);
2576         }
2577
2578         for (i = 1; argv[i]; i++)
2579                 fprintf(stderr, "unhandled option: %s\n", argv[i]);
2580         if (argv[1])
2581                 exit(EXIT_FAILURE);
2582
2583         ec->option_idle_time = idle_time;
2584         ec->idle_time = idle_time;
2585
2586 #ifdef BUILD_XSERVER_LAUNCHER
2587         if (xserver)
2588                 weston_xserver_init(ec);
2589 #endif
2590
2591         if (shell_init(ec) < 0)
2592                 exit(EXIT_FAILURE);
2593
2594         if (wl_display_add_socket(display, socket_name)) {
2595                 fprintf(stderr, "failed to add socket: %m\n");
2596                 exit(EXIT_FAILURE);
2597         }
2598
2599         weston_compositor_dpms_on(ec);
2600         weston_compositor_wake(ec);
2601         if (setjmp(segv_jmp_buf) == 0)
2602                 wl_display_run(display);
2603
2604         /* prevent further rendering while shutting down */
2605         ec->state = WESTON_COMPOSITOR_SLEEPING;
2606
2607 #ifdef BUILD_XSERVER_LAUNCHER
2608         if (xserver)
2609                 weston_xserver_destroy(ec);
2610 #endif
2611
2612         ec->shell->destroy(ec->shell);
2613
2614         if (ec->has_bind_display)
2615                 ec->unbind_display(ec->display, display);
2616
2617         for (i = ARRAY_LENGTH(signals); i;)
2618                 wl_event_source_remove(signals[--i]);
2619
2620         ec->destroy(ec);
2621         wl_display_destroy(display);
2622
2623         return 0;
2624 }