diff --git a/docs/graphics-protocol.rst b/docs/graphics-protocol.rst index 5eab18b43..1df498edb 100644 --- a/docs/graphics-protocol.rst +++ b/docs/graphics-protocol.rst @@ -507,7 +507,8 @@ Key Value Default Description ``a`` Single character. ``t`` The overall action this graphics command is performing. ``(t, T, q, p, d)`` ``t`` - transmit data, ``T`` - transmit data and display image, ``q`` - query terminal, ``p`` - put (display) previous transmitted image, - ``d`` - delete image + ``d`` - delete image, ``f`` - transmit data for animation frames, + ``a`` - start/stop an animation ``q`` ``0, 1, 2`` ``0`` Suppress responses from the terminal to this graphics command. @@ -535,7 +536,7 @@ Key Value Default Description ----------------------------------------------------------- ``x`` Positive integer ``0`` The left edge (in pixels) of the image area to display ``y`` Positive integer ``0`` The top edge (in pixels) of the image area to display -``w`` Positive integer ``0`` The width (in pixels) of the image area to display. By default, the entire width is used. +``w`` Positive integer ``0`` The width (in pixels) of the image area to display. By default, the entire width is used ``h`` Positive integer ``0`` The height (in pixels) of the image area to display. By default, the entire height is used ``X`` Positive integer ``0`` The x-offset within the first cell at which to start displaying the image ``Y`` Positive integer ``0`` The y-offset within the first cell at which to start displaying the image @@ -543,6 +544,18 @@ Key Value Default Description ``r`` Positive integer ``0`` The number of rows to display the image over ``z`` 32-bit integer ``0`` The *z-index* vertical stacking order of the image +**Keys for animation** +----------------------------------------------------------- +``x`` Positive integer ``0`` The left edge (in pixels) of where the frame data should be updated +``y`` Positive integer ``0`` The top edge (in pixels) of where the frame data should be updated +``w`` Positive integer ``0`` The width (in pixels) of the frame area to update. By default, the entire width is used +``h`` Positive integer ``0`` The height (in pixels) of the frame area to update. By default, the entire height is used +``c`` Positive integer ``0`` The frame number of the frame whose image data serves as the base data + when creating a new frame, by default the base data is black transparent pixels +``r`` Positive integer ``0`` The frame number of the frame that is being edited. By default, a new frame is created +``z`` 32-bit integer ``0`` The gap (in milliseconds) of this frame from the previous one. This value is added to + a default of ``40ms``. Negative values are subtracted, with a minimum gap of ``0``. + **Keys for deleting images** ----------------------------------------------------------- ``d`` Single character. ``a`` What to delete. diff --git a/kitty/graphics.c b/kitty/graphics.c index cb077fccb..7f1fa7604 100644 --- a/kitty/graphics.c +++ b/kitty/graphics.c @@ -957,12 +957,30 @@ grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint if (self->used_storage > STORAGE_LIMIT) apply_storage_quota(self, STORAGE_LIMIT, added_image_id); break; } - case 'f': + case 'f': { if (!g->id && !g->image_number) { REPORT_ERROR("Add frame data command without image id or number"); break; } + Image *img = g->id ? img_by_client_id(self, g->id) : img_by_client_number(self, g->image_number); + if (!img) { + set_command_failed_response("ENOENT", "Animation command refers to non-existent image with id: %u and number: %u", g->id, g->image_number); + ret = finish_command_response(g, false, g->id, 0, g->image_number); + break; + } + if (g->payload_sz) { + } else { + const uint32_t frame_number = g->num_lines; + if (frame_number) { + const uint32_t gap = 40 + MAX(-40, g->z_index); + if (frame_number == 1) { img->loop_delay = gap; } + else if (frame_number - 2 < img->extra_framecnt) img->extra_frames[frame_number - 2].gap = gap; + else set_command_failed_response("ENOENT", "Animation command refers to non-existent frame number: %u in image id: %u", frame_number, img->client_id); + } else set_command_failed_response("EINVAL", "Animation command on img: %u has no actions", img->client_id); + ret = finish_command_response(g, true, g->id, 0, g->image_number); + } break; + } case 'p': if (!g->id && !g->image_number) { REPORT_ERROR("Put graphics command without image id or number"); diff --git a/kitty/graphics.h b/kitty/graphics.h index 364317f9e..30418291b 100644 --- a/kitty/graphics.h +++ b/kitty/graphics.h @@ -57,6 +57,7 @@ typedef struct { ImageRef *refs; Frame *extra_frames; + uint32_t loop_delay; size_t refcnt, refcap, extra_framecnt; monotonic_t atime; size_t used_storage;