2 * Copyright © 2010-2011 Intel Corporation
3 * Copyright © 2008-2011 Kristian Høgsberg
4 * Copyright © 2012 Collabora, Ltd.
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.
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.
37 #include <sys/ioctl.h>
40 #include <sys/socket.h>
41 #include <sys/utsname.h>
45 #include <linux/input.h>
53 #include <wayland-server.h>
54 #include "compositor.h"
55 #include "../shared/os-compatibility.h"
56 #include "git-version.h"
58 static struct wl_list child_process_list;
59 static struct weston_compositor *segv_compositor;
62 sigchld_handler(int signal_number, void *data)
64 struct weston_process *p;
68 pid = waitpid(-1, &status, WNOHANG);
72 wl_list_for_each(p, &child_process_list, link) {
77 if (&p->link == &child_process_list) {
78 weston_log("unknown child process exited\n");
82 wl_list_remove(&p->link);
83 p->cleanup(p, status);
89 weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode)
91 if (!output->switch_mode)
94 return output->switch_mode(output, mode);
98 weston_watch_process(struct weston_process *process)
100 wl_list_insert(&child_process_list, &process->link);
104 child_client_exec(int sockfd, const char *path)
110 /* do not give our signal mask to the new process */
111 sigfillset(&allsigs);
112 sigprocmask(SIG_UNBLOCK, &allsigs, NULL);
114 /* Launch clients as the user. */
117 /* SOCK_CLOEXEC closes both ends, so we dup the fd to get a
118 * non-CLOEXEC fd to pass through exec. */
119 clientfd = dup(sockfd);
120 if (clientfd == -1) {
121 weston_log("compositor: dup failed: %m\n");
125 snprintf(s, sizeof s, "%d", clientfd);
126 setenv("WAYLAND_SOCKET", s, 1);
128 if (execl(path, path, NULL) < 0)
129 weston_log("compositor: executing '%s' failed: %m\n",
133 WL_EXPORT struct wl_client *
134 weston_client_launch(struct weston_compositor *compositor,
135 struct weston_process *proc,
137 weston_process_cleanup_func_t cleanup)
141 struct wl_client *client;
143 weston_log("launching '%s'\n", path);
145 if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
146 weston_log("weston_client_launch: "
147 "socketpair failed while launching '%s': %m\n",
156 weston_log("weston_client_launch: "
157 "fork failed while launching '%s': %m\n", path);
162 child_client_exec(sv[1], path);
168 client = wl_client_create(compositor->wl_display, sv[0]);
171 weston_log("weston_client_launch: "
172 "wl_client_create failed while launching '%s'.\n",
178 proc->cleanup = cleanup;
179 weston_watch_process(proc);
185 update_shm_texture(struct weston_surface *surface);
188 surface_handle_buffer_destroy(struct wl_listener *listener, void *data)
190 struct weston_surface *es =
191 container_of(listener, struct weston_surface,
192 buffer_destroy_listener);
194 if (es->buffer && wl_buffer_is_shm(es->buffer))
195 update_shm_texture(es);
200 static const pixman_region32_data_t undef_region_data;
203 undef_region(pixman_region32_t *region)
205 if (region->data != &undef_region_data)
206 pixman_region32_fini(region);
207 region->data = (pixman_region32_data_t *) &undef_region_data;
211 region_is_undefined(pixman_region32_t *region)
213 return region->data == &undef_region_data;
217 empty_region(pixman_region32_t *region)
219 if (!region_is_undefined(region))
220 pixman_region32_fini(region);
222 pixman_region32_init(region);
225 WL_EXPORT struct weston_surface *
226 weston_surface_create(struct weston_compositor *compositor)
228 struct weston_surface *surface;
230 surface = calloc(1, sizeof *surface);
234 wl_signal_init(&surface->surface.resource.destroy_signal);
236 wl_list_init(&surface->link);
237 wl_list_init(&surface->layer_link);
239 surface->surface.resource.client = NULL;
241 surface->compositor = compositor;
242 surface->alpha = 1.0;
245 surface->num_textures = 0;
246 surface->num_images = 0;
248 surface->buffer = NULL;
249 surface->output = NULL;
250 surface->plane = &compositor->primary_plane;
252 pixman_region32_init(&surface->damage);
253 pixman_region32_init(&surface->opaque);
254 pixman_region32_init(&surface->clip);
255 undef_region(&surface->input);
256 pixman_region32_init(&surface->transform.opaque);
257 wl_list_init(&surface->frame_callback_list);
259 surface->buffer_destroy_listener.notify =
260 surface_handle_buffer_destroy;
262 wl_list_init(&surface->geometry.transformation_list);
263 wl_list_insert(&surface->geometry.transformation_list,
264 &surface->transform.position.link);
265 weston_matrix_init(&surface->transform.position.matrix);
266 pixman_region32_init(&surface->transform.boundingbox);
267 surface->geometry.dirty = 1;
273 weston_surface_set_color(struct weston_surface *surface,
274 GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
276 surface->color[0] = red;
277 surface->color[1] = green;
278 surface->color[2] = blue;
279 surface->color[3] = alpha;
280 surface->shader = &surface->compositor->solid_shader;
284 weston_surface_to_global_float(struct weston_surface *surface,
285 GLfloat sx, GLfloat sy, GLfloat *x, GLfloat *y)
287 if (surface->transform.enabled) {
288 struct weston_vector v = { { sx, sy, 0.0f, 1.0f } };
290 weston_matrix_transform(&surface->transform.matrix, &v);
292 if (fabsf(v.f[3]) < 1e-6) {
293 weston_log("warning: numerical instability in "
294 "weston_surface_to_global(), divisor = %g\n",
301 *x = v.f[0] / v.f[3];
302 *y = v.f[1] / v.f[3];
304 *x = sx + surface->geometry.x;
305 *y = sy + surface->geometry.y;
310 weston_surface_move_to_plane(struct weston_surface *surface,
311 struct weston_plane *plane)
313 if (surface->plane == plane)
316 weston_surface_damage_below(surface);
317 surface->plane = plane;
318 weston_surface_damage(surface);
322 weston_surface_damage_below(struct weston_surface *surface)
324 pixman_region32_t damage;
326 pixman_region32_init(&damage);
327 pixman_region32_subtract(&damage, &surface->transform.boundingbox,
329 pixman_region32_union(&surface->plane->damage,
330 &surface->plane->damage, &damage);
331 pixman_region32_fini(&damage);
335 surface_compute_bbox(struct weston_surface *surface, int32_t sx, int32_t sy,
336 int32_t width, int32_t height,
337 pixman_region32_t *bbox)
339 GLfloat min_x = HUGE_VALF, min_y = HUGE_VALF;
340 GLfloat max_x = -HUGE_VALF, max_y = -HUGE_VALF;
345 { sx + width, sy + height }
347 GLfloat int_x, int_y;
350 if (width == 0 || height == 0) {
351 /* avoid rounding empty bbox to 1x1 */
352 pixman_region32_init(bbox);
356 for (i = 0; i < 4; ++i) {
358 weston_surface_to_global_float(surface,
359 s[i][0], s[i][1], &x, &y);
370 int_x = floorf(min_x);
371 int_y = floorf(min_y);
372 pixman_region32_init_rect(bbox, int_x, int_y,
373 ceilf(max_x) - int_x, ceilf(max_y) - int_y);
377 weston_surface_update_transform_disable(struct weston_surface *surface)
379 surface->transform.enabled = 0;
381 /* round off fractions when not transformed */
382 surface->geometry.x = roundf(surface->geometry.x);
383 surface->geometry.y = roundf(surface->geometry.y);
385 pixman_region32_init_rect(&surface->transform.boundingbox,
388 surface->geometry.width,
389 surface->geometry.height);
391 if (surface->alpha == 1.0) {
392 pixman_region32_copy(&surface->transform.opaque,
394 pixman_region32_translate(&surface->transform.opaque,
396 surface->geometry.y);
401 weston_surface_update_transform_enable(struct weston_surface *surface)
403 struct weston_matrix *matrix = &surface->transform.matrix;
404 struct weston_matrix *inverse = &surface->transform.inverse;
405 struct weston_transform *tform;
407 surface->transform.enabled = 1;
409 /* Otherwise identity matrix, but with x and y translation. */
410 surface->transform.position.matrix.d[12] = surface->geometry.x;
411 surface->transform.position.matrix.d[13] = surface->geometry.y;
413 weston_matrix_init(matrix);
414 wl_list_for_each(tform, &surface->geometry.transformation_list, link)
415 weston_matrix_multiply(matrix, &tform->matrix);
417 if (weston_matrix_invert(inverse, matrix) < 0) {
418 /* Oops, bad total transformation, not invertible */
419 weston_log("error: weston_surface %p"
420 " transformation not invertible.\n", surface);
424 surface_compute_bbox(surface, 0, 0, surface->geometry.width,
425 surface->geometry.height,
426 &surface->transform.boundingbox);
432 weston_surface_update_transform(struct weston_surface *surface)
434 if (!surface->geometry.dirty)
437 surface->geometry.dirty = 0;
439 weston_surface_damage_below(surface);
441 pixman_region32_fini(&surface->transform.boundingbox);
442 pixman_region32_fini(&surface->transform.opaque);
443 pixman_region32_init(&surface->transform.opaque);
445 if (region_is_undefined(&surface->input))
446 pixman_region32_init_rect(&surface->input, 0, 0,
447 surface->geometry.width,
448 surface->geometry.height);
450 /* transform.position is always in transformation_list */
451 if (surface->geometry.transformation_list.next ==
452 &surface->transform.position.link &&
453 surface->geometry.transformation_list.prev ==
454 &surface->transform.position.link) {
455 weston_surface_update_transform_disable(surface);
457 if (weston_surface_update_transform_enable(surface) < 0)
458 weston_surface_update_transform_disable(surface);
461 weston_surface_damage_below(surface);
463 if (weston_surface_is_mapped(surface))
464 weston_surface_assign_output(surface);
468 weston_surface_to_global_fixed(struct weston_surface *surface,
469 wl_fixed_t sx, wl_fixed_t sy,
470 wl_fixed_t *x, wl_fixed_t *y)
474 weston_surface_to_global_float(surface,
475 wl_fixed_to_double(sx),
476 wl_fixed_to_double(sy),
478 *x = wl_fixed_from_double(xf);
479 *y = wl_fixed_from_double(yf);
483 weston_surface_from_global_float(struct weston_surface *surface,
484 GLfloat x, GLfloat y, GLfloat *sx, GLfloat *sy)
486 if (surface->transform.enabled) {
487 struct weston_vector v = { { x, y, 0.0f, 1.0f } };
489 weston_matrix_transform(&surface->transform.inverse, &v);
491 if (fabsf(v.f[3]) < 1e-6) {
492 weston_log("warning: numerical instability in "
493 "weston_surface_from_global(), divisor = %g\n",
500 *sx = v.f[0] / v.f[3];
501 *sy = v.f[1] / v.f[3];
503 *sx = x - surface->geometry.x;
504 *sy = y - surface->geometry.y;
509 weston_surface_from_global_fixed(struct weston_surface *surface,
510 wl_fixed_t x, wl_fixed_t y,
511 wl_fixed_t *sx, wl_fixed_t *sy)
515 weston_surface_from_global_float(surface,
516 wl_fixed_to_double(x),
517 wl_fixed_to_double(y),
519 *sx = wl_fixed_from_double(sxf);
520 *sy = wl_fixed_from_double(syf);
524 weston_surface_from_global(struct weston_surface *surface,
525 int32_t x, int32_t y, int32_t *sx, int32_t *sy)
529 weston_surface_from_global_float(surface, x, y, &sxf, &syf);
535 weston_surface_schedule_repaint(struct weston_surface *surface)
537 struct weston_output *output;
539 wl_list_for_each(output, &surface->compositor->output_list, link)
540 if (surface->output_mask & (1 << output->id))
541 weston_output_schedule_repaint(output);
545 weston_surface_damage(struct weston_surface *surface)
547 pixman_region32_union_rect(&surface->damage, &surface->damage,
548 0, 0, surface->geometry.width,
549 surface->geometry.height);
551 weston_surface_schedule_repaint(surface);
555 weston_surface_configure(struct weston_surface *surface,
556 GLfloat x, GLfloat y, int width, int height)
558 surface->geometry.x = x;
559 surface->geometry.y = y;
560 surface->geometry.width = width;
561 surface->geometry.height = height;
562 surface->geometry.dirty = 1;
566 weston_surface_set_position(struct weston_surface *surface,
567 GLfloat x, GLfloat y)
569 surface->geometry.x = x;
570 surface->geometry.y = y;
571 surface->geometry.dirty = 1;
575 weston_surface_is_mapped(struct weston_surface *surface)
584 weston_compositor_get_time(void)
588 gettimeofday(&tv, NULL);
590 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
593 static struct weston_surface *
594 weston_compositor_pick_surface(struct weston_compositor *compositor,
595 wl_fixed_t x, wl_fixed_t y,
596 wl_fixed_t *sx, wl_fixed_t *sy)
598 struct weston_surface *surface;
600 wl_list_for_each(surface, &compositor->surface_list, link) {
601 weston_surface_from_global_fixed(surface, x, y, sx, sy);
602 if (pixman_region32_contains_point(&surface->input,
603 wl_fixed_to_int(*sx),
604 wl_fixed_to_int(*sy),
613 weston_device_repick(struct weston_seat *seat)
615 const struct wl_pointer_grab_interface *interface;
616 struct weston_surface *surface, *focus;
617 struct wl_pointer *pointer = seat->seat.pointer;
622 surface = weston_compositor_pick_surface(seat->compositor,
626 &pointer->current_y);
628 if (&surface->surface != pointer->current) {
629 interface = pointer->grab->interface;
630 pointer->current = &surface->surface;
631 interface->focus(pointer->grab, &surface->surface,
636 focus = (struct weston_surface *) pointer->grab->focus;
638 weston_surface_from_global_fixed(focus,
646 weston_compositor_repick(struct weston_compositor *compositor)
648 struct weston_seat *seat;
650 if (!compositor->focus)
653 wl_list_for_each(seat, &compositor->seat_list, link)
654 weston_device_repick(seat);
658 weston_surface_unmap(struct weston_surface *surface)
660 struct weston_seat *seat;
662 weston_surface_damage_below(surface);
663 surface->output = NULL;
664 wl_list_remove(&surface->layer_link);
666 wl_list_for_each(seat, &surface->compositor->seat_list, link) {
667 if (seat->seat.keyboard &&
668 seat->seat.keyboard->focus == &surface->surface)
669 wl_keyboard_set_focus(seat->seat.keyboard, NULL);
670 if (seat->seat.pointer &&
671 seat->seat.pointer->focus == &surface->surface)
672 wl_pointer_set_focus(seat->seat.pointer,
674 wl_fixed_from_int(0),
675 wl_fixed_from_int(0));
678 weston_surface_schedule_repaint(surface);
681 struct weston_frame_callback {
682 struct wl_resource resource;
687 destroy_surface(struct wl_resource *resource)
691 struct weston_surface *surface =
692 container_of(resource,
693 struct weston_surface, surface.resource);
694 struct weston_compositor *compositor = surface->compositor;
695 struct weston_frame_callback *cb, *next;
697 if (weston_surface_is_mapped(surface))
698 weston_surface_unmap(surface);
700 glDeleteTextures(surface->num_textures, surface->textures);
703 wl_list_remove(&surface->buffer_destroy_listener.link);
705 for (i = 0; i < surface->num_images; i++)
706 compositor->destroy_image(compositor->egl_display,
709 pixman_region32_fini(&surface->transform.boundingbox);
710 pixman_region32_fini(&surface->damage);
711 pixman_region32_fini(&surface->opaque);
712 pixman_region32_fini(&surface->clip);
713 if (!region_is_undefined(&surface->input))
714 pixman_region32_fini(&surface->input);
716 wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link)
717 wl_resource_destroy(&cb->resource);
723 weston_surface_destroy(struct weston_surface *surface)
725 /* Not a valid way to destroy a client surface */
726 assert(surface->surface.resource.client == NULL);
728 wl_signal_emit(&surface->surface.resource.destroy_signal,
729 &surface->surface.resource);
730 destroy_surface(&surface->surface.resource);
734 ensure_textures(struct weston_surface *es, int num_textures)
738 if (num_textures <= es->num_textures)
741 for (i = es->num_textures; i < num_textures; i++) {
742 glGenTextures(1, &es->textures[i]);
743 glBindTexture(es->target, es->textures[i]);
744 glTexParameteri(es->target,
745 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
746 glTexParameteri(es->target,
747 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
749 es->num_textures = num_textures;
750 glBindTexture(es->target, 0);
754 weston_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer)
756 struct weston_surface *es = (struct weston_surface *) surface;
757 struct weston_compositor *ec = es->compositor;
758 EGLint attribs[3], format;
762 weston_buffer_post_release(es->buffer);
763 wl_list_remove(&es->buffer_destroy_listener.link);
769 if (weston_surface_is_mapped(es))
770 weston_surface_unmap(es);
771 for (i = 0; i < es->num_images; i++) {
772 ec->destroy_image(ec->egl_display, es->images[i]);
773 es->images[i] = NULL;
776 glDeleteTextures(es->num_textures, es->textures);
777 es->num_textures = 0;
781 buffer->busy_count++;
782 wl_signal_add(&es->buffer->resource.destroy_signal,
783 &es->buffer_destroy_listener);
785 if (es->geometry.width != buffer->width ||
786 es->geometry.height != buffer->height) {
787 undef_region(&es->input);
788 pixman_region32_fini(&es->opaque);
789 pixman_region32_init(&es->opaque);
792 if (wl_buffer_is_shm(buffer)) {
793 es->pitch = wl_shm_buffer_get_stride(buffer) / 4;
794 es->target = GL_TEXTURE_2D;
796 ensure_textures(es, 1);
797 glBindTexture(GL_TEXTURE_2D, es->textures[0]);
798 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
799 es->pitch, es->buffer->height, 0,
800 GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
801 if (wl_shm_buffer_get_format(buffer) == WL_SHM_FORMAT_XRGB8888)
802 es->shader = &ec->texture_shader_rgbx;
804 es->shader = &ec->texture_shader_rgba;
805 } else if (ec->query_buffer(ec->egl_display, buffer,
806 EGL_TEXTURE_FORMAT, &format)) {
807 for (i = 0; i < es->num_images; i++)
808 ec->destroy_image(ec->egl_display, es->images[i]);
810 es->target = GL_TEXTURE_2D;
812 case EGL_TEXTURE_RGB:
813 case EGL_TEXTURE_RGBA:
816 es->shader = &ec->texture_shader_rgba;
818 case EGL_TEXTURE_EXTERNAL_WL:
820 es->target = GL_TEXTURE_EXTERNAL_OES;
821 es->shader = &ec->texture_shader_egl_external;
823 case EGL_TEXTURE_Y_UV_WL:
825 es->shader = &ec->texture_shader_y_uv;
827 case EGL_TEXTURE_Y_U_V_WL:
829 es->shader = &ec->texture_shader_y_u_v;
831 case EGL_TEXTURE_Y_XUXV_WL:
833 es->shader = &ec->texture_shader_y_xuxv;
837 ensure_textures(es, num_planes);
838 for (i = 0; i < num_planes; i++) {
839 attribs[0] = EGL_WAYLAND_PLANE_WL;
841 attribs[2] = EGL_NONE;
842 es->images[i] = ec->create_image(ec->egl_display,
844 EGL_WAYLAND_BUFFER_WL,
846 if (!es->images[i]) {
847 weston_log("failed to create img for plane %d\n", i);
852 glActiveTexture(GL_TEXTURE0 + i);
853 glBindTexture(es->target, es->textures[i]);
854 ec->image_target_texture_2d(es->target,
858 es->pitch = buffer->width;
860 weston_log("unhandled buffer type!\n");
866 weston_surface_restack(struct weston_surface *surface, struct wl_list *below)
868 wl_list_remove(&surface->layer_link);
869 wl_list_insert(below, &surface->layer_link);
870 weston_surface_damage_below(surface);
871 weston_surface_damage(surface);
875 weston_compositor_damage_all(struct weston_compositor *compositor)
877 struct weston_output *output;
879 wl_list_for_each(output, &compositor->output_list, link)
880 weston_output_damage(output);
884 weston_buffer_post_release(struct wl_buffer *buffer)
886 if (--buffer->busy_count > 0)
889 assert(buffer->resource.client != NULL);
890 wl_resource_queue_event(&buffer->resource, WL_BUFFER_RELEASE);
894 weston_output_damage(struct weston_output *output)
896 struct weston_compositor *compositor = output->compositor;
898 pixman_region32_union(&compositor->primary_plane.damage,
899 &compositor->primary_plane.damage,
901 weston_output_schedule_repaint(output);
905 fade_frame(struct weston_animation *animation,
906 struct weston_output *output, uint32_t msecs)
908 struct weston_compositor *compositor =
909 container_of(animation,
910 struct weston_compositor, fade.animation);
911 struct weston_surface *surface;
913 if (animation->frame_counter <= 1)
914 compositor->fade.spring.timestamp = msecs;
916 surface = compositor->fade.surface;
917 weston_spring_update(&compositor->fade.spring, msecs);
918 weston_surface_set_color(surface, 0.0, 0.0, 0.0,
919 compositor->fade.spring.current);
920 weston_surface_damage(surface);
922 if (weston_spring_done(&compositor->fade.spring)) {
923 compositor->fade.spring.current =
924 compositor->fade.spring.target;
925 wl_list_remove(&animation->link);
926 wl_list_init(&animation->link);
928 if (compositor->fade.spring.current < 0.001) {
929 destroy_surface(&surface->surface.resource);
930 compositor->fade.surface = NULL;
931 } else if (compositor->fade.spring.current > 0.999) {
932 compositor->state = WESTON_COMPOSITOR_SLEEPING;
933 wl_signal_emit(&compositor->lock_signal, compositor);
939 update_shm_texture(struct weston_surface *surface)
941 #ifdef GL_UNPACK_ROW_LENGTH
942 pixman_box32_t *rectangles;
947 glBindTexture(GL_TEXTURE_2D, surface->textures[0]);
949 if (!surface->compositor->has_unpack_subimage) {
950 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
951 surface->pitch, surface->buffer->height, 0,
952 GL_BGRA_EXT, GL_UNSIGNED_BYTE,
953 wl_shm_buffer_get_data(surface->buffer));
958 #ifdef GL_UNPACK_ROW_LENGTH
959 /* Mesa does not define GL_EXT_unpack_subimage */
960 glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch);
961 data = wl_shm_buffer_get_data(surface->buffer);
962 rectangles = pixman_region32_rectangles(&surface->damage, &n);
963 for (i = 0; i < n; i++) {
964 glPixelStorei(GL_UNPACK_SKIP_PIXELS, rectangles[i].x1);
965 glPixelStorei(GL_UNPACK_SKIP_ROWS, rectangles[i].y1);
966 glTexSubImage2D(GL_TEXTURE_2D, 0,
967 rectangles[i].x1, rectangles[i].y1,
968 rectangles[i].x2 - rectangles[i].x1,
969 rectangles[i].y2 - rectangles[i].y1,
970 GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
976 surface_accumulate_damage(struct weston_surface *surface,
977 pixman_region32_t *opaque)
979 if (surface->buffer && wl_buffer_is_shm(surface->buffer))
980 update_shm_texture(surface);
982 if (surface->transform.enabled) {
983 pixman_box32_t *extents;
985 extents = pixman_region32_extents(&surface->damage);
986 surface_compute_bbox(surface, extents->x1, extents->y1,
987 extents->x2 - extents->x1,
988 extents->y2 - extents->y1,
990 pixman_region32_translate(&surface->damage,
994 pixman_region32_translate(&surface->damage,
995 surface->geometry.x - surface->plane->x,
996 surface->geometry.y - surface->plane->y);
999 pixman_region32_subtract(&surface->damage, &surface->damage, opaque);
1000 pixman_region32_union(&surface->plane->damage,
1001 &surface->plane->damage, &surface->damage);
1002 empty_region(&surface->damage);
1003 pixman_region32_copy(&surface->clip, opaque);
1004 pixman_region32_union(opaque, opaque, &surface->transform.opaque);
1008 weston_output_repaint(struct weston_output *output, uint32_t msecs)
1010 struct weston_compositor *ec = output->compositor;
1011 struct weston_surface *es;
1012 struct weston_layer *layer;
1013 struct weston_animation *animation, *next;
1014 struct weston_frame_callback *cb, *cnext;
1015 struct wl_list frame_callback_list;
1016 pixman_region32_t opaque, output_damage, new_damage;
1018 weston_compositor_update_drag_surfaces(ec);
1020 /* Rebuild the surface list and update surface transforms up front. */
1021 wl_list_init(&ec->surface_list);
1022 wl_list_init(&frame_callback_list);
1023 wl_list_for_each(layer, &ec->layer_list, link) {
1024 wl_list_for_each(es, &layer->surface_list, layer_link) {
1025 weston_surface_update_transform(es);
1026 wl_list_insert(ec->surface_list.prev, &es->link);
1027 if (es->output == output) {
1028 wl_list_insert_list(&frame_callback_list,
1029 &es->frame_callback_list);
1030 wl_list_init(&es->frame_callback_list);
1035 if (output->assign_planes && !output->disable_planes)
1036 output->assign_planes(output);
1038 wl_list_for_each(es, &ec->surface_list, link)
1039 weston_surface_move_to_plane(es, &ec->primary_plane);
1041 pixman_region32_init(&opaque);
1043 wl_list_for_each(es, &ec->surface_list, link)
1044 surface_accumulate_damage(es, &opaque);
1046 pixman_region32_fini(&opaque);
1048 pixman_region32_init(&output_damage);
1050 pixman_region32_init(&new_damage);
1051 pixman_region32_copy(&new_damage, &ec->primary_plane.damage);
1053 pixman_region32_union(&ec->primary_plane.damage,
1054 &ec->primary_plane.damage,
1055 &output->previous_damage);
1057 pixman_region32_intersect(&output->previous_damage,
1058 &new_damage, &output->region);
1060 pixman_region32_intersect(&output_damage,
1061 &ec->primary_plane.damage, &output->region);
1063 pixman_region32_fini(&new_damage);
1066 weston_output_update_matrix(output);
1068 output->repaint(output, &output_damage);
1070 pixman_region32_fini(&output_damage);
1072 output->repaint_needed = 0;
1074 weston_compositor_repick(ec);
1075 wl_event_loop_dispatch(ec->input_loop, 0);
1077 wl_list_for_each_safe(cb, cnext, &frame_callback_list, link) {
1078 wl_callback_send_done(&cb->resource, msecs);
1079 wl_resource_destroy(&cb->resource);
1081 wl_list_init(&frame_callback_list);
1083 wl_list_for_each_safe(animation, next, &output->animation_list, link) {
1084 animation->frame_counter++;
1085 animation->frame(animation, output, msecs);
1090 weston_compositor_read_input(int fd, uint32_t mask, void *data)
1092 struct weston_compositor *compositor = data;
1094 wl_event_loop_dispatch(compositor->input_loop, 0);
1100 weston_output_finish_frame(struct weston_output *output, uint32_t msecs)
1102 struct weston_compositor *compositor = output->compositor;
1103 struct wl_event_loop *loop =
1104 wl_display_get_event_loop(compositor->wl_display);
1107 output->frame_time = msecs;
1108 if (output->repaint_needed) {
1109 weston_output_repaint(output, msecs);
1113 output->repaint_scheduled = 0;
1114 if (compositor->input_loop_source)
1117 fd = wl_event_loop_get_fd(compositor->input_loop);
1118 compositor->input_loop_source =
1119 wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
1120 weston_compositor_read_input, compositor);
1124 idle_repaint(void *data)
1126 struct weston_output *output = data;
1128 weston_output_finish_frame(output, weston_compositor_get_time());
1132 weston_layer_init(struct weston_layer *layer, struct wl_list *below)
1134 wl_list_init(&layer->surface_list);
1136 wl_list_insert(below, &layer->link);
1140 weston_output_schedule_repaint(struct weston_output *output)
1142 struct weston_compositor *compositor = output->compositor;
1143 struct wl_event_loop *loop;
1145 if (compositor->state == WESTON_COMPOSITOR_SLEEPING)
1148 loop = wl_display_get_event_loop(compositor->wl_display);
1149 output->repaint_needed = 1;
1150 if (output->repaint_scheduled)
1153 wl_event_loop_add_idle(loop, idle_repaint, output);
1154 output->repaint_scheduled = 1;
1156 if (compositor->input_loop_source) {
1157 wl_event_source_remove(compositor->input_loop_source);
1158 compositor->input_loop_source = NULL;
1163 weston_compositor_schedule_repaint(struct weston_compositor *compositor)
1165 struct weston_output *output;
1167 wl_list_for_each(output, &compositor->output_list, link)
1168 weston_output_schedule_repaint(output);
1172 weston_compositor_fade(struct weston_compositor *compositor, float tint)
1174 struct weston_output *output;
1175 struct weston_surface *surface;
1177 output = container_of(compositor->output_list.next,
1178 struct weston_output, link);
1180 compositor->fade.spring.target = tint;
1181 if (weston_spring_done(&compositor->fade.spring))
1184 if (compositor->fade.surface == NULL) {
1185 surface = weston_surface_create(compositor);
1186 weston_surface_configure(surface, 0, 0, 8192, 8192);
1187 weston_surface_set_color(surface, 0.0, 0.0, 0.0, 0.0);
1188 wl_list_insert(&compositor->fade_layer.surface_list,
1189 &surface->layer_link);
1190 weston_surface_assign_output(surface);
1191 compositor->fade.surface = surface;
1192 pixman_region32_init(&surface->input);
1195 weston_surface_damage(compositor->fade.surface);
1196 if (wl_list_empty(&compositor->fade.animation.link)) {
1197 compositor->fade.animation.frame_counter = 0;
1198 wl_list_insert(output->animation_list.prev,
1199 &compositor->fade.animation.link);
1204 surface_destroy(struct wl_client *client, struct wl_resource *resource)
1206 wl_resource_destroy(resource);
1209 static struct wl_resource *
1210 find_resource_for_client(struct wl_list *list, struct wl_client *client)
1212 struct wl_resource *r;
1214 wl_list_for_each(r, list, link) {
1215 if (r->client == client)
1223 weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask)
1225 uint32_t different = es->output_mask ^ mask;
1226 uint32_t entered = mask & different;
1227 uint32_t left = es->output_mask & different;
1228 struct weston_output *output;
1229 struct wl_resource *resource = NULL;
1230 struct wl_client *client = es->surface.resource.client;
1232 es->output_mask = mask;
1233 if (es->surface.resource.client == NULL)
1238 wl_list_for_each(output, &es->compositor->output_list, link) {
1239 if (1 << output->id & different)
1241 find_resource_for_client(&output->resource_list,
1243 if (resource == NULL)
1245 if (1 << output->id & entered)
1246 wl_surface_send_enter(&es->surface.resource, resource);
1247 if (1 << output->id & left)
1248 wl_surface_send_leave(&es->surface.resource, resource);
1253 weston_surface_assign_output(struct weston_surface *es)
1255 struct weston_compositor *ec = es->compositor;
1256 struct weston_output *output, *new_output;
1257 pixman_region32_t region;
1258 uint32_t max, area, mask;
1264 pixman_region32_init(®ion);
1265 wl_list_for_each(output, &ec->output_list, link) {
1266 pixman_region32_intersect(®ion, &es->transform.boundingbox,
1269 e = pixman_region32_extents(®ion);
1270 area = (e->x2 - e->x1) * (e->y2 - e->y1);
1273 mask |= 1 << output->id;
1276 new_output = output;
1280 pixman_region32_fini(®ion);
1282 es->output = new_output;
1283 weston_surface_update_output_mask(es, mask);
1287 surface_attach(struct wl_client *client,
1288 struct wl_resource *resource,
1289 struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
1291 struct weston_surface *es = resource->data;
1292 struct wl_buffer *buffer = NULL;
1294 if (buffer_resource)
1295 buffer = buffer_resource->data;
1297 weston_surface_attach(&es->surface, buffer);
1299 if (buffer && es->configure)
1300 es->configure(es, sx, sy);
1304 surface_damage(struct wl_client *client,
1305 struct wl_resource *resource,
1306 int32_t x, int32_t y, int32_t width, int32_t height)
1308 struct weston_surface *es = resource->data;
1310 pixman_region32_union_rect(&es->damage, &es->damage,
1311 x, y, width, height);
1312 weston_surface_schedule_repaint(es);
1316 destroy_frame_callback(struct wl_resource *resource)
1318 struct weston_frame_callback *cb = resource->data;
1320 wl_list_remove(&cb->link);
1325 surface_frame(struct wl_client *client,
1326 struct wl_resource *resource, uint32_t callback)
1328 struct weston_frame_callback *cb;
1329 struct weston_surface *es = resource->data;
1331 cb = malloc(sizeof *cb);
1333 wl_resource_post_no_memory(resource);
1337 cb->resource.object.interface = &wl_callback_interface;
1338 cb->resource.object.id = callback;
1339 cb->resource.destroy = destroy_frame_callback;
1340 cb->resource.client = client;
1341 cb->resource.data = cb;
1343 wl_client_add_resource(client, &cb->resource);
1344 wl_list_insert(es->frame_callback_list.prev, &cb->link);
1348 surface_set_opaque_region(struct wl_client *client,
1349 struct wl_resource *resource,
1350 struct wl_resource *region_resource)
1352 struct weston_surface *surface = resource->data;
1353 struct weston_region *region;
1355 pixman_region32_fini(&surface->opaque);
1357 if (region_resource) {
1358 region = region_resource->data;
1359 pixman_region32_init_rect(&surface->opaque, 0, 0,
1360 surface->geometry.width,
1361 surface->geometry.height);
1362 pixman_region32_intersect(&surface->opaque,
1363 &surface->opaque, ®ion->region);
1365 pixman_region32_init(&surface->opaque);
1368 surface->geometry.dirty = 1;
1372 surface_set_input_region(struct wl_client *client,
1373 struct wl_resource *resource,
1374 struct wl_resource *region_resource)
1376 struct weston_surface *surface = resource->data;
1377 struct weston_region *region;
1379 if (region_resource) {
1380 region = region_resource->data;
1381 pixman_region32_init_rect(&surface->input, 0, 0,
1382 surface->geometry.width,
1383 surface->geometry.height);
1384 pixman_region32_intersect(&surface->input,
1385 &surface->input, ®ion->region);
1387 pixman_region32_init_rect(&surface->input, 0, 0,
1388 surface->geometry.width,
1389 surface->geometry.height);
1392 weston_surface_schedule_repaint(surface);
1395 static const struct wl_surface_interface surface_interface = {
1400 surface_set_opaque_region,
1401 surface_set_input_region
1405 compositor_create_surface(struct wl_client *client,
1406 struct wl_resource *resource, uint32_t id)
1408 struct weston_compositor *ec = resource->data;
1409 struct weston_surface *surface;
1411 surface = weston_surface_create(ec);
1412 if (surface == NULL) {
1413 wl_resource_post_no_memory(resource);
1417 surface->surface.resource.destroy = destroy_surface;
1419 surface->surface.resource.object.id = id;
1420 surface->surface.resource.object.interface = &wl_surface_interface;
1421 surface->surface.resource.object.implementation =
1422 (void (**)(void)) &surface_interface;
1423 surface->surface.resource.data = surface;
1425 wl_client_add_resource(client, &surface->surface.resource);
1429 destroy_region(struct wl_resource *resource)
1431 struct weston_region *region =
1432 container_of(resource, struct weston_region, resource);
1434 pixman_region32_fini(®ion->region);
1439 region_destroy(struct wl_client *client, struct wl_resource *resource)
1441 wl_resource_destroy(resource);
1445 region_add(struct wl_client *client, struct wl_resource *resource,
1446 int32_t x, int32_t y, int32_t width, int32_t height)
1448 struct weston_region *region = resource->data;
1450 pixman_region32_union_rect(®ion->region, ®ion->region,
1451 x, y, width, height);
1455 region_subtract(struct wl_client *client, struct wl_resource *resource,
1456 int32_t x, int32_t y, int32_t width, int32_t height)
1458 struct weston_region *region = resource->data;
1459 pixman_region32_t rect;
1461 pixman_region32_init_rect(&rect, x, y, width, height);
1462 pixman_region32_subtract(®ion->region, ®ion->region, &rect);
1463 pixman_region32_fini(&rect);
1466 static const struct wl_region_interface region_interface = {
1473 compositor_create_region(struct wl_client *client,
1474 struct wl_resource *resource, uint32_t id)
1476 struct weston_region *region;
1478 region = malloc(sizeof *region);
1479 if (region == NULL) {
1480 wl_resource_post_no_memory(resource);
1484 region->resource.destroy = destroy_region;
1486 region->resource.object.id = id;
1487 region->resource.object.interface = &wl_region_interface;
1488 region->resource.object.implementation =
1489 (void (**)(void)) ®ion_interface;
1490 region->resource.data = region;
1492 pixman_region32_init(®ion->region);
1494 wl_client_add_resource(client, ®ion->resource);
1497 static const struct wl_compositor_interface compositor_interface = {
1498 compositor_create_surface,
1499 compositor_create_region
1503 weston_compositor_wake(struct weston_compositor *compositor)
1505 compositor->state = WESTON_COMPOSITOR_ACTIVE;
1506 weston_compositor_fade(compositor, 0.0);
1508 wl_event_source_timer_update(compositor->idle_source,
1509 compositor->idle_time * 1000);
1513 weston_compositor_dpms_on(struct weston_compositor *compositor)
1515 struct weston_output *output;
1517 wl_list_for_each(output, &compositor->output_list, link)
1518 if (output->set_dpms)
1519 output->set_dpms(output, WESTON_DPMS_ON);
1523 weston_compositor_activity(struct weston_compositor *compositor)
1525 if (compositor->state == WESTON_COMPOSITOR_ACTIVE) {
1526 weston_compositor_wake(compositor);
1528 weston_compositor_dpms_on(compositor);
1529 wl_signal_emit(&compositor->unlock_signal, compositor);
1534 weston_compositor_idle_inhibit(struct weston_compositor *compositor)
1536 weston_compositor_activity(compositor);
1537 compositor->idle_inhibit++;
1541 weston_compositor_idle_release(struct weston_compositor *compositor)
1543 compositor->idle_inhibit--;
1544 weston_compositor_activity(compositor);
1548 idle_handler(void *data)
1550 struct weston_compositor *compositor = data;
1552 if (compositor->idle_inhibit)
1555 weston_compositor_fade(compositor, 1.0);
1561 weston_plane_init(struct weston_plane *plane, int32_t x, int32_t y)
1563 pixman_region32_init(&plane->damage);
1569 weston_plane_release(struct weston_plane *plane)
1571 pixman_region32_fini(&plane->damage);
1575 weston_seat_update_drag_surface(struct weston_seat *seat, int dx, int dy);
1578 clip_pointer_motion(struct weston_seat *seat, wl_fixed_t *fx, wl_fixed_t *fy)
1580 struct weston_compositor *ec = seat->compositor;
1581 struct weston_output *output, *prev = NULL;
1582 int x, y, old_x, old_y, valid = 0;
1584 x = wl_fixed_to_int(*fx);
1585 y = wl_fixed_to_int(*fy);
1586 old_x = wl_fixed_to_int(seat->seat.pointer->x);
1587 old_y = wl_fixed_to_int(seat->seat.pointer->y);
1589 wl_list_for_each(output, &ec->output_list, link) {
1590 if (pixman_region32_contains_point(&output->region,
1593 if (pixman_region32_contains_point(&output->region,
1594 old_x, old_y, NULL))
1600 *fx = wl_fixed_from_int(prev->x);
1601 else if (x >= prev->x + prev->width)
1602 *fx = wl_fixed_from_int(prev->x +
1605 *fy = wl_fixed_from_int(prev->y);
1606 else if (y >= prev->y + prev->current->height)
1607 *fy = wl_fixed_from_int(prev->y +
1613 notify_motion(struct weston_seat *seat, uint32_t time, wl_fixed_t x, wl_fixed_t y)
1615 const struct wl_pointer_grab_interface *interface;
1616 struct weston_compositor *ec = seat->compositor;
1617 struct weston_output *output;
1618 struct wl_pointer *pointer = seat->seat.pointer;
1621 weston_compositor_activity(ec);
1623 clip_pointer_motion(seat, &x, &y);
1625 weston_seat_update_drag_surface(seat, x - pointer->x, y - pointer->y);
1630 ix = wl_fixed_to_int(x);
1631 iy = wl_fixed_to_int(y);
1633 wl_list_for_each(output, &ec->output_list, link)
1634 if (output->zoom.active &&
1635 pixman_region32_contains_point(&output->region,
1637 weston_output_update_zoom(output, ZOOM_FOCUS_POINTER);
1639 weston_device_repick(seat);
1640 interface = pointer->grab->interface;
1641 interface->motion(pointer->grab, time,
1642 pointer->grab->x, pointer->grab->y);
1645 weston_surface_set_position(seat->sprite,
1646 ix - seat->hotspot_x,
1647 iy - seat->hotspot_y);
1648 weston_surface_schedule_repaint(seat->sprite);
1653 weston_surface_activate(struct weston_surface *surface,
1654 struct weston_seat *seat)
1656 struct weston_compositor *compositor = seat->compositor;
1658 if (seat->seat.keyboard) {
1659 wl_keyboard_set_focus(seat->seat.keyboard, &surface->surface);
1660 wl_data_device_set_keyboard_focus(&seat->seat);
1663 wl_signal_emit(&compositor->activate_signal, surface);
1667 notify_button(struct weston_seat *seat, uint32_t time, int32_t button,
1668 enum wl_pointer_button_state state)
1670 struct weston_compositor *compositor = seat->compositor;
1671 struct wl_pointer *pointer = seat->seat.pointer;
1672 struct weston_surface *focus =
1673 (struct weston_surface *) pointer->focus;
1674 uint32_t serial = wl_display_next_serial(compositor->wl_display);
1676 if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
1677 if (compositor->ping_handler && focus)
1678 compositor->ping_handler(focus, serial);
1679 weston_compositor_idle_inhibit(compositor);
1680 if (pointer->button_count == 0) {
1681 pointer->grab_button = button;
1682 pointer->grab_time = time;
1683 pointer->grab_x = pointer->x;
1684 pointer->grab_y = pointer->y;
1686 pointer->button_count++;
1688 weston_compositor_idle_release(compositor);
1689 pointer->button_count--;
1692 weston_compositor_run_button_binding(compositor, seat, time, button,
1695 pointer->grab->interface->button(pointer->grab, time, button, state);
1697 if (pointer->button_count == 1)
1698 pointer->grab_serial =
1699 wl_display_get_serial(compositor->wl_display);
1703 notify_axis(struct weston_seat *seat, uint32_t time, uint32_t axis,
1706 struct weston_compositor *compositor = seat->compositor;
1707 struct wl_pointer *pointer = seat->seat.pointer;
1708 struct weston_surface *focus =
1709 (struct weston_surface *) pointer->focus;
1710 uint32_t serial = wl_display_next_serial(compositor->wl_display);
1712 if (compositor->ping_handler && focus)
1713 compositor->ping_handler(focus, serial);
1715 weston_compositor_activity(compositor);
1718 weston_compositor_run_axis_binding(compositor, seat,
1723 if (pointer->focus_resource)
1724 wl_pointer_send_axis(pointer->focus_resource, time, axis,
1729 notify_modifiers(struct weston_seat *seat, uint32_t serial)
1731 struct wl_keyboard *keyboard = &seat->keyboard;
1732 struct wl_keyboard_grab *grab = keyboard->grab;
1733 uint32_t mods_depressed, mods_latched, mods_locked, group;
1734 uint32_t mods_lookup;
1735 enum weston_led leds = 0;
1738 /* Serialize and update our internal state, checking to see if it's
1739 * different to the previous state. */
1740 mods_depressed = xkb_state_serialize_mods(seat->xkb_state.state,
1741 XKB_STATE_DEPRESSED);
1742 mods_latched = xkb_state_serialize_mods(seat->xkb_state.state,
1744 mods_locked = xkb_state_serialize_mods(seat->xkb_state.state,
1746 group = xkb_state_serialize_group(seat->xkb_state.state,
1747 XKB_STATE_EFFECTIVE);
1749 if (mods_depressed != seat->seat.keyboard->modifiers.mods_depressed ||
1750 mods_latched != seat->seat.keyboard->modifiers.mods_latched ||
1751 mods_locked != seat->seat.keyboard->modifiers.mods_locked ||
1752 group != seat->seat.keyboard->modifiers.group)
1755 seat->seat.keyboard->modifiers.mods_depressed = mods_depressed;
1756 seat->seat.keyboard->modifiers.mods_latched = mods_latched;
1757 seat->seat.keyboard->modifiers.mods_locked = mods_locked;
1758 seat->seat.keyboard->modifiers.group = group;
1760 /* And update the modifier_state for bindings. */
1761 mods_lookup = mods_depressed | mods_latched;
1762 seat->modifier_state = 0;
1763 if (mods_lookup & (1 << seat->xkb_info.ctrl_mod))
1764 seat->modifier_state |= MODIFIER_CTRL;
1765 if (mods_lookup & (1 << seat->xkb_info.alt_mod))
1766 seat->modifier_state |= MODIFIER_ALT;
1767 if (mods_lookup & (1 << seat->xkb_info.super_mod))
1768 seat->modifier_state |= MODIFIER_SUPER;
1769 if (mods_lookup & (1 << seat->xkb_info.shift_mod))
1770 seat->modifier_state |= MODIFIER_SHIFT;
1772 /* Finally, notify the compositor that LEDs have changed. */
1773 if (xkb_state_led_index_is_active(seat->xkb_state.state,
1774 seat->xkb_info.num_led))
1775 leds |= LED_NUM_LOCK;
1776 if (xkb_state_led_index_is_active(seat->xkb_state.state,
1777 seat->xkb_info.caps_led))
1778 leds |= LED_CAPS_LOCK;
1779 if (xkb_state_led_index_is_active(seat->xkb_state.state,
1780 seat->xkb_info.scroll_led))
1781 leds |= LED_SCROLL_LOCK;
1782 if (leds != seat->xkb_state.leds && seat->led_update)
1783 seat->led_update(seat, leds);
1784 seat->xkb_state.leds = leds;
1787 grab->interface->modifiers(grab,
1789 keyboard->modifiers.mods_depressed,
1790 keyboard->modifiers.mods_latched,
1791 keyboard->modifiers.mods_locked,
1792 keyboard->modifiers.group);
1797 update_modifier_state(struct weston_seat *seat, uint32_t serial, uint32_t key,
1798 enum wl_keyboard_key_state state)
1800 enum xkb_key_direction direction;
1802 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1803 direction = XKB_KEY_DOWN;
1805 direction = XKB_KEY_UP;
1807 /* Offset the keycode by 8, as the evdev XKB rules reflect X's
1808 * broken keycode system, which starts at 8. */
1809 xkb_state_update_key(seat->xkb_state.state, key + 8, direction);
1811 notify_modifiers(seat, serial);
1815 notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
1816 enum wl_keyboard_key_state state,
1817 enum weston_key_state_update update_state)
1819 struct weston_compositor *compositor = seat->compositor;
1820 struct wl_keyboard *keyboard = seat->seat.keyboard;
1821 struct weston_surface *focus =
1822 (struct weston_surface *) keyboard->focus;
1823 struct wl_keyboard_grab *grab = keyboard->grab;
1824 uint32_t serial = wl_display_next_serial(compositor->wl_display);
1827 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1828 if (compositor->ping_handler && focus)
1829 compositor->ping_handler(focus, serial);
1831 weston_compositor_idle_inhibit(compositor);
1832 keyboard->grab_key = key;
1833 keyboard->grab_time = time;
1835 weston_compositor_idle_release(compositor);
1838 end = keyboard->keys.data + keyboard->keys.size;
1839 for (k = keyboard->keys.data; k < end; k++) {
1841 /* Ignore server-generated repeats. */
1842 if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
1847 keyboard->keys.size = (void *) end - keyboard->keys.data;
1848 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1849 k = wl_array_add(&keyboard->keys, sizeof *k);
1853 if (grab == &keyboard->default_grab) {
1854 weston_compositor_run_key_binding(compositor, seat, time, key,
1856 grab = keyboard->grab;
1859 grab->interface->key(grab, time, key, state);
1861 if (update_state == STATE_UPDATE_AUTOMATIC) {
1862 update_modifier_state(seat,
1863 wl_display_get_serial(compositor->wl_display),
1870 notify_pointer_focus(struct weston_seat *seat, struct weston_output *output,
1871 wl_fixed_t x, wl_fixed_t y)
1873 struct weston_compositor *compositor = seat->compositor;
1874 struct wl_pointer *pointer = seat->seat.pointer;
1877 weston_seat_update_drag_surface(seat,
1883 compositor->focus = 1;
1884 weston_compositor_repick(compositor);
1886 compositor->focus = 0;
1887 /* FIXME: We should call wl_pointer_set_focus(seat,
1888 * NULL) here, but somehow that breaks re-entry... */
1893 destroy_device_saved_kbd_focus(struct wl_listener *listener, void *data)
1895 struct weston_seat *ws;
1897 ws = container_of(listener, struct weston_seat,
1898 saved_kbd_focus_listener);
1900 ws->saved_kbd_focus = NULL;
1904 notify_keyboard_focus_in(struct weston_seat *seat, struct wl_array *keys,
1905 enum weston_key_state_update update_state)
1907 struct weston_compositor *compositor = seat->compositor;
1908 struct wl_keyboard *keyboard = seat->seat.keyboard;
1909 struct wl_surface *surface;
1910 uint32_t *k, serial;
1912 serial = wl_display_next_serial(compositor->wl_display);
1913 wl_array_copy(&keyboard->keys, keys);
1914 wl_array_for_each(k, &keyboard->keys) {
1915 weston_compositor_idle_inhibit(compositor);
1916 if (update_state == STATE_UPDATE_AUTOMATIC)
1917 update_modifier_state(seat, serial, *k,
1918 WL_KEYBOARD_KEY_STATE_PRESSED);
1921 /* Run key bindings after we've updated the state. */
1922 wl_array_for_each(k, &keyboard->keys) {
1923 weston_compositor_run_key_binding(compositor, seat, 0, *k,
1924 WL_KEYBOARD_KEY_STATE_PRESSED);
1927 surface = seat->saved_kbd_focus;
1930 wl_list_remove(&seat->saved_kbd_focus_listener.link);
1931 wl_keyboard_set_focus(keyboard, surface);
1932 seat->saved_kbd_focus = NULL;
1937 notify_keyboard_focus_out(struct weston_seat *seat)
1939 struct weston_compositor *compositor = seat->compositor;
1940 struct wl_keyboard *keyboard = seat->seat.keyboard;
1941 uint32_t *k, serial;
1943 serial = wl_display_next_serial(compositor->wl_display);
1944 wl_array_for_each(k, &keyboard->keys) {
1945 weston_compositor_idle_release(compositor);
1946 update_modifier_state(seat, serial, *k,
1947 WL_KEYBOARD_KEY_STATE_RELEASED);
1950 seat->modifier_state = 0;
1952 if (keyboard->focus) {
1953 seat->saved_kbd_focus = keyboard->focus;
1954 seat->saved_kbd_focus_listener.notify =
1955 destroy_device_saved_kbd_focus;
1956 wl_signal_add(&keyboard->focus->resource.destroy_signal,
1957 &seat->saved_kbd_focus_listener);
1960 wl_keyboard_set_focus(keyboard, NULL);
1961 /* FIXME: We really need keyboard grab cancel here to
1962 * let the grab shut down properly. As it is we leak
1964 wl_keyboard_end_grab(keyboard);
1968 touch_set_focus(struct weston_seat *ws, struct wl_surface *surface)
1970 struct wl_seat *seat = &ws->seat;
1971 struct wl_resource *resource;
1973 if (seat->touch->focus == surface)
1976 if (seat->touch->focus_resource)
1977 wl_list_remove(&seat->touch->focus_listener.link);
1978 seat->touch->focus = NULL;
1979 seat->touch->focus_resource = NULL;
1983 find_resource_for_client(&seat->touch->resource_list,
1984 surface->resource.client);
1986 weston_log("couldn't find resource\n");
1990 seat->touch->focus = surface;
1991 seat->touch->focus_resource = resource;
1992 wl_signal_add(&resource->destroy_signal,
1993 &seat->touch->focus_listener);
1998 * notify_touch - emulates button touches and notifies surfaces accordingly.
2000 * It assumes always the correct cycle sequence until it gets here: touch_down
2001 * → touch_update → ... → touch_update → touch_end. The driver is responsible
2002 * for sending along such order.
2006 notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
2007 wl_fixed_t x, wl_fixed_t y, int touch_type)
2009 struct weston_compositor *ec = seat->compositor;
2010 struct wl_touch *touch = seat->seat.touch;
2011 struct weston_surface *es;
2013 uint32_t serial = 0;
2015 switch (touch_type) {
2017 weston_compositor_idle_inhibit(ec);
2021 /* the first finger down picks the surface, and all further go
2022 * to that surface for the remainder of the touch session i.e.
2023 * until all touch points are up again. */
2024 if (seat->num_tp == 1) {
2025 es = weston_compositor_pick_surface(ec, x, y, &sx, &sy);
2026 touch_set_focus(seat, &es->surface);
2027 } else if (touch->focus) {
2028 es = (struct weston_surface *) touch->focus;
2029 weston_surface_from_global_fixed(es, x, y, &sx, &sy);
2032 if (touch->focus_resource && touch->focus)
2033 wl_touch_send_down(touch->focus_resource,
2035 &touch->focus->resource,
2038 case WL_TOUCH_MOTION:
2039 es = (struct weston_surface *) touch->focus;
2043 weston_surface_from_global_fixed(es, x, y, &sx, &sy);
2044 if (touch->focus_resource)
2045 wl_touch_send_motion(touch->focus_resource,
2046 time, touch_id, sx, sy);
2049 weston_compositor_idle_release(ec);
2052 if (touch->focus_resource)
2053 wl_touch_send_up(touch->focus_resource,
2054 serial, time, touch_id);
2055 if (seat->num_tp == 0)
2056 touch_set_focus(seat, NULL);
2062 pointer_handle_sprite_destroy(struct wl_listener *listener, void *data)
2064 struct weston_seat *seat = container_of(listener, struct weston_seat,
2065 sprite_destroy_listener);
2067 seat->sprite = NULL;
2071 pointer_cursor_surface_configure(struct weston_surface *es,
2072 int32_t dx, int32_t dy)
2074 struct weston_seat *seat = es->private;
2077 assert(es == seat->sprite);
2079 seat->hotspot_x -= dx;
2080 seat->hotspot_y -= dy;
2082 x = wl_fixed_to_int(seat->seat.pointer->x) - seat->hotspot_x;
2083 y = wl_fixed_to_int(seat->seat.pointer->y) - seat->hotspot_y;
2085 weston_surface_configure(seat->sprite, x, y,
2086 es->buffer->width, es->buffer->height);
2088 empty_region(&es->input);
2090 if (!weston_surface_is_mapped(es)) {
2091 wl_list_insert(&es->compositor->cursor_layer.surface_list,
2093 weston_surface_assign_output(es);
2098 pointer_unmap_sprite(struct weston_seat *seat)
2100 if (weston_surface_is_mapped(seat->sprite))
2101 weston_surface_unmap(seat->sprite);
2103 wl_list_remove(&seat->sprite_destroy_listener.link);
2104 seat->sprite->configure = NULL;
2105 seat->sprite->private = NULL;
2106 seat->sprite = NULL;
2110 pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
2111 uint32_t serial, struct wl_resource *surface_resource,
2112 int32_t x, int32_t y)
2114 struct weston_seat *seat = resource->data;
2115 struct weston_surface *surface = NULL;
2117 if (surface_resource)
2118 surface = container_of(surface_resource->data,
2119 struct weston_surface, surface);
2121 if (seat->seat.pointer->focus == NULL)
2123 if (seat->seat.pointer->focus->resource.client != client)
2125 if (seat->seat.pointer->focus_serial - serial > UINT32_MAX / 2)
2128 if (surface && surface != seat->sprite) {
2129 if (surface->configure) {
2130 wl_resource_post_error(&surface->surface.resource,
2131 WL_DISPLAY_ERROR_INVALID_OBJECT,
2132 "surface->configure already "
2139 pointer_unmap_sprite(seat);
2144 wl_signal_add(&surface->surface.resource.destroy_signal,
2145 &seat->sprite_destroy_listener);
2147 surface->configure = pointer_cursor_surface_configure;
2148 surface->private = seat;
2149 seat->sprite = surface;
2150 seat->hotspot_x = x;
2151 seat->hotspot_y = y;
2153 if (surface->buffer)
2154 pointer_cursor_surface_configure(surface, 0, 0);
2157 static const struct wl_pointer_interface pointer_interface = {
2162 handle_drag_surface_destroy(struct wl_listener *listener, void *data)
2164 struct weston_seat *seat;
2166 seat = container_of(listener, struct weston_seat,
2167 drag_surface_destroy_listener);
2169 seat->drag_surface = NULL;
2172 static void unbind_resource(struct wl_resource *resource)
2174 wl_list_remove(&resource->link);
2179 seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
2182 struct weston_seat *seat = resource->data;
2183 struct wl_resource *cr;
2185 if (!seat->seat.pointer)
2188 cr = wl_client_add_object(client, &wl_pointer_interface,
2189 &pointer_interface, id, seat);
2190 wl_list_insert(&seat->seat.pointer->resource_list, &cr->link);
2191 cr->destroy = unbind_resource;
2193 if (seat->seat.pointer->focus &&
2194 seat->seat.pointer->focus->resource.client == client) {
2195 struct weston_surface *surface;
2198 surface = (struct weston_surface *) seat->seat.pointer->focus;
2199 weston_surface_from_global_fixed(surface,
2200 seat->seat.pointer->x,
2201 seat->seat.pointer->y,
2204 wl_pointer_set_focus(seat->seat.pointer,
2205 seat->seat.pointer->focus,
2212 seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
2215 struct weston_seat *seat = resource->data;
2216 struct wl_resource *cr;
2218 if (!seat->seat.keyboard)
2221 cr = wl_client_add_object(client, &wl_keyboard_interface, NULL, id,
2223 wl_list_insert(&seat->seat.keyboard->resource_list, &cr->link);
2224 cr->destroy = unbind_resource;
2226 wl_keyboard_send_keymap(cr, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
2227 seat->xkb_info.keymap_fd,
2228 seat->xkb_info.keymap_size);
2230 if (seat->seat.keyboard->focus &&
2231 seat->seat.keyboard->focus->resource.client == client) {
2232 wl_keyboard_set_focus(seat->seat.keyboard,
2233 seat->seat.keyboard->focus);
2238 seat_get_touch(struct wl_client *client, struct wl_resource *resource,
2241 struct weston_seat *seat = resource->data;
2242 struct wl_resource *cr;
2244 if (!seat->seat.touch)
2247 cr = wl_client_add_object(client, &wl_touch_interface, NULL, id, seat);
2248 wl_list_insert(&seat->seat.touch->resource_list, &cr->link);
2249 cr->destroy = unbind_resource;
2252 static const struct wl_seat_interface seat_interface = {
2259 bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
2261 struct wl_seat *seat = data;
2262 struct wl_resource *resource;
2263 enum wl_seat_capability caps = 0;
2265 resource = wl_client_add_object(client, &wl_seat_interface,
2266 &seat_interface, id, data);
2267 wl_list_insert(&seat->base_resource_list, &resource->link);
2268 resource->destroy = unbind_resource;
2271 caps |= WL_SEAT_CAPABILITY_POINTER;
2273 caps |= WL_SEAT_CAPABILITY_KEYBOARD;
2275 caps |= WL_SEAT_CAPABILITY_TOUCH;
2277 wl_seat_send_capabilities(resource, caps);
2281 device_handle_new_drag_icon(struct wl_listener *listener, void *data)
2283 struct weston_seat *seat;
2285 seat = container_of(listener, struct weston_seat,
2286 new_drag_icon_listener);
2288 weston_seat_update_drag_surface(seat, 0, 0);
2291 static void weston_compositor_xkb_init(struct weston_compositor *ec,
2292 struct xkb_rule_names *names)
2294 if (ec->xkb_context == NULL) {
2295 ec->xkb_context = xkb_context_new(0);
2296 if (ec->xkb_context == NULL) {
2297 weston_log("failed to create XKB context\n");
2303 ec->xkb_names = *names;
2304 if (!ec->xkb_names.rules)
2305 ec->xkb_names.rules = strdup("evdev");
2306 if (!ec->xkb_names.model)
2307 ec->xkb_names.model = strdup("pc105");
2308 if (!ec->xkb_names.layout)
2309 ec->xkb_names.layout = strdup("us");
2312 static void xkb_info_destroy(struct weston_xkb_info *xkb_info)
2314 if (xkb_info->keymap)
2315 xkb_map_unref(xkb_info->keymap);
2317 if (xkb_info->keymap_area)
2318 munmap(xkb_info->keymap_area, xkb_info->keymap_size);
2319 if (xkb_info->keymap_fd >= 0)
2320 close(xkb_info->keymap_fd);
2323 static void weston_compositor_xkb_destroy(struct weston_compositor *ec)
2325 free((char *) ec->xkb_names.rules);
2326 free((char *) ec->xkb_names.model);
2327 free((char *) ec->xkb_names.layout);
2328 free((char *) ec->xkb_names.variant);
2329 free((char *) ec->xkb_names.options);
2331 xkb_info_destroy(&ec->xkb_info);
2332 xkb_context_unref(ec->xkb_context);
2336 weston_xkb_info_new_keymap(struct weston_xkb_info *xkb_info)
2340 xkb_info->shift_mod = xkb_map_mod_get_index(xkb_info->keymap,
2341 XKB_MOD_NAME_SHIFT);
2342 xkb_info->caps_mod = xkb_map_mod_get_index(xkb_info->keymap,
2344 xkb_info->ctrl_mod = xkb_map_mod_get_index(xkb_info->keymap,
2346 xkb_info->alt_mod = xkb_map_mod_get_index(xkb_info->keymap,
2348 xkb_info->mod2_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod2");
2349 xkb_info->mod3_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod3");
2350 xkb_info->super_mod = xkb_map_mod_get_index(xkb_info->keymap,
2352 xkb_info->mod5_mod = xkb_map_mod_get_index(xkb_info->keymap, "Mod5");
2354 xkb_info->num_led = xkb_map_led_get_index(xkb_info->keymap,
2356 xkb_info->caps_led = xkb_map_led_get_index(xkb_info->keymap,
2358 xkb_info->scroll_led = xkb_map_led_get_index(xkb_info->keymap,
2359 XKB_LED_NAME_SCROLL);
2361 keymap_str = xkb_map_get_as_string(xkb_info->keymap);
2362 if (keymap_str == NULL) {
2363 weston_log("failed to get string version of keymap\n");
2366 xkb_info->keymap_size = strlen(keymap_str) + 1;
2368 xkb_info->keymap_fd = os_create_anonymous_file(xkb_info->keymap_size);
2369 if (xkb_info->keymap_fd < 0) {
2370 weston_log("creating a keymap file for %lu bytes failed: %m\n",
2371 (unsigned long) xkb_info->keymap_size);
2372 goto err_keymap_str;
2375 xkb_info->keymap_area = mmap(NULL, xkb_info->keymap_size,
2376 PROT_READ | PROT_WRITE,
2377 MAP_SHARED, xkb_info->keymap_fd, 0);
2378 if (xkb_info->keymap_area == MAP_FAILED) {
2379 weston_log("failed to mmap() %lu bytes\n",
2380 (unsigned long) xkb_info->keymap_size);
2383 strcpy(xkb_info->keymap_area, keymap_str);
2389 close(xkb_info->keymap_fd);
2390 xkb_info->keymap_fd = -1;
2397 weston_compositor_build_global_keymap(struct weston_compositor *ec)
2399 if (ec->xkb_info.keymap != NULL)
2402 ec->xkb_info.keymap = xkb_map_new_from_names(ec->xkb_context,
2405 if (ec->xkb_info.keymap == NULL) {
2406 weston_log("failed to compile global XKB keymap\n");
2407 weston_log(" tried rules %s, model %s, layout %s, variant %s, "
2409 ec->xkb_names.rules, ec->xkb_names.model,
2410 ec->xkb_names.layout, ec->xkb_names.variant,
2411 ec->xkb_names.options);
2415 weston_xkb_info_new_keymap(&ec->xkb_info);
2419 weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap)
2421 if (seat->has_keyboard)
2424 if (keymap != NULL) {
2425 seat->xkb_info.keymap = xkb_map_ref(keymap);
2426 weston_xkb_info_new_keymap(&seat->xkb_info);
2429 weston_compositor_build_global_keymap(seat->compositor);
2430 seat->xkb_info = seat->compositor->xkb_info;
2431 seat->xkb_info.keymap = xkb_map_ref(seat->xkb_info.keymap);
2434 seat->xkb_state.state = xkb_state_new(seat->xkb_info.keymap);
2435 if (seat->xkb_state.state == NULL) {
2436 weston_log("failed to initialise XKB state\n");
2440 seat->xkb_state.leds = 0;
2442 wl_keyboard_init(&seat->keyboard);
2443 wl_seat_set_keyboard(&seat->seat, &seat->keyboard);
2445 seat->has_keyboard = 1;
2449 weston_seat_init_pointer(struct weston_seat *seat)
2451 if (seat->has_pointer)
2454 wl_pointer_init(&seat->pointer);
2455 wl_seat_set_pointer(&seat->seat, &seat->pointer);
2457 seat->has_pointer = 1;
2461 weston_seat_init_touch(struct weston_seat *seat)
2463 if (seat->has_touch)
2466 wl_touch_init(&seat->touch);
2467 wl_seat_set_touch(&seat->seat, &seat->touch);
2469 seat->has_touch = 1;
2473 weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec)
2475 wl_seat_init(&seat->seat);
2476 seat->has_pointer = 0;
2477 seat->has_keyboard = 0;
2478 seat->has_touch = 0;
2480 wl_display_add_global(ec->wl_display, &wl_seat_interface, seat,
2483 seat->sprite = NULL;
2484 seat->sprite_destroy_listener.notify = pointer_handle_sprite_destroy;
2486 seat->compositor = ec;
2487 seat->hotspot_x = 16;
2488 seat->hotspot_y = 16;
2489 seat->modifier_state = 0;
2492 seat->drag_surface_destroy_listener.notify =
2493 handle_drag_surface_destroy;
2495 wl_list_insert(ec->seat_list.prev, &seat->link);
2497 seat->new_drag_icon_listener.notify = device_handle_new_drag_icon;
2498 wl_signal_add(&seat->seat.drag_icon_signal,
2499 &seat->new_drag_icon_listener);
2501 clipboard_create(seat);
2502 input_method_create(ec, seat);
2506 weston_seat_release(struct weston_seat *seat)
2508 wl_list_remove(&seat->link);
2509 /* The global object is destroyed at wl_display_destroy() time. */
2512 pointer_unmap_sprite(seat);
2514 if (seat->xkb_state.state != NULL)
2515 xkb_state_unref(seat->xkb_state.state);
2516 xkb_info_destroy(&seat->xkb_info);
2518 wl_seat_release(&seat->seat);
2522 drag_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy)
2524 weston_surface_configure(es,
2525 es->geometry.x + sx, es->geometry.y + sy,
2526 es->buffer->width, es->buffer->height);
2530 device_setup_new_drag_surface(struct weston_seat *ws,
2531 struct weston_surface *surface)
2533 struct wl_seat *seat = &ws->seat;
2535 if (surface->configure) {
2536 wl_resource_post_error(&surface->surface.resource,
2537 WL_DISPLAY_ERROR_INVALID_OBJECT,
2538 "surface->configure already set");
2542 ws->drag_surface = surface;
2544 weston_surface_set_position(ws->drag_surface,
2545 wl_fixed_to_double(seat->pointer->x),
2546 wl_fixed_to_double(seat->pointer->y));
2548 surface->configure = drag_surface_configure;
2550 wl_signal_add(&surface->surface.resource.destroy_signal,
2551 &ws->drag_surface_destroy_listener);
2557 device_release_drag_surface(struct weston_seat *seat)
2559 seat->drag_surface->configure = NULL;
2560 undef_region(&seat->drag_surface->input);
2561 wl_list_remove(&seat->drag_surface_destroy_listener.link);
2562 seat->drag_surface = NULL;
2566 device_map_drag_surface(struct weston_seat *seat)
2568 struct wl_list *list;
2570 if (weston_surface_is_mapped(seat->drag_surface) ||
2571 !seat->drag_surface->buffer)
2574 if (seat->sprite && weston_surface_is_mapped(seat->sprite))
2575 list = &seat->sprite->layer_link;
2577 list = &seat->compositor->cursor_layer.surface_list;
2579 wl_list_insert(list, &seat->drag_surface->layer_link);
2580 weston_surface_assign_output(seat->drag_surface);
2581 empty_region(&seat->drag_surface->input);
2585 weston_seat_update_drag_surface(struct weston_seat *seat,
2588 int surface_changed = 0;
2590 if (!seat->drag_surface && !seat->seat.drag_surface)
2593 if (seat->drag_surface && seat->seat.drag_surface &&
2594 (&seat->drag_surface->surface.resource !=
2595 &seat->seat.drag_surface->resource))
2596 /* between calls to this funcion we got a new drag_surface */
2597 surface_changed = 1;
2599 if (!seat->seat.drag_surface || surface_changed) {
2600 device_release_drag_surface(seat);
2601 if (!surface_changed)
2605 if (!seat->drag_surface || surface_changed) {
2606 struct weston_surface *surface = (struct weston_surface *)
2607 seat->seat.drag_surface;
2608 if (!device_setup_new_drag_surface(seat, surface))
2612 /* the client may not have attached a buffer to the drag surface
2613 * when we setup it up, so check if map is needed on every update */
2614 device_map_drag_surface(seat);
2616 /* the client may have attached a buffer with a different size to
2617 * the drag surface, causing the input region to be reset */
2618 if (region_is_undefined(&seat->drag_surface->input))
2619 empty_region(&seat->drag_surface->input);
2624 weston_surface_set_position(seat->drag_surface,
2625 seat->drag_surface->geometry.x + wl_fixed_to_double(dx),
2626 seat->drag_surface->geometry.y + wl_fixed_to_double(dy));
2630 weston_compositor_update_drag_surfaces(struct weston_compositor *compositor)
2632 struct weston_seat *seat;
2634 wl_list_for_each(seat, &compositor->seat_list, link)
2635 weston_seat_update_drag_surface(seat, 0, 0);
2639 bind_output(struct wl_client *client,
2640 void *data, uint32_t version, uint32_t id)
2642 struct weston_output *output = data;
2643 struct weston_mode *mode;
2644 struct wl_resource *resource;
2646 resource = wl_client_add_object(client,
2647 &wl_output_interface, NULL, id, data);
2649 wl_list_insert(&output->resource_list, &resource->link);
2650 resource->destroy = unbind_resource;
2652 wl_output_send_geometry(resource,
2658 output->make, output->model,
2661 wl_list_for_each (mode, &output->mode_list, link) {
2662 wl_output_send_mode(resource,
2670 static const char vertex_shader[] =
2671 "uniform mat4 proj;\n"
2672 "attribute vec2 position;\n"
2673 "attribute vec2 texcoord;\n"
2674 "varying vec2 v_texcoord;\n"
2677 " gl_Position = proj * vec4(position, 0.0, 1.0);\n"
2678 " v_texcoord = texcoord;\n"
2681 /* Declare common fragment shader uniforms */
2682 #define FRAGMENT_CONVERT_YUV \
2686 " gl_FragColor.r = y + 1.59602678 * v;\n" \
2687 " gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v;\n" \
2688 " gl_FragColor.b = y + 2.01723214 * u;\n" \
2689 " gl_FragColor.a = alpha;\n"
2691 static const char texture_fragment_shader_rgba[] =
2692 "precision mediump float;\n"
2693 "varying vec2 v_texcoord;\n"
2694 "uniform sampler2D tex;\n"
2695 "uniform float alpha;\n"
2698 " gl_FragColor = alpha * texture2D(tex, v_texcoord)\n;"
2701 static const char texture_fragment_shader_rgbx[] =
2702 "precision mediump float;\n"
2703 "varying vec2 v_texcoord;\n"
2704 "uniform sampler2D tex;\n"
2705 "uniform float alpha;\n"
2708 " gl_FragColor.rgb = alpha * texture2D(tex, v_texcoord).rgb\n;"
2709 " gl_FragColor.a = alpha;\n"
2712 static const char texture_fragment_shader_egl_external[] =
2713 "#extension GL_OES_EGL_image_external : require\n"
2714 "precision mediump float;\n"
2715 "varying vec2 v_texcoord;\n"
2716 "uniform samplerExternalOES tex;\n"
2717 "uniform float alpha;\n"
2720 " gl_FragColor = alpha * texture2D(tex, v_texcoord)\n;"
2723 static const char texture_fragment_shader_y_uv[] =
2724 "precision mediump float;\n"
2725 "uniform sampler2D tex;\n"
2726 "uniform sampler2D tex1;\n"
2727 "varying vec2 v_texcoord;\n"
2728 "uniform float alpha;\n"
2730 " float y = 1.16438356 * (texture2D(tex, v_texcoord).x - 0.0625);\n"
2731 " float u = texture2D(tex1, v_texcoord).r - 0.5;\n"
2732 " float v = texture2D(tex1, v_texcoord).g - 0.5;\n"
2733 FRAGMENT_CONVERT_YUV
2736 static const char texture_fragment_shader_y_u_v[] =
2737 "precision mediump float;\n"
2738 "uniform sampler2D tex;\n"
2739 "uniform sampler2D tex1;\n"
2740 "uniform sampler2D tex2;\n"
2741 "varying vec2 v_texcoord;\n"
2742 "uniform float alpha;\n"
2744 " float y = 1.16438356 * (texture2D(tex, v_texcoord).x - 0.0625);\n"
2745 " float u = texture2D(tex1, v_texcoord).x - 0.5;\n"
2746 " float v = texture2D(tex2, v_texcoord).x - 0.5;\n"
2747 FRAGMENT_CONVERT_YUV
2750 static const char texture_fragment_shader_y_xuxv[] =
2751 "precision mediump float;\n"
2752 "uniform sampler2D tex;\n"
2753 "uniform sampler2D tex1;\n"
2754 "varying vec2 v_texcoord;\n"
2755 "uniform float alpha;\n"
2757 " float y = 1.16438356 * (texture2D(tex, v_texcoord).x - 0.0625);\n"
2758 " float u = texture2D(tex1, v_texcoord).g - 0.5;\n"
2759 " float v = texture2D(tex1, v_texcoord).a - 0.5;\n"
2760 FRAGMENT_CONVERT_YUV
2763 static const char solid_fragment_shader[] =
2764 "precision mediump float;\n"
2765 "uniform vec4 color;\n"
2766 "uniform float alpha;\n"
2769 " gl_FragColor = alpha * color\n;"
2773 compile_shader(GLenum type, const char *source)
2779 s = glCreateShader(type);
2780 glShaderSource(s, 1, &source, NULL);
2782 glGetShaderiv(s, GL_COMPILE_STATUS, &status);
2784 glGetShaderInfoLog(s, sizeof msg, NULL, msg);
2785 weston_log("shader info: %s\n", msg);
2793 weston_shader_init(struct weston_shader *shader,
2794 const char *vertex_source, const char *fragment_source)
2799 shader->vertex_shader =
2800 compile_shader(GL_VERTEX_SHADER, vertex_source);
2801 shader->fragment_shader =
2802 compile_shader(GL_FRAGMENT_SHADER, fragment_source);
2804 shader->program = glCreateProgram();
2805 glAttachShader(shader->program, shader->vertex_shader);
2806 glAttachShader(shader->program, shader->fragment_shader);
2807 glBindAttribLocation(shader->program, 0, "position");
2808 glBindAttribLocation(shader->program, 1, "texcoord");
2810 glLinkProgram(shader->program);
2811 glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
2813 glGetProgramInfoLog(shader->program, sizeof msg, NULL, msg);
2814 weston_log("link info: %s\n", msg);
2818 shader->proj_uniform = glGetUniformLocation(shader->program, "proj");
2819 shader->tex_uniforms[0] = glGetUniformLocation(shader->program, "tex");
2820 shader->tex_uniforms[1] = glGetUniformLocation(shader->program, "tex1");
2821 shader->tex_uniforms[2] = glGetUniformLocation(shader->program, "tex2");
2822 shader->alpha_uniform = glGetUniformLocation(shader->program, "alpha");
2823 shader->color_uniform = glGetUniformLocation(shader->program, "color");
2829 weston_output_destroy(struct weston_output *output)
2831 struct weston_compositor *c = output->compositor;
2833 pixman_region32_fini(&output->region);
2834 pixman_region32_fini(&output->previous_damage);
2835 output->compositor->output_id_pool &= ~(1 << output->id);
2837 wl_display_remove_global(c->wl_display, output->global);
2841 weston_output_compute_transform(struct weston_output *output)
2843 struct weston_matrix transform;
2846 weston_matrix_init(&transform);
2848 switch(output->transform) {
2849 case WL_OUTPUT_TRANSFORM_FLIPPED:
2850 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2851 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2852 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2860 switch(output->transform) {
2861 case WL_OUTPUT_TRANSFORM_NORMAL:
2862 case WL_OUTPUT_TRANSFORM_FLIPPED:
2863 transform.d[0] = flip;
2868 case WL_OUTPUT_TRANSFORM_90:
2869 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2871 transform.d[1] = -flip;
2875 case WL_OUTPUT_TRANSFORM_180:
2876 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2877 transform.d[0] = -flip;
2880 transform.d[5] = -1;
2882 case WL_OUTPUT_TRANSFORM_270:
2883 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2885 transform.d[1] = flip;
2886 transform.d[4] = -1;
2893 weston_matrix_multiply(&output->matrix, &transform);
2897 weston_output_update_matrix(struct weston_output *output)
2899 float magnification;
2900 struct weston_matrix camera;
2901 struct weston_matrix modelview;
2903 weston_matrix_init(&output->matrix);
2904 weston_matrix_translate(&output->matrix,
2905 -(output->x + (output->border.right + output->width - output->border.left) / 2.0),
2906 -(output->y + (output->border.bottom + output->height - output->border.top) / 2.0), 0);
2908 weston_matrix_scale(&output->matrix,
2909 2.0 / (output->width + output->border.left + output->border.right),
2910 -2.0 / (output->height + output->border.top + output->border.bottom), 1);
2912 weston_output_compute_transform(output);
2914 if (output->zoom.active) {
2915 magnification = 1 / (1 - output->zoom.spring_z.current);
2916 weston_matrix_init(&camera);
2917 weston_matrix_init(&modelview);
2918 weston_output_update_zoom(output, output->zoom.type);
2919 weston_matrix_translate(&camera, output->zoom.trans_x,
2920 -output->zoom.trans_y, 0);
2921 weston_matrix_invert(&modelview, &camera);
2922 weston_matrix_scale(&modelview, magnification, magnification, 1.0);
2923 weston_matrix_multiply(&output->matrix, &modelview);
2930 weston_output_transform_init(struct weston_output *output, uint32_t transform)
2932 output->transform = transform;
2934 switch (transform) {
2935 case WL_OUTPUT_TRANSFORM_90:
2936 case WL_OUTPUT_TRANSFORM_270:
2937 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2938 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2939 /* Swap width and height */
2940 output->width = output->current->height;
2941 output->height = output->current->width;
2943 case WL_OUTPUT_TRANSFORM_NORMAL:
2944 case WL_OUTPUT_TRANSFORM_180:
2945 case WL_OUTPUT_TRANSFORM_FLIPPED:
2946 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2947 output->width = output->current->width;
2948 output->height = output->current->height;
2956 weston_output_move(struct weston_output *output, int x, int y)
2961 pixman_region32_init(&output->previous_damage);
2962 pixman_region32_init_rect(&output->region, x, y,
2968 weston_output_init(struct weston_output *output, struct weston_compositor *c,
2969 int x, int y, int width, int height, uint32_t transform)
2971 output->compositor = c;
2974 output->border.top = 0;
2975 output->border.bottom = 0;
2976 output->border.left = 0;
2977 output->border.right = 0;
2978 output->mm_width = width;
2979 output->mm_height = height;
2982 if (transform != WL_OUTPUT_TRANSFORM_NORMAL)
2983 output->disable_planes++;
2985 weston_output_transform_init(output, transform);
2986 weston_output_init_zoom(output);
2988 weston_output_move(output, x, y);
2989 weston_output_damage(output);
2991 wl_signal_init(&output->frame_signal);
2992 wl_list_init(&output->animation_list);
2993 wl_list_init(&output->resource_list);
2995 output->id = ffs(~output->compositor->output_id_pool) - 1;
2996 output->compositor->output_id_pool |= 1 << output->id;
2999 wl_display_add_global(c->wl_display, &wl_output_interface,
3000 output, bind_output);
3004 compositor_bind(struct wl_client *client,
3005 void *data, uint32_t version, uint32_t id)
3007 struct weston_compositor *compositor = data;
3009 wl_client_add_object(client, &wl_compositor_interface,
3010 &compositor_interface, id, compositor);
3016 struct utsname usys;
3020 weston_log("OS: %s, %s, %s, %s\n", usys.sysname, usys.release,
3021 usys.version, usys.machine);
3025 log_extensions(const char *name, const char *extensions)
3027 const char *p, *end;
3031 l = weston_log("%s:", name);
3034 end = strchrnul(p, ' ');
3037 l = weston_log_continue("\n" STAMP_SPACE "%.*s",
3040 l += weston_log_continue(" %.*s", len, p);
3041 for (p = end; isspace(*p); p++)
3044 weston_log_continue("\n");
3048 log_egl_gl_info(EGLDisplay egldpy)
3052 str = eglQueryString(egldpy, EGL_VERSION);
3053 weston_log("EGL version: %s\n", str ? str : "(null)");
3055 str = eglQueryString(egldpy, EGL_VENDOR);
3056 weston_log("EGL vendor: %s\n", str ? str : "(null)");
3058 str = eglQueryString(egldpy, EGL_CLIENT_APIS);
3059 weston_log("EGL client APIs: %s\n", str ? str : "(null)");
3061 str = eglQueryString(egldpy, EGL_EXTENSIONS);
3062 log_extensions("EGL extensions", str ? str : "(null)");
3064 str = (char *)glGetString(GL_VERSION);
3065 weston_log("GL version: %s\n", str ? str : "(null)");
3067 str = (char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
3068 weston_log("GLSL version: %s\n", str ? str : "(null)");
3070 str = (char *)glGetString(GL_VENDOR);
3071 weston_log("GL vendor: %s\n", str ? str : "(null)");
3073 str = (char *)glGetString(GL_RENDERER);
3074 weston_log("GL renderer: %s\n", str ? str : "(null)");
3076 str = (char *)glGetString(GL_EXTENSIONS);
3077 log_extensions("GL extensions", str ? str : "(null)");
3081 weston_compositor_init(struct weston_compositor *ec,
3082 struct wl_display *display,
3085 const char *config_file)
3087 struct wl_event_loop *loop;
3088 struct xkb_rule_names xkb_names;
3089 const struct config_key keyboard_config_keys[] = {
3090 { "keymap_rules", CONFIG_KEY_STRING, &xkb_names.rules },
3091 { "keymap_model", CONFIG_KEY_STRING, &xkb_names.model },
3092 { "keymap_layout", CONFIG_KEY_STRING, &xkb_names.layout },
3093 { "keymap_variant", CONFIG_KEY_STRING, &xkb_names.variant },
3094 { "keymap_options", CONFIG_KEY_STRING, &xkb_names.options },
3096 const struct config_section cs[] = {
3098 keyboard_config_keys, ARRAY_LENGTH(keyboard_config_keys) },
3101 memset(&xkb_names, 0, sizeof(xkb_names));
3102 parse_config_file(config_file, cs, ARRAY_LENGTH(cs), ec);
3104 ec->wl_display = display;
3105 wl_signal_init(&ec->destroy_signal);
3106 wl_signal_init(&ec->activate_signal);
3107 wl_signal_init(&ec->lock_signal);
3108 wl_signal_init(&ec->unlock_signal);
3109 wl_signal_init(&ec->show_input_panel_signal);
3110 wl_signal_init(&ec->hide_input_panel_signal);
3111 ec->launcher_sock = weston_environment_get_fd("WESTON_LAUNCHER_SOCK");
3113 ec->output_id_pool = 0;
3115 if (!wl_display_add_global(display, &wl_compositor_interface,
3116 ec, compositor_bind))
3119 wl_list_init(&ec->surface_list);
3120 wl_list_init(&ec->layer_list);
3121 wl_list_init(&ec->seat_list);
3122 wl_list_init(&ec->output_list);
3123 wl_list_init(&ec->key_binding_list);
3124 wl_list_init(&ec->button_binding_list);
3125 wl_list_init(&ec->axis_binding_list);
3126 wl_list_init(&ec->fade.animation.link);
3128 weston_plane_init(&ec->primary_plane, 0, 0);
3130 weston_compositor_xkb_init(ec, &xkb_names);
3132 ec->ping_handler = NULL;
3134 screenshooter_create(ec);
3135 text_cursor_position_notifier_create(ec);
3137 wl_data_device_manager_init(ec->wl_display);
3139 wl_display_init_shm(display);
3141 loop = wl_display_get_event_loop(ec->wl_display);
3142 ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
3143 wl_event_source_timer_update(ec->idle_source, ec->idle_time * 1000);
3145 ec->input_loop = wl_event_loop_create();
3151 weston_compositor_init_gl(struct weston_compositor *ec)
3153 const char *extensions;
3154 int has_egl_image_external = 0;
3156 log_egl_gl_info(ec->egl_display);
3158 ec->image_target_texture_2d =
3159 (void *) eglGetProcAddress("glEGLImageTargetTexture2DOES");
3160 ec->image_target_renderbuffer_storage = (void *)
3161 eglGetProcAddress("glEGLImageTargetRenderbufferStorageOES");
3162 ec->create_image = (void *) eglGetProcAddress("eglCreateImageKHR");
3163 ec->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
3165 (void *) eglGetProcAddress("eglBindWaylandDisplayWL");
3166 ec->unbind_display =
3167 (void *) eglGetProcAddress("eglUnbindWaylandDisplayWL");
3169 (void *) eglGetProcAddress("eglQueryWaylandBufferWL");
3171 extensions = (const char *) glGetString(GL_EXTENSIONS);
3173 weston_log("Retrieving GL extension string failed.\n");
3177 if (!strstr(extensions, "GL_EXT_texture_format_BGRA8888")) {
3178 weston_log("GL_EXT_texture_format_BGRA8888 not available\n");
3182 if (strstr(extensions, "GL_EXT_read_format_bgra"))
3183 ec->read_format = GL_BGRA_EXT;
3185 ec->read_format = GL_RGBA;
3187 if (strstr(extensions, "GL_EXT_unpack_subimage"))
3188 ec->has_unpack_subimage = 1;
3190 if (strstr(extensions, "GL_OES_EGL_image_external"))
3191 has_egl_image_external = 1;
3194 (const char *) eglQueryString(ec->egl_display, EGL_EXTENSIONS);
3196 weston_log("Retrieving EGL extension string failed.\n");
3200 if (strstr(extensions, "EGL_WL_bind_wayland_display"))
3201 ec->has_bind_display = 1;
3202 if (ec->has_bind_display)
3203 ec->bind_display(ec->egl_display, ec->wl_display);
3205 weston_spring_init(&ec->fade.spring, 30.0, 1.0, 1.0);
3206 ec->fade.animation.frame = fade_frame;
3208 weston_layer_init(&ec->fade_layer, &ec->layer_list);
3209 weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link);
3211 glActiveTexture(GL_TEXTURE0);
3213 if (weston_shader_init(&ec->texture_shader_rgba,
3214 vertex_shader, texture_fragment_shader_rgba) < 0)
3216 if (weston_shader_init(&ec->texture_shader_rgbx,
3217 vertex_shader, texture_fragment_shader_rgbx) < 0)
3219 if (has_egl_image_external &&
3220 weston_shader_init(&ec->texture_shader_egl_external,
3221 vertex_shader, texture_fragment_shader_egl_external) < 0)
3223 if (weston_shader_init(&ec->texture_shader_y_uv,
3224 vertex_shader, texture_fragment_shader_y_uv) < 0)
3226 if (weston_shader_init(&ec->texture_shader_y_u_v,
3227 vertex_shader, texture_fragment_shader_y_u_v) < 0)
3229 if (weston_shader_init(&ec->texture_shader_y_xuxv,
3230 vertex_shader, texture_fragment_shader_y_xuxv) < 0)
3232 if (weston_shader_init(&ec->solid_shader,
3233 vertex_shader, solid_fragment_shader) < 0)
3236 weston_compositor_schedule_repaint(ec);
3242 weston_compositor_shutdown(struct weston_compositor *ec)
3244 struct weston_output *output, *next;
3246 wl_event_source_remove(ec->idle_source);
3247 if (ec->input_loop_source)
3248 wl_event_source_remove(ec->input_loop_source);
3250 /* Destroy all outputs associated with this compositor */
3251 wl_list_for_each_safe(output, next, &ec->output_list, link)
3252 output->destroy(output);
3254 weston_binding_list_destroy_all(&ec->key_binding_list);
3255 weston_binding_list_destroy_all(&ec->button_binding_list);
3256 weston_binding_list_destroy_all(&ec->axis_binding_list);
3258 weston_plane_release(&ec->primary_plane);
3260 wl_array_release(&ec->vertices);
3261 wl_array_release(&ec->indices);
3262 wl_array_release(&ec->vtxcnt);
3264 wl_event_loop_destroy(ec->input_loop);
3267 static int on_term_signal(int signal_number, void *data)
3269 struct wl_display *display = data;
3271 weston_log("caught signal %d\n", signal_number);
3272 wl_display_terminate(display);
3278 on_segv_signal(int s, siginfo_t *siginfo, void *context)
3284 /* This SIGSEGV handler will do a best-effort backtrace, and
3285 * then call the backend restore function, which will switch
3286 * back to the vt we launched from or ungrab X etc and then
3287 * raise SIGTRAP. If we run weston under gdb from X or a
3288 * different vt, and tell gdb "handle SIGSEGV nostop", this
3289 * will allow weston to switch back to gdb on crash and then
3290 * gdb will catch the crash with SIGTRAP. */
3292 weston_log("caught segv\n");
3294 count = backtrace(buffer, ARRAY_LENGTH(buffer));
3295 for (i = 0; i < count; i++) {
3296 dladdr(buffer[i], &info);
3297 weston_log(" [%016lx] %s (%s)\n",
3299 info.dli_sname ? info.dli_sname : "--",
3303 segv_compositor->restore(segv_compositor);
3310 load_module(const char *name, const char *entrypoint, void **handle)
3312 char path[PATH_MAX];
3313 void *module, *init;
3316 snprintf(path, sizeof path, "%s/%s", MODULEDIR, name);
3318 snprintf(path, sizeof path, "%s", name);
3320 weston_log("Loading module '%s'\n", path);
3321 module = dlopen(path, RTLD_NOW);
3323 weston_log("Failed to load module: %s\n", dlerror());
3327 init = dlsym(module, entrypoint);
3329 weston_log("Failed to lookup init function: %s\n", dlerror());
3336 static const char xdg_error_message[] =
3337 "fatal: environment variable XDG_RUNTIME_DIR is not set.\n";
3339 static const char xdg_wrong_message[] =
3340 "fatal: environment variable XDG_RUNTIME_DIR\n"
3341 "is set to \"%s\", which is not a directory.\n";
3343 static const char xdg_wrong_mode_message[] =
3344 "warning: XDG_RUNTIME_DIR \"%s\" is not configured\n"
3345 "correctly. Unix access mode must be 0700 but is %o,\n"
3346 "and XDG_RUNTIME_DIR must be owned by the user, but is\n"
3347 "owned by UID %d.\n";
3349 static const char xdg_detail_message[] =
3350 "Refer to your distribution on how to get it, or\n"
3351 "http://www.freedesktop.org/wiki/Specifications/basedir-spec\n"
3352 "on how to implement it.\n";
3355 verify_xdg_runtime_dir(void)
3357 char *dir = getenv("XDG_RUNTIME_DIR");
3361 weston_log(xdg_error_message);
3362 weston_log_continue(xdg_detail_message);
3366 if (stat(dir, &s) || !S_ISDIR(s.st_mode)) {
3367 weston_log(xdg_wrong_message, dir);
3368 weston_log_continue(xdg_detail_message);
3372 if ((s.st_mode & 0777) != 0700 || s.st_uid != getuid()) {
3373 weston_log(xdg_wrong_mode_message,
3374 dir, s.st_mode & 0777, s.st_uid);
3375 weston_log_continue(xdg_detail_message);
3380 usage(int error_code)
3383 "Usage: weston [OPTIONS]\n\n"
3384 "This is weston version " VERSION ", the Wayland reference compositor.\n"
3385 "Weston supports multiple backends, and depending on which backend is in use\n"
3386 "different options will be accepted.\n\n"
3390 " -B, --backend=MODULE\tBackend module, one of drm-backend.so,\n"
3391 "\t\t\t\tx11-backend.so or wayland-backend.so\n"
3392 " -S, --socket=NAME\tName of socket to listen on\n"
3393 " -i, --idle-time=SECS\tIdle time in seconds\n"
3394 " --xserver\t\tEnable X server integration\n"
3395 " --module\t\tLoad the specified module\n"
3396 " --log==FILE\t\tLog to the given file\n"
3397 " -h, --help\t\tThis help message\n\n");
3400 "Options for drm-backend.so:\n\n"
3401 " --connector=ID\tBring up only this connector\n"
3402 " --seat=SEAT\t\tThe seat that weston should run on\n"
3403 " --tty=TTY\t\tThe tty to use\n"
3404 " --current-mode\tPrefer current KMS mode over EDID preferred mode\n\n");
3407 "Options for x11-backend.so:\n\n"
3408 " --width=WIDTH\t\tWidth of X window\n"
3409 " --height=HEIGHT\tHeight of X window\n"
3410 " --fullscreen\t\tRun in fullscreen mode\n"
3411 " --output-count=COUNT\tCreate multiple outputs\n"
3412 " --no-input\t\tDont create input devices\n\n");
3415 "Options for wayland-backend.so:\n\n"
3416 " --width=WIDTH\t\tWidth of Wayland surface\n"
3417 " --height=HEIGHT\tHeight of Wayland surface\n"
3418 " --display=DISPLAY\tWayland display to connect to\n\n");
3423 int main(int argc, char *argv[])
3425 int ret = EXIT_SUCCESS;
3426 struct wl_display *display;
3427 struct weston_compositor *ec;
3428 struct wl_event_source *signals[4];
3429 struct wl_event_loop *loop;
3430 struct sigaction segv_action;
3431 void *shell_module, *backend_module, *xserver_module;
3432 int (*module_init)(struct weston_compositor *ec);
3433 struct weston_compositor
3434 *(*backend_init)(struct wl_display *display,
3435 int argc, char *argv[], const char *config_file);
3437 char *backend = NULL;
3439 char *module = NULL;
3441 int32_t idle_time = 300;
3442 int32_t xserver = 0;
3444 char *socket_name = NULL;
3447 const struct config_key shell_config_keys[] = {
3448 { "type", CONFIG_KEY_STRING, &shell },
3451 const struct config_section cs[] = {
3453 shell_config_keys, ARRAY_LENGTH(shell_config_keys) },
3456 const struct weston_option core_options[] = {
3457 { WESTON_OPTION_STRING, "backend", 'B', &backend },
3458 { WESTON_OPTION_STRING, "socket", 'S', &socket_name },
3459 { WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time },
3460 { WESTON_OPTION_BOOLEAN, "xserver", 0, &xserver },
3461 { WESTON_OPTION_STRING, "module", 0, &module },
3462 { WESTON_OPTION_STRING, "log", 0, &log },
3463 { WESTON_OPTION_BOOLEAN, "help", 'h', &help },
3466 argc = parse_options(core_options,
3467 ARRAY_LENGTH(core_options), argc, argv);
3470 usage(EXIT_SUCCESS);
3472 weston_log_file_open(log);
3476 STAMP_SPACE "Bug reports to: %s\n"
3477 STAMP_SPACE "Build: %s\n",
3478 PACKAGE_STRING, PACKAGE_URL, PACKAGE_BUGREPORT,
3482 verify_xdg_runtime_dir();
3484 display = wl_display_create();
3486 loop = wl_display_get_event_loop(display);
3487 signals[0] = wl_event_loop_add_signal(loop, SIGTERM, on_term_signal,
3489 signals[1] = wl_event_loop_add_signal(loop, SIGINT, on_term_signal,
3491 signals[2] = wl_event_loop_add_signal(loop, SIGQUIT, on_term_signal,
3494 wl_list_init(&child_process_list);
3495 signals[3] = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler,
3499 if (getenv("WAYLAND_DISPLAY"))
3500 backend = "wayland-backend.so";
3501 else if (getenv("DISPLAY"))
3502 backend = "x11-backend.so";
3504 backend = "drm-backend.so";
3507 config_file = config_file_path("weston.ini");
3508 parse_config_file(config_file, cs, ARRAY_LENGTH(cs), shell);
3510 backend_init = load_module(backend, "backend_init", &backend_module);
3514 ec = backend_init(display, argc, argv, config_file);
3516 weston_log("fatal: failed to create compositor\n");
3520 segv_action.sa_flags = SA_SIGINFO | SA_RESETHAND;
3521 segv_action.sa_sigaction = on_segv_signal;
3522 sigemptyset(&segv_action.sa_mask);
3523 sigaction(SIGSEGV, &segv_action, NULL);
3524 segv_compositor = ec;
3526 for (i = 1; argv[i]; i++)
3527 weston_log("fatal: unhandled option: %s\n", argv[i]);
3535 ec->option_idle_time = idle_time;
3536 ec->idle_time = idle_time;
3540 module_init = load_module("xwayland.so",
3541 "weston_xserver_init",
3543 if (module_init && module_init(ec) < 0) {
3549 setenv("WAYLAND_DISPLAY", socket_name, 1);
3552 shell = "desktop-shell.so";
3553 module_init = load_module(shell, "shell_init", &shell_module);
3554 if (!module_init || module_init(ec) < 0) {
3562 module_init = load_module(module, "module_init", NULL);
3563 if (module_init && module_init(ec) < 0) {
3568 if (wl_display_add_socket(display, socket_name)) {
3569 weston_log("fatal: failed to add socket: %m\n");
3574 weston_compositor_dpms_on(ec);
3575 weston_compositor_wake(ec);
3577 wl_display_run(display);
3580 /* prevent further rendering while shutting down */
3581 ec->state = WESTON_COMPOSITOR_SLEEPING;
3583 wl_signal_emit(&ec->destroy_signal, ec);
3585 if (ec->has_bind_display)
3586 ec->unbind_display(ec->egl_display, display);
3588 for (i = ARRAY_LENGTH(signals); i;)
3589 wl_event_source_remove(signals[--i]);
3591 weston_compositor_xkb_destroy(ec);
3594 wl_display_destroy(display);
3596 weston_log_file_close();