static void redraw(void *data, struct wl_callback *callback, uint32_t time) { struct window *window = data; struct buffer *buffer; buffer = window_next_buffer(window); if (!buffer) { fprintf(stderr, !callback ? "Failed to create the first buffer.\n" : "Both buffers busy at redraw(). Server bug?\n"); abort(); } /* XXX: would be nice to draw something that changes here... */ wl_surface_attach(window->surface, buffer->buffer, 0, 0); wl_surface_damage(window->surface, 0, 0, window->width, window->height); if (callback) wl_callback_destroy(callback); window->callback = wl_surface_frame(window->surface); wl_callback_add_listener(window->callback, &frame_listener, window); wl_surface_commit(window->surface); buffer->busy = 1; }
static void redraw(void *data, struct wl_callback *callback, uint32_t time) { struct window *window = data; struct buffer *buffer; buffer = window_next_buffer(window); if (!buffer) { fprintf(stderr, !callback ? "Failed to create the first buffer.\n" : "Both buffers busy at redraw(). Server bug?\n"); abort(); } paint_pixels(buffer->shm_data, 20, window->width, window->height, time); wl_surface_attach(window->surface, buffer->buffer, 0, 0); wl_surface_damage(window->surface, 20, 20, window->width - 40, window->height - 40); if (callback) wl_callback_destroy(callback); window->callback = wl_surface_frame(window->surface); wl_callback_add_listener(window->callback, &frame_listener, window); wl_surface_commit(window->surface); buffer->busy = 1; }
static void redraw(void *data, struct wl_callback *callback, uint32_t time) { struct window *window = data; struct buffer *buffer; int off_x, off_y, bwidth, bheight, bborder, bpitch, bradius; uint32_t *buffer_data; float bx, by; buffer = window_next_buffer(window); if (!buffer) { fprintf(stderr, !callback ? "Failed to create the first buffer.\n" : "Both buffers busy at redraw(). Server bug?\n"); abort(); } /* Rotate the damage, but keep the even/odd parity so the * dimensions of the buffers don't change */ if (window->flags & WINDOW_FLAG_ROTATING_TRANSFORM) window->transform = (window->transform + 2) % 8; switch (window->transform) { default: case WL_OUTPUT_TRANSFORM_NORMAL: case WL_OUTPUT_TRANSFORM_180: case WL_OUTPUT_TRANSFORM_FLIPPED: case WL_OUTPUT_TRANSFORM_FLIPPED_180: bwidth = window->width * window->scale; bheight = window->height * window->scale; break; case WL_OUTPUT_TRANSFORM_90: case WL_OUTPUT_TRANSFORM_270: case WL_OUTPUT_TRANSFORM_FLIPPED_90: case WL_OUTPUT_TRANSFORM_FLIPPED_270: bwidth = window->height * window->scale; bheight = window->width * window->scale; break; } bpitch = bwidth; bborder = window->border * window->scale; bradius = window->ball.radius * window->scale; buffer_data = buffer->shm_data; if (window->viewport) { /* Fill the whole thing with red to detect viewport errors */ paint_box(buffer->shm_data, bpitch, 0, 0, bwidth, bheight, 0xffff0000); /* The buffer is the same size. However, we crop it * and scale it up by a factor of 2 */ bborder /= 2; bradius /= 2; bwidth /= 2; bheight /= 2; /* Offset the drawing region */ off_x = (window->width / 3) * window->scale; off_y = (window->height / 5) * window->scale; switch (window->transform) { default: case WL_OUTPUT_TRANSFORM_NORMAL: buffer_data += off_y * bpitch + off_x; break; case WL_OUTPUT_TRANSFORM_90: buffer_data += off_x * bpitch + (bwidth - off_y); break; case WL_OUTPUT_TRANSFORM_180: buffer_data += (bheight - off_y) * bpitch + (bwidth - off_x); break; case WL_OUTPUT_TRANSFORM_270: buffer_data += (bheight - off_x) * bpitch + off_y; break; case WL_OUTPUT_TRANSFORM_FLIPPED: buffer_data += off_y * bpitch + (bwidth - off_x); break; case WL_OUTPUT_TRANSFORM_FLIPPED_90: buffer_data += (bheight - off_x) * bpitch + (bwidth - off_y); break; case WL_OUTPUT_TRANSFORM_FLIPPED_180: buffer_data += (bheight - off_y) * bpitch + off_x; break; case WL_OUTPUT_TRANSFORM_FLIPPED_270: buffer_data += off_x * bpitch + off_y; break; } wl_viewport_set_source(window->viewport, wl_fixed_from_int(window->width / 3), wl_fixed_from_int(window->height / 5), wl_fixed_from_int(window->width / 2), wl_fixed_from_int(window->height / 2)); } /* Paint the border */ paint_box(buffer_data, bpitch, 0, 0, bwidth, bborder, 0xffffffff); paint_box(buffer_data, bpitch, 0, 0, bborder, bheight, 0xffffffff); paint_box(buffer_data, bpitch, bwidth - bborder, 0, bborder, bheight, 0xffffffff); paint_box(buffer_data, bpitch, 0, bheight - bborder, bwidth, bborder, 0xffffffff); /* fill with translucent */ paint_box(buffer_data, bpitch, bborder, bborder, bwidth - 2 * bborder, bheight - 2 * bborder, 0x80000000); /* Damage where the ball was */ wl_surface_damage(window->surface, window->ball.x - window->ball.radius, window->ball.y - window->ball.radius, window->ball.radius * 2 + 1, window->ball.radius * 2 + 1); window_advance_game(window, time); window_get_transformed_ball(window, &bx, &by); /* Paint the ball */ paint_circle(buffer_data, bpitch, bx, by, bradius, 0xff00ff00); if (print_debug) { printf("Ball now located at (%f, %f)\n", window->ball.x, window->ball.y); printf("Circle painted at (%f, %f), radius %d\n", bx, by, bradius); printf("Buffer damage rectangle: (%d, %d) @ %dx%d\n", (int)(bx - bradius), (int)(by - bradius), bradius * 2 + 1, bradius * 2 + 1); } /* Damage where the ball is now */ wl_surface_damage(window->surface, window->ball.x - window->ball.radius, window->ball.y - window->ball.radius, window->ball.radius * 2 + 1, window->ball.radius * 2 + 1); wl_surface_attach(window->surface, buffer->buffer, 0, 0); if (window->display->compositor_version >= 2 && (window->transform != WL_OUTPUT_TRANSFORM_NORMAL || window->flags & WINDOW_FLAG_ROTATING_TRANSFORM)) wl_surface_set_buffer_transform(window->surface, window->transform); if (window->viewport) wl_viewport_set_destination(window->viewport, window->width, window->height); if (window->scale != 1) wl_surface_set_buffer_scale(window->surface, window->scale); if (callback) wl_callback_destroy(callback); window->callback = wl_surface_frame(window->surface); wl_callback_add_listener(window->callback, &frame_listener, window); wl_surface_commit(window->surface); buffer->busy = 1; }