static void paint_mark(U8 invert) { U8 col = MIN(g_clip_x1, g_clip_x2); const U8 col_max = MAX(g_clip_x1, g_clip_x2); const U8 y_offset = cursor_y_offset(); U8 row_min = MIN(g_clip_y1, g_clip_y2) - y_offset; U8 row_max = MAX(g_clip_y1, g_clip_y2) - y_offset; if (0xf0u == (row_min & 0xf0u)) row_min = 0; if (row_max & 0xf0u) row_max = 0xf; row_min += TOP_Y; row_max += TOP_Y; while (col <= col_max) { const U8 x = g_cur_screen_data->column_x[col]; const U8 w = g_cur_screen_data->column_w[col]; paint_box(x, row_min, x + w - 1, row_max, invert); ++col; } }
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; }
static void draw_cursor(U8 invert) { paint_box(cursor_x, cursor_y, cursor_x + cursor_w - 1, cursor_y, invert); }