mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Create KittyApchandler.ts
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Copyright (c) 2025 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*
|
||||
* Kitty graphics protocol types, constants, and parsing utilities.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Kitty graphics protocol action types.
|
||||
* See: https://sw.kovidgoyal.net/kitty/graphics-protocol/#control-data-reference under key 'a'.
|
||||
*/
|
||||
export const enum KittyAction {
|
||||
TRANSMIT = 't',
|
||||
TRANSMIT_DISPLAY = 'T',
|
||||
QUERY = 'q',
|
||||
PLACEMENT = 'p',
|
||||
DELETE = 'd'
|
||||
}
|
||||
|
||||
/**
|
||||
* Kitty graphics protocol format types.
|
||||
* See: https://sw.kovidgoyal.net/kitty/graphics-protocol/#control-data-reference
|
||||
*/
|
||||
export const enum KittyFormat {
|
||||
RGB = 24,
|
||||
RGBA = 32,
|
||||
PNG = 100
|
||||
}
|
||||
|
||||
/**
|
||||
* Kitty graphics protocol compression types.
|
||||
* See: https://sw.kovidgoyal.net/kitty/graphics-protocol/#control-data-reference under key 'o'.
|
||||
*/
|
||||
export const enum KittyCompression {
|
||||
NONE = '',
|
||||
ZLIB = 'z'
|
||||
}
|
||||
|
||||
/**
|
||||
* Kitty graphics protocol control data keys.
|
||||
* See: https://sw.kovidgoyal.net/kitty/graphics-protocol/#control-data-reference
|
||||
*/
|
||||
export const enum KittyKey {
|
||||
// Action to perform (t=transmit, T=transmit+display, q=query, p=placement, d=delete)
|
||||
ACTION = 'a',
|
||||
// Image format (24=RGB, 32=RGBA, 100=PNG)
|
||||
FORMAT = 'f',
|
||||
// Image ID for referencing stored images
|
||||
ID = 'i',
|
||||
// Source image width in pixels
|
||||
WIDTH = 's',
|
||||
// Source image height in pixels
|
||||
HEIGHT = 'v',
|
||||
// The left edge (in pixels) of the image area to display
|
||||
X_OFFSET = 'x',
|
||||
// The top edge (in pixels) of the image area to display
|
||||
Y_OFFSET = 'y',
|
||||
// Number of terminal columns to display the image over
|
||||
COLUMNS = 'c',
|
||||
// Number of terminal rows to display the image over
|
||||
ROWS = 'r',
|
||||
// More data flag (1=more chunks coming, 0=final chunk)
|
||||
MORE = 'm',
|
||||
// Compression type (z=zlib). This is essential for chunking larger images.
|
||||
COMPRESSION = 'o',
|
||||
// Quiet mode (1=suppress OK responses, 2=suppress error responses)
|
||||
QUIET = 'q'
|
||||
}
|
||||
|
||||
// Pixel format constants
|
||||
export const BYTES_PER_PIXEL_RGB = 3;
|
||||
export const BYTES_PER_PIXEL_RGBA = 4;
|
||||
export const ALPHA_OPAQUE = 255;
|
||||
|
||||
/**
|
||||
* Parsed Kitty graphics command.
|
||||
*/
|
||||
export interface IKittyCommand {
|
||||
action?: string;
|
||||
format?: number;
|
||||
id?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
x?: number;
|
||||
y?: number;
|
||||
columns?: number;
|
||||
rows?: number;
|
||||
more?: number;
|
||||
quiet?: number;
|
||||
compression?: string;
|
||||
payload?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Kitty graphics control data into a command object.
|
||||
*/
|
||||
export function parseKittyCommand(data: string): IKittyCommand {
|
||||
const cmd: IKittyCommand = {};
|
||||
const parts = data.split(',');
|
||||
|
||||
for (const part of parts) {
|
||||
const eqIdx = part.indexOf('=');
|
||||
if (eqIdx === -1) continue;
|
||||
|
||||
const key = part.substring(0, eqIdx);
|
||||
const value = part.substring(eqIdx + 1);
|
||||
|
||||
// Handle string keys first
|
||||
if (key === KittyKey.ACTION) {
|
||||
cmd.action = value;
|
||||
continue;
|
||||
}
|
||||
if (key === KittyKey.COMPRESSION) {
|
||||
cmd.compression = value;
|
||||
continue;
|
||||
}
|
||||
const numValue = parseInt(value);
|
||||
switch (key) {
|
||||
case KittyKey.FORMAT: cmd.format = numValue; break;
|
||||
case KittyKey.ID: cmd.id = numValue; break;
|
||||
case KittyKey.WIDTH: cmd.width = numValue; break;
|
||||
case KittyKey.HEIGHT: cmd.height = numValue; break;
|
||||
case KittyKey.X_OFFSET: cmd.x = numValue; break;
|
||||
case KittyKey.Y_OFFSET: cmd.y = numValue; break;
|
||||
case KittyKey.COLUMNS: cmd.columns = numValue; break;
|
||||
case KittyKey.ROWS: cmd.rows = numValue; break;
|
||||
case KittyKey.MORE: cmd.more = numValue; break;
|
||||
case KittyKey.QUIET: cmd.quiet = numValue; break;
|
||||
}
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
@@ -4,7 +4,8 @@
|
||||
*/
|
||||
import { assert } from 'chai';
|
||||
import { Terminal } from 'browser/public/Terminal';
|
||||
import { KittyGraphicsAddon, parseKittyCommand } from './KittyGraphicsAddon';
|
||||
import { KittyGraphicsAddon } from './KittyGraphicsAddon';
|
||||
import { parseKittyCommand } from './KittyApcHandler';
|
||||
|
||||
/**
|
||||
* Write data to terminal and wait for completion.
|
||||
|
||||
@@ -7,135 +7,16 @@ import type { Terminal, ITerminalAddon, IDisposable } from '@xterm/xterm';
|
||||
import type { KittyGraphicsAddon as IKittyGraphicsApi, IKittyGraphicsOptions, IKittyImage } from '@xterm/addon-kitty-graphics';
|
||||
import { KittyImageRenderer } from './KittyImageRenderer';
|
||||
import type { ITerminalExt } from './Types';
|
||||
|
||||
/**
|
||||
* Kitty graphics protocol action types.
|
||||
* Possible actions from protocol.
|
||||
* See: https://sw.kovidgoyal.net/kitty/graphics-protocol/#control-data-reference under key 'a'.
|
||||
*/
|
||||
const enum KittyAction {
|
||||
TRANSMIT = 't',
|
||||
TRANSMIT_DISPLAY = 'T',
|
||||
QUERY = 'q',
|
||||
PLACEMENT = 'p',
|
||||
DELETE = 'd'
|
||||
}
|
||||
|
||||
/**
|
||||
* Kitty graphics protocol format types.
|
||||
* See: https://sw.kovidgoyal.net/kitty/graphics-protocol/#control-data-reference where the format for *-bit came from.
|
||||
*/
|
||||
const enum KittyFormat {
|
||||
RGB = 24,
|
||||
RGBA = 32,
|
||||
PNG = 100
|
||||
}
|
||||
|
||||
/**
|
||||
* Kitty graphics protocol compression types.
|
||||
* See: https://sw.kovidgoyal.net/kitty/graphics-protocol/#control-data-reference under key 'o'.
|
||||
*/
|
||||
const enum KittyCompression {
|
||||
NONE = '',
|
||||
ZLIB = 'z'
|
||||
}
|
||||
|
||||
/**
|
||||
* Kitty graphics protocol control data keys.
|
||||
* See: https://sw.kovidgoyal.net/kitty/graphics-protocol/#control-data-reference
|
||||
*/
|
||||
const enum KittyKey {
|
||||
// Action to perform (t=transmit, T=transmit+display, q=query, p=placement, d=delete)
|
||||
ACTION = 'a',
|
||||
// Image format (24=RGB, 32=RGBA, 100=PNG)
|
||||
FORMAT = 'f',
|
||||
// Image ID for referencing stored images
|
||||
ID = 'i',
|
||||
// Source image width in pixels
|
||||
WIDTH = 's',
|
||||
// Source image height in pixels
|
||||
HEIGHT = 'v',
|
||||
// The left edge (in pixels) of the image area to display
|
||||
X_OFFSET = 'x',
|
||||
// The top edge (in pixels) of the image area to display
|
||||
Y_OFFSET = 'y',
|
||||
// Number of terminal columns to display the image over
|
||||
COLUMNS = 'c',
|
||||
// Number of terminal rows to display the image over
|
||||
ROWS = 'r',
|
||||
// More data flag (1=more chunks coming, 0=final chunk)
|
||||
MORE = 'm',
|
||||
// Compression type (z=zlib). This is essential for chunking larger images.
|
||||
COMPRESSION = 'o',
|
||||
// Quiet mode (1=suppress OK responses, 2=suppress error responses)
|
||||
QUIET = 'q'
|
||||
}
|
||||
|
||||
// Pixel format constants
|
||||
const BYTES_PER_PIXEL_RGB = 3;
|
||||
const BYTES_PER_PIXEL_RGBA = 4;
|
||||
const ALPHA_OPAQUE = 255;
|
||||
|
||||
/**
|
||||
* Parsed Kitty graphics command.
|
||||
*/
|
||||
export interface IKittyCommand {
|
||||
action?: string;
|
||||
format?: number;
|
||||
id?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
x?: number;
|
||||
y?: number;
|
||||
columns?: number;
|
||||
rows?: number;
|
||||
more?: number;
|
||||
quiet?: number;
|
||||
compression?: string;
|
||||
payload?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Kitty graphics control data into a command object.
|
||||
* Exported for testing.
|
||||
*/
|
||||
export function parseKittyCommand(data: string): IKittyCommand {
|
||||
const cmd: IKittyCommand = {};
|
||||
const parts = data.split(',');
|
||||
|
||||
for (const part of parts) {
|
||||
const eqIdx = part.indexOf('=');
|
||||
if (eqIdx === -1) continue;
|
||||
|
||||
const key = part.substring(0, eqIdx);
|
||||
const value = part.substring(eqIdx + 1);
|
||||
|
||||
// Handle string keys first
|
||||
if (key === KittyKey.ACTION) {
|
||||
cmd.action = value;
|
||||
continue;
|
||||
}
|
||||
if (key === KittyKey.COMPRESSION) {
|
||||
cmd.compression = value;
|
||||
continue;
|
||||
}
|
||||
const numValue = parseInt(value);
|
||||
switch (key) {
|
||||
case KittyKey.FORMAT: cmd.format = numValue; break;
|
||||
case KittyKey.ID: cmd.id = numValue; break;
|
||||
case KittyKey.WIDTH: cmd.width = numValue; break;
|
||||
case KittyKey.HEIGHT: cmd.height = numValue; break;
|
||||
case KittyKey.X_OFFSET: cmd.x = numValue; break;
|
||||
case KittyKey.Y_OFFSET: cmd.y = numValue; break;
|
||||
case KittyKey.COLUMNS: cmd.columns = numValue; break;
|
||||
case KittyKey.ROWS: cmd.rows = numValue; break;
|
||||
case KittyKey.MORE: cmd.more = numValue; break;
|
||||
case KittyKey.QUIET: cmd.quiet = numValue; break;
|
||||
}
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
import {
|
||||
KittyAction,
|
||||
KittyFormat,
|
||||
KittyCompression,
|
||||
BYTES_PER_PIXEL_RGB,
|
||||
BYTES_PER_PIXEL_RGBA,
|
||||
ALPHA_OPAQUE,
|
||||
parseKittyCommand,
|
||||
type IKittyCommand
|
||||
} from './KittyApcHandler';
|
||||
|
||||
/**
|
||||
* Pending chunked transmission state.
|
||||
|
||||
Reference in New Issue
Block a user