mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-09-21 11:39:57 +03:00
Graphics protocol: Add support for giving individual image placements their
Fixes #3133
This commit is contained in:
parent
0173959e64
commit
b5e704a934
@ -13,6 +13,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
- Add a new mappable `select_tab` action to choose a tab to switch to even
|
||||
when the tab bar is hidden (:iss:`3115`)
|
||||
|
||||
- Graphics protocol: Add support for giving individual image placements their
|
||||
own ids. This is a backwards compatible protocol extension. (:iss:`3133`)
|
||||
|
||||
- Distribute extra pixels among all eight-blocks rather than adding them
|
||||
all to the last block (:iss:`3097`)
|
||||
|
||||
|
@ -344,6 +344,25 @@ scheme described above for querying available transmission media, except that
|
||||
here we are querying if the image with the specified id is available or needs to
|
||||
be re-transmitted.
|
||||
|
||||
Since there can be many placements per image, you can also give placements an
|
||||
id. To do so add the ``p`` key with a number between ``1`` and ``4294967295``.
|
||||
When you specify a placement id, it will be added to the acknowledgement code
|
||||
above. Every placement is uniquely identified by the pair of the ``image id``
|
||||
and the ``placement id``. If you specify a placement id for an image that does
|
||||
not have an id, it will be ignored. An example response::
|
||||
|
||||
<ESC>_Gi=<image id>,p=<placement id>;OK<ESC>\
|
||||
|
||||
If you send two placements with the same ``image id`` and ``placement id`` the
|
||||
second one will replace the first. This can be used to resize or move
|
||||
placements around the screen, without flicker.
|
||||
|
||||
|
||||
.. note:: Support for specifying placement ids was added to kitty in
|
||||
versions after 0.19.2. You can use the protocol documented in the
|
||||
:doc:`kittens/query_terminal` to query kitty version.
|
||||
|
||||
|
||||
Controlling displayed image layout
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -386,24 +405,30 @@ scrollback buffer. The values of the ``x`` and ``y`` keys are the same as cursor
|
||||
================= ============
|
||||
Value of ``d`` Meaning
|
||||
================= ============
|
||||
``a`` or ``A`` Delete all images visible on screen
|
||||
``i`` or ``I`` Delete all images with the specified id, specified using the ``i`` key.
|
||||
``c`` or ``C`` Delete all images that intersect with the current cursor position.
|
||||
``p`` or ``P`` Delete all images that intersect a specific cell, the cell is specified using the ``x`` and ``y`` keys
|
||||
``q`` or ``Q`` Delete all images that intersect a specific cell having a specific z-index. The cell and z-index is specified using the ``x``, ``y`` and ``z`` keys.
|
||||
``x`` or ``X`` Delete all images that intersect the specified column, specified using the ``x`` key.
|
||||
``y`` or ``Y`` Delete all images that intersect the specified row, specified using the ``y`` key.
|
||||
``z`` or ``Z`` Delete all images that have the specified z-index, specified using the ``z`` key.
|
||||
``a`` or ``A`` Delete all placements visible on screen
|
||||
``i`` or ``I`` Delete all images with the specified id, specified using the ``i`` key. If you specify a ``p`` key for the placement id as well, then only the placement with the specified image id and placement id will be deleted.
|
||||
placement id
|
||||
``c`` or ``C`` Delete all placements that intersect with the current cursor position.
|
||||
``p`` or ``P`` Delete all placements that intersect a specific cell, the cell is specified using the ``x`` and ``y`` keys
|
||||
``q`` or ``Q`` Delete all placements that intersect a specific cell having a specific z-index. The cell and z-index is specified using the ``x``, ``y`` and ``z`` keys.
|
||||
``x`` or ``X`` Delete all placements that intersect the specified column, specified using the ``x`` key.
|
||||
``y`` or ``Y`` Delete all placements that intersect the specified row, specified using the ``y`` key.
|
||||
``z`` or ``Z`` Delete all placements that have the specified z-index, specified using the ``z`` key.
|
||||
================= ============
|
||||
|
||||
|
||||
Note when all placements for an image have been deleted, the image is also
|
||||
deleted, if the capital letter form above is specified. Also, when the terminal
|
||||
is running out of quota space for image, images without placements will be
|
||||
preferentially deleted.
|
||||
|
||||
Some examples::
|
||||
|
||||
<ESC>_Ga=d<ESC>\ # delete all visible images
|
||||
<ESC>_Ga=d,d=i,i=10<ESC>\ # delete the image with id=10, without freeing data
|
||||
<ESC>_Ga=d,d=Z,z=-1<ESC>\ # delete the images with z-index -1, also freeing up image data
|
||||
<ESC>_Ga=d,d=p,x=3,y=4<ESC>\ # delete all images that intersect the cell at (3, 4), without freeing data
|
||||
<ESC>_Ga=d<ESC>\ # delete all visible placements
|
||||
<ESC>_Ga=d,d=i,i=10<ESC>\ # delete the image with id=10, without freeing data
|
||||
<ESC>_Ga=d,d=i,i=10,p=7<ESC>\ # delete the image with id=10 and placement id=7, without freeing data
|
||||
<ESC>_Ga=d,d=Z,z=-1<ESC>\ # delete the placements with z-index -1, also freeing up image data
|
||||
<ESC>_Ga=d,d=p,x=3,y=4<ESC>\ # delete all placements that intersect the cell at (3, 4), without freeing data
|
||||
|
||||
Image persistence and storage quotas
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -438,6 +463,8 @@ Key Value Default Description
|
||||
``O`` Positive integer. ``0`` The offset from which to read data from a file.
|
||||
``i`` Positive integer.
|
||||
``(0 - 4294967295)`` ``0`` The image id
|
||||
``p`` Positive integer.
|
||||
``(0 - 4294967295)`` ``0`` The placement id
|
||||
``o`` Single character. ``null`` The type of data compression.
|
||||
``only z``
|
||||
``m`` zero or one ``0`` Whether there is more chunked data available.
|
||||
|
@ -257,6 +257,7 @@ def graphics_parser() -> None:
|
||||
'f': ('format', 'uint'),
|
||||
'm': ('more', 'uint'),
|
||||
'i': ('id', 'uint'),
|
||||
'p': ('placement_id', 'uint'),
|
||||
'w': ('width', 'uint'),
|
||||
'h': ('height', 'uint'),
|
||||
'x': ('x_offset', 'uint'),
|
||||
|
@ -475,14 +475,15 @@ handle_add_command(GraphicsManager *self, const GraphicsCommand *g, const uint8_
|
||||
}
|
||||
|
||||
static inline const char*
|
||||
create_add_response(GraphicsManager UNUSED *self, bool data_loaded, uint32_t iid) {
|
||||
static char rbuf[sizeof(add_response)/sizeof(add_response[0]) + 64];
|
||||
create_add_response(GraphicsManager UNUSED *self, bool data_loaded, uint32_t iid, uint32_t placement_id) {
|
||||
static char rbuf[sizeof(add_response)/sizeof(add_response[0]) + 128];
|
||||
if (iid) {
|
||||
if (!has_add_respose) {
|
||||
if (!data_loaded) return NULL;
|
||||
snprintf(add_response, 10, "OK");
|
||||
}
|
||||
snprintf(rbuf, sizeof(rbuf)/sizeof(rbuf[0]) - 1, "Gi=%u;%s", iid, add_response);
|
||||
if (placement_id) snprintf(rbuf, sizeof(rbuf)/sizeof(rbuf[0]) - 1, "Gi=%u,p=%u;%s", iid, placement_id, add_response);
|
||||
else snprintf(rbuf, sizeof(rbuf)/sizeof(rbuf[0]) - 1, "Gi=%u;%s", iid, add_response);
|
||||
return rbuf;
|
||||
}
|
||||
return NULL;
|
||||
@ -529,10 +530,12 @@ handle_put_command(GraphicsManager *self, const GraphicsCommand *g, Cursor *c, b
|
||||
*is_dirty = true;
|
||||
self->layers_dirty = true;
|
||||
ImageRef *ref = NULL;
|
||||
for (size_t i=0; i < img->refcnt; i++) {
|
||||
if ((unsigned)img->refs[i].start_row == c->x && (unsigned)img->refs[i].start_column == c->y) {
|
||||
ref = img->refs + i;
|
||||
break;
|
||||
if (g->placement_id && img->client_id) {
|
||||
for (size_t i=0; i < img->refcnt; i++) {
|
||||
if (img->refs[i].client_id == g->placement_id) {
|
||||
ref = img->refs + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ref == NULL) {
|
||||
@ -548,6 +551,7 @@ handle_put_command(GraphicsManager *self, const GraphicsCommand *g, Cursor *c, b
|
||||
ref->cell_x_offset = MIN(g->cell_x_offset, cell.width - 1);
|
||||
ref->cell_y_offset = MIN(g->cell_y_offset, cell.height - 1);
|
||||
ref->num_cols = g->num_cells; ref->num_rows = g->num_lines;
|
||||
if (img->client_id) ref->client_id = g->placement_id;
|
||||
update_src_rect(ref, img);
|
||||
update_dest_rect(ref, g->num_cells, g->num_lines, cell);
|
||||
// Move the cursor, the screen will take care of ensuring it is in bounds
|
||||
@ -743,9 +747,10 @@ grman_clear(GraphicsManager *self, bool all, CellPixelSize cell) {
|
||||
}
|
||||
|
||||
static inline bool
|
||||
id_filter_func(const ImageRef UNUSED *ref, Image *img, const void *data, CellPixelSize cell UNUSED) {
|
||||
uint32_t iid = *(uint32_t*)data;
|
||||
return img->client_id == iid;
|
||||
id_filter_func(const ImageRef *ref, Image *img, const void *data, CellPixelSize cell UNUSED) {
|
||||
const GraphicsCommand *g = data;
|
||||
if (img->client_id == g->id) return !g->placement_id || ref->client_id == g->placement_id;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
@ -787,7 +792,7 @@ handle_delete_command(GraphicsManager *self, const GraphicsCommand *g, Cursor *c
|
||||
#define G(l, u, func) D(l, u, g, func)
|
||||
case 0:
|
||||
D('a', 'A', NULL, clear_filter_func);
|
||||
D('i', 'I', &g->id, id_filter_func);
|
||||
G('i', 'I', id_filter_func);
|
||||
G('p', 'P', point_filter_func);
|
||||
G('q', 'Q', point3d_filter_func);
|
||||
G('x', 'X', x_filter_func);
|
||||
@ -839,9 +844,11 @@ grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint
|
||||
case 'T':
|
||||
case 'q': {
|
||||
uint32_t iid = g->id, q_iid = iid;
|
||||
if (g->action == 'q') { iid = 0; if (!q_iid) { REPORT_ERROR("Query graphics command without image id"); break; } }
|
||||
bool is_query = g->action == 'q';
|
||||
if (is_query) { iid = 0; if (!q_iid) { REPORT_ERROR("Query graphics command without image id"); break; } }
|
||||
Image *image = handle_add_command(self, g, payload, is_dirty, iid);
|
||||
ret = create_add_response(self, image != NULL, g->action == 'q' ? q_iid: self->last_init_graphics_command.id);
|
||||
if (is_query) ret = create_add_response(self, image != NULL, q_iid, 0);
|
||||
else ret = create_add_response(self, image != NULL, self->last_init_graphics_command.id, self->last_init_graphics_command.placement_id);
|
||||
if (self->last_init_graphics_command.action == 'T' && image && image->data_loaded) handle_put_command(self, &self->last_init_graphics_command, c, is_dirty, image, cell);
|
||||
id_type added_image_id = image ? image->internal_id : 0;
|
||||
if (g->action == 'q') remove_images(self, add_trim_predicate, 0);
|
||||
@ -854,7 +861,7 @@ grman_handle_command(GraphicsManager *self, const GraphicsCommand *g, const uint
|
||||
break;
|
||||
}
|
||||
handle_put_command(self, g, c, is_dirty, NULL, cell);
|
||||
ret = create_add_response(self, true, g->id);
|
||||
ret = create_add_response(self, true, g->id, g->placement_id);
|
||||
break;
|
||||
case 'd':
|
||||
handle_delete_command(self, g, c, is_dirty, cell);
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
typedef struct {
|
||||
unsigned char action, transmission_type, compressed, delete_action;
|
||||
uint32_t format, more, id, data_sz, data_offset;
|
||||
uint32_t format, more, id, data_sz, data_offset, placement_id;
|
||||
uint32_t width, height, x_offset, y_offset, data_height, data_width, num_cells, num_lines, cell_x_offset, cell_y_offset;
|
||||
int32_t z_index;
|
||||
size_t payload_sz;
|
||||
@ -38,6 +38,7 @@ typedef struct {
|
||||
uint32_t cell_x_offset, cell_y_offset, num_cols, num_rows, effective_num_rows, effective_num_cols;
|
||||
int32_t z_index;
|
||||
int32_t start_row, start_column;
|
||||
uint32_t client_id;
|
||||
ImageRect src_rect;
|
||||
} ImageRef;
|
||||
|
||||
|
49
kitty/parse-graphics-command.h
generated
49
kitty/parse-graphics-command.h
generated
@ -23,6 +23,7 @@ static inline void parse_graphics_code(Screen *screen,
|
||||
format = 'f',
|
||||
more = 'm',
|
||||
id = 'i',
|
||||
placement_id = 'p',
|
||||
width = 'w',
|
||||
height = 'h',
|
||||
x_offset = 'x',
|
||||
@ -69,6 +70,9 @@ static inline void parse_graphics_code(Screen *screen,
|
||||
case id:
|
||||
value_state = UINT;
|
||||
break;
|
||||
case placement_id:
|
||||
value_state = UINT;
|
||||
break;
|
||||
case width:
|
||||
value_state = UINT;
|
||||
break;
|
||||
@ -131,8 +135,8 @@ static inline void parse_graphics_code(Screen *screen,
|
||||
|
||||
case action: {
|
||||
g.action = screen->parser_buf[pos++] & 0xff;
|
||||
if (g.action != 't' && g.action != 'd' && g.action != 'p' &&
|
||||
g.action != 'q' && g.action != 'T') {
|
||||
if (g.action != 'p' && g.action != 'q' && g.action != 't' &&
|
||||
g.action != 'T' && g.action != 'd') {
|
||||
REPORT_ERROR("Malformed GraphicsCommand control block, unknown flag "
|
||||
"value for action: 0x%x",
|
||||
g.action);
|
||||
@ -142,14 +146,14 @@ static inline void parse_graphics_code(Screen *screen,
|
||||
|
||||
case delete_action: {
|
||||
g.delete_action = screen->parser_buf[pos++] & 0xff;
|
||||
if (g.delete_action != 'X' && g.delete_action != 'y' &&
|
||||
if (g.delete_action != 'p' && g.delete_action != 'q' &&
|
||||
g.delete_action != 'Z' && g.delete_action != 'x' &&
|
||||
g.delete_action != 'Q' && g.delete_action != 'C' &&
|
||||
g.delete_action != 'y' && g.delete_action != 'Y' &&
|
||||
g.delete_action != 'i' && g.delete_action != 'I' &&
|
||||
g.delete_action != 'A' && g.delete_action != 'p' &&
|
||||
g.delete_action != 'Y' && g.delete_action != 'z' &&
|
||||
g.delete_action != 'a' && g.delete_action != 'P' &&
|
||||
g.delete_action != 'x' && g.delete_action != 'q' &&
|
||||
g.delete_action != 'Z' && g.delete_action != 'Q' &&
|
||||
g.delete_action != 'c' && g.delete_action != 'C') {
|
||||
g.delete_action != 'a' && g.delete_action != 'z' &&
|
||||
g.delete_action != 'A' && g.delete_action != 'X' &&
|
||||
g.delete_action != 'P' && g.delete_action != 'c') {
|
||||
REPORT_ERROR("Malformed GraphicsCommand control block, unknown flag "
|
||||
"value for delete_action: 0x%x",
|
||||
g.delete_action);
|
||||
@ -159,8 +163,8 @@ static inline void parse_graphics_code(Screen *screen,
|
||||
|
||||
case transmission_type: {
|
||||
g.transmission_type = screen->parser_buf[pos++] & 0xff;
|
||||
if (g.transmission_type != 'f' && g.transmission_type != 'd' &&
|
||||
g.transmission_type != 's' && g.transmission_type != 't') {
|
||||
if (g.transmission_type != 'd' && g.transmission_type != 'f' &&
|
||||
g.transmission_type != 't' && g.transmission_type != 's') {
|
||||
REPORT_ERROR("Malformed GraphicsCommand control block, unknown flag "
|
||||
"value for transmission_type: 0x%x",
|
||||
g.transmission_type);
|
||||
@ -233,6 +237,7 @@ static inline void parse_graphics_code(Screen *screen,
|
||||
U(format);
|
||||
U(more);
|
||||
U(id);
|
||||
U(placement_id);
|
||||
U(width);
|
||||
U(height);
|
||||
U(x_offset);
|
||||
@ -303,19 +308,21 @@ static inline void parse_graphics_code(Screen *screen,
|
||||
}
|
||||
|
||||
REPORT_VA_COMMAND(
|
||||
"s {sc sc sc sc sI sI sI sI sI sI sI sI sI sI sI sI sI sI sI si sI} y#",
|
||||
"s {sc sc sc sc sI sI sI sI sI sI sI sI sI sI sI sI sI sI sI sI si sI} "
|
||||
"y#",
|
||||
"graphics_command", "action", g.action, "delete_action", g.delete_action,
|
||||
"transmission_type", g.transmission_type, "compressed", g.compressed,
|
||||
"format", (unsigned int)g.format, "more", (unsigned int)g.more, "id",
|
||||
(unsigned int)g.id, "width", (unsigned int)g.width, "height",
|
||||
(unsigned int)g.height, "x_offset", (unsigned int)g.x_offset, "y_offset",
|
||||
(unsigned int)g.y_offset, "data_height", (unsigned int)g.data_height,
|
||||
"data_width", (unsigned int)g.data_width, "data_sz",
|
||||
(unsigned int)g.data_sz, "data_offset", (unsigned int)g.data_offset,
|
||||
"num_cells", (unsigned int)g.num_cells, "num_lines",
|
||||
(unsigned int)g.num_lines, "cell_x_offset", (unsigned int)g.cell_x_offset,
|
||||
"cell_y_offset", (unsigned int)g.cell_y_offset, "z_index", (int)g.z_index,
|
||||
"payload_sz", g.payload_sz, payload, g.payload_sz);
|
||||
(unsigned int)g.id, "placement_id", (unsigned int)g.placement_id, "width",
|
||||
(unsigned int)g.width, "height", (unsigned int)g.height, "x_offset",
|
||||
(unsigned int)g.x_offset, "y_offset", (unsigned int)g.y_offset,
|
||||
"data_height", (unsigned int)g.data_height, "data_width",
|
||||
(unsigned int)g.data_width, "data_sz", (unsigned int)g.data_sz,
|
||||
"data_offset", (unsigned int)g.data_offset, "num_cells",
|
||||
(unsigned int)g.num_cells, "num_lines", (unsigned int)g.num_lines,
|
||||
"cell_x_offset", (unsigned int)g.cell_x_offset, "cell_y_offset",
|
||||
(unsigned int)g.cell_y_offset, "z_index", (int)g.z_index, "payload_sz",
|
||||
g.payload_sz, payload, g.payload_sz);
|
||||
|
||||
screen_handle_graphics_command(screen, &g, payload);
|
||||
}
|
||||
|
@ -48,6 +48,15 @@ def parse_response(res):
|
||||
return res.decode('ascii').partition(';')[2].partition('\033')[0]
|
||||
|
||||
|
||||
def parse_response_with_ids(res):
|
||||
if not res:
|
||||
return
|
||||
a, b = res.decode('ascii').split(';', 1)
|
||||
code = b.partition('\033')[0].split(':', 1)[0]
|
||||
a = a.split('G', 1)[1]
|
||||
return code, a
|
||||
|
||||
|
||||
all_bytes = bytes(bytearray(range(256)))
|
||||
|
||||
|
||||
@ -90,8 +99,9 @@ def create_screen():
|
||||
s = self.create_screen(10, 5, cell_width=cw, cell_height=ch)
|
||||
return s, 2 / s.columns, 2 / s.lines
|
||||
|
||||
def put_cmd(z=0, num_cols=0, num_lines=0, x_off=0, y_off=0, width=0, height=0, cell_x_off=0, cell_y_off=0):
|
||||
return 'z=%d,c=%d,r=%d,x=%d,y=%d,w=%d,h=%d,X=%d,Y=%d' % (z, num_cols, num_lines, x_off, y_off, width, height, cell_x_off, cell_y_off)
|
||||
def put_cmd(z=0, num_cols=0, num_lines=0, x_off=0, y_off=0, width=0, height=0, cell_x_off=0, cell_y_off=0, placement_id=0):
|
||||
return 'z=%d,c=%d,r=%d,x=%d,y=%d,w=%d,h=%d,X=%d,Y=%d,p=%d' % (
|
||||
z, num_cols, num_lines, x_off, y_off, width, height, cell_x_off, cell_y_off, placement_id)
|
||||
|
||||
def put_image(screen, w, h, **kw):
|
||||
nonlocal iid
|
||||
@ -103,7 +113,7 @@ def put_image(screen, w, h, **kw):
|
||||
|
||||
def put_ref(screen, **kw):
|
||||
cmd = 'a=p,i=%d,%s' % (iid, put_cmd(**kw))
|
||||
send_command(screen, cmd)
|
||||
return iid, parse_response_with_ids(send_command(screen, cmd))
|
||||
|
||||
def layers(screen, scrolled_by=0, xstart=-1, ystart=1):
|
||||
return screen.grman.update_layers(scrolled_by, xstart, ystart, dx, dy, screen.columns, screen.lines, cw, ch)
|
||||
@ -226,7 +236,8 @@ def test_image_put(self):
|
||||
rect_eq(l0[0]['dest_rect'], -1, 1, -1 + dx, 1 - dy)
|
||||
self.ae(l0[0]['group_count'], 1)
|
||||
self.ae(s.cursor.x, 1), self.ae(s.cursor.y, 0)
|
||||
put_ref(s, num_cols=s.columns, x_off=2, y_off=1, width=3, height=5, cell_x_off=3, cell_y_off=1, z=-1)
|
||||
iid, (code, idstr) = put_ref(s, num_cols=s.columns, x_off=2, y_off=1, width=3, height=5, cell_x_off=3, cell_y_off=1, z=-1, placement_id=17)
|
||||
self.ae(idstr, f'i={iid},p=17')
|
||||
l2 = layers(s)
|
||||
self.ae(len(l2), 2)
|
||||
rect_eq(l2[0]['src_rect'], 2 / 10, 1 / 20, (2 + 3) / 10, (1 + 5)/20)
|
||||
@ -320,8 +331,13 @@ def delete(ac=None, **kw):
|
||||
delete('A')
|
||||
self.ae(s.grman.image_count, 0)
|
||||
iid = put_image(s, cw, ch)[0]
|
||||
delete('I', i=iid, p=7)
|
||||
self.ae(s.grman.image_count, 1)
|
||||
delete('I', i=iid)
|
||||
self.ae(s.grman.image_count, 0)
|
||||
iid = put_image(s, cw, ch, placement_id=9)[0]
|
||||
delete('I', i=iid, p=9)
|
||||
self.ae(s.grman.image_count, 0)
|
||||
s.reset()
|
||||
put_image(s, cw, ch)
|
||||
put_image(s, cw, ch)
|
||||
|
@ -379,7 +379,7 @@ def c(**k):
|
||||
for f in 'action delete_action transmission_type compressed'.split():
|
||||
k.setdefault(f, b'\0')
|
||||
for f in ('format more id data_sz data_offset width height x_offset y_offset data_height data_width'
|
||||
' num_cells num_lines cell_x_offset cell_y_offset z_index').split():
|
||||
' num_cells num_lines cell_x_offset cell_y_offset z_index placement_id').split():
|
||||
k.setdefault(f, 0)
|
||||
p = k.pop('payload', '').encode('utf-8')
|
||||
k['payload_sz'] = len(p)
|
||||
@ -395,6 +395,7 @@ def e(cmd, err):
|
||||
pb = partial(self.parse_bytes_dump, s)
|
||||
uint32_max = 2**32 - 1
|
||||
t('i=%d' % uint32_max, id=uint32_max)
|
||||
t('i=3,p=4', id=3, placement_id=4)
|
||||
e('i=%d' % (uint32_max + 1), 'Malformed GraphicsCommand control block, number is too large')
|
||||
pb('\033_Gi=12\033\\', c(id=12))
|
||||
t('a=t,t=d,s=100,z=-9', payload='X', action='t', transmission_type='d', data_width=100, z_index=-9, payload_sz=1)
|
||||
|
Loading…
Reference in New Issue
Block a user