Commit graph

41 commits

Author SHA1 Message Date
Craig Barnes
674a535fc3 Rename various uses of "curly" in the source code with "underline"
Since "curly" could make it seem as if all underline styles are curled
(to people unfamiliar with the codebase), whereas in reality only 1 is.
2024-07-01 20:00:16 +01:00
Daniel Eklöf
64e7f25124
dcs: DECRQSS: styled+colored underlines 2024-07-01 16:25:45 +02:00
Daniel Eklöf
4d4ef5eed5
dcs: XTGETTCAP: handle empty request
If the XTGETTCAP request is empty (no capabilities in it), reply with
an empty error reply.

Closes #1694
2024-04-20 08:27:25 +02:00
Daniel Eklöf
9287946b36
dcs: DECRQSS: fix off-by-one when checking for space in the DCS buffer 2024-04-10 05:44:33 +02:00
Daniel Eklöf
7999975016
Don't use fancy Unicode quotes, stick to ASCII 2024-02-06 12:36:45 +01:00
Daniel Eklöf
8a5f2915e9
dcs: xtgettcap: ignore queries with invalid hex encodings
When we receive an XTGETTCAP query, where the capability is not
correctly hex encoded, ignore it.

Before this patch, we echo:ed it back to the TTY inside an error
resonse.
2023-09-25 16:37:32 +02:00
Daniel Eklöf
3555e81fee
sixel: special case parsing of images with an aspect ratio of 1:1
Images with an aspect ratio of 1:1 are by far the most common (though
not the default).

It makes a lot of sense, performance wise, to special case
them.

Specifically, the sixel_add() function benefits greatly from this, as
it is the inner most, most heavily executed function when parsing a
sixel image.

sixel_add_many() also benefits, since allows us to drop a
multiplication. Since sixel_add_many() always called first (no other
call sites call sixel_add() directly), this has a noticeable effect on
performance.

Another thing that helps (though not as much), and not specifically
with AR 1:1 images, is special casing DECGRI a bit.

Up until now, it simply updated the current sixel parameter value. The
problem is that the default parameter value is 0. But, a value of 0
should be treated as 1. By adding a special ‘repeat_count’ variable to
the sixel struct, we can initialize it to ‘1’ when we see DECGRI, and
then simply overwrite it as the parameter value gets updated. This
allows us to drop an if..else when emitting the sixel.
2023-06-29 15:40:00 +02:00
jvoisin
58a1ffe724
config: add tweak option to allow disabling sixels
Closes #950
2022-04-06 19:25:43 +02:00
Daniel Eklöf
de5226c930
dcs: don’t automatically buffer anything
If a request handler doesn’t define its own put() handler, simply drop
all DCS parameter data. This way, we won’t end up allocating
potentially large buffers for unsupported/unimplemented DCS requests.

Closes #959
2022-03-21 20:40:51 +01:00
Daniel Eklöf
67a228bf4b
dcs: xtgettcap: use custom put() handler
Grow buffer exponentially, since XTGETTCAP requests can,
theoretically, be very large.
2022-03-21 20:40:50 +01:00
Daniel Eklöf
af88c19561
dcs: decrqss: use a custom put() handler
Only buffer up to two bytes, as that’s the largest DECRQSS request we
support.
2022-03-21 20:40:50 +01:00
Daniel Eklöf
8f06436985
dcs: map BSU/ESU unhook handlers directly to term_{enable,disable}_app_sync_upates()
That is, drop the local bsu() and esu() functions.
2022-03-21 20:40:50 +01:00
Craig Barnes
cc8e86fd2d dcs: prevent possibility of out-of-bounds reads in decrqss()
This could be triggered by running, for example:

    printf '\033P$qrxyz\033\\'

...which would cause a memcmp() of 4 bytes on a 2 byte string literal.

Fixes: #960
2022-03-02 19:05:51 +00:00
Daniel Eklöf
b292e735bb
dcs: decrqss: refactor: append_sgr_attr_n() is now a proper function 2022-01-14 14:09:28 +01:00
Daniel Eklöf
7243b094b7
dcs: decrqss: add note about Ps in the reply 2022-01-14 13:52:42 +01:00
Daniel Eklöf
a8681ea440
dcs: decrqss: BUG on invalid cursor style 2022-01-14 13:52:42 +01:00
Daniel Eklöf
add530e66d
dcs: implement DECRQSS
This patch adds support for DECRQSS (request Selection or Setting),
for the following sub-queries:

* DECSTBM   Set Top and Bottom Margins
* SGR       Set Graphic Rendition
* DECSCUSR  Set Cursor Style

Closes #798
2022-01-14 13:52:41 +01:00
Daniel Eklöf
5a032c4c6f
xtgettcap: switch from a table based internal structure, to a single char array
Having the builtin terminfo DB as a table, with one entry per
capability/value pair was ineffective memory-wise - we ended up adding
~20K to the final binary size.

This patch changes the internal representation from a table, to a
single NULL-separated (and NULL-terminated) char array:

  cap1-name \0 cap1-value \0 cap2-name \0 cap2-value \0

The capabilities are still sorted; to lookup a capability we need to
scan from the beginning until we either find a match, or until the
capabilities from the DB sort higher (lexicographically) than the
searched-for capability.

The terminfo char array is 3.3K - more better than before.
2022-01-13 13:42:12 +01:00
Daniel Eklöf
44aad0941f
dcs: xtgettcap: handle boolean capabilities
Reply with DCS 1 + r <cap> ST
2022-01-13 13:42:11 +01:00
Daniel Eklöf
3fa6bec912
dcs: implement XTGETTCAP
We emit one DCS reply for each queried capability (like Kitty, but
unlike XTerm), as this allows us to a) not skip any capabilities in
the query, and b) reply with correct success/fail flag for each
capability.

We do not batch the entire reply - as soon as the reply for _one_
capability is done, we write it to the PTY.

Closes #846
2022-01-13 13:42:11 +01:00
Craig Barnes
9026095a24 dcs: only log debug warnings in bsu() and esu() for unhandled params 2021-04-25 21:04:46 +01:00
Daniel Eklöf
7d315d7bf9
sixel: implement P2=1 - transparent pixels
When P2=1, empty pixels are transparent.

This patch also changes the behavior of P2=0|2, from setting empty
pixels to the default background color, to instead use the *current*
background color.

To implement this, a couple of changes are needed:

* Sixel pixels always use alpha=1.0, except for *empty* cells when
  P2=1 (i.e. transparent pixels).
* The renderer draws sixels with the OVER operator, instead of the SRC
  operator.
* The renderer *must* now render the cells beneath the sixel. As an
  optimization, this is only done for sixels where P2=1. I.e. for
  fully opaque sixels, there’s no need to render the cells beneath.

The sixel renderer isn’t yet hooked into the multi-threaded
renderer. This means *rows* (not just the cells) beneath
maybe-transparent sixels are rendered single-threaded.

Closes #391.
2021-03-11 17:34:19 +01:00
Craig Barnes
e56136ce11 debug: rename assert() to xassert(), to avoid clashing with <assert.h> 2021-01-16 20:16:00 +00:00
Daniel Eklöf
2e137c0a7e
vt: don’t ignore extra private/intermediate characters
Take ‘\E(#0’ for example - this is *not* the same as ‘\E(0’.

Up until now, foot has however treated them as the same escape,
because the handler for ‘\E(0’ didn’t verify there weren’t any _other_
private characters present.

Fix this by turning the ‘private’ array into a single 4-byte
integer. This allows us to match *all* privates with a single
comparison.

Private characters are added to the LSB first, and MSB last. This
means we can check for single privates in pretty much the same way as
before:

  switch (term->vt.private) {
  case ‘?’:
      ...
      break;
  }

Checking for two (or more) is much uglier, but foot only supports
a *single* escape with two privates, and no escapes with three or
more:

  switch (term->vt.private) {
  case 0x243f:  /* ‘?$’ */
      ...
      break;
  }

The ‘clear’ action remains simple (and fast), with a single write
operation.

Collecting privates is potentially _slightly_ more complex than
before; we now need mask and compare, instead of simply comparing,
when checking how many privates we already have.

We _could_ add a counter, which would make collecting privates easier,
but this would add an additional write to the ‘clean’ action which is
really bad since it’s in the hot path.
2020-12-16 14:30:49 +01:00
Daniel Eklöf
9e3bfb1eab
sixel: initial support
This implements basic parsing of sixel data. Lots of limitations and
temporary solutions as this is still work-in-progress:

* Maximum image size hardcoded to 800x800
* No HLS color format support
* Image is always rendered at 0x0 in the terminal
2020-02-21 21:53:23 +01:00
Daniel Eklöf
26d39fe96e
dcs: fix comment: ESU is *End* synchronized update 2020-01-29 19:43:58 +01:00
Daniel Eklöf
f74364979d
dcs: bsu/esu: convert warning log to debug log 2020-01-26 15:28:30 +01:00
Daniel Eklöf
16237eccde
dcs: remove abort() from BSU/ESU 2020-01-25 23:43:36 +01:00
Daniel Eklöf
97afba1b14
dcs: remove assert; handler may be zero on unimplemented OCS command 2020-01-20 18:35:34 +01:00
Daniel Eklöf
1623fc0c0a
term: shorten application_synchronized_updates -> app_sync_updates 2020-01-12 12:55:19 +01:00
Daniel Eklöf
d9bd1ef2d4
dcs: bsu/esu: add link to spec 2020-01-12 12:49:42 +01:00
Daniel Eklöf
14982159e4
dcs: abort() in bsu/esu
Since I haven't seen this in the wild, let's abort() to make sure we
catch when an application does this, so we can verify it really works.
2020-01-12 12:47:41 +01:00
Daniel Eklöf
bdf127fc7e
term/render: move {enable,disable}_application_synchronized_updates()
From render -> terminal
2020-01-12 12:43:28 +01:00
Daniel Eklöf
6e474e77e5
render: rename render_{enable,disable}_refresh() 2020-01-12 12:28:00 +01:00
Daniel Eklöf
7b27fa857f
dcs: bsu/esu: call render_{disable,enable}_refresh() 2020-01-12 12:21:31 +01:00
Daniel Eklöf
5ef55a7f52
dcs: abort() in bsu/esu
I **really** want to know if someone is using these...
2020-01-12 12:02:39 +01:00
Daniel Eklöf
a2652d2447
dcs: put: don't append data if buffer resize failed 2020-01-12 12:00:43 +01:00
Daniel Eklöf
a1ce31cd1d
dcs: use default param value of 0 in log message 2020-01-12 12:00:30 +01:00
Daniel Eklöf
5a6cbb8c3e
dcs: initial handling of DCS in general
Add data structure to term->vt. This structure tracks the free-form
data that is passed-through, and the handler to call at the end.

Intermediates and parameters are collected by the normal VT
parser. Then, when we enter the passthrough state, we call dcs_hook().

This function checks the intermediate(s) and parameters, and selects
the appropriate unhook handler (and optionally does some execution
already).

In passthrough mode, we simply append strings to an internal
buffer. This might have to be changed in the future, if we need to
support a DCS that needs to execute as we go.

In unhook (i.e. when the DCS is terminated), we execute the unhook
handler.

As a proof-of-concept, handlers for BSU/ESU (Begin/End Synchronized
Update) has been added (but are left unimplemented).
2020-01-12 11:55:22 +01:00
Daniel Eklöf
2096753b52
dcs: we have no parent terminal to pass through to 2019-07-21 18:22:26 +02:00
Daniel Eklöf
b953326768
dcs: sort of implement DCS passthrough
We now store the passthrough characters in a buffer, and call
dcs_passthrough() on unhook.

However, dcs_passthrough() doesn't do anything.
2019-07-19 09:55:07 +02:00