diff --git a/sys/dev/syscons/scterm-teken.c b/sys/dev/syscons/scterm-teken.c index 48504757052f..8aebac8e1cb3 100644 --- a/sys/dev/syscons/scterm-teken.c +++ b/sys/dev/syscons/scterm-teken.c @@ -673,8 +673,21 @@ scteken_copy(void *arg, const teken_rect_t *r, const teken_pos_t *p) static void scteken_param(void *arg, int cmd, unsigned int value) { + static int cattrs[] = { + 0, /* block */ + CONS_BLINK_CURSOR, /* blinking block */ + CONS_CHAR_CURSOR, /* underline */ + CONS_CHAR_CURSOR | CONS_BLINK_CURSOR, /* blinking underline */ + CONS_RESET_CURSOR, /* reset to default */ + CONS_HIDDEN_CURSOR, /* hide cursor */ + }; + static int tcattrs[] = { + CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, /* normal */ + CONS_HIDDEN_CURSOR | CONS_LOCAL_CURSOR, /* invisible */ + CONS_BLINK_CURSOR | CONS_LOCAL_CURSOR, /* very visible */ + }; scr_stat *scp = arg; - int flags; + int flags, n, v0, v1, v2; switch (cmd) { case TP_SETBORDER: @@ -682,6 +695,39 @@ scteken_param(void *arg, int cmd, unsigned int value) if (scp == scp->sc->cur_scp) sc_set_border(scp, scp->border); break; + case TP_SETGLOBALCURSOR: + n = value & 0xff; + v0 = (value >> 8) & 0xff; + v1 = (value >> 16) & 0xff; + v2 = (value >> 24) & 0xff; + switch (n) { + case 1: /* flags only */ + if (v0 < sizeof(cattrs) / sizeof(cattrs[0])) + v0 = cattrs[v0]; + else /* backward compatibility */ + v0 = cattrs[v0 & 0x3]; + sc_change_cursor_shape(scp, v0, -1, -1); + break; + case 2: + v2 = 0; + v0 &= 0x1f; /* backward compatibility */ + v1 &= 0x1f; + /* FALL THROUGH */ + case 3: /* base and height */ + if (v2 == 0) /* count from top */ + sc_change_cursor_shape(scp, -1, + scp->font_size - v1 - 1, + v1 - v0 + 1); + else if (v2 == 1) /* count from bottom */ + sc_change_cursor_shape(scp, -1, + v0, v1 - v0 + 1); + break; + } + break; + case TP_SETLOCALCURSOR: + if (value < sizeof(tcattrs) / sizeof(tcattrs[0])) + sc_change_cursor_shape(scp, tcattrs[value], -1, -1); + break; case TP_SHOWCURSOR: if (value != 0) flags = scp->curr_curs_attr.flags & ~CONS_HIDDEN_CURSOR; diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c index 3c572e056342..2743a3492270 100644 --- a/sys/dev/vt/vt_core.c +++ b/sys/dev/vt/vt_core.c @@ -1052,6 +1052,15 @@ vtterm_param(struct terminal *tm, int cmd, unsigned int arg) struct vt_window *vw = tm->tm_softc; switch (cmd) { + case TP_SETLOCALCURSOR: + /* + * 0 means normal (usually block), 1 means hidden, and + * 2 means blinking (always block) for compatibility with + * syscons. We don't support any changes except hiding, + * so must map 2 to 0. + */ + arg = (arg == 1) ? 0 : 1; + /* FALLTHROUGH */ case TP_SHOWCURSOR: vtbuf_cursor_visibility(&vw->vw_buf, arg); vt_resume_flush_timer(vw->vw_device, 0); diff --git a/sys/teken/sequences b/sys/teken/sequences index 76eebd185296..0891f17e06b7 100644 --- a/sys/teken/sequences +++ b/sys/teken/sequences @@ -103,9 +103,10 @@ VPA Vertical Position Absolute ^[ [ d n # Cons25 compatibility sequences C25BLPD Cons25 set bell pitch duration ^[ [ = B r r C25BORD Cons25 set border ^[ [ = A r -C25CURS Cons25 set cursor type ^[ [ = S r C25DBG Cons25 set default background ^[ [ = G r C25DFG Cons25 set default foreground ^[ [ = F r +C25GCS Cons25 set global cursor shape ^[ [ = C v +C25LCT Cons25 set local cursor type ^[ [ = S r C25MODE Cons25 set terminal mode ^[ [ = T r C25SGR Cons25 set graphic rendition ^[ [ x r r C25VTSW Cons25 switch virtual terminal ^[ [ z r diff --git a/sys/teken/teken.h b/sys/teken/teken.h index e1ea13673554..61efe5417c0c 100644 --- a/sys/teken/teken.h +++ b/sys/teken/teken.h @@ -102,6 +102,8 @@ typedef void tf_param_t(void *, int, unsigned int); #define TP_SETBELLPD_DURATION(pd) ((pd) & 0xffff) #define TP_MOUSE 6 #define TP_SETBORDER 7 +#define TP_SETLOCALCURSOR 8 +#define TP_SETGLOBALCURSOR 9 typedef void tf_respond_t(void *, const void *, size_t); typedef struct { diff --git a/sys/teken/teken_subr_compat.h b/sys/teken/teken_subr_compat.h index 64341eec6d17..6142c7958f9f 100644 --- a/sys/teken/teken_subr_compat.h +++ b/sys/teken/teken_subr_compat.h @@ -34,10 +34,32 @@ teken_subr_cons25_set_border(teken_t *t, unsigned int c) } static void -teken_subr_cons25_set_cursor_type(teken_t *t, unsigned int type) +teken_subr_cons25_set_global_cursor_shape(teken_t *t, unsigned int ncmds, + unsigned int cmds[]) +{ + unsigned int code, i; + + /* + * Pack the args to work around API deficiencies. This requires + * knowing too much about the low level to be fully compatible. + * Returning when ncmds > 3 is necessary and happens to be + * compatible. Discarding high bits is necessary and happens to + * be incompatible only for invalid args when ncmds == 3. + */ + if (ncmds > 3) + return; + code = 0; + for (i = ncmds; i > 0; i--) + code = (code << 8) | (cmds[i - 1] & 0xff); + code = (code << 8) | ncmds; + teken_funcs_param(t, TP_SETGLOBALCURSOR, code); +} + +static void +teken_subr_cons25_set_local_cursor_type(teken_t *t, unsigned int type) { - teken_funcs_param(t, TP_SHOWCURSOR, type != 1); + teken_funcs_param(t, TP_SETLOCALCURSOR, type); } static const teken_color_t cons25_colors[8] = { TC_BLACK, TC_BLUE,