diff options
Diffstat (limited to 'src/screenshooter.c')
-rw-r--r-- | src/screenshooter.c | 110 |
1 files changed, 42 insertions, 68 deletions
diff --git a/src/screenshooter.c b/src/screenshooter.c index 645114d0..26e503ce 100644 --- a/src/screenshooter.c +++ b/src/screenshooter.c @@ -144,6 +144,8 @@ screenshooter_frame_notify(struct wl_listener *listener, void *data) d = wl_shm_buffer_get_data(l->buffer->shm_buffer); s = pixels + stride * (l->buffer->height - 1); + wl_shm_buffer_begin_access(l->buffer->shm_buffer); + switch (compositor->read_format) { case PIXMAN_a8r8g8b8: case PIXMAN_x8r8g8b8: @@ -163,6 +165,8 @@ screenshooter_frame_notify(struct wl_listener *listener, void *data) break; } + wl_shm_buffer_end_access(l->buffer->shm_buffer); + screenshooter_send_done(l->resource); free(pixels); free(l); @@ -263,7 +267,7 @@ struct weston_recorder { uint32_t total; int fd; struct wl_listener frame_listener; - int count; + int count, destroying; }; static uint32_t * @@ -298,58 +302,7 @@ component_delta(uint32_t next, uint32_t prev) } static void -transform_rect(struct weston_output *output, pixman_box32_t *r) -{ - pixman_box32_t s = *r; - - switch (output->transform) { - case WL_OUTPUT_TRANSFORM_FLIPPED: - case WL_OUTPUT_TRANSFORM_FLIPPED_90: - case WL_OUTPUT_TRANSFORM_FLIPPED_180: - case WL_OUTPUT_TRANSFORM_FLIPPED_270: - s.x1 = output->width - r->x2; - s.x2 = output->width - r->x1; - break; - default: - break; - } - - switch (output->transform) { - case WL_OUTPUT_TRANSFORM_NORMAL: - case WL_OUTPUT_TRANSFORM_FLIPPED: - r->x1 = s.x1; - r->x2 = s.x2; - break; - case WL_OUTPUT_TRANSFORM_90: - case WL_OUTPUT_TRANSFORM_FLIPPED_90: - r->x1 = output->current_mode->width - s.y2; - r->y1 = s.x1; - r->x2 = output->current_mode->width - s.y1; - r->y2 = s.x2; - break; - case WL_OUTPUT_TRANSFORM_180: - case WL_OUTPUT_TRANSFORM_FLIPPED_180: - r->x1 = output->current_mode->width - s.x2; - r->y1 = output->current_mode->height - s.y2; - r->x2 = output->current_mode->width - s.x1; - r->y2 = output->current_mode->height - s.y1; - break; - case WL_OUTPUT_TRANSFORM_270: - case WL_OUTPUT_TRANSFORM_FLIPPED_270: - r->x1 = s.y1; - r->y1 = output->current_mode->height - s.x2; - r->x2 = s.y2; - r->y2 = output->current_mode->height - s.x1; - break; - default: - break; - } - - r->x1 *= output->current_scale; - r->y1 *= output->current_scale; - r->x2 *= output->current_scale; - r->y2 *= output->current_scale; -} +weston_recorder_destroy(struct weston_recorder *recorder); static void weston_recorder_frame_notify(struct wl_listener *listener, void *data) @@ -360,7 +313,7 @@ weston_recorder_frame_notify(struct wl_listener *listener, void *data) struct weston_compositor *compositor = output->compositor; uint32_t msecs = output->frame_time; pixman_box32_t *r; - pixman_region32_t damage; + pixman_region32_t damage, transformed_damage; int i, j, k, n, width, height, run, stride; uint32_t delta, prev, *d, *s, *p, next; struct { @@ -379,15 +332,20 @@ weston_recorder_frame_notify(struct wl_listener *listener, void *data) outbuf = recorder->tmpbuf; pixman_region32_init(&damage); + pixman_region32_init(&transformed_damage); pixman_region32_intersect(&damage, &output->region, &output->previous_damage); + pixman_region32_translate(&damage, -output->x, -output->y); + weston_transformed_region(output->width, output->height, + output->transform, output->current_scale, + &damage, &transformed_damage); + pixman_region32_fini(&damage); - r = pixman_region32_rectangles(&damage, &n); - if (n == 0) + r = pixman_region32_rectangles(&transformed_damage, &n); + if (n == 0) { + pixman_region32_fini(&transformed_damage); return; - - for (i = 0; i < n; i++) - transform_rect(output, &r[i]); + } header.msecs = msecs; header.nrects = n; @@ -450,8 +408,11 @@ weston_recorder_frame_notify(struct wl_listener *listener, void *data) #endif } - pixman_region32_fini(&damage); + pixman_region32_fini(&transformed_damage); recorder->count++; + + if (recorder->destroying) + weston_recorder_destroy(recorder); } static void @@ -473,6 +434,7 @@ weston_recorder_create(struct weston_output *output, const char *filename) recorder->rect = malloc(size); recorder->total = 0; recorder->count = 0; + recorder->destroying = 0; recorder->output = output; if (do_yflip) @@ -532,15 +494,18 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *da { struct weston_seat *ws = (struct weston_seat *) seat; struct weston_compositor *ec = ws->compositor; - struct weston_output *output = - container_of(ec->output_list.next, - struct weston_output, link); - struct wl_listener *listener; + struct weston_output *output; + struct wl_listener *listener = NULL; struct weston_recorder *recorder; static const char filename[] = "capture.wcap"; - listener = wl_signal_get(&output->frame_signal, - weston_recorder_frame_notify); + wl_list_for_each(output, &seat->compositor->output_list, link) { + listener = wl_signal_get(&output->frame_signal, + weston_recorder_frame_notify); + if (listener) + break; + } + if (listener) { recorder = container_of(listener, struct weston_recorder, frame_listener); @@ -549,9 +514,18 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *da "stopping recorder, total file size %dM, %d frames\n", recorder->total / (1024 * 1024), recorder->count); - weston_recorder_destroy(recorder); + recorder->destroying = 1; + weston_output_schedule_repaint(recorder->output); } else { - weston_log("starting recorder, file %s\n", filename); + if (seat->keyboard && seat->keyboard->focus && + seat->keyboard->focus->output) + output = seat->keyboard->focus->output; + else + output = container_of(ec->output_list.next, + struct weston_output, link); + + weston_log("starting recorder for output %s, file %s\n", + output->name, filename); weston_recorder_create(output, filename); } } |