Skip to content

Commit

Permalink
Combine sixel options into one struct.
Browse files Browse the repository at this point in the history
Easier to pass around and also not forget to initialize fields.
  • Loading branch information
hzeller committed Jan 12, 2025
1 parent fa2f659 commit bd3d5c5
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 37 deletions.
11 changes: 6 additions & 5 deletions src/sixel-canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "buffered-write-sequencer.h"
#include "display-options.h"
#include "framebuffer.h"
#include "term-query.h"
#include "terminal-canvas.h"
#include "thread-pool.h"
#include "timg-time.h"
Expand All @@ -35,11 +36,11 @@
namespace timg {

SixelCanvas::SixelCanvas(BufferedWriteSequencer *ws, ThreadPool *thread_pool,
bool required_cursor_placement_workaround,
bool full_cell_jump, const DisplayOptions &opts)
const SixelOptions &sixel_options,
const DisplayOptions &display_opts)
: TerminalCanvas(ws),
options_(opts),
full_cell_jump_(full_cell_jump),
options_(display_opts),
full_cell_jump_(sixel_options.full_cell_jump),
executor_(thread_pool) {
// Terminals might have different understanding where the curosr is placed
// after an image is sent.
Expand All @@ -62,7 +63,7 @@ SixelCanvas::SixelCanvas(BufferedWriteSequencer *ws, ThreadPool *thread_pool,
// * https://vt100.net/dec/ek-vt382-rm-001.pdf#page=112
// * https://vt100.net/dec/ek-vt38t-ug-001.pdf#page=132
// Plese send PR or issue if you know a less ugly way to deal with this.
if (!required_cursor_placement_workaround) {
if (!sixel_options.known_broken_cursor_placement) {
//** The default way of doing things; works with most terminals.
// works: konsole, mlterm, libvte-based, alacritty-sixel
// breaks: xterm, wezterm
Expand Down
5 changes: 3 additions & 2 deletions src/sixel-canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "buffered-write-sequencer.h"
#include "display-options.h"
#include "framebuffer.h"
#include "term-query.h"
#include "terminal-canvas.h"
#include "timg-time.h"

Expand All @@ -28,8 +29,8 @@ class ThreadPool;
class SixelCanvas final : public TerminalCanvas {
public:
SixelCanvas(BufferedWriteSequencer *ws, ThreadPool *thread_pool,
bool required_cursor_placement_workaround, bool full_cell_jump,
const DisplayOptions &opts);
const SixelOptions &sixel_options,
const DisplayOptions &display_opts);

int cell_height_for_pixels(int pixels) const final;

Expand Down
16 changes: 8 additions & 8 deletions src/term-query.cc
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,8 @@ TermGraphicsInfo QuerySupportedGraphicsProtocol() {
TermGraphicsInfo result{};
result.preferred_graphics = GraphicsProtocol::kNone;
const int sixel_env_bits = timg::GetIntEnv("TIMG_SIXEL_NEWLINE_WORKAROUND");
result.known_broken_sixel_cursor_placement = sixel_env_bits & 0b01;
result.sixel_full_cell_jump = sixel_env_bits & 0b10;
result.sixel.known_broken_cursor_placement = sixel_env_bits & 0b01;
result.sixel.full_cell_jump = sixel_env_bits & 0b10;
result.in_tmux = false;

// Environment variables can be changed, so guesses from environment
Expand All @@ -249,7 +249,7 @@ TermGraphicsInfo QuerySupportedGraphicsProtocol() {
if (term_program && strcmp(term_program, "vscode") == 0) {
result.preferred_graphics = GraphicsProtocol::kIterm2;
// In case the user chooses sixel.
result.known_broken_sixel_cursor_placement = true;
result.sixel.known_broken_cursor_placement = true;
}

// Note, there is a kitty protocol way to determine if kitty is supported,
Expand Down Expand Up @@ -278,7 +278,7 @@ TermGraphicsInfo QuerySupportedGraphicsProtocol() {
}
if (find_str(data, len, "WezTerm")) {
result.preferred_graphics = GraphicsProtocol::kIterm2;
result.known_broken_sixel_cursor_placement = true;
result.sixel.known_broken_cursor_placement = true;
}
if (find_str(data, len, "kitty")) {
result.preferred_graphics = GraphicsProtocol::kKitty;
Expand All @@ -291,20 +291,20 @@ TermGraphicsInfo QuerySupportedGraphicsProtocol() {
}
if (find_str(data, len, "XTerm")) {
// Don't know yet if supports sixel, will query below
result.known_broken_sixel_cursor_placement = true;
result.sixel.known_broken_cursor_placement = true;
}
if (find_str(data, len, "foot")) {
result.preferred_graphics = GraphicsProtocol::kSixel;
result.known_broken_sixel_cursor_placement = true;
result.sixel.known_broken_cursor_placement = true;
}
if (find_str(data, len, "tmux")) {
result.in_tmux = true;
}
if (find_str(data, len, "WindowsTerminal")) {
// TODO: check again once name is established
// https://github.com/microsoft/terminal/issues/18382
result.known_broken_sixel_cursor_placement = true;
result.sixel_full_cell_jump = true;
result.sixel.known_broken_cursor_placement = true;
result.sixel.full_cell_jump = true;
}
// We finish once we found the response to DSR5
return find_str(data, len, TERM_CSI "0");
Expand Down
13 changes: 9 additions & 4 deletions src/term-query.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,16 @@ enum class GraphicsProtocol {
kKitty,
kSixel,
};
// See SixelCanvas for explanations of these values. The default values
// are boolean false.
struct SixelOptions {
bool known_broken_cursor_placement = false;
bool full_cell_jump = false;
};
struct TermGraphicsInfo {
GraphicsProtocol preferred_graphics;
bool known_broken_sixel_cursor_placement; // see SixelCanvas impl. doc
bool sixel_full_cell_jump;
bool in_tmux;
GraphicsProtocol preferred_graphics = GraphicsProtocol::kNone;
SixelOptions sixel;
bool in_tmux = false;
};

// Query the terminal if and what graphics protocol it supports.
Expand Down
31 changes: 13 additions & 18 deletions src/timg.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,8 @@ namespace timg {
// Options configuring how images/videos are arranged and presented.
struct PresentationOptions {
// Rendering
Pixelation pixelation = Pixelation::kNotChosen;
bool sixel_cursor_workaround = false;
bool sixel_full_cell_jump = false;
Pixelation pixelation = Pixelation::kNotChosen;
SixelOptions sixel_options{};
bool tmux_workaround = false;
bool terminal_use_upper_block = false;
bool use_256_color = false; // For terminals that don't do 24 bit color
Expand Down Expand Up @@ -332,9 +331,9 @@ static int PresentImages(LoadedImageSources *loaded_sources,
#ifdef WITH_TIMG_SIXEL
case Pixelation::kSixelGraphics:
compression_pool.reset(new ThreadPool(sequencer->max_queue_len() + 1));
canvas.reset(new timg::SixelCanvas(
sequencer, compression_pool.get(), present.sixel_cursor_workaround,
present.sixel_full_cell_jump, display_opts));
canvas.reset(new timg::SixelCanvas(sequencer, compression_pool.get(),
present.sixel_options,
display_opts));
break;
#endif
case Pixelation::kHalfBlock:
Expand Down Expand Up @@ -782,11 +781,8 @@ int main(int argc, char *argv[]) {
break;
case timg::GraphicsProtocol::kSixel:
#ifdef WITH_TIMG_SIXEL
present.pixelation = Pixelation::kSixelGraphics;
present.sixel_cursor_workaround =
graphics_info.known_broken_sixel_cursor_placement;
present.sixel_full_cell_jump =
graphics_info.sixel_full_cell_jump;
present.pixelation = Pixelation::kSixelGraphics;
present.sixel_options = graphics_info.sixel;
#else
present.pixelation = Pixelation::kQuarterBlock;
#endif
Expand All @@ -804,10 +800,8 @@ int main(int argc, char *argv[]) {
// If the user manually choose sixel, we still can't avoid a terminal
// query, as we have to figure out if it has a broken cursor implementation.
else if (present.pixelation == Pixelation::kSixelGraphics) {
auto graphics_info = timg::QuerySupportedGraphicsProtocol();
present.sixel_cursor_workaround =
graphics_info.known_broken_sixel_cursor_placement;
present.sixel_full_cell_jump = graphics_info.sixel_full_cell_jump;
auto graphics_info = timg::QuerySupportedGraphicsProtocol();
present.sixel_options = graphics_info.sixel;
}
#endif

Expand Down Expand Up @@ -1036,11 +1030,12 @@ int main(int argc, char *argv[]) {
#ifdef WITH_TIMG_SIXEL
if (present.pixelation == Pixelation::kSixelGraphics) {
fprintf(stderr, " (%s and %s)",
present.sixel_cursor_workaround
present.sixel_options.known_broken_cursor_placement
? "with cursor placment workaround"
: "with default cursor placement",
present.sixel_full_cell_jump ? "full cursor cell jump"
: "default cursor cell jump");
present.sixel_options.full_cell_jump
? "full cursor cell jump"
: "default cursor cell jump");
}
#endif
if (present.pixelation == Pixelation::kKittyGraphics) {
Expand Down

0 comments on commit bd3d5c5

Please sign in to comment.