1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
|
/**
* @file kitty_graphics.h
*
* Kitty graphics protocol
*
* See @ref kitty_graphics for a full usage guide.
*/
#ifndef GHOSTTY_VT_KITTY_GRAPHICS_H
#define GHOSTTY_VT_KITTY_GRAPHICS_H
#include <stdbool.h>
#include <stdint.h>
#include <ghostty/vt/allocator.h>
#include <ghostty/vt/selection.h>
#include <ghostty/vt/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup kitty_graphics Kitty Graphics
*
* API for inspecting images and placements stored via the
* [Kitty graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/).
*
* The central object is @ref GhosttyKittyGraphics, an opaque handle to
* the image storage associated with a terminal's active screen. From it
* you can iterate over placements and look up individual images.
*
* ## Obtaining a KittyGraphics Handle
*
* A @ref GhosttyKittyGraphics handle is obtained from a terminal via
* ghostty_terminal_get() with @ref GHOSTTY_TERMINAL_DATA_KITTY_GRAPHICS.
* The handle is borrowed from the terminal and remains valid until the
* next mutating terminal call (e.g. ghostty_terminal_vt_write() or
* ghostty_terminal_reset()).
*
* Before images can be stored, Kitty graphics must be enabled on the
* terminal by setting a non-zero storage limit with
* @ref GHOSTTY_TERMINAL_OPT_KITTY_IMAGE_STORAGE_LIMIT, and a PNG
* decoder callback must be installed via ghostty_sys_set() with
* @ref GHOSTTY_SYS_OPT_DECODE_PNG.
*
* @snippet c-vt-kitty-graphics/src/main.c kitty-graphics-decode-png
*
* ## Iterating Placements
*
* Placements are inspected through a @ref GhosttyKittyGraphicsPlacementIterator.
* The typical workflow is:
*
* 1. Create an iterator with ghostty_kitty_graphics_placement_iterator_new().
* 2. Populate it from the storage with ghostty_kitty_graphics_get() using
* @ref GHOSTTY_KITTY_GRAPHICS_DATA_PLACEMENT_ITERATOR.
* 3. Optionally filter by z-layer with
* ghostty_kitty_graphics_placement_iterator_set().
* 4. Advance with ghostty_kitty_graphics_placement_next() and read
* per-placement data with ghostty_kitty_graphics_placement_get().
* 5. For each placement, look up its image with
* ghostty_kitty_graphics_image() to access pixel data and dimensions.
* 6. Free the iterator with ghostty_kitty_graphics_placement_iterator_free().
*
* ## Looking Up Images
*
* Given an image ID (obtained from a placement via
* @ref GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_IMAGE_ID), call
* ghostty_kitty_graphics_image() to get a @ref GhosttyKittyGraphicsImage
* handle. From this handle, ghostty_kitty_graphics_image_get() provides
* the image dimensions, pixel format, compression, and a borrowed pointer
* to the raw pixel data.
*
* ## Rendering Helpers
*
* Several functions assist with rendering a placement:
*
* - ghostty_kitty_graphics_placement_pixel_size() — rendered pixel
* dimensions accounting for source rect and aspect ratio.
* - ghostty_kitty_graphics_placement_grid_size() — number of grid
* columns and rows the placement occupies.
* - ghostty_kitty_graphics_placement_viewport_pos() — viewport-relative
* grid position (may be negative for partially scrolled placements).
* - ghostty_kitty_graphics_placement_source_rect() — resolved source
* rectangle in pixels, clamped to image bounds.
* - ghostty_kitty_graphics_placement_rect() — bounding rectangle as a
* @ref GhosttySelection.
*
* ## Change Detection
*
* Generation stamps allow renderers to cheaply detect whether Kitty
* graphics state changed between frames:
*
* - @ref GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION is a storage-wide stamp
* updated on any transmit, placement, or delete. If unchanged, the
* placement set and all image data are identical and both placement
* snapshots and per-image staleness checks can be skipped. Placement
* geometry can still change independently (scrolling moves
* placements), so ghostty_kitty_graphics_placement_render_info()
* should still be recomputed on dirty frames.
* - @ref GHOSTTY_KITTY_IMAGE_DATA_GENERATION is a per-image stamp
* changed on every add/replace of that image ID. Texture caches
* should treat a cached texture as stale when this differs from the
* cached value; dimension/length heuristics cannot detect a
* same-sized retransmission.
*
* Stamps are unique and monotonically increasing process-wide, so
* caches keyed on a generation value never alias across screens
* (main/alternate), resets, or terminals.
*
* ## Lifetime and Thread Safety
*
* All handles borrowed from the terminal (GhosttyKittyGraphics,
* GhosttyKittyGraphicsImage) are invalidated by any mutating terminal
* call. The placement iterator is independently owned and must be freed
* by the caller, but the data it yields is only valid while the
* underlying terminal is not mutated.
*
* ## Example
*
* The following example creates a terminal, sends a Kitty graphics
* image, then iterates placements and prints image metadata:
*
* @snippet c-vt-kitty-graphics/src/main.c kitty-graphics-main
*
* @{
*/
/**
* Queryable data kinds for ghostty_kitty_graphics_get().
*
* @ingroup kitty_graphics
*/
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid / sentinel value. */
GHOSTTY_KITTY_GRAPHICS_DATA_INVALID = 0,
/**
* Populate a pre-allocated placement iterator with placement data from
* the storage. Iterator data is only valid as long as the underlying
* terminal is not mutated.
*
* Output type: GhosttyKittyGraphicsPlacementIterator *
*/
GHOSTTY_KITTY_GRAPHICS_DATA_PLACEMENT_ITERATOR = 1,
/**
* Generation stamp of the last content mutation to this storage:
* any image transmit/replace, placement add, or delete. Zero means
* the storage has never been mutated (and is therefore empty).
*
* If the generation is unchanged since a previous query, the set of
* placements and all image data are identical, so placement iteration
* and image staleness checks can be skipped entirely. Note that
* placement *geometry* may still have changed (scrolling and resizing
* move placements without changing the storage contents), so rendering
* geometry such as ghostty_kitty_graphics_placement_render_info()
* must still be recomputed for frames marked dirty.
*
* Stamps are unique and monotonically increasing process-wide: a
* value observed from any storage never recurs for different content,
* even across screen switches (main vs. alternate screen have
* independent storages) or terminal resets. It is therefore safe to
* key caches on this value alone.
*
* Output type: uint64_t *
*/
GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION = 2,
GHOSTTY_KITTY_GRAPHICS_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
} GhosttyKittyGraphicsData;
/**
* Queryable data kinds for ghostty_kitty_graphics_placement_get().
*
* @ingroup kitty_graphics
*/
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid / sentinel value. */
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_INVALID = 0,
/**
* The image ID this placement belongs to.
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_IMAGE_ID = 1,
/**
* The placement ID.
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_PLACEMENT_ID = 2,
/**
* Whether this is a virtual placement (unicode placeholder).
*
* Output type: bool *
*/
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_IS_VIRTUAL = 3,
/**
* Pixel offset from the left edge of the cell.
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_X_OFFSET = 4,
/**
* Pixel offset from the top edge of the cell.
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_Y_OFFSET = 5,
/**
* Source rectangle x origin in pixels.
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_SOURCE_X = 6,
/**
* Source rectangle y origin in pixels.
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_SOURCE_Y = 7,
/**
* Source rectangle width in pixels (0 = full image width).
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_SOURCE_WIDTH = 8,
/**
* Source rectangle height in pixels (0 = full image height).
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_SOURCE_HEIGHT = 9,
/**
* Number of columns this placement occupies.
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_COLUMNS = 10,
/**
* Number of rows this placement occupies.
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_ROWS = 11,
/**
* Z-index for this placement.
*
* Output type: int32_t *
*/
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_Z = 12,
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
} GhosttyKittyGraphicsPlacementData;
/**
* Z-layer classification for kitty graphics placements.
*
* Based on the kitty protocol z-index conventions:
* - BELOW_BG: z < INT32_MIN/2 (drawn below cell background)
* - BELOW_TEXT: INT32_MIN/2 <= z < 0 (above background, below text)
* - ABOVE_TEXT: z >= 0 (above text)
* - ALL: no filtering (current behavior)
*
* @ingroup kitty_graphics
*/
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_KITTY_PLACEMENT_LAYER_ALL = 0,
GHOSTTY_KITTY_PLACEMENT_LAYER_BELOW_BG = 1,
GHOSTTY_KITTY_PLACEMENT_LAYER_BELOW_TEXT = 2,
GHOSTTY_KITTY_PLACEMENT_LAYER_ABOVE_TEXT = 3,
GHOSTTY_KITTY_PLACEMENT_LAYER_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
} GhosttyKittyPlacementLayer;
/**
* Settable options for ghostty_kitty_graphics_placement_iterator_set().
*
* @ingroup kitty_graphics
*/
typedef enum GHOSTTY_ENUM_TYPED {
/**
* Set the z-layer filter for the iterator.
*
* Input type: GhosttyKittyPlacementLayer *
*/
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_ITERATOR_OPTION_LAYER = 0,
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_ITERATOR_OPTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
} GhosttyKittyGraphicsPlacementIteratorOption;
/**
* Pixel format of a Kitty graphics image.
*
* Note that stored images are always fully decoded:
* GHOSTTY_KITTY_IMAGE_FORMAT_PNG is never returned by
* ghostty_kitty_graphics_image_get() because PNG payloads are decoded
* to GHOSTTY_KITTY_IMAGE_FORMAT_RGBA before storage. The PNG value
* exists only for protocol-level completeness.
*
* @ingroup kitty_graphics
*/
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_KITTY_IMAGE_FORMAT_RGB = 0,
GHOSTTY_KITTY_IMAGE_FORMAT_RGBA = 1,
GHOSTTY_KITTY_IMAGE_FORMAT_PNG = 2,
GHOSTTY_KITTY_IMAGE_FORMAT_GRAY_ALPHA = 3,
GHOSTTY_KITTY_IMAGE_FORMAT_GRAY = 4,
GHOSTTY_KITTY_IMAGE_FORMAT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
} GhosttyKittyImageFormat;
/**
* Compression of a Kitty graphics image.
*
* Note that stored images are always decompressed:
* GHOSTTY_KITTY_IMAGE_COMPRESSION_ZLIB_DEFLATE payloads are inflated
* before storage, so ghostty_kitty_graphics_image_get() always reports
* GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE. Consumers never need to
* inflate image data themselves.
*
* @ingroup kitty_graphics
*/
typedef enum GHOSTTY_ENUM_TYPED {
GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE = 0,
GHOSTTY_KITTY_IMAGE_COMPRESSION_ZLIB_DEFLATE = 1,
GHOSTTY_KITTY_IMAGE_COMPRESSION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
} GhosttyKittyImageCompression;
/**
* Queryable data kinds for ghostty_kitty_graphics_image_get().
*
* @ingroup kitty_graphics
*/
typedef enum GHOSTTY_ENUM_TYPED {
/** Invalid / sentinel value. */
GHOSTTY_KITTY_IMAGE_DATA_INVALID = 0,
/**
* The image ID.
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_IMAGE_DATA_ID = 1,
/**
* The image number.
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_IMAGE_DATA_NUMBER = 2,
/**
* Image width in pixels.
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_IMAGE_DATA_WIDTH = 3,
/**
* Image height in pixels.
*
* Output type: uint32_t *
*/
GHOSTTY_KITTY_IMAGE_DATA_HEIGHT = 4,
/**
* Pixel format of the image. Never GHOSTTY_KITTY_IMAGE_FORMAT_PNG;
* PNG payloads are decoded to RGBA before storage.
*
* Output type: GhosttyKittyImageFormat *
*/
GHOSTTY_KITTY_IMAGE_DATA_FORMAT = 5,
/**
* Compression of the image. Always
* GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE; compressed payloads are
* inflated before storage.
*
* Output type: GhosttyKittyImageCompression *
*/
GHOSTTY_KITTY_IMAGE_DATA_COMPRESSION = 6,
/**
* Borrowed pointer to the raw pixel data. Valid as long as the
* underlying terminal is not mutated. Returns GHOSTTY_NO_VALUE when
* the image metadata is resident but its pixel payload is pending.
*
* The data is always fully decoded, uncompressed pixels in the
* format reported by GHOSTTY_KITTY_IMAGE_DATA_FORMAT: zlib payloads
* are inflated and PNG payloads are decoded to RGBA at transmission
* time, before the image is stored. Consumers can upload this
* directly to the GPU without any decode step.
*
* For an animated image (Kitty graphics animation, actions a=f/a=a)
* this is the pixel data of the current animation frame. The
* image's GHOSTTY_KITTY_IMAGE_DATA_GENERATION changes whenever the
* current frame changes, so generation-keyed caches remain
* coherent.
*
* Output type: const uint8_t **
*/
GHOSTTY_KITTY_IMAGE_DATA_DATA_PTR = 7,
/**
* Length of the raw pixel data in bytes. Always equal to
* width * height * bytes-per-pixel for the reported format. For a
* pending image, this is the expected length reserved against the
* storage limit even though DATA_PTR is not available yet.
*
* Output type: size_t *
*/
GHOSTTY_KITTY_IMAGE_DATA_DATA_LEN = 8,
/**
* Generation stamp assigned when this image was added to (or
* replaced in) the storage. A changed generation for a given image
* ID means the pixel contents may have changed even when the
* dimensions, format, and data length are identical (e.g. a
* retransmission of the same image ID), so texture caches must key
* staleness on this value rather than on size heuristics.
*
* Stamps are unique and monotonically increasing process-wide and
* are drawn from the same sequence as
* GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION. Never zero for a stored
* image, so zero can be used as an "empty" sentinel by callers. Pending
* payload completion preserves this value to retain image age; consumers
* detect that completion through GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION
* and retry DATA_PTR.
*
* Output type: uint64_t *
*/
GHOSTTY_KITTY_IMAGE_DATA_GENERATION = 9,
GHOSTTY_KITTY_IMAGE_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
} GhosttyKittyGraphicsImageData;
/**
* Combined rendering geometry for a placement in a single sized struct.
*
* Combines the results of ghostty_kitty_graphics_placement_pixel_size(),
* ghostty_kitty_graphics_placement_grid_size(),
* ghostty_kitty_graphics_placement_viewport_pos(), and
* ghostty_kitty_graphics_placement_source_rect() into one call. This is
* an optimization over calling those four functions individually,
* particularly useful in environments with high per-call overhead such
* as FFI or Cgo.
*
* This struct uses the sized-struct ABI pattern. Initialize with
* GHOSTTY_INIT_SIZED(GhosttyKittyGraphicsPlacementRenderInfo) before calling
* ghostty_kitty_graphics_placement_render_info().
*
* @ingroup kitty_graphics
*/
typedef struct {
/** Size of this struct in bytes. Must be set to sizeof(GhosttyKittyGraphicsPlacementRenderInfo). */
size_t size;
/** Rendered width in pixels. */
uint32_t pixel_width;
/** Rendered height in pixels. */
uint32_t pixel_height;
/** Number of grid columns the placement occupies. */
uint32_t grid_cols;
/** Number of grid rows the placement occupies. */
uint32_t grid_rows;
/** Viewport-relative column (may be negative for partially visible placements). */
int32_t viewport_col;
/** Viewport-relative row (may be negative for partially visible placements). */
int32_t viewport_row;
/** False when the placement is fully off-screen or virtual. */
bool viewport_visible;
/** Resolved source rectangle x origin in pixels. */
uint32_t source_x;
/** Resolved source rectangle y origin in pixels. */
uint32_t source_y;
/** Resolved source rectangle width in pixels. */
uint32_t source_width;
/** Resolved source rectangle height in pixels. */
uint32_t source_height;
} GhosttyKittyGraphicsPlacementRenderInfo;
/**
* Get data from a kitty graphics storage instance.
*
* The output pointer must be of the appropriate type for the requested
* data kind.
*
* Returns GHOSTTY_NO_VALUE when Kitty graphics are disabled at build time.
*
* @param graphics The kitty graphics handle
* @param data The type of data to extract
* @param[out] out Pointer to store the extracted data
* @return GHOSTTY_SUCCESS on success
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_get(
GhosttyKittyGraphics graphics,
GhosttyKittyGraphicsData data,
void* out);
/**
* Look up a Kitty graphics image by its image ID.
*
* Returns NULL if no image with the given ID exists or if Kitty graphics
* are disabled at build time.
*
* @param graphics The kitty graphics handle
* @param image_id The image ID to look up
* @return An opaque image handle, or NULL if not found
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyKittyGraphicsImage ghostty_kitty_graphics_image(
GhosttyKittyGraphics graphics,
uint32_t image_id);
/**
* Get data from a Kitty graphics image.
*
* The output pointer must be of the appropriate type for the requested
* data kind.
*
* @param image The image handle (NULL returns GHOSTTY_INVALID_VALUE)
* @param data The data kind to query
* @param[out] out Pointer to receive the queried value
* @return GHOSTTY_SUCCESS on success
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_image_get(
GhosttyKittyGraphicsImage image,
GhosttyKittyGraphicsImageData data,
void* out);
/**
* Get multiple data fields from a Kitty graphics image in a single call.
*
* This is an optimization over calling ghostty_kitty_graphics_image_get()
* repeatedly, particularly useful in environments with high per-call
* overhead such as FFI or Cgo.
*
* Each element in the keys array specifies a data kind, and the
* corresponding element in the values array receives the result.
* The type of each values[i] pointer must match the output type
* documented for keys[i].
*
* Processing stops at the first error; on success out_written
* is set to count, on error it is set to the index of the
* failing key (i.e. the number of values successfully written).
*
* @param image The image handle (NULL returns GHOSTTY_INVALID_VALUE)
* @param count Number of key/value pairs
* @param keys Array of data kinds to query
* @param values Array of output pointers (types must match each key's
* documented output type)
* @param[out] out_written On return, receives the number of values
* successfully written (may be NULL)
* @return GHOSTTY_SUCCESS if all queries succeed
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_image_get_multi(
GhosttyKittyGraphicsImage image,
size_t count,
const GhosttyKittyGraphicsImageData* keys,
void** values,
size_t* out_written);
/**
* Create a new placement iterator instance.
*
* All fields except the allocator are left undefined until populated
* via ghostty_kitty_graphics_get() with
* GHOSTTY_KITTY_GRAPHICS_DATA_PLACEMENT_ITERATOR.
*
* @param allocator Pointer to allocator, or NULL to use the default allocator
* @param[out] out_iterator On success, receives the created iterator handle
* @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_MEMORY on allocation
* failure
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_iterator_new(
const GhosttyAllocator* allocator,
GhosttyKittyGraphicsPlacementIterator* out_iterator);
/**
* Free a placement iterator.
*
* @param iterator The iterator handle to free (may be NULL)
*
* @ingroup kitty_graphics
*/
GHOSTTY_API void ghostty_kitty_graphics_placement_iterator_free(
GhosttyKittyGraphicsPlacementIterator iterator);
/**
* Set an option on a placement iterator.
*
* Use GHOSTTY_KITTY_GRAPHICS_PLACEMENT_ITERATOR_OPTION_LAYER with a
* GhosttyKittyPlacementLayer value to filter placements by z-layer.
* The filter is applied during iteration: ghostty_kitty_graphics_placement_next()
* will skip placements that do not match the configured layer.
*
* The default layer is GHOSTTY_KITTY_PLACEMENT_LAYER_ALL (no filtering).
*
* @param iterator The iterator handle (NULL returns GHOSTTY_INVALID_VALUE)
* @param option The option to set
* @param value Pointer to the value (type depends on option; NULL returns
* GHOSTTY_INVALID_VALUE)
* @return GHOSTTY_SUCCESS on success
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_iterator_set(
GhosttyKittyGraphicsPlacementIterator iterator,
GhosttyKittyGraphicsPlacementIteratorOption option,
const void* value);
/**
* Advance the placement iterator to the next placement.
*
* If a layer filter has been set via
* ghostty_kitty_graphics_placement_iterator_set(), only placements
* matching that layer are returned.
*
* @param iterator The iterator handle (may be NULL)
* @return true if advanced to the next placement, false if at the end
*
* @ingroup kitty_graphics
*/
GHOSTTY_API bool ghostty_kitty_graphics_placement_next(
GhosttyKittyGraphicsPlacementIterator iterator);
/**
* Get data from the current placement in a placement iterator.
*
* Call ghostty_kitty_graphics_placement_next() at least once before
* calling this function.
*
* @param iterator The iterator handle (NULL returns GHOSTTY_INVALID_VALUE)
* @param data The data kind to query
* @param[out] out Pointer to receive the queried value
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the
* iterator is NULL or not positioned on a placement
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_get(
GhosttyKittyGraphicsPlacementIterator iterator,
GhosttyKittyGraphicsPlacementData data,
void* out);
/**
* Get multiple data fields from the current placement in a single call.
*
* This is an optimization over calling ghostty_kitty_graphics_placement_get()
* repeatedly, particularly useful in environments with high per-call
* overhead such as FFI or Cgo.
*
* Each element in the keys array specifies a data kind, and the
* corresponding element in the values array receives the result.
* The type of each values[i] pointer must match the output type
* documented for keys[i].
*
* Processing stops at the first error; on success out_written
* is set to count, on error it is set to the index of the
* failing key (i.e. the number of values successfully written).
*
* @param iterator The iterator handle (NULL returns GHOSTTY_INVALID_VALUE)
* @param count Number of key/value pairs
* @param keys Array of data kinds to query
* @param values Array of output pointers (types must match each key's
* documented output type)
* @param[out] out_written On return, receives the number of values
* successfully written (may be NULL)
* @return GHOSTTY_SUCCESS if all queries succeed
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_get_multi(
GhosttyKittyGraphicsPlacementIterator iterator,
size_t count,
const GhosttyKittyGraphicsPlacementData* keys,
void** values,
size_t* out_written);
/**
* Compute the grid rectangle occupied by the current placement.
*
* Uses the placement's pin, the image dimensions, and the terminal's
* cell/pixel geometry to calculate the bounding rectangle. Virtual
* placements (unicode placeholders) return GHOSTTY_NO_VALUE.
*
* @param terminal The terminal handle
* @param image The image handle for this placement's image
* @param iterator The placement iterator positioned on a placement
* @param[out] out_selection On success, receives the bounding rectangle
* as a selection with rectangle=true
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if any handle
* is NULL or the iterator is not positioned, GHOSTTY_NO_VALUE for
* virtual placements or when Kitty graphics are disabled
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_rect(
GhosttyKittyGraphicsPlacementIterator iterator,
GhosttyKittyGraphicsImage image,
GhosttyTerminal terminal,
GhosttySelection* out_selection);
/**
* Compute the rendered pixel size of the current placement.
*
* Takes into account the placement's source rectangle, specified
* columns/rows, and aspect ratio to calculate the final rendered
* pixel dimensions.
*
* @param iterator The placement iterator positioned on a placement
* @param image The image handle for this placement's image
* @param terminal The terminal handle
* @param[out] out_width On success, receives the width in pixels
* @param[out] out_height On success, receives the height in pixels
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if any handle
* is NULL or the iterator is not positioned, GHOSTTY_NO_VALUE when
* Kitty graphics are disabled
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_pixel_size(
GhosttyKittyGraphicsPlacementIterator iterator,
GhosttyKittyGraphicsImage image,
GhosttyTerminal terminal,
uint32_t* out_width,
uint32_t* out_height);
/**
* Compute the grid cell size of the current placement.
*
* Returns the number of columns and rows that the placement occupies
* in the terminal grid. If the placement specifies explicit columns
* and rows, those are returned directly; otherwise they are calculated
* from the pixel size and cell dimensions.
*
* @param iterator The placement iterator positioned on a placement
* @param image The image handle for this placement's image
* @param terminal The terminal handle
* @param[out] out_cols On success, receives the number of columns
* @param[out] out_rows On success, receives the number of rows
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if any handle
* is NULL or the iterator is not positioned, GHOSTTY_NO_VALUE when
* Kitty graphics are disabled
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_grid_size(
GhosttyKittyGraphicsPlacementIterator iterator,
GhosttyKittyGraphicsImage image,
GhosttyTerminal terminal,
uint32_t* out_cols,
uint32_t* out_rows);
/**
* Get the viewport-relative grid position of the current placement.
*
* Converts the placement's internal pin to viewport-relative column and
* row coordinates. The returned coordinates represent the top-left
* corner of the placement in the viewport's grid coordinate space.
*
* The row value can be negative when the placement's origin has
* scrolled above the top of the viewport. For example, a 4-row
* image that has scrolled up by 2 rows returns row=-2, meaning
* its top 2 rows are above the visible area but its bottom 2 rows
* are still on screen. Embedders should use these coordinates
* directly when computing the destination rectangle for rendering;
* the embedder is responsible for clipping the portion of the image
* that falls outside the viewport.
*
* Returns GHOSTTY_SUCCESS for any placement that is at least
* partially visible in the viewport. Returns GHOSTTY_NO_VALUE when
* the placement is completely outside the viewport (its bottom edge
* is above the viewport or its top edge is at or below the last
* viewport row), or when the placement is a virtual (unicode
* placeholder) placement.
*
* @param iterator The placement iterator positioned on a placement
* @param image The image handle for this placement's image
* @param terminal The terminal handle
* @param[out] out_col On success, receives the viewport-relative column
* @param[out] out_row On success, receives the viewport-relative row
* (may be negative for partially visible placements)
* @return GHOSTTY_SUCCESS on success, GHOSTTY_NO_VALUE if fully
* off-screen or virtual, GHOSTTY_INVALID_VALUE if any handle
* is NULL or the iterator is not positioned
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_viewport_pos(
GhosttyKittyGraphicsPlacementIterator iterator,
GhosttyKittyGraphicsImage image,
GhosttyTerminal terminal,
int32_t* out_col,
int32_t* out_row);
/**
* Get the resolved source rectangle for the current placement.
*
* Applies kitty protocol semantics: a width or height of 0 in the
* placement means "use the full image dimension", and the resulting
* rectangle is clamped to the actual image bounds. The returned
* values are in pixels and are ready to use for texture sampling.
*
* @param iterator The placement iterator positioned on a placement
* @param image The image handle for this placement's image
* @param[out] out_x Source rect x origin in pixels
* @param[out] out_y Source rect y origin in pixels
* @param[out] out_width Source rect width in pixels
* @param[out] out_height Source rect height in pixels
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if any
* handle is NULL or the iterator is not positioned
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_source_rect(
GhosttyKittyGraphicsPlacementIterator iterator,
GhosttyKittyGraphicsImage image,
uint32_t* out_x,
uint32_t* out_y,
uint32_t* out_width,
uint32_t* out_height);
/**
* Get all rendering geometry for a placement in a single call.
*
* Combines pixel size, grid size, viewport position, and source
* rectangle into one struct. Initialize with
* GHOSTTY_INIT_SIZED(GhosttyKittyGraphicsPlacementRenderInfo).
*
* When viewport_visible is false, the placement is fully off-screen
* or is a virtual placement; viewport_col and viewport_row may
* contain meaningless values in that case.
*
* @param iterator The iterator positioned on a placement
* @param image The image handle for this placement's image
* @param terminal The terminal handle
* @param[out] out_info Pointer to receive the rendering geometry
* @return GHOSTTY_SUCCESS on success
*
* @ingroup kitty_graphics
*/
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_render_info(
GhosttyKittyGraphicsPlacementIterator iterator,
GhosttyKittyGraphicsImage image,
GhosttyTerminal terminal,
GhosttyKittyGraphicsPlacementRenderInfo* out_info);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* GHOSTTY_VT_KITTY_GRAPHICS_H */
|