X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fcompositor-wayland.c;h=7fe7d5da60cff5659c97e56711d287562d1cf04a;hb=acf948cdfa6bba2bbe783ac6ce962e7acaa29b22;hp=386f9b6a242f0bd9a13e130760c371d8edb9bfe7;hpb=06d58b74afc55866fda0d93fc630e96bb4594962;p=profile%2Fivi%2Fweston.git diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c index 386f9b6..7fe7d5d 100644 --- a/src/compositor-wayland.c +++ b/src/compositor-wayland.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -41,12 +42,14 @@ #include #include "compositor.h" +#include "../shared/image-loader.h" struct wayland_compositor { struct weston_compositor base; struct { - struct wl_display *display; + struct wl_display *wl_display; + struct wl_registry *registry; struct wl_compositor *compositor; struct wl_shell *shell; struct wl_output *output; @@ -70,20 +73,27 @@ struct wayland_compositor { struct wayland_output { struct weston_output base; - + struct wl_listener frame_listener; struct { struct wl_surface *surface; struct wl_shell_surface *shell_surface; struct wl_egl_window *egl_window; } parent; - EGLSurface egl_surface; struct weston_mode mode; }; struct wayland_input { + struct weston_seat base; struct wayland_compositor *compositor; - struct wl_input_device *input_device; + struct wl_seat *seat; + struct wl_pointer *pointer; + struct wl_keyboard *keyboard; + struct wl_touch *touch; struct wl_list link; + uint32_t key_serial; + uint32_t enter_serial; + int focus; + struct wayland_output *output; }; @@ -168,7 +178,7 @@ draw_border(struct wayland_output *output) { struct wayland_compositor *c = (struct wayland_compositor *) output->base.compositor; - struct weston_shader *shader = &c->base.texture_shader; + struct weston_shader *shader = &c->base.texture_shader_rgba; GLfloat *v; int n; @@ -179,9 +189,8 @@ draw_border(struct wayland_output *output) glUniformMatrix4fv(shader->proj_uniform, 1, GL_FALSE, output->base.matrix.d); - glUniform1i(shader->tex_uniform, 0); + glUniform1i(shader->tex_uniforms[0], 0); glUniform1f(shader->alpha_uniform, 1); - glUniform1f(shader->texwidth_uniform, 1); n = texture_border(output); @@ -206,16 +215,17 @@ draw_border(struct wayland_output *output) static void create_border(struct wayland_compositor *c) { - uint32_t *pixels, stride; + pixman_image_t *image; - pixels = weston_load_image(DATADIR "/weston/border.png", - &c->border.width, - &c->border.height, &stride); - if (!pixels) { - fprintf(stderr, "could'nt load border image\n"); + image = load_image(DATADIR "/weston/border.png"); + if (!image) { + weston_log("could'nt load border image\n"); return; } + c->border.width = pixman_image_get_width(image); + c->border.height = pixman_image_get_height(image); + glGenTextures(1, &c->border.texture); glBindTexture(GL_TEXTURE_2D, c->border.texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -226,29 +236,10 @@ create_border(struct wayland_compositor *c) glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, c->border.width, c->border.height, - 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels); - - c->border.top = 25; - c->border.bottom = 50; - c->border.left = 25; - c->border.right = 25; -} - -static int -wayland_input_create(struct wayland_compositor *c) -{ - struct weston_input_device *input; - - input = malloc(sizeof *input); - if (input == NULL) - return -1; - - memset(input, 0, sizeof *input); - weston_input_device_init(input, &c->base); - - c->base.input_device = &input->input_device; + 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, + pixman_image_get_data(image)); - return 0; + pixman_image_unref(image); } static int @@ -256,59 +247,30 @@ wayland_compositor_init_egl(struct wayland_compositor *c) { EGLint major, minor; EGLint n; - const char *extensions; EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_ALPHA_SIZE, 1, - EGL_DEPTH_SIZE, 1, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; - static const EGLint context_attribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE - }; - - c->base.display = eglGetDisplay(c->parent.display); - if (c->base.display == NULL) { - fprintf(stderr, "failed to create display\n"); - return -1; - } - if (!eglInitialize(c->base.display, &major, &minor)) { - fprintf(stderr, "failed to initialize display\n"); + c->base.egl_display = eglGetDisplay(c->parent.wl_display); + if (c->base.egl_display == NULL) { + weston_log("failed to create display\n"); return -1; } - extensions = eglQueryString(c->base.display, EGL_EXTENSIONS); - if (!strstr(extensions, "EGL_KHR_surfaceless_gles2")) { - fprintf(stderr, "EGL_KHR_surfaceless_gles2 not available\n"); + if (!eglInitialize(c->base.egl_display, &major, &minor)) { + weston_log("failed to initialize display\n"); return -1; } - if (!eglBindAPI(EGL_OPENGL_ES_API)) { - fprintf(stderr, "failed to bind EGL_OPENGL_ES_API\n"); - return -1; - } - if (!eglChooseConfig(c->base.display, config_attribs, - &c->base.config, 1, &n) || n == 0) { - fprintf(stderr, "failed to choose config: %d\n", n); - return -1; - } - - c->base.context = eglCreateContext(c->base.display, c->base.config, - EGL_NO_CONTEXT, context_attribs); - if (c->base.context == NULL) { - fprintf(stderr, "failed to create context\n"); - return -1; - } - - if (!eglMakeCurrent(c->base.display, EGL_NO_SURFACE, - EGL_NO_SURFACE, c->base.context)) { - fprintf(stderr, "failed to make context current\n"); + if (!eglChooseConfig(c->base.egl_display, config_attribs, + &c->base.egl_config, 1, &n) || n == 0) { + weston_log("failed to choose config: %d\n", n); return -1; } @@ -329,37 +291,31 @@ static const struct wl_callback_listener frame_listener = { }; static void -wayland_output_repaint(struct weston_output *output_base) +wayland_output_frame_notify(struct wl_listener *listener, void *data) { - struct wayland_output *output = (struct wayland_output *) output_base; - struct wayland_compositor *compositor = - (struct wayland_compositor *) output->base.compositor; - struct wl_callback *callback; - struct weston_surface *surface; - - if (!eglMakeCurrent(compositor->base.display, output->egl_surface, - output->egl_surface, compositor->base.context)) { - fprintf(stderr, "failed to make current\n"); - return; - } - - wl_list_for_each_reverse(surface, &compositor->base.surface_list, link) - weston_surface_draw(surface, &output->base); + struct wayland_output *output = + container_of(listener, + struct wayland_output, frame_listener); draw_border(output); +} + +static void +wayland_output_repaint(struct weston_output *output_base, + pixman_region32_t *damage) +{ + struct wayland_output *output = (struct wayland_output *) output_base; + struct weston_compositor *ec = output->base.compositor; + struct wl_callback *callback; - eglSwapBuffers(compositor->base.display, output->egl_surface); callback = wl_surface_frame(output->parent.surface); wl_callback_add_listener(callback, &frame_listener, output); - return; -} + ec->renderer->repaint_output(&output->base, damage); + + pixman_region32_subtract(&ec->primary_plane.damage, + &ec->primary_plane.damage, damage); -static int -wayland_output_set_cursor(struct weston_output *output_base, - struct weston_input_device *input) -{ - return -1; } static void @@ -368,13 +324,15 @@ wayland_output_destroy(struct weston_output *output_base) struct wayland_output *output = (struct wayland_output *) output_base; struct weston_compositor *ec = output->base.compositor; - eglDestroySurface(ec->display, output->egl_surface); + eglDestroySurface(ec->egl_display, output->base.egl_surface); wl_egl_window_destroy(output->parent.egl_window); free(output); return; } +static const struct wl_shell_surface_listener shell_surface_listener; + static int wayland_compositor_create_output(struct wayland_compositor *c, int width, int height) @@ -396,12 +354,14 @@ wayland_compositor_create_output(struct wayland_compositor *c, output->base.current = &output->mode; weston_output_init(&output->base, &c->base, 0, 0, width, height, - WL_OUTPUT_FLIPPED); + WL_OUTPUT_TRANSFORM_NORMAL); output->base.border.top = c->border.top; output->base.border.bottom = c->border.bottom; output->base.border.left = c->border.left; output->base.border.right = c->border.right; + output->base.make = "waywayland"; + output->base.model = "none"; weston_output_move(&output->base, 0, 0); @@ -414,41 +374,40 @@ wayland_compositor_create_output(struct wayland_compositor *c, width + c->border.left + c->border.right, height + c->border.top + c->border.bottom); if (!output->parent.egl_window) { - fprintf(stderr, "failure to create wl_egl_window\n"); + weston_log("failure to create wl_egl_window\n"); goto cleanup_output; } - output->egl_surface = - eglCreateWindowSurface(c->base.display, c->base.config, + output->base.egl_surface = + eglCreateWindowSurface(c->base.egl_display, c->base.egl_config, output->parent.egl_window, NULL); - if (!output->egl_surface) { - fprintf(stderr, "failed to create window surface\n"); + if (!output->base.egl_surface) { + weston_log("failed to create window surface\n"); goto cleanup_window; } - if (!eglMakeCurrent(c->base.display, output->egl_surface, - output->egl_surface, c->base.context)) { - fprintf(stderr, "failed to make surface current\n"); - goto cleanup_surface; - return -1; - } - output->parent.shell_surface = wl_shell_get_shell_surface(c->parent.shell, output->parent.surface); - /* FIXME: add shell_surface listener for resizing */ + wl_shell_surface_add_listener(output->parent.shell_surface, + &shell_surface_listener, output); wl_shell_surface_set_toplevel(output->parent.shell_surface); + output->base.origin = output->base.current; output->base.repaint = wayland_output_repaint; - output->base.set_hardware_cursor = wayland_output_set_cursor; output->base.destroy = wayland_output_destroy; + output->base.assign_planes = NULL; + output->base.set_backlight = NULL; + output->base.set_dpms = NULL; + output->base.switch_mode = NULL; wl_list_insert(c->base.output_list.prev, &output->base.link); + output->frame_listener.notify = wayland_output_frame_notify; + wl_signal_add(&output->base.frame_signal, &output->frame_listener); + return 0; -cleanup_surface: - eglDestroySurface(c->base.display, output->egl_surface); cleanup_window: wl_egl_window_destroy(output->parent.egl_window); cleanup_output: @@ -458,6 +417,31 @@ cleanup_output: return -1; } +static void +shell_surface_ping(void *data, struct wl_shell_surface *shell_surface, + uint32_t serial) +{ + wl_shell_surface_pong(shell_surface, serial); +} + +static void +shell_surface_configure(void *data, struct wl_shell_surface *shell_surface, + uint32_t edges, int32_t width, int32_t height) +{ + /* FIXME: implement resizing */ +} + +static void +shell_surface_popup_done(void *data, struct wl_shell_surface *shell_surface) +{ +} + +static const struct wl_shell_surface_listener shell_surface_listener = { + shell_surface_ping, + shell_surface_configure, + shell_surface_popup_done +}; + /* Events received from the wayland-server this compositor is client of: */ /* parent output interface */ @@ -470,7 +454,8 @@ display_handle_geometry(void *data, int physical_height, int subpixel, const char *make, - const char *model) + const char *model, + int transform) { struct wayland_compositor *c = data; @@ -497,105 +482,247 @@ static const struct wl_output_listener output_listener = { display_handle_mode }; +static void +check_focus(struct wayland_input *input, wl_fixed_t x, wl_fixed_t y) +{ + struct wayland_compositor *c = input->compositor; + int width, height, inside; + + width = input->output->mode.width; + height = input->output->mode.height; + + inside = c->border.left <= wl_fixed_to_int(x) && + wl_fixed_to_int(x) < width + c->border.left && + c->border.top <= wl_fixed_to_int(y) && + wl_fixed_to_int(y) < height + c->border.top; + + if (!input->focus && inside) { + notify_pointer_focus(&input->base, &input->output->base, + x - wl_fixed_from_int(c->border.left), + y = wl_fixed_from_int(c->border.top)); + wl_pointer_set_cursor(input->pointer, + input->enter_serial, NULL, 0, 0); + } else if (input->focus && !inside) { + notify_pointer_focus(&input->base, NULL, 0, 0); + /* FIXME: Should set default cursor here. */ + } + + input->focus = inside; +} + /* parent input interface */ static void -input_handle_motion(void *data, struct wl_input_device *input_device, - uint32_t time, int32_t sx, int32_t sy) +input_handle_pointer_enter(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface, + wl_fixed_t x, wl_fixed_t y) { struct wayland_input *input = data; - struct wayland_compositor *c = input->compositor; - notify_motion(c->base.input_device, time, - sx - c->border.left, sy - c->border.top); + /* XXX: If we get a modifier event immediately before the focus, + * we should try to keep the same serial. */ + input->enter_serial = serial; + input->output = wl_surface_get_user_data(surface); + check_focus(input, x, y); } static void -input_handle_button(void *data, - struct wl_input_device *input_device, - uint32_t time, uint32_t button, uint32_t state) +input_handle_pointer_leave(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface) { struct wayland_input *input = data; - struct wayland_compositor *c = input->compositor; - notify_button(c->base.input_device, time, button, state); + notify_pointer_focus(&input->base, NULL, 0, 0); + input->output = NULL; + input->focus = 0; } static void -input_handle_key(void *data, struct wl_input_device *input_device, - uint32_t time, uint32_t key, uint32_t state) +input_handle_motion(void *data, struct wl_pointer *pointer, + uint32_t time, wl_fixed_t x, wl_fixed_t y) { struct wayland_input *input = data; struct wayland_compositor *c = input->compositor; - notify_key(c->base.input_device, time, key, state); + check_focus(input, x, y); + if (input->focus) + notify_motion(&input->base, time, + x - wl_fixed_from_int(c->border.left), + y - wl_fixed_from_int(c->border.top)); } static void -input_handle_pointer_enter(void *data, - struct wl_input_device *input_device, - uint32_t time, struct wl_surface *surface, - int32_t sx, int32_t sy) +input_handle_button(void *data, struct wl_pointer *pointer, + uint32_t serial, uint32_t time, uint32_t button, + uint32_t state_w) { struct wayland_input *input = data; - struct wayland_output *output; - struct wayland_compositor *c = input->compositor; + enum wl_pointer_button_state state = state_w; - output = wl_surface_get_user_data(surface); - notify_pointer_focus(c->base.input_device, - time, &output->base, sx, sy); - wl_input_device_attach(input->input_device, time, NULL, 0, 0); + notify_button(&input->base, time, button, state); } static void -input_handle_pointer_leave(void *data, - struct wl_input_device *input_device, - uint32_t time, struct wl_surface *surface) +input_handle_axis(void *data, struct wl_pointer *pointer, + uint32_t time, uint32_t axis, wl_fixed_t value) { struct wayland_input *input = data; - struct wayland_compositor *c = input->compositor; - notify_pointer_focus(c->base.input_device, time, NULL, 0, 0); + notify_axis(&input->base, time, axis, value); +} + +static const struct wl_pointer_listener pointer_listener = { + input_handle_pointer_enter, + input_handle_pointer_leave, + input_handle_motion, + input_handle_button, + input_handle_axis, +}; + +static void +input_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, + int fd, uint32_t size) +{ + struct wayland_input *input = data; + struct xkb_keymap *keymap; + char *map_str; + + if (!data) { + close(fd); + return; + } + + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { + close(fd); + return; + } + + map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (map_str == MAP_FAILED) { + close(fd); + return; + } + + keymap = xkb_map_new_from_string(input->compositor->base.xkb_context, + map_str, + XKB_KEYMAP_FORMAT_TEXT_V1, + 0); + munmap(map_str, size); + close(fd); + + if (!keymap) { + weston_log("failed to compile keymap\n"); + return; + } + + weston_seat_init_keyboard(&input->base, keymap); + xkb_map_unref(keymap); } static void input_handle_keyboard_enter(void *data, - struct wl_input_device *input_device, - uint32_t time, + struct wl_keyboard *keyboard, + uint32_t serial, struct wl_surface *surface, struct wl_array *keys) { struct wayland_input *input = data; - struct wayland_compositor *c = input->compositor; - struct wayland_output *output; - output = wl_surface_get_user_data(surface); - notify_keyboard_focus(c->base.input_device, time, &output->base, keys); + /* XXX: If we get a modifier event immediately before the focus, + * we should try to keep the same serial. */ + notify_keyboard_focus_in(&input->base, keys, + STATE_UPDATE_AUTOMATIC); } static void input_handle_keyboard_leave(void *data, - struct wl_input_device *input_device, - uint32_t time, + struct wl_keyboard *keyboard, + uint32_t serial, struct wl_surface *surface) { struct wayland_input *input = data; - struct wayland_compositor *c = input->compositor; - notify_keyboard_focus(c->base.input_device, time, NULL, NULL); + notify_keyboard_focus_out(&input->base); } -static const struct wl_input_device_listener input_device_listener = { - input_handle_motion, - input_handle_button, - input_handle_key, - input_handle_pointer_enter, - input_handle_pointer_leave, +static void +input_handle_key(void *data, struct wl_keyboard *keyboard, + uint32_t serial, uint32_t time, uint32_t key, uint32_t state) +{ + struct wayland_input *input = data; + + input->key_serial = serial; + notify_key(&input->base, time, key, + state ? WL_KEYBOARD_KEY_STATE_PRESSED : + WL_KEYBOARD_KEY_STATE_RELEASED, + STATE_UPDATE_NONE); +} + +static void +input_handle_modifiers(void *data, struct wl_keyboard *keyboard, + uint32_t serial_in, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) +{ + struct wayland_input *input = data; + struct wayland_compositor *c = input->compositor; + uint32_t serial_out; + + /* If we get a key event followed by a modifier event with the + * same serial number, then we try to preserve those semantics by + * reusing the same serial number on the way out too. */ + if (serial_in == input->key_serial) + serial_out = wl_display_get_serial(c->base.wl_display); + else + serial_out = wl_display_next_serial(c->base.wl_display); + + xkb_state_update_mask(input->base.xkb_state.state, + mods_depressed, mods_latched, + mods_locked, 0, 0, group); + notify_modifiers(&input->base, serial_out); +} + +static const struct wl_keyboard_listener keyboard_listener = { + input_handle_keymap, input_handle_keyboard_enter, input_handle_keyboard_leave, + input_handle_key, + input_handle_modifiers, }; static void -display_add_input(struct wayland_compositor *c, uint32_t id) +input_handle_capabilities(void *data, struct wl_seat *seat, + enum wl_seat_capability caps) +{ + struct wayland_input *input = data; + + if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) { + input->pointer = wl_seat_get_pointer(seat); + wl_pointer_set_user_data(input->pointer, input); + wl_pointer_add_listener(input->pointer, &pointer_listener, + input); + weston_seat_init_pointer(&input->base); + } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) { + wl_pointer_destroy(input->pointer); + input->pointer = NULL; + } + + if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) { + input->keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_set_user_data(input->keyboard, input); + wl_keyboard_add_listener(input->keyboard, &keyboard_listener, + input); + } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) { + wl_keyboard_destroy(input->keyboard); + input->keyboard = NULL; + } +} + +static const struct wl_seat_listener seat_listener = { + input_handle_capabilities, +}; + +static void +display_add_seat(struct wayland_compositor *c, uint32_t id) { struct wayland_input *input; @@ -605,65 +732,73 @@ display_add_input(struct wayland_compositor *c, uint32_t id) memset(input, 0, sizeof *input); + weston_seat_init(&input->base, &c->base); input->compositor = c; - input->input_device = wl_display_bind(c->parent.display, - id, &wl_input_device_interface); + input->seat = wl_registry_bind(c->parent.registry, id, + &wl_seat_interface, 1); wl_list_insert(c->input_list.prev, &input->link); - wl_input_device_add_listener(input->input_device, - &input_device_listener, input); - wl_input_device_set_user_data(input->input_device, input); + wl_seat_add_listener(input->seat, &seat_listener, input); + wl_seat_set_user_data(input->seat, input); } static void -display_handle_global(struct wl_display *display, uint32_t id, - const char *interface, uint32_t version, void *data) +registry_handle_global(void *data, struct wl_registry *registry, uint32_t name, + const char *interface, uint32_t version) { struct wayland_compositor *c = data; if (strcmp(interface, "wl_compositor") == 0) { c->parent.compositor = - wl_display_bind(display, id, &wl_compositor_interface); + wl_registry_bind(registry, name, + &wl_compositor_interface, 1); } else if (strcmp(interface, "wl_output") == 0) { c->parent.output = - wl_display_bind(display, id, &wl_output_interface); + wl_registry_bind(registry, name, + &wl_output_interface, 1); wl_output_add_listener(c->parent.output, &output_listener, c); - } else if (strcmp(interface, "wl_input_device") == 0) { - display_add_input(c, id); } else if (strcmp(interface, "wl_shell") == 0) { c->parent.shell = - wl_display_bind(display, id, &wl_shell_interface); + wl_registry_bind(registry, name, + &wl_shell_interface, 1); + } else if (strcmp(interface, "wl_seat") == 0) { + display_add_seat(c, name); } } -static int -update_event_mask(uint32_t mask, void *data) -{ - struct wayland_compositor *c = data; - - c->parent.event_mask = mask; - if (c->parent.wl_source) - wl_event_source_fd_update(c->parent.wl_source, mask); - - return 0; -} +static const struct wl_registry_listener registry_listener = { + registry_handle_global +}; static int wayland_compositor_handle_event(int fd, uint32_t mask, void *data) { struct wayland_compositor *c = data; + int count = 0; if (mask & WL_EVENT_READABLE) - wl_display_iterate(c->parent.display, WL_DISPLAY_READABLE); + count = wl_display_dispatch(c->parent.wl_display); if (mask & WL_EVENT_WRITABLE) - wl_display_iterate(c->parent.display, WL_DISPLAY_WRITABLE); + wl_display_flush(c->parent.wl_display); + + if (mask == 0) { + count = wl_display_dispatch_pending(c->parent.wl_display); + wl_display_flush(c->parent.wl_display); + } - return 1; + return count; +} + +static void +wayland_restore(struct weston_compositor *ec) +{ } static void wayland_destroy(struct weston_compositor *ec) { + gles2_renderer_destroy(ec); + weston_compositor_shutdown(ec); free(ec); @@ -671,7 +806,8 @@ wayland_destroy(struct weston_compositor *ec) static struct weston_compositor * wayland_compositor_create(struct wl_display *display, - int width, int height, const char *display_name) + int width, int height, const char *display_name, + int argc, char *argv[], const char *config_file) { struct wayland_compositor *c; struct wl_event_loop *loop; @@ -683,73 +819,83 @@ wayland_compositor_create(struct wl_display *display, memset(c, 0, sizeof *c); - c->parent.display = wl_display_connect(display_name); + if (weston_compositor_init(&c->base, display, argc, argv, + config_file) < 0) + goto err_free; - if (c->parent.display == NULL) { - fprintf(stderr, "failed to create display: %m\n"); - return NULL; + c->parent.wl_display = wl_display_connect(display_name); + + if (c->parent.wl_display == NULL) { + weston_log("failed to create display: %m\n"); + goto err_compositor; } wl_list_init(&c->input_list); - wl_display_add_global_listener(c->parent.display, - display_handle_global, c); - - wl_display_iterate(c->parent.display, WL_DISPLAY_READABLE); + c->parent.registry = wl_display_get_registry(c->parent.wl_display); + wl_registry_add_listener(c->parent.registry, ®istry_listener, c); + wl_display_dispatch(c->parent.wl_display); c->base.wl_display = display; if (wayland_compositor_init_egl(c) < 0) - return NULL; + goto err_display; c->base.destroy = wayland_destroy; + c->base.restore = wayland_restore; - /* Can't init base class until we have a current egl context */ - if (weston_compositor_init(&c->base, display) < 0) - return NULL; + c->border.top = 30; + c->border.bottom = 24; + c->border.left = 25; + c->border.right = 26; - create_border(c); + /* requires border fields */ if (wayland_compositor_create_output(c, width, height) < 0) - return NULL; + goto err_display; - if (wayland_input_create(c) < 0) - return NULL; + /* requires wayland_compositor_create_output */ + if (gles2_renderer_init(&c->base) < 0) + goto err_display; + + /* requires gles2_renderer_init */ + create_border(c); loop = wl_display_get_event_loop(c->base.wl_display); - fd = wl_display_get_fd(c->parent.display, update_event_mask, c); + fd = wl_display_get_fd(c->parent.wl_display); c->parent.wl_source = - wl_event_loop_add_fd(loop, fd, c->parent.event_mask, + wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE, wayland_compositor_handle_event, c); if (c->parent.wl_source == NULL) - return NULL; + goto err_display; + + wl_event_source_check(c->parent.wl_source); return &c->base; -} -struct weston_compositor * -backend_init(struct wl_display *display, char *options); +err_display: + wl_display_disconnect(c->parent.wl_display); +err_compositor: + weston_compositor_shutdown(&c->base); +err_free: + free(c); + return NULL; +} WL_EXPORT struct weston_compositor * -backend_init(struct wl_display *display, char *options) -{ - int width = 1024, height = 640, i; - char *p, *value, *display_name = NULL; - - static char * const tokens[] = { "width", "height", "display", NULL }; - - p = options; - while (i = getsubopt(&p, tokens, &value), i != -1) { - switch (i) { - case 0: - width = strtol(value, NULL, 0); - break; - case 1: - height = strtol(value, NULL, 0); - break; - case 2: - display_name = strdup(value); - break; - } - } +backend_init(struct wl_display *display, int argc, char *argv[], + const char *config_file) +{ + int width = 1024, height = 640; + char *display_name = NULL; + + const struct weston_option wayland_options[] = { + { WESTON_OPTION_INTEGER, "width", 0, &width }, + { WESTON_OPTION_INTEGER, "height", 0, &height }, + { WESTON_OPTION_STRING, "display", 0, &display_name }, + }; + + parse_options(wayland_options, + ARRAY_LENGTH(wayland_options), argc, argv); - return wayland_compositor_create(display, width, height, display_name); + return wayland_compositor_create(display, width, height, display_name, + argc, argv, config_file); }