| 1 | #define main guest_main |
| 2 | #include "linux.c" |
| 3 | #undef main |
| 4 | #include <assert.h> |
| 5 | #include <sys/socket.h> |
| 6 | |
| 7 | static 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 | |
| 9 | int 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 | } |