From ef9195febc0e67a116b2f1d093cbcbeb629c92b4 Mon Sep 17 00:00:00 2001 From: Nobuhiko Tanibata Date: Wed, 29 Jan 2014 21:16:05 +0900 Subject: Weston 1.4.0 --- clients/desktop-shell.c | 10 +++- clients/nested.c | 4 +- clients/resizor.c | 13 +++-- clients/terminal.c | 9 +-- clients/weston-info.c | 126 +++++++++++++++++++++++++++++++++++++----- clients/window.c | 2 + configure.ac | 11 +++- desktop-shell/exposay.c | 9 +-- desktop-shell/input-panel.c | 8 ++- desktop-shell/shell.c | 130 +++++++++++++++++++++++++++++++++++--------- desktop-shell/shell.h | 1 + man/weston.ini.man | 2 +- shared/frame.c | 56 ++++++++++--------- src/animation.c | 12 ++++ src/compositor-drm.c | 10 ++-- src/compositor-rdp.c | 12 ++++ src/compositor-wayland.c | 4 +- src/compositor.c | 62 +++++++++++++-------- src/evdev.c | 59 +++++++++++++++++--- src/evdev.h | 4 ++ src/libbacklight.c | 7 ++- src/log.c | 3 + src/rpi-renderer.c | 18 ++++-- src/screenshooter.c | 13 ++++- src/text-backend.c | 41 ++++++++++---- src/udev-seat.c | 12 +++- tests/.gitignore | 2 + wcap/main.c | 6 +- xwayland/window-manager.c | 6 +- 29 files changed, 496 insertions(+), 156 deletions(-) diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c index 4e7a815e..a0c6b6d4 100644 --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c @@ -21,12 +21,15 @@ * OF THIS SOFTWARE. */ +#include "config.h" + #include #include #include #include #include #include +#include #include #include #include @@ -609,7 +612,7 @@ panel_add_launcher(struct panel *panel, const char *icon, const char *path) launcher = xzalloc(sizeof *launcher); launcher->icon = load_icon_or_fallback(icon); - launcher->path = strdup(path); + launcher->path = xstrdup(path); wl_array_init(&launcher->envp); wl_array_init(&launcher->argv); @@ -1061,6 +1064,11 @@ background_create(struct desktop *desktop) weston_config_section_get_string(s, "background-type", &type, "tile"); + if (type == NULL) { + fprintf(stderr, "%s: out of memory\n", program_invocation_short_name); + exit(EXIT_FAILURE); + } + if (strcmp(type, "scale") == 0) { background->type = BACKGROUND_SCALE; } else if (strcmp(type, "scale-crop") == 0) { diff --git a/clients/nested.c b/clients/nested.c index 74767795..d75e953a 100644 --- a/clients/nested.c +++ b/clients/nested.c @@ -844,7 +844,7 @@ static void blit_surface_init(struct nested_surface *surface) { struct nested_blit_surface *blit_surface = - zalloc(sizeof *blit_surface); + xzalloc(sizeof *blit_surface); glGenTextures(1, &blit_surface->texture); glBindTexture(GL_TEXTURE_2D, blit_surface->texture); @@ -967,7 +967,7 @@ ss_surface_init(struct nested_surface *surface) struct wl_compositor *compositor = display_get_compositor(nested->display); struct nested_ss_surface *ss_surface = - zalloc(sizeof *ss_surface); + xzalloc(sizeof *ss_surface); struct rectangle allocation; struct wl_region *region; diff --git a/clients/resizor.c b/clients/resizor.c index 9cf1a3c6..b5ea55f6 100644 --- a/clients/resizor.c +++ b/clients/resizor.c @@ -77,6 +77,14 @@ frame_callback(void *data, struct wl_callback *callback, uint32_t time) assert(!callback || callback == resizor->frame_callback); + if (resizor->frame_callback) { + wl_callback_destroy(resizor->frame_callback); + resizor->frame_callback = NULL; + } + + if (window_is_maximized(resizor->window)) + return; + spring_update(&resizor->width); spring_update(&resizor->height); @@ -84,11 +92,6 @@ frame_callback(void *data, struct wl_callback *callback, uint32_t time) resizor->width.current + 0.5, resizor->height.current + 0.5); - if (resizor->frame_callback) { - wl_callback_destroy(resizor->frame_callback); - resizor->frame_callback = NULL; - } - if (!spring_done(&resizor->width) || !spring_done(&resizor->height)) { resizor->frame_callback = wl_surface_frame( diff --git a/clients/terminal.c b/clients/terminal.c index e2a6236c..f3646fe3 100644 --- a/clients/terminal.c +++ b/clients/terminal.c @@ -848,9 +848,10 @@ resize_handler(struct widget *widget, width = columns * terminal->average_width + m; height = rows * terminal->extents.height + m; widget_set_size(terminal->widget, width, height); - asprintf(&p, "%s — [%dx%d]", terminal->title, columns, rows); - window_set_title(terminal->window, p); - free(p); + if (asprintf(&p, "%s — [%dx%d]", terminal->title, columns, rows) > 0) { + window_set_title(terminal->window, p); + free(p); + } } terminal_resize_cells(terminal, columns, rows); @@ -2829,7 +2830,7 @@ terminal_create(struct display *display) terminal->margin_bottom = -1; terminal->window = window_create(display); terminal->widget = window_frame_create(terminal->window, terminal); - terminal->title = strdup("Wayland Terminal"); + terminal->title = xstrdup("Wayland Terminal"); window_set_title(terminal->window, terminal->title); widget_set_transparent(terminal->widget, 0); diff --git a/clients/weston-info.c b/clients/weston-info.c index 4cc05723..147dc489 100644 --- a/clients/weston-info.c +++ b/clients/weston-info.c @@ -20,6 +20,9 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "config.h" + +#include #include #include #include @@ -30,6 +33,7 @@ #include "../shared/os-compatibility.h" typedef void (*print_info_t)(void *info); +typedef void (*destroy_info_t)(void *info); struct global_info { struct wl_list link; @@ -39,6 +43,7 @@ struct global_info { char *interface; print_info_t print; + destroy_info_t destroy; }; struct output_mode { @@ -96,18 +101,34 @@ struct weston_info { }; static void * -xmalloc(size_t s) +fail_on_null(void *p) { - void *p = malloc(s); - if (p == NULL) { - fprintf(stderr, "out of memory\n"); - exit(1); + fprintf(stderr, "%s: out of memory\n", program_invocation_short_name); + exit(EXIT_FAILURE); } return p; } +static void * +xmalloc(size_t s) +{ + return fail_on_null(malloc(s)); +} + +static void * +xzalloc(size_t s) +{ + return fail_on_null(calloc(1, s)); +} + +static char * +xstrdup(const char *s) +{ + return fail_on_null(strdup(s)); +} + static void print_global_info(void *data) { @@ -124,7 +145,7 @@ init_global_info(struct weston_info *info, { global->id = id; global->version = version; - global->interface = strdup(interface); + global->interface = xstrdup(interface); wl_list_insert(info->infos.prev, &global->link); } @@ -285,7 +306,7 @@ seat_handle_name(void *data, struct wl_seat *wl_seat, const char *name) { struct seat_info *seat = data; - seat->name = strdup(name); + seat->name = xstrdup(name); } static const struct wl_seat_listener seat_listener = { @@ -293,13 +314,25 @@ static const struct wl_seat_listener seat_listener = { seat_handle_name, }; +static void +destroy_seat_info(void *data) +{ + struct seat_info *seat = data; + + wl_seat_destroy(seat->seat); + + if (seat->name != NULL) + free(seat->name); +} + static void add_seat_info(struct weston_info *info, uint32_t id, uint32_t version) { - struct seat_info *seat = xmalloc(sizeof *seat); + struct seat_info *seat = xzalloc(sizeof *seat); init_global_info(info, &seat->global, id, "wl_seat", version); seat->global.print = print_seat_info; + seat->global.destroy = destroy_seat_info; seat->seat = wl_registry_bind(info->registry, id, &wl_seat_interface, 2); @@ -312,7 +345,7 @@ static void shm_handle_format(void *data, struct wl_shm *wl_shm, uint32_t format) { struct shm_info *shm = data; - struct shm_format *shm_format = xmalloc(sizeof *shm_format); + struct shm_format *shm_format = xzalloc(sizeof *shm_format); wl_list_insert(&shm->formats, &shm_format->link); shm_format->format = format; @@ -322,13 +355,29 @@ static const struct wl_shm_listener shm_listener = { shm_handle_format, }; +static void +destroy_shm_info(void *data) +{ + struct shm_info *shm = data; + struct shm_format *format, *tmp; + + wl_list_for_each_safe(format, tmp, &shm->formats, link) { + wl_list_remove(&format->link); + free(format); + } + + wl_shm_destroy(shm->shm); +} + static void add_shm_info(struct weston_info *info, uint32_t id, uint32_t version) { - struct shm_info *shm = xmalloc(sizeof *shm); + struct shm_info *shm = xzalloc(sizeof *shm); init_global_info(info, &shm->global, id, "wl_shm", version); shm->global.print = print_shm_info; + shm->global.destroy = destroy_shm_info; + wl_list_init(&shm->formats); shm->shm = wl_registry_bind(info->registry, @@ -353,8 +402,8 @@ output_handle_geometry(void *data, struct wl_output *wl_output, output->geometry.physical_width = physical_width; output->geometry.physical_height = physical_height; output->geometry.subpixel = subpixel; - output->geometry.make = strdup(make); - output->geometry.model = strdup(model); + output->geometry.make = xstrdup(make); + output->geometry.model = xstrdup(model); output->geometry.output_transform = output_transform; } @@ -379,13 +428,33 @@ static const struct wl_output_listener output_listener = { output_handle_mode, }; +static void +destroy_output_info(void *data) +{ + struct output_info *output = data; + struct output_mode *mode, *tmp; + + wl_output_destroy(output->output); + + if (output->geometry.make != NULL) + free(output->geometry.make); + if (output->geometry.model != NULL) + free(output->geometry.model); + + wl_list_for_each_safe(mode, tmp, &output->modes, link) { + wl_list_remove(&mode->link); + free(mode); + } +} + static void add_output_info(struct weston_info *info, uint32_t id, uint32_t version) { - struct output_info *output = xmalloc(sizeof *output); + struct output_info *output = xzalloc(sizeof *output); init_global_info(info, &output->global, id, "wl_output", version); output->global.print = print_output_info; + output->global.destroy = destroy_output_info; wl_list_init(&output->modes); @@ -397,14 +466,20 @@ add_output_info(struct weston_info *info, uint32_t id, uint32_t version) info->roundtrip_needed = true; } +static void +destroy_global_info(void *data) +{ +} + static void add_global_info(struct weston_info *info, uint32_t id, const char *interface, uint32_t version) { - struct global_info *global = xmalloc(sizeof *global); + struct global_info *global = xzalloc(sizeof *global); init_global_info(info, global, id, interface, version); global->print = print_global_info; + global->destroy = destroy_global_info; } static void @@ -442,6 +517,25 @@ print_infos(struct wl_list *infos) info->print(info); } +static void +destroy_info(void *data) +{ + struct global_info *global = data; + + global->destroy(data); + wl_list_remove(&global->link); + free(global->interface); + free(data); +} + +static void +destroy_infos(struct wl_list *infos) +{ + struct global_info *info, *tmp; + wl_list_for_each_safe(info, tmp, infos, link) + destroy_info(info); +} + int main(int argc, char **argv) { @@ -464,6 +558,10 @@ main(int argc, char **argv) } while (info.roundtrip_needed); print_infos(&info.infos); + destroy_infos(&info.infos); + + wl_registry_destroy(info.registry); + wl_display_disconnect(info.display); return 0; } diff --git a/clients/window.c b/clients/window.c index d59b9c7f..d8d79d04 100644 --- a/clients/window.c +++ b/clients/window.c @@ -2934,6 +2934,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard, if (num_syms == 1) sym = syms[0]; + if (sym == XKB_KEY_F5 && input->modifiers == MOD_ALT_MASK) { if (state == WL_KEYBOARD_KEY_STATE_PRESSED) window_set_maximized(window, @@ -4593,6 +4594,7 @@ window_show_menu(struct display *display, window_set_buffer_transform (menu->window, window_get_buffer_transform (parent)); menu->frame = frame_create(window->display->theme, 0, 0, FRAME_BUTTON_NONE, NULL); + fail_on_null(menu->frame); menu->entries = entries; menu->count = count; menu->release_count = 0; diff --git a/configure.ac b/configure.ac index 571bf601..cce18500 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ m4_define([weston_major_version], [1]) -m4_define([weston_minor_version], [3]) -m4_define([weston_micro_version], [91]) +m4_define([weston_minor_version], [4]) +m4_define([weston_micro_version], [0]) m4_define([weston_version], [weston_major_version.weston_minor_version.weston_micro_version]) @@ -204,6 +204,11 @@ AM_CONDITIONAL([ENABLE_RDP_COMPOSITOR], if test x$enable_rdp_compositor = xyes; then AC_DEFINE([BUILD_RDP_COMPOSITOR], [1], [Build the RDP compositor]) PKG_CHECK_MODULES(RDP_COMPOSITOR, [freerdp >= 1.1.0]) + + SAVED_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $RDP_COMPOSITOR_CFLAGS" + AC_CHECK_HEADERS([freerdp/version.h]) + CPPFLAGS="$SAVED_CPPFLAGS" fi AC_ARG_WITH(cairo, @@ -320,7 +325,7 @@ AC_ARG_ENABLE(resize-optimization, AS_IF([test "x$enable_resize_optimization" = "xyes"], [AC_DEFINE([USE_RESIZE_POOL], [1], [Use resize memory pool as a performance optimization])]) -PKG_CHECK_MODULES(SYSTEMD_LOGIN, [libsystemd-login], +PKG_CHECK_MODULES(SYSTEMD_LOGIN, [libsystemd-login >= 198], [have_systemd_login=yes], [have_systemd_login=no]) AS_IF([test "x$have_systemd_login" = "xyes"], [AC_DEFINE([HAVE_SYSTEMD_LOGIN], [1], [Have systemd-login])]) diff --git a/desktop-shell/exposay.c b/desktop-shell/exposay.c index 01bf0b13..fe7a3a71 100644 --- a/desktop-shell/exposay.c +++ b/desktop-shell/exposay.c @@ -136,13 +136,10 @@ static void exposay_highlight_surface(struct desktop_shell *shell, struct exposay_surface *esurface) { - struct weston_view *view = NULL; + struct weston_view *view = esurface->view; - if (esurface) { - shell->exposay.row_current = esurface->row; - shell->exposay.column_current = esurface->column; - view = esurface->view; - } + shell->exposay.row_current = esurface->row; + shell->exposay.column_current = esurface->column; activate(shell, view->surface, shell->exposay.seat); shell->exposay.focus_current = view; diff --git a/desktop-shell/input-panel.c b/desktop-shell/input-panel.c index 267b3ef0..c08a403f 100644 --- a/desktop-shell/input-panel.c +++ b/desktop-shell/input-panel.c @@ -116,14 +116,18 @@ input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy) { struct input_panel_surface *ip_surface = surface->configure_private; struct desktop_shell *shell = ip_surface->shell; + struct weston_view *view; float x, y; if (surface->width == 0) return; if (ip_surface->panel) { - x = get_default_view(shell->text_input.surface)->geometry.x + shell->text_input.cursor_rectangle.x2; - y = get_default_view(shell->text_input.surface)->geometry.y + shell->text_input.cursor_rectangle.y2; + view = get_default_view(shell->text_input.surface); + if (view == NULL) + return; + x = view->geometry.x + shell->text_input.cursor_rectangle.x2; + y = view->geometry.y + shell->text_input.cursor_rectangle.y2; } else { x = ip_surface->output->x + (ip_surface->output->width - surface->width) / 2; y = ip_surface->output->y + ip_surface->output->height - surface->height; diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index a8c4b3ea..c2755433 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -198,6 +198,7 @@ struct weston_move_grab { struct weston_touch_move_grab { struct shell_touch_grab base; + int active; wl_fixed_t dx, dy; }; @@ -355,7 +356,7 @@ shell_touch_grab_start(struct shell_touch_grab *grab, struct weston_touch *touch) { struct desktop_shell *shell = shsurf->shell; - + grab->grab.interface = interface; grab->shsurf = shsurf; grab->shsurf_destroy_listener.notify = destroy_shell_grab_shsurf; @@ -405,6 +406,9 @@ get_modifier(char *modifier) static enum animation_type get_animation_type(char *animation) { + if (!animation) + return ANIMATION_NONE; + if (!strcmp("zoom", animation)) return ANIMATION_ZOOM; else if (!strcmp("fade", animation)) @@ -438,6 +442,15 @@ shell_configuration(struct desktop_shell *shell) "binding-modifier", &s, "super"); shell->binding_modifier = get_modifier(s); free(s); + + weston_config_section_get_string(section, + "exposay-modifier", &s, "none"); + if (strcmp(s, "none") == 0) + shell->exposay_modifier = 0; + else + shell->exposay_modifier = get_modifier(s); + free(s); + weston_config_section_get_string(section, "animation", &s, "none"); shell->win_animation_type = get_animation_type(s); free(s); @@ -512,7 +525,12 @@ create_focus_surface(struct weston_compositor *ec, surface->output = output; surface->configure_private = fsurf; - fsurf->view = weston_view_create (surface); + fsurf->view = weston_view_create(surface); + if (fsurf->view == NULL) { + weston_surface_destroy(surface); + free(fsurf); + return NULL; + } fsurf->view->output = output; weston_surface_set_size(surface, output->width, output->height); @@ -649,6 +667,21 @@ ensure_focus_state(struct desktop_shell *shell, struct weston_seat *seat) return state; } +static void +focus_state_set_focus(struct focus_state *state, + struct weston_surface *surface) +{ + if (state->keyboard_focus) { + wl_list_remove(&state->surface_destroy_listener.link); + wl_list_init(&state->surface_destroy_listener.link); + } + + state->keyboard_focus = surface; + if (surface) + wl_signal_add(&surface->destroy_signal, + &state->surface_destroy_listener); +} + static void restore_focus_state(struct desktop_shell *shell, struct workspace *ws) { @@ -656,6 +689,9 @@ restore_focus_state(struct desktop_shell *shell, struct workspace *ws) struct weston_surface *surface; wl_list_for_each_safe(state, next, &ws->focus_list, link) { + if (state->seat->keyboard == NULL) + continue; + surface = state->keyboard_focus; weston_keyboard_set_focus(state->seat->keyboard, surface); @@ -667,12 +703,10 @@ replace_focus_state(struct desktop_shell *shell, struct workspace *ws, struct weston_seat *seat) { struct focus_state *state; - struct weston_surface *surface; wl_list_for_each(state, &ws->focus_list, link) { if (state->seat == seat) { - surface = seat->keyboard->focus; - state->keyboard_focus = surface; + focus_state_set_focus(state, seat->keyboard->focus); return; } } @@ -686,7 +720,7 @@ drop_focus_state(struct desktop_shell *shell, struct workspace *ws, wl_list_for_each(state, &ws->focus_list, link) if (state->keyboard_focus == surface) - state->keyboard_focus = NULL; + focus_state_set_focus(state, NULL); } static void @@ -703,9 +737,17 @@ animate_focus_change(struct desktop_shell *shell, struct workspace *ws, output = get_default_output(shell->compositor); if (ws->fsurf_front == NULL && (from || to)) { ws->fsurf_front = create_focus_surface(shell->compositor, output); - ws->fsurf_back = create_focus_surface(shell->compositor, output); + if (ws->fsurf_front == NULL) + return; ws->fsurf_front->view->alpha = 0.0; + + ws->fsurf_back = create_focus_surface(shell->compositor, output); + if (ws->fsurf_back == NULL) { + focus_surface_destroy(ws->fsurf_front); + return; + } ws->fsurf_back->view->alpha = 0.0; + focus_surface_created = true; } else { wl_list_remove(&ws->fsurf_front->view->layer_link); @@ -1229,7 +1271,7 @@ take_surface_to_workspace_by_seat(struct desktop_shell *shell, state = ensure_focus_state(shell, seat); if (state != NULL) - state->keyboard_focus = surface; + focus_state_set_focus(state, surface); } static void @@ -1301,6 +1343,9 @@ touch_move_grab_up(struct weston_touch_grab *grab, uint32_t time, int touch_id) (struct weston_touch_move_grab *) container_of( grab, struct shell_touch_grab, grab); + if (touch_id == 0) + move->active = 0; + if (grab->touch->num_tp == 0) { shell_touch_grab_end(&move->base); free(move); @@ -1317,7 +1362,7 @@ touch_move_grab_motion(struct weston_touch_grab *grab, uint32_t time, int dx = wl_fixed_to_int(grab->touch->grab_x + move->dx); int dy = wl_fixed_to_int(grab->touch->grab_y + move->dy); - if (!shsurf) + if (!shsurf || !move->active) return; es = shsurf->surface; @@ -1362,6 +1407,7 @@ surface_touch_move(struct shell_surface *shsurf, struct weston_seat *seat) if (!move) return -1; + move->active = 1; move->dx = wl_fixed_from_double(shsurf->view->geometry.x) - seat->touch->grab_x; move->dy = wl_fixed_from_double(shsurf->view->geometry.y) - @@ -1442,7 +1488,7 @@ surface_move(struct shell_surface *shsurf, struct weston_seat *seat) if (shsurf->grabbed) return 0; - if (shsurf->state.fullscreen) + if (shsurf->state.fullscreen || shsurf->state.maximized) return 0; move = malloc(sizeof *move); @@ -1473,14 +1519,14 @@ common_surface_move(struct wl_resource *resource, seat->pointer->button_count > 0 && seat->pointer->grab_serial == serial) { surface = weston_surface_get_main_surface(seat->pointer->focus->surface); - if ((surface == shsurf->surface) && + if ((surface == shsurf->surface) && (surface_move(shsurf, seat) < 0)) wl_resource_post_no_memory(resource); } else if (seat->touch && seat->touch->focus && seat->touch->grab_serial == serial) { surface = weston_surface_get_main_surface(seat->touch->focus->surface); - if ((surface == shsurf->surface) && + if ((surface == shsurf->surface) && (surface_touch_move(shsurf, seat) < 0)) wl_resource_post_no_memory(resource); } @@ -1545,6 +1591,8 @@ send_configure(struct weston_surface *surface, { struct shell_surface *shsurf = get_shell_surface(surface); + assert(shsurf); + wl_shell_surface_send_configure(shsurf->resource, edges, width, height); } @@ -1786,7 +1834,7 @@ ping_timeout_handler(void *data) shsurf->unresponsive = 1; wl_list_for_each(seat, &shsurf->surface->compositor->seat_list, link) - if (seat->pointer->focus && + if (seat->pointer && seat->pointer->focus && seat->pointer->focus->surface == shsurf->surface) set_busy_cursor(shsurf, seat->pointer); @@ -3225,6 +3273,8 @@ xdg_send_configure(struct weston_surface *surface, { struct shell_surface *shsurf = get_shell_surface(surface); + assert(shsurf); + xdg_surface_send_configure(shsurf->resource, edges, width, height); } @@ -4188,11 +4238,11 @@ activate(struct desktop_shell *shell, struct weston_surface *es, return; old_es = state->keyboard_focus; - state->keyboard_focus = es; - wl_list_remove(&state->surface_destroy_listener.link); - wl_signal_add(&es->destroy_signal, &state->surface_destroy_listener); + focus_state_set_focus(state, es); shsurf = get_shell_surface(main_surface); + assert(shsurf); + if (shsurf->state.fullscreen) shell_configure_fullscreen(shsurf); else @@ -4205,7 +4255,7 @@ activate(struct desktop_shell *shell, struct weston_surface *es, /* Update the surface’s layer. This brings it to the top of the stacking * order as appropriate. */ - shell_surface_update_layer(get_shell_surface(main_surface)); + shell_surface_update_layer(shsurf); } /* no-op func for checking black surface */ @@ -4395,13 +4445,22 @@ shell_fade(struct desktop_shell *shell, enum fade_type type) weston_view_update_transform(shell->fade.view); } - if (shell->fade.animation) + if (shell->fade.view->output == NULL) { + /* If the black view gets a NULL output, we lost the + * last output and we'll just cancel the fade. This + * happens when you close the last window under the + * X11 or Wayland backends. */ + shell->locked = false; + weston_surface_destroy(shell->fade.view->surface); + shell->fade.view = NULL; + } else if (shell->fade.animation) { weston_fade_update(shell->fade.animation, tint); - else + } else { shell->fade.animation = weston_fade_run(shell->fade.view, 1.0 - tint, tint, 300.0, shell_fade_done, shell); + } } static void @@ -4475,6 +4534,11 @@ idle_handler(struct wl_listener *listener, void *data) { struct desktop_shell *shell = container_of(listener, struct desktop_shell, idle_listener); + struct weston_seat *seat; + + wl_list_for_each(seat, &shell->compositor->seat_list, link) + if (seat->pointer) + popup_grab_end(seat->pointer); shell_fade(shell, FADE_OUT); /* lock() is called from shell_fade_done() */ @@ -4669,6 +4733,8 @@ configure(struct desktop_shell *shell, struct weston_surface *surface, shsurf = get_shell_surface(surface); + assert(shsurf); + if (shsurf->state.fullscreen) shell_configure_fullscreen(shsurf); else if (shsurf->state.maximized) { @@ -4697,10 +4763,13 @@ static void shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy) { struct shell_surface *shsurf = get_shell_surface(es); - struct desktop_shell *shell = shsurf->shell; - + struct desktop_shell *shell; int type_changed = 0; + assert(shsurf); + + shell = shsurf->shell; + if (!weston_surface_is_mapped(es) && !wl_list_empty(&shsurf->popup.grab_link)) { remove_popup_grab(shsurf); @@ -4737,6 +4806,8 @@ shell_surface_output_destroyed(struct weston_surface *es) { struct shell_surface *shsurf = get_shell_surface(es); + assert(shsurf); + shsurf->saved_position_valid = false; shsurf->next_state.maximized = false; shsurf->next_state.fullscreen = false; @@ -5423,6 +5494,8 @@ shell_destroy(struct wl_listener *listener, void *data) struct workspace **ws; struct shell_output *shell_output, *tmp; + /* Force state to unlocked so we don't try to fade */ + shell->locked = false; if (shell->child.client) wl_client_destroy(shell->child.client); @@ -5477,15 +5550,18 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell) zoom_key_binding, NULL); weston_compositor_add_key_binding(ec, KEY_PAGEDOWN, mod, zoom_key_binding, NULL); - weston_compositor_add_key_binding(ec, KEY_M, mod, maximize_binding, - NULL); - weston_compositor_add_key_binding(ec, KEY_F, mod, fullscreen_binding, - NULL); + weston_compositor_add_key_binding(ec, KEY_M, mod | MODIFIER_SHIFT, + maximize_binding, NULL); + weston_compositor_add_key_binding(ec, KEY_F, mod | MODIFIER_SHIFT, + fullscreen_binding, NULL); weston_compositor_add_button_binding(ec, BTN_LEFT, mod, move_binding, shell); weston_compositor_add_touch_binding(ec, mod, touch_move_binding, shell); weston_compositor_add_button_binding(ec, BTN_MIDDLE, mod, resize_binding, shell); + weston_compositor_add_button_binding(ec, BTN_LEFT, + mod | MODIFIER_SHIFT, + resize_binding, shell); if (ec->capabilities & WESTON_CAP_ROTATION_ANY) weston_compositor_add_button_binding(ec, BTN_RIGHT, mod, @@ -5514,7 +5590,9 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell) workspace_move_surface_down_binding, shell); - weston_compositor_add_modifier_binding(ec, mod, exposay_binding, shell); + if (shell->exposay_modifier) + weston_compositor_add_modifier_binding(ec, shell->exposay_modifier, + exposay_binding, shell); /* Add bindings for mod+F[1-6] for workspace 1 to 6. */ if (shell->workspaces.num > 1) { diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h index 8ef550f6..dbb28543 100644 --- a/desktop-shell/shell.h +++ b/desktop-shell/shell.h @@ -178,6 +178,7 @@ struct desktop_shell { } exposay; uint32_t binding_modifier; + uint32_t exposay_modifier; enum animation_type win_animation_type; enum animation_type startup_animation_type; enum animation_type focus_animation_type; diff --git a/man/weston.ini.man b/man/weston.ini.man index 6be90bf4..ce3f9280 100644 --- a/man/weston.ini.man +++ b/man/weston.ini.man @@ -388,7 +388,7 @@ Contains settings for the weston terminal application (weston-terminal). It allows to customize the font and shell of the command line interface. .TP 7 .BI "font=" "DejaVu Sans Mono" -sets the font of the terminal (string). For a good experience it is recommend +sets the font of the terminal (string). For a good experience it is recommended to use monospace fonts. In case the font is not found, the default one is used. .RE .RE diff --git a/shared/frame.c b/shared/frame.c index a501649f..a039d157 100644 --- a/shared/frame.c +++ b/shared/frame.c @@ -277,6 +277,26 @@ frame_touch_destroy(struct frame_touch *touch) free(touch); } +void +frame_destroy(struct frame *frame) +{ + struct frame_button *button, *next; + struct frame_touch *touch, *next_touch; + struct frame_pointer *pointer, *next_pointer; + + wl_list_for_each_safe(button, next, &frame->buttons, link) + frame_button_destroy(button); + + wl_list_for_each_safe(touch, next_touch, &frame->touches, link) + frame_touch_destroy(touch); + + wl_list_for_each_safe(pointer, next_pointer, &frame->pointers, link) + frame_pointer_destroy(pointer); + + free(frame->title); + free(frame); +} + struct frame * frame_create(struct theme *t, int32_t width, int32_t height, uint32_t buttons, const char *title) @@ -295,16 +315,16 @@ frame_create(struct theme *t, int32_t width, int32_t height, uint32_t buttons, frame->status = FRAME_STATUS_REPAINT; frame->geometry_dirty = 1; + wl_list_init(&frame->buttons); + wl_list_init(&frame->pointers); + wl_list_init(&frame->touches); + if (title) { frame->title = strdup(title); if (!frame->title) goto free_frame; } - wl_list_init(&frame->buttons); - wl_list_init(&frame->pointers); - wl_list_init(&frame->touches); - if (title) { button = frame_button_create(frame, DATADIR "/weston/icon_window.png", @@ -347,23 +367,10 @@ frame_create(struct theme *t, int32_t width, int32_t height, uint32_t buttons, return frame; free_frame: - free(frame->title); - free(frame); + frame_destroy(frame); return NULL; } -void -frame_destroy(struct frame *frame) -{ - struct frame_button *button, *next; - - wl_list_for_each_safe(button, next, &frame->buttons, link) - frame_button_destroy(button); - - free(frame->title); - free(frame); -} - int frame_set_title(struct frame *frame, const char *title) { @@ -729,16 +736,16 @@ frame_pointer_button(struct frame *frame, void *data, { struct frame_pointer *pointer = frame_pointer_get(frame, data); struct frame_pointer_button *button; - enum theme_location location; + enum theme_location location = THEME_LOCATION_EXTERIOR; + + if (!pointer) + return location; location = theme_get_location(frame->theme, pointer->x, pointer->y, frame->width, frame->height, frame->flags & FRAME_FLAG_MAXIMIZED ? THEME_FRAME_MAXIMIZED : 0); - if (!pointer) - return location; - if (state == FRAME_BUTTON_PRESSED) { button = malloc(sizeof *button); if (!button) @@ -777,7 +784,7 @@ frame_touch_down(struct frame *frame, void *data, int32_t id, int x, int y) if (id > 0) return; - if (button) { + if (touch && button) { touch->button = button; frame_button_press(touch->button); return; @@ -815,10 +822,9 @@ frame_touch_up(struct frame *frame, void *data, int32_t id) if (id > 0) return; - if (touch->button) { + if (touch && touch->button) { frame_button_release(touch->button); frame_touch_destroy(touch); - return; } } diff --git a/src/animation.c b/src/animation.c index ee120367..33875d99 100644 --- a/src/animation.c +++ b/src/animation.c @@ -262,6 +262,9 @@ weston_zoom_run(struct weston_view *view, float start, float stop, zoom_frame, reset_alpha, done, data, NULL); + if (zoom == NULL) + return NULL; + weston_spring_init(&zoom->spring, 300.0, start, stop); zoom->spring.friction = 1400; zoom->spring.previous = start - (stop - start) * 0.03; @@ -291,6 +294,9 @@ weston_fade_run(struct weston_view *view, fade_frame, reset_alpha, done, data, NULL); + if (fade == NULL) + return NULL; + weston_spring_init(&fade->spring, k, start, end); fade->spring.friction = 1400; @@ -337,6 +343,8 @@ weston_stable_fade_run(struct weston_view *front_view, float start, stable_fade_frame, NULL, done, data, back_view); + if (fade == NULL) + return NULL; weston_spring_init(&fade->spring, 400, start, end); fade->spring.friction = 1150; @@ -434,6 +442,10 @@ weston_move_scale_run(struct weston_view *view, int dx, int dy, animation = weston_view_animation_run(view, start, end, move_frame, NULL, move_done, data, move); + + if (animation == NULL) + return NULL; + animation->spring.k = 400; animation->spring.friction = 1150; diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 136d517e..154e15e4 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -431,9 +431,10 @@ drm_output_check_scanout_format(struct drm_output *output, /* We can scanout an ARGB buffer if the surface's * opaque region covers the whole output, but we have * to use XRGB as the KMS format code. */ - pixman_region32_init(&r); - pixman_region32_subtract(&r, &output->base.region, - &es->opaque); + pixman_region32_init_rect(&r, 0, 0, + output->base.width, + output->base.height); + pixman_region32_subtract(&r, &r, &es->opaque); if (!pixman_region32_not_empty(&r)) format = GBM_FORMAT_XRGB8888; @@ -668,6 +669,7 @@ drm_output_repaint(struct weston_output *output_base, return 0; err_pageflip: + output->cursor_view = NULL; if (output->next) { drm_output_release_fb(output, output->next); output->next = NULL; @@ -2058,7 +2060,7 @@ create_output_for_connector(struct drm_compositor *ec, weston_log("Output %s, (connector %d, crtc %d)\n", output->base.name, output->connector_id, output->crtc_id); wl_list_for_each(m, &output->base.mode_list, link) - weston_log_continue(" mode %dx%d@%.1f%s%s%s\n", + weston_log_continue(STAMP_SPACE "mode %dx%d@%.1f%s%s%s\n", m->width, m->height, m->refresh / 1000.0, m->flags & WL_OUTPUT_MODE_PREFERRED ? ", preferred" : "", diff --git a/src/compositor-rdp.c b/src/compositor-rdp.c index b9c36cfd..e8e4a8dc 100644 --- a/src/compositor-rdp.c +++ b/src/compositor-rdp.c @@ -27,6 +27,14 @@ #include #include +#if HAVE_FREERDP_VERSION_H +#include +#else +/* assume it's a early 1.1 version */ +#define FREERDP_VERSION_MAJOR 1 +#define FREERDP_VERSION_MINOR 1 +#endif + #include #include #include @@ -571,7 +579,11 @@ rdp_peer_context_new(freerdp_peer* client, RdpPeerContext* context) context->item.peer = client; context->item.flags = RDP_PEER_OUTPUT_ENABLED; +#if FREERDP_VERSION_MAJOR == 1 && FREERDP_VERSION_MINOR == 1 context->rfx_context = rfx_context_new(); +#else + context->rfx_context = rfx_context_new(TRUE); +#endif context->rfx_context->mode = RLGR3; context->rfx_context->width = client->settings->DesktopWidth; context->rfx_context->height = client->settings->DesktopHeight; diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c index d2d89427..899c3293 100644 --- a/src/compositor-wayland.c +++ b/src/compositor-wayland.c @@ -879,7 +879,7 @@ wayland_output_create_for_config(struct wayland_compositor *c, name = str; } if (!name) - name = WINDOW_TITLE; + name = strdup(WINDOW_TITLE); weston_config_section_get_string(config_section, "mode", &mode, "1024x600"); @@ -1427,6 +1427,8 @@ create_cursor(struct wayland_compositor *c, struct weston_config *config) c->cursor_theme = wl_cursor_theme_load(theme, size, c->parent.shm); + free(theme); + c->cursor = NULL; for (i = 0; !c->cursor && i < ARRAY_LENGTH(left_ptrs); ++i) c->cursor = wl_cursor_theme_get_cursor(c->cursor_theme, diff --git a/src/compositor.c b/src/compositor.c index bb1dfa9c..40e4b119 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -1509,7 +1509,7 @@ weston_buffer_from_resource(struct wl_resource *resource) { struct weston_buffer *buffer; struct wl_listener *listener; - + listener = wl_resource_get_destroy_listener(resource, weston_buffer_destroy_handler); @@ -1526,7 +1526,7 @@ weston_buffer_from_resource(struct wl_resource *resource) buffer->destroy_listener.notify = weston_buffer_destroy_handler; buffer->y_inverted = 1; wl_resource_add_destroy_listener(resource, &buffer->destroy_listener); - + return buffer; } @@ -2110,10 +2110,10 @@ weston_surface_commit(struct weston_surface *surface) surface->buffer_viewport = surface->pending.buffer_viewport; /* wl_surface.attach */ - if (surface->pending.buffer || surface->pending.newly_attached) + if (surface->pending.buffer || surface->pending.newly_attached) { weston_surface_attach(surface, surface->pending.buffer); - - weston_surface_set_size_from_buffer(surface); + weston_surface_set_size_from_buffer(surface); + } if (surface->configure && surface->pending.newly_attached) surface->configure(surface, @@ -2336,12 +2336,12 @@ weston_subsurface_commit_from_cache(struct weston_subsurface *sub) surface->buffer_viewport = sub->cached.buffer_viewport; /* wl_surface.attach */ - if (sub->cached.buffer_ref.buffer || sub->cached.newly_attached) + if (sub->cached.buffer_ref.buffer || sub->cached.newly_attached) { weston_surface_attach(surface, sub->cached.buffer_ref.buffer); + weston_surface_set_size_from_buffer(surface); + } weston_buffer_reference(&sub->cached.buffer_ref, NULL); - weston_surface_set_size_from_buffer(surface); - if (surface->configure && sub->cached.newly_attached) surface->configure(surface, sub->cached.sx, sub->cached.sy); sub->cached.sx = 0; @@ -3857,7 +3857,7 @@ print_backtrace(void) filename = dlinfo.dli_fname; else filename = "?"; - + weston_log("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname, ret == -UNW_ENOMEM ? "..." : "", (int)off, (void *)(pip.start_ip + off)); @@ -3914,6 +3914,9 @@ weston_load_module(const char *name, const char *entrypoint) char path[PATH_MAX]; void *module, *init; + if (name == NULL) + return NULL; + if (name[0] != '/') snprintf(path, sizeof path, "%s/%s", MODULEDIR, name); else @@ -4125,6 +4128,7 @@ int main(int argc, char *argv[]) char *backend = NULL; char *option_backend = NULL; char *shell = NULL; + char *option_shell = NULL; char *modules, *option_modules = NULL; char *log = NULL; int32_t idle_time = 300; @@ -4136,7 +4140,7 @@ int main(int argc, char *argv[]) const struct weston_option core_options[] = { { WESTON_OPTION_STRING, "backend", 'B', &option_backend }, - { WESTON_OPTION_STRING, "shell", 0, &shell }, + { WESTON_OPTION_STRING, "shell", 0, &option_shell }, { WESTON_OPTION_STRING, "socket", 'S', &socket_name }, { WESTON_OPTION_INTEGER, "idle-time", 'i', &idle_time }, { WESTON_OPTION_STRING, "modules", 0, &option_modules }, @@ -4156,7 +4160,7 @@ int main(int argc, char *argv[]) } weston_log_file_open(log); - + weston_log("%s\n" STAMP_SPACE "%s\n" STAMP_SPACE "Bug reports to: %s\n" @@ -4190,22 +4194,23 @@ int main(int argc, char *argv[]) } section = weston_config_get_section(config, "core", NULL, NULL); - weston_config_section_get_string(section, "backend", &backend, NULL); - if (option_backend) { - backend = option_backend; - } + if (option_backend) + backend = strdup(option_backend); + else + weston_config_section_get_string(section, "backend", &backend, + NULL); + if (!backend) { if (getenv("WAYLAND_DISPLAY")) - backend = "wayland-backend.so"; + backend = strdup("wayland-backend.so"); else if (getenv("DISPLAY")) - backend = "x11-backend.so"; + backend = strdup("x11-backend.so"); else - backend = WESTON_NATIVE_BACKEND; + backend = strdup(WESTON_NATIVE_BACKEND); } - weston_config_section_get_string(section, "modules", &modules, ""); - backend_init = weston_load_module(backend, "backend_init"); + free(backend); if (!backend_init) exit(EXIT_FAILURE); @@ -4223,14 +4228,25 @@ int main(int argc, char *argv[]) setenv("WAYLAND_DISPLAY", socket_name, 1); - if (!shell) + if (option_shell) + shell = strdup(option_shell); + else weston_config_section_get_string(section, "shell", &shell, "desktop-shell.so"); - if (load_modules(ec, shell, &argc, argv) < 0) + + if (load_modules(ec, shell, &argc, argv) < 0) { + free(shell); goto out; + } + free(shell); - if (load_modules(ec, modules, &argc, argv) < 0) + weston_config_section_get_string(section, "modules", &modules, ""); + if (load_modules(ec, modules, &argc, argv) < 0) { + free(modules); goto out; + } + free(modules); + if (load_modules(ec, option_modules, &argc, argv) < 0) goto out; diff --git a/src/evdev.c b/src/evdev.c index d38f63bd..d9b7d320 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -102,6 +102,8 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) device->rel.dy = 0; goto handled; case EVDEV_ABSOLUTE_MT_DOWN: + if (device->output == NULL) + break; weston_output_transform_coordinate(device->output, wl_fixed_from_int(device->mt.slots[slot].x), wl_fixed_from_int(device->mt.slots[slot].y), @@ -113,6 +115,8 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) notify_touch(master, time, seat_slot, x, y, WL_TOUCH_DOWN); goto handled; case EVDEV_ABSOLUTE_MT_MOTION: + if (device->output == NULL) + break; weston_output_transform_coordinate(device->output, wl_fixed_from_int(device->mt.slots[slot].x), wl_fixed_from_int(device->mt.slots[slot].y), @@ -126,6 +130,8 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) notify_touch(master, time, seat_slot, 0, 0, WL_TOUCH_UP); goto handled; case EVDEV_ABSOLUTE_TOUCH_DOWN: + if (device->output == NULL) + break; transform_absolute(device, &cx, &cy); weston_output_transform_coordinate(device->output, wl_fixed_from_int(cx), @@ -137,6 +143,8 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time) notify_touch(master, time, seat_slot, x, y, WL_TOUCH_DOWN); goto handled; case EVDEV_ABSOLUTE_MOTION: + if (device->output == NULL) + break; transform_absolute(device, &cx, &cy); weston_output_transform_coordinate(device->output, wl_fixed_from_int(cx), @@ -219,8 +227,13 @@ evdev_process_touch(struct evdev_device *device, struct input_event *e, uint32_t time) { - const int screen_width = device->output->current_mode->width; - const int screen_height = device->output->current_mode->height; + int screen_width, screen_height; + + if (device->output == NULL) + return; + + screen_width = device->output->current_mode->width; + screen_height = device->output->current_mode->height; switch (e->code) { case ABS_MT_SLOT: @@ -257,8 +270,13 @@ static inline void evdev_process_absolute_motion(struct evdev_device *device, struct input_event *e) { - const int screen_width = device->output->current_mode->width; - const int screen_height = device->output->current_mode->height; + int screen_width, screen_height; + + if (device->output == NULL) + return; + + screen_width = device->output->current_mode->width; + screen_height = device->output->current_mode->height; switch (e->code) { case ABS_X: @@ -575,6 +593,34 @@ evdev_configure_device(struct evdev_device *device) return 0; } +static void +notify_output_destroy(struct wl_listener *listener, void *data) +{ + struct evdev_device *device = + container_of(listener, + struct evdev_device, output_destroy_listener); + struct weston_compositor *c = device->seat->compositor; + struct weston_output *output; + + if (device->output_name) { + output = container_of(c->output_list.next, + struct weston_output, link); + evdev_device_set_output(device, output); + } else { + device->output = NULL; + } +} + +void +evdev_device_set_output(struct evdev_device *device, + struct weston_output *output) +{ + device->output = output; + device->output_destroy_listener.notify = notify_output_destroy; + wl_signal_add(&output->destroy_signal, + &device->output_destroy_listener); +} + struct evdev_device * evdev_device_create(struct weston_seat *seat, const char *path, int device_fd) { @@ -587,9 +633,6 @@ evdev_device_create(struct weston_seat *seat, const char *path, int device_fd) return NULL; ec = seat->compositor; - device->output = - container_of(ec->output_list.next, struct weston_output, link); - device->seat = seat; device->seat_caps = 0; device->is_mt = 0; @@ -652,6 +695,8 @@ evdev_device_destroy(struct evdev_device *device) if (device->source) wl_event_source_remove(device->source); + if (device->output) + wl_list_remove(&device->output_destroy_listener.link); wl_list_remove(&device->link); if (device->mtdev) mtdev_close_delete(device->mtdev); diff --git a/src/evdev.h b/src/evdev.h index 36a52e34..10f9724e 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -53,6 +53,7 @@ struct evdev_device { struct wl_event_source *source; struct weston_output *output; struct evdev_dispatch *dispatch; + struct wl_listener output_destroy_listener; char *devnode; char *devname; char *output_name; @@ -123,6 +124,9 @@ evdev_led_update(struct evdev_device *device, enum weston_led leds); struct evdev_device * evdev_device_create(struct weston_seat *seat, const char *path, int device_fd); +void +evdev_device_set_output(struct evdev_device *device, + struct weston_output *output); void evdev_device_destroy(struct evdev_device *device); diff --git a/src/libbacklight.c b/src/libbacklight.c index b3acc63f..54f33182 100644 --- a/src/libbacklight.c +++ b/src/libbacklight.c @@ -51,8 +51,7 @@ static long backlight_get(struct backlight *backlight, char *node) long value, ret; if (asprintf(&path, "%s/%s", backlight->path, node) < 0) - return -ENOMEM -; + return -ENOMEM; fd = open(path, O_RDONLY); if (fd < 0) { ret = -1; @@ -211,8 +210,10 @@ struct backlight *backlight_init(struct udev_device *drm_device, entry->d_name) < 0) goto err; - if (asprintf(&path, "%s/%s", backlight_path, "type") < 0) + if (asprintf(&path, "%s/%s", backlight_path, "type") < 0) { + free(backlight_path); goto err; + } fd = open(path, O_RDONLY); diff --git a/src/log.c b/src/log.c index 911b0c63..99bbe180 100644 --- a/src/log.c +++ b/src/log.c @@ -46,6 +46,9 @@ static int weston_log_timestamp(void) gettimeofday(&tv, NULL); brokendown_time = localtime(&tv.tv_sec); + if (brokendown_time == NULL) + return fprintf(weston_logfile, "[(NULL)localtime] "); + if (brokendown_time->tm_mday != cached_tm_mday) { strftime(string, sizeof string, "%Y-%m-%d %Z", brokendown_time); fprintf(weston_logfile, "Date: %s\n", string); diff --git a/src/rpi-renderer.c b/src/rpi-renderer.c index c6b924c6..3a7f65cc 100644 --- a/src/rpi-renderer.c +++ b/src/rpi-renderer.c @@ -363,6 +363,7 @@ rpi_resource_update(struct rpi_resource *resource, struct weston_buffer *buffer, int height; int stride; int ret; + int applied_opaque_region = 0; #ifdef HAVE_RESOURCE_WRITE_DATA_RECT int n; #endif @@ -384,13 +385,18 @@ rpi_resource_update(struct rpi_resource *resource, struct weston_buffer *buffer, if (!pixels) return -1; + + applied_opaque_region = 1; } #endif ret = rpi_resource_realloc(resource, ifmt & ~PREMULT_ALPHA_FLAG, width, height, stride, height); - if (ret < 0) + if (ret < 0) { + if (applied_opaque_region) + free(pixels); return -1; + } pixman_region32_init_rect(&write_region, 0, 0, width, height); if (ret == 0) @@ -437,12 +443,8 @@ rpi_resource_update(struct rpi_resource *resource, struct weston_buffer *buffer, pixman_region32_fini(&write_region); -#ifndef HAVE_ELEMENT_SET_OPAQUE_RECT - if (pixman_region32_not_empty(opaque_region) && - wl_shm_buffer_get_format(buffer->shm_buffer) == WL_SHM_FORMAT_ARGB8888 && - resource->enable_opaque_regions) + if (applied_opaque_region) free(pixels); -#endif return ret ? -1 : 0; } @@ -1742,11 +1744,13 @@ rpi_renderer_create(struct weston_compositor *compositor, renderer->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (renderer->egl_display == EGL_NO_DISPLAY) { weston_log("failed to create EGL display\n"); + free(renderer); return -1; } if (!eglInitialize(renderer->egl_display, &major, &minor)) { weston_log("failed to initialize EGL display\n"); + free(renderer); return -1; } @@ -1761,6 +1765,8 @@ rpi_renderer_create(struct weston_compositor *compositor, EGL_EXTENSIONS); if (!extensions) { weston_log("Retrieving EGL extension string failed.\n"); + eglTerminate(renderer->egl_display); + free(renderer); return -1; } diff --git a/src/screenshooter.c b/src/screenshooter.c index 26e503ce..1d1c1b38 100644 --- a/src/screenshooter.c +++ b/src/screenshooter.c @@ -190,7 +190,7 @@ screenshooter_shoot(struct wl_client *client, } if (!wl_shm_buffer_get(buffer->resource)) return; - + buffer->shm_buffer = wl_shm_buffer_get(buffer->resource); buffer->width = wl_shm_buffer_get_width(buffer->shm_buffer); buffer->height = wl_shm_buffer_get_height(buffer->shm_buffer); @@ -428,6 +428,11 @@ weston_recorder_create(struct weston_output *output, const char *filename) recorder = malloc(sizeof *recorder); + if (recorder == NULL) { + weston_log("%s: out of memory\n", __func__); + return; + } + stride = output->current_mode->width; size = stride * 4 * output->current_mode->height; recorder->frame = zalloc(size); @@ -454,6 +459,9 @@ weston_recorder_create(struct weston_output *output, const char *filename) break; default: weston_log("unknown recorder format\n"); + free(recorder->rect); + free(recorder->tmpbuf); + free(recorder->frame); free(recorder); return; } @@ -463,6 +471,9 @@ weston_recorder_create(struct weston_output *output, const char *filename) if (recorder->fd < 0) { weston_log("problem opening output file %s: %m\n", filename); + free(recorder->rect); + free(recorder->tmpbuf); + free(recorder->frame); free(recorder); return; } diff --git a/src/text-backend.c b/src/text-backend.c index 59a8b946..d6a6f3b3 100644 --- a/src/text-backend.c +++ b/src/text-backend.c @@ -121,6 +121,7 @@ deactivate_text_input(struct text_input *text_input, input_method_context_end_keyboard_grab(input_method->context); wl_input_method_send_deactivate(input_method->input_method_binding, input_method->context->resource); + input_method->context->model = NULL; } wl_list_remove(&input_method->link); @@ -437,7 +438,9 @@ input_method_context_commit_string(struct wl_client *client, struct input_method_context *context = wl_resource_get_user_data(resource); - wl_text_input_send_commit_string(context->model->resource, serial, text); + if (context->model) + wl_text_input_send_commit_string(context->model->resource, + serial, text); } static void @@ -450,7 +453,9 @@ input_method_context_preedit_string(struct wl_client *client, struct input_method_context *context = wl_resource_get_user_data(resource); - wl_text_input_send_preedit_string(context->model->resource, serial, text, commit); + if (context->model) + wl_text_input_send_preedit_string(context->model->resource, + serial, text, commit); } static void @@ -463,7 +468,9 @@ input_method_context_preedit_styling(struct wl_client *client, struct input_method_context *context = wl_resource_get_user_data(resource); - wl_text_input_send_preedit_styling(context->model->resource, index, length, style); + if (context->model) + wl_text_input_send_preedit_styling(context->model->resource, + index, length, style); } static void @@ -474,7 +481,9 @@ input_method_context_preedit_cursor(struct wl_client *client, struct input_method_context *context = wl_resource_get_user_data(resource); - wl_text_input_send_preedit_cursor(context->model->resource, cursor); + if (context->model) + wl_text_input_send_preedit_cursor(context->model->resource, + cursor); } static void @@ -486,7 +495,9 @@ input_method_context_delete_surrounding_text(struct wl_client *client, struct input_method_context *context = wl_resource_get_user_data(resource); - wl_text_input_send_delete_surrounding_text(context->model->resource, index, length); + if (context->model) + wl_text_input_send_delete_surrounding_text(context->model->resource, + index, length); } static void @@ -498,7 +509,9 @@ input_method_context_cursor_position(struct wl_client *client, struct input_method_context *context = wl_resource_get_user_data(resource); - wl_text_input_send_cursor_position(context->model->resource, index, anchor); + if (context->model) + wl_text_input_send_cursor_position(context->model->resource, + index, anchor); } static void @@ -509,7 +522,8 @@ input_method_context_modifiers_map(struct wl_client *client, struct input_method_context *context = wl_resource_get_user_data(resource); - wl_text_input_send_modifiers_map(context->model->resource, map); + if (context->model) + wl_text_input_send_modifiers_map(context->model->resource, map); } static void @@ -524,8 +538,9 @@ input_method_context_keysym(struct wl_client *client, struct input_method_context *context = wl_resource_get_user_data(resource); - wl_text_input_send_keysym(context->model->resource, serial, time, - sym, state, modifiers); + if (context->model) + wl_text_input_send_keysym(context->model->resource, + serial, time, sym, state, modifiers); } static void @@ -653,7 +668,9 @@ input_method_context_language(struct wl_client *client, { struct input_method_context *context = wl_resource_get_user_data(resource); - wl_text_input_send_language(context->model->resource, serial, language); + if (context->model) + wl_text_input_send_language(context->model->resource, + serial, language); } static void @@ -664,7 +681,9 @@ input_method_context_text_direction(struct wl_client *client, { struct input_method_context *context = wl_resource_get_user_data(resource); - wl_text_input_send_text_direction(context->model->resource, serial, direction); + if (context->model) + wl_text_input_send_text_direction(context->model->resource, + serial, direction); } diff --git a/src/udev-seat.c b/src/udev-seat.c index f9723f2f..f5c2fa88 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -126,7 +126,11 @@ device_added(struct udev_device *udev_device, struct udev_input *input) device->output_name = strdup(output_name); wl_list_for_each(output, &c->output_list, link) if (strcmp(output->name, device->output_name) == 0) - device->output = output; + evdev_device_set_output(device, output); + } else if (device->output == NULL) { + output = container_of(c->output_list.next, + struct weston_output, link); + evdev_device_set_output(device, output); } if (input->enabled == 1) @@ -354,8 +358,10 @@ notify_output_create(struct wl_listener *listener, void *data) wl_list_for_each(device, &seat->devices_list, link) if (device->output_name && - strcmp(output->name, device->output_name) == 0) - device->output = output; + strcmp(output->name, device->output_name) == 0) { + evdev_device_set_output(device, output); + break; + } } static struct udev_seat * diff --git a/tests/.gitignore b/tests/.gitignore index 32a64921..dc4a71a8 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -7,6 +7,8 @@ matrix-test setbacklight test-client test-text-client +text-client-protocol.h +text-protocol.c wayland-test-client-protocol.h wayland-test-protocol.c wayland-test-server-protocol.h diff --git a/wcap/main.c b/wcap/main.c index 1e4605ae..29bb9c30 100644 --- a/wcap/main.c +++ b/wcap/main.c @@ -214,7 +214,7 @@ int main(int argc, char *argv[]) int num = 30, denom = 1; char filename[200]; char *mode; - uint32_t msecs, frame_time, *frame, frame_size; + uint32_t msecs, frame_time; for (i = 1, j = 1; i < argc; i++) { if (strcmp(argv[i], "--yuv4mpeg2-444") == 0) { @@ -276,11 +276,7 @@ int main(int argc, char *argv[]) has_frame = wcap_decoder_get_frame(decoder); msecs = decoder->msecs; frame_time = 1000 * denom / num; - frame_size = decoder->width * decoder->height * 4; - frame = malloc(frame_size); while (has_frame) { - if (decoder->msecs >= msecs) - memcpy(frame, decoder->frame, frame_size); if (all || i == output_frame) { snprintf(filename, sizeof filename, "wcap-frame-%d.png", i); diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c index 70c8cf7c..1bb9825d 100644 --- a/xwayland/window-manager.c +++ b/xwayland/window-manager.c @@ -2214,12 +2214,12 @@ xserver_map_shell_surface(struct weston_wm *wm, window->x, window->y, WL_SHELL_SURFACE_TRANSIENT_INACTIVE); - } else if (window->transient_for) { + } else if (window->transient_for && window->transient_for->surface) { parent = window->transient_for; shell_interface->set_transient(window->shsurf, parent->surface, - parent->x - window->x, - parent->y - window->y, 0); + window->x - parent->x, + window->y - parent->y, 0); } else { shell_interface->set_toplevel(window->shsurf); } -- cgit v1.2.1