Refactor sixdraw code.
continuous-integration/drone/push Build is passing Details

This commit is contained in:
CismonX 2021-10-30 23:14:10 +08:00
parent 473b119416
commit 471825b0ac
Signed by: cismonx
GPG Key ID: 3094873E29A482FB
1 changed files with 50 additions and 27 deletions

View File

@ -2,8 +2,8 @@
* sixdraw.c - draw on your terminal * sixdraw.c - draw on your terminal
* *
* Requires sixel graphics and 1016 mouse mode to run on your terminal. * Requires sixel graphics and 1016 mouse mode to run on your terminal.
* These features are not widely supported. To save yourself from trouble, * These features are not widely supported.
* use a latest version of XTerm or mintty. * To save yourself from trouble, use a latest version of XTerm or mintty.
* *
* Before 1016 mode was introduced in XTerm patch #359, it is also possible * Before 1016 mode was introduced in XTerm patch #359, it is also possible
* to report mouse position in pixels using DEC locator (which is also rarely * to report mouse position in pixels using DEC locator (which is also rarely
@ -89,8 +89,11 @@ struct sixdraw_ctx {
}; };
static inline void static inline void
print_error(struct sixdraw_ctx const *ctx, char const *format, ...) print_error(
{ struct sixdraw_ctx const *ctx,
char const *format,
...
) {
char msg[1024]; char msg[1024];
va_list args; va_list args;
va_start(args, format); va_start(args, format);
@ -100,8 +103,9 @@ print_error(struct sixdraw_ctx const *ctx, char const *format, ...)
} }
static void static void
terminate(struct sixdraw_ctx *ctx) terminate(
{ struct sixdraw_ctx *ctx
) {
ctlseqs_matcher_free(ctx->matcher); ctlseqs_matcher_free(ctx->matcher);
ctlseqs_reader_free(ctx->reader); ctlseqs_reader_free(ctx->reader);
@ -139,8 +143,9 @@ terminate(struct sixdraw_ctx *ctx)
} }
static bool static bool
get_winsize(struct sixdraw_ctx *ctx) get_winsize(
{ struct sixdraw_ctx *ctx
) {
struct winsize ws = { 0 }; struct winsize ws = { 0 };
if (ioctl(ctx->in_fd, TIOCGWINSZ, &ws) != 0) { if (ioctl(ctx->in_fd, TIOCGWINSZ, &ws) != 0) {
print_error(ctx, "failed to get terminal window size"); print_error(ctx, "failed to get terminal window size");
@ -150,17 +155,20 @@ get_winsize(struct sixdraw_ctx *ctx)
print_error(ctx, "failed to get terminal window size (in pixels)"); print_error(ctx, "failed to get terminal window size (in pixels)");
return false; return false;
} }
ctx->rows = ws.ws_row; ctx->rows = ws.ws_row;
ctx->ch_width = ws.ws_xpixel / ws.ws_col; ctx->ch_width = ws.ws_xpixel / ws.ws_col;
ctx->ch_height = ws.ws_ypixel / ws.ws_row; ctx->ch_height = ws.ws_ypixel / ws.ws_row;
ctx->canvas_width = ctx->ch_width * ws.ws_col; ctx->canvas_width = ctx->ch_width * ws.ws_col;
ctx->canvas_height = ctx->ch_height * ws.ws_row - ctx->ch_height * 2; ctx->canvas_height = ctx->ch_height * ws.ws_row - ctx->ch_height * 2;
return true; return true;
} }
static bool static bool
decrqm(struct sixdraw_ctx *ctx, unsigned mode, char const *name) decrqm(
{ struct sixdraw_ctx *ctx,
unsigned mode,
char const *name
) {
ssize_t retval; ssize_t retval;
union ctlseqs_value *result = ctx->result; union ctlseqs_value *result = ctx->result;
fprintf(ctx->out_file, CTLSEQS_DECRQM("%d"), mode); fprintf(ctx->out_file, CTLSEQS_DECRQM("%d"), mode);
@ -181,7 +189,9 @@ decrqm(struct sixdraw_ctx *ctx, unsigned mode, char const *name)
} }
static long static long
xtversion(struct sixdraw_ctx *ctx) { xtversion(
struct sixdraw_ctx *ctx
) {
ssize_t retval; ssize_t retval;
union ctlseqs_value *result = ctx->result; union ctlseqs_value *result = ctx->result;
fprintf(ctx->out_file, CTLSEQS_XTVERSION()); fprintf(ctx->out_file, CTLSEQS_XTVERSION());
@ -209,8 +219,11 @@ xtversion(struct sixdraw_ctx *ctx) {
} }
static void static void
print_sixel_dot(struct sixdraw_ctx *ctx, unsigned x, unsigned y) print_sixel_dot(
{ struct sixdraw_ctx *ctx,
unsigned x,
unsigned y
) {
if (x >= ctx->canvas_width || y >= ctx->canvas_height) { if (x >= ctx->canvas_width || y >= ctx->canvas_height) {
return; return;
} }
@ -224,15 +237,21 @@ print_sixel_dot(struct sixdraw_ctx *ctx, unsigned x, unsigned y)
row = y % ctx->ch_height; row = y % ctx->ch_height;
col = x % ctx->ch_width; col = x % ctx->ch_width;
unsigned seq_size = ctx->sixel_init_size; unsigned seq_size = ctx->sixel_init_size;
seq_size += sprintf(sixel_seq + seq_size, "%.*s!%u?%c" CTLSEQS_ST, seq_size += sprintf(
row / 6, "------------------------", col, (1 << row % 6) + 0x3F); sixel_seq + seq_size,
"%.*s!%u?%c" CTLSEQS_ST,
row / 6, "------------------------", col, (1 << row % 6) + 0x3F
);
fwrite(sixel_seq, seq_size, 1, ctx->out_file); fwrite(sixel_seq, seq_size, 1, ctx->out_file);
} }
static bool static bool
init(struct sixdraw_ctx *ctx, int argc, char **argv) init(
{ struct sixdraw_ctx *ctx,
int argc,
char *argv[]
) {
*ctx = (struct sixdraw_ctx) { *ctx = (struct sixdraw_ctx) {
.prog_name = argc > 0 ? argv[0] : "sixdraw", .prog_name = argc > 0 ? argv[0] : "sixdraw",
.out_file = stdout, .out_file = stdout,
@ -303,8 +322,9 @@ init(struct sixdraw_ctx *ctx, int argc, char **argv)
} }
static bool static bool
prepare(struct sixdraw_ctx *ctx) prepare(
{ struct sixdraw_ctx *ctx
) {
// Check whether we're running on a terminal. // Check whether we're running on a terminal.
if (!isatty(ctx->in_fd) || !isatty(ctx->out_fd)) { if (!isatty(ctx->in_fd) || !isatty(ctx->out_fd)) {
print_error(ctx, "this program can only run in a terminal"); print_error(ctx, "this program can only run in a terminal");
@ -443,8 +463,9 @@ prepare(struct sixdraw_ctx *ctx)
} }
static bool static bool
draw(struct sixdraw_ctx *ctx) draw(
{ struct sixdraw_ctx *ctx
) {
fprintf( fprintf(
ctx->out_file, ctx->out_file,
CTLSEQS_CUP("%d", "1") "Canvas size: %ux%u. Line color: #%06X.", CTLSEQS_CUP("%d", "1") "Canvas size: %ux%u. Line color: #%06X.",
@ -478,8 +499,10 @@ draw(struct sixdraw_ctx *ctx)
} }
int int
main(int argc, char **argv) main(
{ int argc,
char *argv[]
) {
int status; int status;
struct sixdraw_ctx ctx; struct sixdraw_ctx ctx;
if (init(&ctx, argc, argv) && prepare(&ctx)) { if (init(&ctx, argc, argv) && prepare(&ctx)) {