This example demonstrates how to use the system interface to install a PNG decoder callback and send a Kitty Graphics Protocol image.
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
bool decode_png(void* userdata,
const uint8_t* data,
size_t data_len,
int* count = (int*)userdata;
(*count)++;
printf(" decode_png called (size=%zu, call #%d)\n", data_len, *count);
const size_t pixel_len = 4;
if (!pixels) return false;
pixels[0] = 255;
pixels[1] = 0;
pixels[2] = 0;
pixels[3] = 255;
return true;
}
void* userdata,
const uint8_t* data,
size_t len) {
(void)terminal;
(void)userdata;
printf(" response (%zu bytes): ", len);
fwrite(data, 1, len, stdout);
printf("\n");
}
int main() {
int decode_count = 0;
.cols = 80,
.rows = 24,
.max_scrollback = 0,
};
fprintf(stderr, "Failed to create terminal\n");
return 1;
}
uint64_t storage_limit = 64 * 1024 * 1024;
&storage_limit);
(const void*)on_write_pty);
printf("Sending Kitty graphics PNG image:\n");
const char* kitty_cmd =
"\x1b_Ga=T,f=100,q=1;"
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAA"
"DUlEQVR4nGP4z8DwHwAFAAH/iZk9HQAAAABJRU5ErkJggg=="
"\x1b\\";
strlen(kitty_cmd));
printf("PNG decode calls: %d\n", decode_count);
fprintf(stderr, "Failed to get kitty graphics storage\n");
return 1;
}
printf("\nKitty graphics storage is available.\n");
fprintf(stderr, "Failed to create placement iterator\n");
return 1;
}
fprintf(stderr, "Failed to get placement iterator\n");
return 1;
}
int placement_count = 0;
placement_count++;
uint32_t image_id = 0;
uint32_t placement_id = 0;
bool is_virtual = false;
int32_t z = 0;
},
(void*[]){ &image_id, &placement_id, &is_virtual, &z },
NULL);
printf(" placement #%d: image_id=%u placement_id=%u virtual=%s z=%d\n",
placement_count, image_id, placement_id,
is_virtual ? "true" : "false", z);
if (!image) {
fprintf(stderr, "Failed to look up image %u\n", image_id);
return 1;
}
uint32_t width = 0, height = 0, number = 0;
size_t data_len = 0;
},
(void*[]){ &number, &width, &height, &format, &data_len },
NULL);
printf(" image: number=%u size=%ux%u format=%d data_len=%zu\n",
number, width, height, format, data_len);
uint32_t px_w = 0, px_h = 0, cols = 0, rows = 0;
printf(" rendered pixel size: %ux%u\n", px_w, px_h);
}
printf(" grid size: %u cols x %u rows\n", cols, rows);
}
}
printf("Total placements: %d\n", placement_count);
return 0;
}
GHOSTTY_API uint8_t * ghostty_alloc(const GhosttyAllocator *allocator, size_t len)
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_pixel_size(GhosttyKittyGraphicsPlacementIterator iterator, GhosttyKittyGraphicsImage image, GhosttyTerminal terminal, uint32_t *out_width, uint32_t *out_height)
GHOSTTY_API void ghostty_kitty_graphics_placement_iterator_free(GhosttyKittyGraphicsPlacementIterator iterator)
struct GhosttyKittyGraphicsImpl * GhosttyKittyGraphics
GhosttyKittyGraphicsPlacementData
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_iterator_new(const GhosttyAllocator *allocator, GhosttyKittyGraphicsPlacementIterator *out_iterator)
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_get_multi(GhosttyKittyGraphicsPlacementIterator iterator, size_t count, const GhosttyKittyGraphicsPlacementData *keys, void **values, size_t *out_written)
struct GhosttyKittyGraphicsPlacementIteratorImpl * GhosttyKittyGraphicsPlacementIterator
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_get(GhosttyKittyGraphics graphics, GhosttyKittyGraphicsData data, void *out)
GHOSTTY_API GhosttyKittyGraphicsImage ghostty_kitty_graphics_image(GhosttyKittyGraphics graphics, uint32_t image_id)
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_grid_size(GhosttyKittyGraphicsPlacementIterator iterator, GhosttyKittyGraphicsImage image, GhosttyTerminal terminal, uint32_t *out_cols, uint32_t *out_rows)
GhosttyKittyGraphicsImageData
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_image_get_multi(GhosttyKittyGraphicsImage image, size_t count, const GhosttyKittyGraphicsImageData *keys, void **values, size_t *out_written)
GHOSTTY_API bool ghostty_kitty_graphics_placement_next(GhosttyKittyGraphicsPlacementIterator iterator)
const struct GhosttyKittyGraphicsImageImpl * GhosttyKittyGraphicsImage
@ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_Z
@ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_IMAGE_ID
@ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_PLACEMENT_ID
@ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_IS_VIRTUAL
@ GHOSTTY_KITTY_IMAGE_DATA_NUMBER
@ GHOSTTY_KITTY_IMAGE_DATA_HEIGHT
@ GHOSTTY_KITTY_IMAGE_DATA_WIDTH
@ GHOSTTY_KITTY_IMAGE_DATA_DATA_LEN
@ GHOSTTY_KITTY_IMAGE_DATA_FORMAT
@ GHOSTTY_KITTY_GRAPHICS_DATA_PLACEMENT_ITERATOR
GHOSTTY_API GhosttyResult ghostty_sys_set(GhosttySysOption option, const void *value)
@ GHOSTTY_SYS_OPT_DECODE_PNG
@ GHOSTTY_SYS_OPT_USERDATA
GHOSTTY_API GhosttyResult ghostty_terminal_set(GhosttyTerminal terminal, GhosttyTerminalOption option, const void *value)
GHOSTTY_API GhosttyResult ghostty_terminal_get(GhosttyTerminal terminal, GhosttyTerminalData data, void *out)
struct GhosttyTerminalImpl * GhosttyTerminal
GHOSTTY_API GhosttyResult ghostty_terminal_new(const GhosttyAllocator *allocator, GhosttyTerminal *terminal, GhosttyTerminalOptions options)
GHOSTTY_API void ghostty_terminal_free(GhosttyTerminal terminal)
GHOSTTY_API void ghostty_terminal_vt_write(GhosttyTerminal terminal, const uint8_t *data, size_t len)
GHOSTTY_API GhosttyResult ghostty_terminal_resize(GhosttyTerminal terminal, uint16_t cols, uint16_t rows, uint32_t cell_width_px, uint32_t cell_height_px)
@ GHOSTTY_TERMINAL_DATA_KITTY_GRAPHICS
@ GHOSTTY_TERMINAL_OPT_KITTY_IMAGE_STORAGE_LIMIT
@ GHOSTTY_TERMINAL_OPT_WRITE_PTY