From 7ab6d7dc9c38d0f75c9d048e2249489f316c5b18 Mon Sep 17 00:00:00 2001 From: fang Date: Tue, 9 Feb 2021 15:43:16 +0100 Subject: [PATCH] term: add minimal mouse support Only detects mouse clicks. Though, "9" mode seems broken, or unsupported or something? Probably need to upgrade to "1000" mode or higher, but that also reports scrolling events and such, which don't want to steal from the context we're running in just yet. --- pkg/arvo/lib/hood/drum.hoon | 10 +++++++++ pkg/arvo/mar/belt.hoon | 1 + pkg/arvo/sys/lull.hoon | 1 + pkg/urbit/include/vere/vere.h | 3 +++ pkg/urbit/vere/io/term.c | 40 +++++++++++++++++++++++++++++++++++ 5 files changed, 55 insertions(+) diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index 801b8559d6..3a9f18d0aa 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -699,6 +699,7 @@ [%bac *] ta-bac [%ctl *] (ta-ctl p.bet) [%del *] ta-del + [%hit *] (ta-hit +.bet) [%met *] (ta-met p.bet) [%ret *] ta-ret [%txt *] (ta-txt p.bet) @@ -779,6 +780,15 @@ ta-bel (ta-hom %del pos.inp) :: + ++ ta-hit :: hear click + |= [r=@ud c=@ud] + ^+ +> + ?. =(0 r) +> + =/ pol=@ud + (lent-char:klr (make:klr cad.pom)) + ?: (lth c pol) +>.$ + +>.$(pos.inp (min (sub c pol) (lent buf.say.inp))) + :: ++ ta-erl :: hear local error |= pos=@ud ta-bel(pos.inp (min pos (lent buf.say.inp))) diff --git a/pkg/arvo/mar/belt.hoon b/pkg/arvo/mar/belt.hoon index 1c5a6e1ea6..bb8e29ce5e 100644 --- a/pkg/arvo/mar/belt.hoon +++ b/pkg/arvo/mar/belt.hoon @@ -15,6 +15,7 @@ bac+ul ctl+(cu taft so) del+ul + hit+(ot 'r'^ni 'c'^ni ~) met+(cu taft so) ret+ul txt+(ar (cu taft so)) diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 02daec58c2..53cf2d2c77 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -1050,6 +1050,7 @@ [%bac ~] :: true backspace [%ctl p=@c] :: control-key [%del ~] :: true delete + [%hit r=@ud c=@ud] :: mouse click [%met p=@c] :: meta-key [%ret ~] :: return [%txt p=(list @c)] :: utf32 text diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h index f1646ee1bc..7dba712c32 100644 --- a/pkg/urbit/include/vere/vere.h +++ b/pkg/urbit/include/vere/vere.h @@ -154,6 +154,9 @@ struct { // escape code control c3_o ape; // escape received c3_o bra; // bracket or O received + c3_o mou; // M (for mouse event) received + c3_y ton_y; // mouse button + c3_y col_y; // column coordinate } esc; struct { diff --git a/pkg/urbit/vere/io/term.c b/pkg/urbit/vere/io/term.c index 47481f7de4..f09f059a03 100644 --- a/pkg/urbit/vere/io/term.c +++ b/pkg/urbit/vere/io/term.c @@ -224,6 +224,9 @@ u3_term_log_init(void) uty_u->tat_u.esc.ape = c3n; uty_u->tat_u.esc.bra = c3n; + uty_u->tat_u.esc.mou = c3n; + uty_u->tat_u.esc.ton_y = 0; + uty_u->tat_u.esc.col_y = 0; uty_u->tat_u.fut.len_w = 0; uty_u->tat_u.fut.wid_w = 0; @@ -723,6 +726,8 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) { u3_utat* tat_u = &uty_u->tat_u; + // escape sequences + // if ( c3y == tat_u->esc.ape ) { if ( c3y == tat_u->esc.bra ) { switch ( cay_y ) { @@ -734,6 +739,8 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) case 'B': _term_io_belt(uty_u, u3nc(c3__aro, 'd')); break; case 'C': _term_io_belt(uty_u, u3nc(c3__aro, 'r')); break; case 'D': _term_io_belt(uty_u, u3nc(c3__aro, 'l')); break; + // + case 'M': tat_u->esc.mou = c3y; break; } tat_u->esc.ape = tat_u->esc.bra = c3n; } @@ -760,6 +767,27 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) } } } + // mouse input + // + else if ( c3y == tat_u->esc.mou ) { + if ( 0 == tat_u->esc.ton_y ) { + tat_u->esc.ton_y = cay_y - 31; + } + else if ( 0 == tat_u->esc.col_y ) { + tat_u->esc.col_y = cay_y - 32; + } + else { + c3_y row_y = cay_y - 32; + // only acknowledge button 1 presses within our window + if ( 1 != tat_u->esc.ton_y && row_y <= tat_u->siz.row_l ) { + _term_io_belt(uty_u, u3nt(c3__hit, tat_u->siz.row_l - row_y, tat_u->esc.col_y - 1)); + } + tat_u->esc.mou = c3n; + tat_u->esc.ton_y = tat_u->esc.col_y = 0; + } + } + // unicode inputs + // else if ( 0 != tat_u->fut.wid_w ) { tat_u->fut.syb_y[tat_u->fut.len_w++] = cay_y; @@ -775,6 +803,8 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y) _term_io_belt(uty_u, u3nt(c3__txt, wug, u3_nul)); } } + // individual characters + // else { if ( (cay_y >= 32) && (cay_y < 127) ) { _term_io_belt(uty_u, u3nt(c3__txt, cay_y, u3_nul)); @@ -1615,6 +1645,11 @@ _term_io_talk(u3_auto* car_u) if ( c3n == u3_Host.ops_u.tem ) { u3_utty* uty_u = _term_main(); + // start mouse handling + // + uv_buf_t mon_u = TERM_LIT_BUF("\033[?9h"); + _term_it_dump_buf(uty_u, &mon_u); + uv_read_start((uv_stream_t*)&(uty_u->pop_u), _term_alloc, _term_read_cb); @@ -1781,6 +1816,11 @@ _term_io_exit(u3_auto* car_u) uv_read_stop((uv_stream_t*)&(uty_u->pop_u)); if ( c3n == u3_Host.ops_u.tem ) { + // stop mouse handling + // + uv_buf_t mof_u = TERM_LIT_BUF("\033[?9l"); + _term_it_dump_buf(uty_u, &mof_u); + uv_timer_t* han_u = &(uty_u->tat_u.sun_u.tim_u); han_u->data = car_u;