1#define main guest_main
2#include "linux.c"
3#undef main
4#include <assert.h>
5#include <sys/socket.h>
6
7static uint32_t word(const uint8_t *p) { return (uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | p[3]; }
8
9int main(void) {
10 out = g_byte_array_new(); cursor_packet = g_byte_array_new();
11 int sockets[2]; assert(!socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, sockets));
12 channel = sockets[0];
13 uint8_t metadata[sizeof(struct spa_meta_cursor) + sizeof(struct spa_meta_bitmap) + 8] = {0};
14 struct spa_meta_cursor *cursor = (void *)metadata;
15 struct spa_meta_bitmap *bitmap = (void *)(metadata + sizeof(*cursor));
16 cursor->id = 7; cursor->position.x = -17; cursor->position.y = 25;
17 cursor->bitmap_offset = sizeof(*cursor); cursor->hotspot.x = 1;
18 bitmap->format = SPA_VIDEO_FORMAT_BGRA; bitmap->size = SPA_RECTANGLE(2, 1);
19 bitmap->stride = 8; bitmap->offset = sizeof(*bitmap);
20 uint8_t *pixels = metadata + sizeof(*cursor) + sizeof(*bitmap);
21 memcpy(pixels, (uint8_t[]){16, 32, 64, 128, 0, 0, 0, 0}, 8);
22 struct spa_meta meta = {SPA_META_Cursor, sizeof(metadata), metadata};
23 struct spa_buffer buffer = {.n_metas = 1, .metas = &meta};
24 pw_cursor(&buffer);
25 assert(cursor_packet->len == SG_CURSOR_WORDS * 4 + 4 + 10);
26 const uint8_t *rgba = cursor_packet->data + SG_CURSOR_WORDS * 4 + 4;
27 assert(rgba[0] == 128 && rgba[1] == 64 && rgba[2] == 32 && rgba[3] == 128);
28 assert(!rgba[4] && !rgba[5] && !rgba[6] && !rgba[7]);
29 assert(word(cursor_packet->data + SG_CURSOR_HOT_X * 4) == 1);
30 assert((int32_t)pointer[SG_POINTER_X] == -17 && pointer[SG_POINTER_VISIBLE]);
31 size_t length = cursor_packet->len;
32 cursor->bitmap_offset = UINT32_MAX;
33 pw_cursor(&buffer); assert(cursor_packet->len == length);
34 cursor->bitmap_offset = sizeof(*cursor) + 1; pw_cursor(&buffer);
35 cursor->bitmap_offset = sizeof(*cursor); bitmap->stride = -8;
36 pw_cursor(&buffer); assert(cursor_packet->len == SG_CURSOR_WORDS * 4);
37 bitmap->stride = 8; bitmap->offset = UINT32_MAX;
38 pw_cursor(&buffer); assert(cursor_packet->len == SG_CURSOR_WORDS * 4);
39 bitmap->offset = sizeof(*bitmap); cursor->hotspot.x = 2;
40 pw_cursor(&buffer); assert(cursor_packet->len == SG_CURSOR_WORDS * 4);
41 cursor->hotspot.x = 1; bitmap->offset = sizeof(*bitmap); pw_cursor(&buffer);
42 assert(pointer[SG_POINTER_VISIBLE]);
43 length = cursor_packet->len;
44 cursor->id = 0; pw_cursor(&buffer); assert(!pointer[SG_POINTER_VISIBLE] && cursor_packet->len == length);
45 cursor->id = 7; cursor->bitmap_offset = 0; pw_cursor(&buffer);
46 assert(pointer[SG_POINTER_VISIBLE] && cursor_packet->len == length);
47 cursor->bitmap_offset = sizeof(*cursor); bitmap->offset = 0; bitmap->format = 0;
48 pw_cursor(&buffer);
49 assert(word(cursor_packet->data + SG_CURSOR_WIDTH * 4) == 1);
50 assert(word(cursor_packet->data + SG_CURSOR_HEIGHT * 4) == 1);
51 assert(!memcmp(cursor_packet->data + SG_CURSOR_WORDS * 4 + 4, (uint8_t[4]){0}, 4));
52 length = cursor_packet->len; cursor->bitmap_offset = 0; pw_cursor(&buffer);
53 assert(pointer[SG_POINTER_VISIBLE] && cursor_packet->len == length);
54 cursor->bitmap_offset = sizeof(*cursor); bitmap->offset = sizeof(*bitmap);
55 pw_cursor(&buffer); assert(cursor_packet->len == length);
56 bitmap->format = SPA_VIDEO_FORMAT_BGRA; bitmap->offset = sizeof(*bitmap); pw_cursor(&buffer); assert(pointer[SG_POINTER_VISIBLE]);
57 uint8_t drain[4096]; while (read(sockets[1], drain, sizeof(drain)) > 0) {}
58 g_byte_array_set_size(cursor_packet, 0);
59 capturing = 1; uint8_t screen[16] = {0, 0, 255, 0, 0, 255, 0, 0, 255, 0, 0, 0, 255, 255, 255, 0};
60 screen_frame(screen, 2, 2);
61 ssize_t count = read(sockets[1], drain, sizeof(drain));
62 assert(count == 12 + SG_SCREEN_WORDS * 4 + 16 && word(drain + 4) == SG_SCREEN);
63 screen_frame(screen, 2, 2); assert(read(sockets[1], drain, sizeof(drain)) < 0 && errno == EAGAIN);
64 screen[4] = 128; screen_frame(screen, 2, 2);
65 count = read(sockets[1], drain, sizeof(drain));
66 assert(count == 12 + SG_SCREEN_WORDS * 4 + 4 && word(drain + 12 + SG_SCREEN_X * 4) == 1 && word(drain + 12 + SG_SCREEN_RECT_WIDTH * 4) == 1);
67 uint8_t stop[12] = SG_MAGIC; sg_word(stop + 4, SG_STOP); sg_word(stop + 8, 0);
68 assert(write(sockets[1], stop, 3) == 3); assert(read_requests(channel, G_IO_IN, NULL) == G_SOURCE_CONTINUE);
69 assert(write(sockets[1], stop + 3, 9) == 9); assert(read_requests(channel, G_IO_IN, NULL) == G_SOURCE_REMOVE);
70 count = read(sockets[1], drain, sizeof(drain)); assert(count == 12 && word(drain + 4) == SG_STOP && channel == -1);
71 close(sockets[1]); free(before); g_byte_array_unref(out); g_byte_array_unref(cursor_packet);
72 return 0;
73}