Skip to content

Commit

Permalink
- far2l extensions: added cursor shape change support
Browse files Browse the repository at this point in the history
- worked around one more Wine issue
  • Loading branch information
unxed committed Dec 15, 2024
1 parent b17cb74 commit ac5fbee
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 27 deletions.
12 changes: 6 additions & 6 deletions putty.h
Original file line number Diff line number Diff line change
Expand Up @@ -1641,14 +1641,14 @@ struct TermWinVtable {
bool (*setup_draw_ctx)(TermWin *);
/* Draw text in the window, during a painting operation */
void (*draw_text)(TermWin *, int x, int y, wchar_t *text, int len,
unsigned long attrs, int line_attrs, truecolour tc);
unsigned long attrs, int line_attrs, truecolour tc, int custom);
/* Draw the visible cursor. Expects you to have called do_text
* first (because it might just draw an underline over a character
* presumed to exist already), but also expects you to pass in all
* the details of the character under the cursor (because it might
* redraw it in different colours). */
void (*draw_cursor)(TermWin *, int x, int y, wchar_t *text, int len,
unsigned long attrs, int line_attrs, truecolour tc);
unsigned long attrs, int line_attrs, truecolour tc, int custom);
/* Draw the sigil indicating that a line of text has come from
* PuTTY itself rather than the far end (defence against end-of-
* authentication spoofing) */
Expand Down Expand Up @@ -1729,12 +1729,12 @@ static inline bool win_setup_draw_ctx(TermWin *win)
{ return win->vt->setup_draw_ctx(win); }
static inline void win_draw_text(
TermWin *win, int x, int y, wchar_t *text, int len,
unsigned long attrs, int line_attrs, truecolour tc)
{ win->vt->draw_text(win, x, y, text, len, attrs, line_attrs, tc); }
unsigned long attrs, int line_attrs, truecolour tc, int custom)
{ win->vt->draw_text(win, x, y, text, len, attrs, line_attrs, tc, custom); }
static inline void win_draw_cursor(
TermWin *win, int x, int y, wchar_t *text, int len,
unsigned long attrs, int line_attrs, truecolour tc)
{ win->vt->draw_cursor(win, x, y, text, len, attrs, line_attrs, tc); }
unsigned long attrs, int line_attrs, truecolour tc, int custom)
{ win->vt->draw_cursor(win, x, y, text, len, attrs, line_attrs, tc, custom); }
static inline void win_draw_trust_sigil(TermWin *win, int x, int y)
{ win->vt->draw_trust_sigil(win, x, y); }
static inline int win_char_width(TermWin *win, int uc)
Expand Down
26 changes: 23 additions & 3 deletions terminal/terminal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,7 @@ static void power_on(Terminal *term, bool clear)
term->far2l_ext = 0;
term->prev_uchar = 0;
term->notif_hwnd = 0;
term->cursor_custom = -1;

term->alt_x = term->alt_y = 0;
term->savecurs.x = term->savecurs.y = 0;
Expand Down Expand Up @@ -2075,6 +2076,7 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata, TermWin *win)
term->far2l_ext = 0;
term->is_apc = 0;
//term->clip_allowed = -1;
term->cursor_custom = -1;

term->win = win;
term->ucsdata = ucsdata;
Expand Down Expand Up @@ -3256,6 +3258,24 @@ static void do_osc(Terminal *term)
// next from the end byte is command
switch (d_out[d_count-2]) {

case 'h':;

int height = d_out[d_count-3];

if (height < 30) {
term->cursor_custom = CURSOR_UNDERLINE;
term->big_cursor = false;
} else {
term->cursor_custom = CURSOR_BLOCK;
}
term->blink_cur = 1; // should always blink in far2l exts mode

reply_size = 5;
reply = malloc(reply_size);
memcpy(reply, &zero, sizeof(DWORD));

break;

case 'f':;

reply_size = 5;
Expand Down Expand Up @@ -6639,13 +6659,13 @@ static void do_paint_draw(Terminal *term, termline *ldata, int x, int y,
wchar_t tch[2];
tch[0] = tch[1] = L' ';
win_draw_text(term->win, x, y, tch, 2, term->basic_erase_char.attr,
ldata->lattr, term->basic_erase_char.truecolour);
ldata->lattr, term->basic_erase_char.truecolour, term->cursor_custom);
win_draw_trust_sigil(term->win, x, y);
} else {
win_draw_text(term->win, x, y, ch, ccount, attr, ldata->lattr, tc);
win_draw_text(term->win, x, y, ch, ccount, attr, ldata->lattr, tc, term->cursor_custom);
if (attr & (TATTR_ACTCURS | TATTR_PASCURS))
win_draw_cursor(term->win, x, y, ch, ccount,
attr, ldata->lattr, tc);
attr, ldata->lattr, tc, term->cursor_custom);
}
}

Expand Down
1 change: 1 addition & 0 deletions terminal/terminal.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ struct terminal_tag {
/* far2l */
#define OSC_ALLOCATE_BLOCK_SIZE 1048576

int cursor_custom;
int osc_strlen;
int osc_allocated_size;
char* osc_string;
Expand Down
4 changes: 2 additions & 2 deletions test/fuzzterm.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ int main(int argc, char **argv)
static bool fuzz_setup_draw_ctx(TermWin *tw) { return true; }
static void fuzz_draw_text(
TermWin *tw, int x, int y, wchar_t *text, int len,
unsigned long attr, int lattr, truecolour tc)
unsigned long attr, int lattr, truecolour tc, int custom)
{
int i;

Expand All @@ -54,7 +54,7 @@ static void fuzz_draw_text(
}
static void fuzz_draw_cursor(
TermWin *tw, int x, int y, wchar_t *text, int len,
unsigned long attr, int lattr, truecolour tc)
unsigned long attr, int lattr, truecolour tc, int custom)
{
int i;

Expand Down
4 changes: 2 additions & 2 deletions test/test_terminal.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ typedef struct Mock {

static bool mock_setup_draw_ctx(TermWin *win) { return false; }
static void mock_draw_text(TermWin *win, int x, int y, wchar_t *text, int len,
unsigned long attrs, int lattrs, truecolour tc) {}
unsigned long attrs, int lattrs, truecolour tc, int custom) {}
static void mock_draw_cursor(TermWin *win, int x, int y, wchar_t *text,
int len, unsigned long attrs, int lattrs,
truecolour tc) {}
truecolour tc, int custom) {}
static void mock_set_raw_mouse_mode(TermWin *win, bool enable) {}
static void mock_set_raw_mouse_mode_pointer(TermWin *win, bool enable) {}
static void mock_palette_set(TermWin *win, unsigned start, unsigned ncolours,
Expand Down
4 changes: 2 additions & 2 deletions unix/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -4034,7 +4034,7 @@ static void do_text_internal(

static void gtkwin_draw_text(
TermWin *tw, int x, int y, wchar_t *text, int len,
unsigned long attr, int lattr, truecolour truecolour)
unsigned long attr, int lattr, truecolour truecolour, int custom)
{
GtkFrontend *inst = container_of(tw, GtkFrontend, termwin);
int widefactor;
Expand Down Expand Up @@ -4064,7 +4064,7 @@ static void gtkwin_draw_text(

static void gtkwin_draw_cursor(
TermWin *tw, int x, int y, wchar_t *text, int len,
unsigned long attr, int lattr, truecolour truecolour)
unsigned long attr, int lattr, truecolour truecolour, int custom)
{
GtkFrontend *inst = container_of(tw, GtkFrontend, termwin);
bool active, passive;
Expand Down
40 changes: 28 additions & 12 deletions windows/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ struct WinGuiSeatListNode wgslisthead = {

static bool wintw_setup_draw_ctx(TermWin *);
static void wintw_draw_text(TermWin *, int x, int y, wchar_t *text, int len,
unsigned long attrs, int lattrs, truecolour tc);
unsigned long attrs, int lattrs, truecolour tc, int custom);
static void wintw_draw_cursor(TermWin *, int x, int y, wchar_t *text, int len,
unsigned long attrs, int lattrs, truecolour tc);
unsigned long attrs, int lattrs, truecolour tc, int custom);
static void wintw_draw_trust_sigil(TermWin *, int x, int y);
static int wintw_char_width(TermWin *, int uc);
static void wintw_free_draw_ctx(TermWin *);
Expand Down Expand Up @@ -3328,6 +3328,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
}
}

if ((ctrl & 504) == 504) { ctrl = 0; } // work around one more Wine issue (kb layout change affects?)

char* kev = malloc(15); // keyboard event structure length
memcpy(kev, &repeat, sizeof(repeat));
memcpy(kev + 2, &vkc, sizeof(vkc));
Expand All @@ -3336,6 +3338,16 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
memcpy(kev + 10, &uchar, sizeof(uchar));
memcpy(kev + 14, &type, sizeof(type));

/*
// debug
printf(" type: %u\n", type);
printf(" vkc: %u (0x%04X)\n", vkc, vkc);
printf(" vsc: %u (0x%04X)\n", vsc, vsc);
printf(" ctrl: %lu (0x%08lX)\n", ctrl, ctrl);
printf(" repeat: %u\n", repeat);
printf("\n");
*/

// base64-encode kev
base64_encodestate _state;
base64_init_encodestate(&_state);
Expand Down Expand Up @@ -3671,7 +3683,7 @@ static void draw_horizontal_line_on_text(
*/
static void do_text_internal(
WinGuiSeat *wgs, int x, int y, wchar_t *text, int len,
unsigned long attr, int lattr, truecolour truecolour)
unsigned long attr, int lattr, truecolour truecolour, int custom)
{
COLORREF fg, bg, t;
int nfg, nbg, nfont;
Expand Down Expand Up @@ -3707,8 +3719,11 @@ static void do_text_internal(
x += wgs->offset_width;
y += wgs->offset_height;

int ctype = wgs->cursor_type;
if (custom != -1) { ctype = custom; }

if ((attr & TATTR_ACTCURS) &&
(wgs->cursor_type == CURSOR_BLOCK || wgs->term->big_cursor)) {
(ctype == CURSOR_BLOCK || wgs->term->big_cursor)) {
truecolour.fg = truecolour.bg = optionalrgb_none;
attr &= ~(ATTR_REVERSE|ATTR_BLINK|ATTR_COLOURS|ATTR_DIM);
/* cursor fg and bg */
Expand Down Expand Up @@ -4050,7 +4065,7 @@ static void do_text_internal(
*/
static void wintw_draw_text(
TermWin *tw, int x, int y, wchar_t *text, int len,
unsigned long attr, int lattr, truecolour truecolour)
unsigned long attr, int lattr, truecolour truecolour, int custom)
{
WinGuiSeat *wgs = container_of(tw, WinGuiSeat, termwin);
if (attr & TATTR_COMBINING) {
Expand All @@ -4061,13 +4076,13 @@ static void wintw_draw_text(
len0 = 2;
if (len-len0 >= 1 && IS_LOW_VARSEL(text[len0])) {
attr &= ~TATTR_COMBINING;
do_text_internal(wgs, x, y, text, len0+1, attr, lattr, truecolour);
do_text_internal(wgs, x, y, text, len0+1, attr, lattr, truecolour, custom);
text += len0+1;
len -= len0+1;
a = TATTR_COMBINING;
} else if (len-len0 >= 2 && IS_HIGH_VARSEL(text[len0], text[len0+1])) {
attr &= ~TATTR_COMBINING;
do_text_internal(wgs, x, y, text, len0+2, attr, lattr, truecolour);
do_text_internal(wgs, x, y, text, len0+2, attr, lattr, truecolour, custom);
text += len0+2;
len -= len0+2;
a = TATTR_COMBINING;
Expand All @@ -4078,35 +4093,36 @@ static void wintw_draw_text(
while (len--) {
if (len >= 1 && IS_SURROGATE_PAIR(text[0], text[1])) {
do_text_internal(wgs, x, y, text, 2, attr | a, lattr,
truecolour);
truecolour, custom);
len--;
text++;
} else
do_text_internal(wgs, x, y, text, 1, attr | a, lattr,
truecolour);
truecolour, custom);

text++;
a = TATTR_COMBINING;
}
} else
do_text_internal(wgs, x, y, text, len, attr, lattr, truecolour);
do_text_internal(wgs, x, y, text, len, attr, lattr, truecolour, custom);
}

static void wintw_draw_cursor(
TermWin *tw, int x, int y, wchar_t *text, int len,
unsigned long attr, int lattr, truecolour truecolour)
unsigned long attr, int lattr, truecolour truecolour, int custom)
{
WinGuiSeat *wgs = container_of(tw, WinGuiSeat, termwin);
int fnt_width;
int char_width;
int ctype = wgs->cursor_type;
if (custom != -1) { ctype = custom; }

lattr &= LATTR_MODE;

if ((attr & TATTR_ACTCURS) &&
(ctype == CURSOR_BLOCK || wgs->term->big_cursor)) {
if (*text != UCSWIDE) {
win_draw_text(tw, x, y, text, len, attr, lattr, truecolour);
win_draw_text(tw, x, y, text, len, attr, lattr, truecolour, custom);
return;
}
ctype = CURSOR_VERTICAL_LINE;
Expand Down

0 comments on commit ac5fbee

Please sign in to comment.