diff --git a/src/bin/termio.c b/src/bin/termio.c index 004962bb..877fe64f 100644 --- a/src/bin/termio.c +++ b/src/bin/termio.c @@ -2544,10 +2544,20 @@ _smart_cb_mouse_down(void *data, { Evas_Event_Mouse_Down *ev = event; Termio *sd = evas_object_smart_data_get(data); + Termio_Modifiers modifiers = {}; EINA_SAFETY_ON_NULL_RETURN(sd); - termio_internal_mouse_down(sd, ev); + modifiers.alt = evas_key_modifier_is_set(ev->modifiers, "Alt"); + modifiers.shift = evas_key_modifier_is_set(ev->modifiers, "Shift"); + modifiers.ctrl = evas_key_modifier_is_set(ev->modifiers, "Control"); + modifiers.super = evas_key_modifier_is_set(ev->modifiers, "Super"); + modifiers.meta = evas_key_modifier_is_set(ev->modifiers, "Meta"); + modifiers.hyper = evas_key_modifier_is_set(ev->modifiers, "Hyper"); + modifiers.iso_level3_shift = evas_key_modifier_is_set(ev->modifiers, "ISO_Level3_Shift"); + modifiers.altgr= evas_key_modifier_is_set(ev->modifiers, "AltGr"); + + termio_internal_mouse_down(sd, ev, modifiers); } static void @@ -2558,10 +2568,20 @@ _smart_cb_mouse_up(void *data, { Evas_Event_Mouse_Up *ev = event; Termio *sd = evas_object_smart_data_get(data); + Termio_Modifiers modifiers = {}; EINA_SAFETY_ON_NULL_RETURN(sd); - termio_internal_mouse_up(sd, ev); + modifiers.alt = evas_key_modifier_is_set(ev->modifiers, "Alt"); + modifiers.shift = evas_key_modifier_is_set(ev->modifiers, "Shift"); + modifiers.ctrl = evas_key_modifier_is_set(ev->modifiers, "Control"); + modifiers.super = evas_key_modifier_is_set(ev->modifiers, "Super"); + modifiers.meta = evas_key_modifier_is_set(ev->modifiers, "Meta"); + modifiers.hyper = evas_key_modifier_is_set(ev->modifiers, "Hyper"); + modifiers.iso_level3_shift = evas_key_modifier_is_set(ev->modifiers, "ISO_Level3_Shift"); + modifiers.altgr= evas_key_modifier_is_set(ev->modifiers, "AltGr"); + + termio_internal_mouse_up(sd, ev, modifiers); } static void @@ -2572,9 +2592,20 @@ _smart_cb_mouse_move(void *data, { Evas_Event_Mouse_Move *ev = event; Termio *sd = evas_object_smart_data_get(data); + Termio_Modifiers modifiers = {}; + EINA_SAFETY_ON_NULL_RETURN(sd); - termio_internal_mouse_move(sd, ev); + modifiers.alt = evas_key_modifier_is_set(ev->modifiers, "Alt"); + modifiers.shift = evas_key_modifier_is_set(ev->modifiers, "Shift"); + modifiers.ctrl = evas_key_modifier_is_set(ev->modifiers, "Control"); + modifiers.super = evas_key_modifier_is_set(ev->modifiers, "Super"); + modifiers.meta = evas_key_modifier_is_set(ev->modifiers, "Meta"); + modifiers.hyper = evas_key_modifier_is_set(ev->modifiers, "Hyper"); + modifiers.iso_level3_shift = evas_key_modifier_is_set(ev->modifiers, "ISO_Level3_Shift"); + modifiers.altgr= evas_key_modifier_is_set(ev->modifiers, "AltGr"); + + termio_internal_mouse_move(sd, ev, modifiers); } static void diff --git a/src/bin/termiointernals.c b/src/bin/termiointernals.c index cdc0c103..9ecc2b2e 100644 --- a/src/bin/termiointernals.c +++ b/src/bin/termiointernals.c @@ -1385,7 +1385,7 @@ termio_selection_dbl_fix(Termio *sd) static void _handle_mouse_down_single_click(Termio *sd, int cx, int cy, - int ctrl, int alt, int shift) + Termio_Modifiers modifiers) { sd->didclick = EINA_FALSE; /* SINGLE CLICK */ @@ -1435,18 +1435,18 @@ _handle_mouse_down_single_click(Termio *sd, sd->pty->selection.end.y = cy; termio_selection_dbl_fix(sd); } - else if (!shift && alt && !sd->pty->selection.is_active + else if (!modifiers.shift && modifiers.alt && !sd->pty->selection.is_active && (sd->pty->mouse_mode == MOUSE_OFF)) { /* move cursor to position */ termpty_move_cursor(sd->pty, cx, cy); } - else if (!shift && !sd->pty->selection.is_active) + else if (!modifiers.shift && !sd->pty->selection.is_active) { /* New selection */ sd->moved = EINA_FALSE; termio_sel_set(sd, EINA_FALSE); - sd->pty->selection.is_box = (ctrl || alt); + sd->pty->selection.is_box = (modifiers.ctrl || modifiers.alt); sd->pty->selection.start.x = cx; sd->pty->selection.start.y = cy - sd->scroll; sd->pty->selection.orig.x = sd->pty->selection.start.x; @@ -1458,23 +1458,23 @@ _handle_mouse_down_single_click(Termio *sd, sd->pty->selection.by_word = EINA_FALSE; termio_selection_dbl_fix(sd); } - else if (shift && sd->pty->selection.is_active) + else if (modifiers.shift && sd->pty->selection.is_active) { /* let cb_up handle it */ /* do nothing */ return; } - else if (shift && + else if (modifiers.shift && (time(NULL) - sd->pty->selection.last_click) <= 5) { - sd->pty->selection.is_box = ctrl; + sd->pty->selection.is_box = modifiers.ctrl; _sel_to(sd, cx, cy - sd->scroll, EINA_FALSE); sd->pty->selection.is_active = EINA_TRUE; termio_selection_dbl_fix(sd); } else { - sd->pty->selection.is_box = ctrl; + sd->pty->selection.is_box = modifiers.ctrl; sd->pty->selection.start.x = sd->pty->selection.end.x = cx; sd->pty->selection.orig.x = cx; sd->pty->selection.start.y = sd->pty->selection.end.y = cy - sd->scroll; @@ -1487,13 +1487,15 @@ _handle_mouse_down_single_click(Termio *sd, } static Eina_Bool -_rep_mouse_down(Termio *sd, Evas_Event_Mouse_Down *ev, int cx, int cy) +_rep_mouse_down(Termio *sd, Evas_Event_Mouse_Down *ev, + int cx, int cy, Termio_Modifiers modifiers) { char buf[64]; Eina_Bool ret = EINA_FALSE; int btn; - if (sd->pty->mouse_mode == MOUSE_OFF) return EINA_FALSE; + if (sd->pty->mouse_mode == MOUSE_OFF) + return EINA_FALSE; if (!sd->mouse.button) { /* Need to remember the first button pressed for terminal handling */ @@ -1523,7 +1525,7 @@ _rep_mouse_down(Termio *sd, Evas_Event_Mouse_Down *ev, int cx, int cy) } else { - int meta = evas_key_modifier_is_set(ev->modifiers, "Alt") ? 8 : 0; + int meta = (modifiers.alt) ? 8 : 0; if (btn > 2) btn = 0; buf[0] = 0x1b; @@ -1540,7 +1542,7 @@ _rep_mouse_down(Termio *sd, Evas_Event_Mouse_Down *ev, int cx, int cy) break; case MOUSE_EXT_UTF8: // ESC.[.M.BTN/FLGS.XUTF8.YUTF8 { - int meta = evas_key_modifier_is_set(ev->modifiers, "Alt") ? 8 : 0; + int meta = (modifiers.alt) ? 8 : 0; int v, i; if (btn > 2) btn = 0; @@ -1570,7 +1572,7 @@ _rep_mouse_down(Termio *sd, Evas_Event_Mouse_Down *ev, int cx, int cy) break; case MOUSE_EXT_SGR: // ESC.[.<.NUM.;.NUM.;.NUM.M { - int meta = evas_key_modifier_is_set(ev->modifiers, "Alt") ? 8 : 0; + int meta = (modifiers.alt) ? 8 : 0; if (btn > 2) btn = 0; snprintf(buf, sizeof(buf), "%c[<%i;%i;%iM", 0x1b, @@ -1581,7 +1583,7 @@ _rep_mouse_down(Termio *sd, Evas_Event_Mouse_Down *ev, int cx, int cy) break; case MOUSE_EXT_URXVT: // ESC.[.NUM.;.NUM.;.NUM.M { - int meta = evas_key_modifier_is_set(ev->modifiers, "Alt") ? 8 : 0; + int meta = (modifiers.alt) ? 8 : 0; if (btn > 2) btn = 0; snprintf(buf, sizeof(buf), "%c[%i;%i;%iM", 0x1b, @@ -1597,27 +1599,22 @@ _rep_mouse_down(Termio *sd, Evas_Event_Mouse_Down *ev, int cx, int cy) return ret; } - void termio_internal_mouse_down(Termio *sd, - Evas_Event_Mouse_Down *ev) + Evas_Event_Mouse_Down *ev, + Termio_Modifiers modifiers) { int cx, cy; - int shift, ctrl, alt; termio_cursor_to_xy(sd, ev->canvas.x, ev->canvas.y, &cx, &cy); - shift = evas_key_modifier_is_set(ev->modifiers, "Shift"); - ctrl = evas_key_modifier_is_set(ev->modifiers, "Control"); - alt = evas_key_modifier_is_set(ev->modifiers, "Alt"); - - if ((ev->button == 3) && ctrl) + if ((ev->button == 3) && modifiers.ctrl) { termio_handle_right_click(ev, sd, cx, cy); return; } - if (!shift && !ctrl) - if (_rep_mouse_down(sd, ev, cx, cy)) + if (!modifiers.shift && !modifiers.ctrl) + if (_rep_mouse_down(sd, ev, cx, cy, modifiers)) { if (sd->pty->selection.is_active) { @@ -1631,7 +1628,7 @@ termio_internal_mouse_down(Termio *sd, sd->pty->selection.makesel = EINA_TRUE; if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK) { - if (shift && sd->pty->selection.is_active) + if (modifiers.shift && sd->pty->selection.is_active) _sel_line_to(sd, cy - sd->scroll, EINA_TRUE); else _sel_line(sd, cy - sd->scroll); @@ -1646,7 +1643,7 @@ termio_internal_mouse_down(Termio *sd, { if (!sd->pty->selection.is_active && sd->didclick) sd->pty->selection.is_active = EINA_TRUE; - if (shift && sd->pty->selection.is_active) + if (modifiers.shift && sd->pty->selection.is_active) _sel_word_to(sd, cx, cy - sd->scroll, EINA_TRUE); else _sel_word(sd, cx, cy - sd->scroll); @@ -1660,7 +1657,7 @@ termio_internal_mouse_down(Termio *sd, } else { - _handle_mouse_down_single_click(sd, cx, cy, ctrl, alt, shift); + _handle_mouse_down_single_click(sd, cx, cy, modifiers); } termio_smart_update_queue(sd); } @@ -1675,7 +1672,8 @@ termio_internal_mouse_down(Termio *sd, } static Eina_Bool -_rep_mouse_up(Termio *sd, Evas_Event_Mouse_Up *ev, int cx, int cy) +_rep_mouse_up(Termio *sd, Evas_Event_Mouse_Up *ev, + int cx, int cy, Termio_Modifiers modifiers) { char buf[64]; Eina_Bool ret = EINA_FALSE; @@ -1687,7 +1685,7 @@ _rep_mouse_up(Termio *sd, Evas_Event_Mouse_Up *ev, int cx, int cy) if (sd->mouse.button == ev->button) sd->mouse.button = 0; - meta = evas_key_modifier_is_set(ev->modifiers, "Alt") ? 8 : 0; + meta = (modifiers.alt) ? 8 : 0; switch (sd->pty->mouse_ext) { @@ -1845,18 +1843,15 @@ _rep_mouse_move(Termio *sd, int cx, int cy) void termio_internal_mouse_up(Termio *sd, - Evas_Event_Mouse_Up *ev) + Evas_Event_Mouse_Up *ev, + Termio_Modifiers modifiers) { - int shift, ctrl; int cx = 0, cy = 0; termio_cursor_to_xy(sd, ev->canvas.x, ev->canvas.y, &cx, &cy); - shift = evas_key_modifier_is_set(ev->modifiers, "Shift"); - ctrl = evas_key_modifier_is_set(ev->modifiers, "Control"); - - if (!shift && !ctrl && !sd->pty->selection.makesel) - if (_rep_mouse_up(sd, ev, cx, cy)) + if (!modifiers.shift && !modifiers.ctrl && !sd->pty->selection.makesel) + if (_rep_mouse_up(sd, ev, cx, cy, modifiers)) { if (sd->pty->selection.is_active) { @@ -1895,15 +1890,15 @@ termio_internal_mouse_up(Termio *sd, { if (sd->pty->selection.by_line) { - _sel_line_to(sd, cy - sd->scroll, shift); + _sel_line_to(sd, cy - sd->scroll, modifiers.shift); } else if (sd->pty->selection.by_word) { - _sel_word_to(sd, cx, cy - sd->scroll, shift); + _sel_word_to(sd, cx, cy - sd->scroll, modifiers.shift); } else { - if (shift) + if (modifiers.shift) { /* extend selection */ _sel_to(sd, cx, cy - sd->scroll, EINA_TRUE); @@ -1977,24 +1972,23 @@ termio_cursor_to_xy(Termio *sd, Evas_Coord x, Evas_Coord y, void termio_internal_mouse_move(Termio *sd, - Evas_Event_Mouse_Move *ev) + Evas_Event_Mouse_Move *ev, + Termio_Modifiers modifiers) { int cx, cy; float fcy; Evas_Coord ox, oy; - int shift, ctrl; Eina_Bool scroll = EINA_FALSE; termio_object_geometry_get(sd, &ox, &oy, NULL, NULL); cx = (ev->cur.canvas.x - ox) / sd->font.chw; fcy = (ev->cur.canvas.y - oy) / (float)sd->font.chh; - shift = evas_key_modifier_is_set(ev->modifiers, "Shift"); - ctrl = evas_key_modifier_is_set(ev->modifiers, "Control"); - cy = fcy; - if (cx < 0) cx = 0; - else if (cx >= sd->grid.w) cx = sd->grid.w - 1; + if (cx < 0) + cx = 0; + else if (cx >= sd->grid.w) + cx = sd->grid.w - 1; if (fcy < 0.3) { cy = 0; @@ -2026,8 +2020,11 @@ termio_internal_mouse_move(Termio *sd, sd->mouse.cx = cx; sd->mouse.cy = cy; - if (!shift && !ctrl) - if (_rep_mouse_move(sd, cx, cy)) return; + if (!modifiers.shift && !modifiers.ctrl) + { + if (_rep_mouse_move(sd, cx, cy)) + return; + } if (sd->link.down.dnd) { sd->pty->selection.makesel = EINA_FALSE; diff --git a/src/bin/termiointernals.h b/src/bin/termiointernals.h index d9e4f422..641fa3d6 100644 --- a/src/bin/termiointernals.h +++ b/src/bin/termiointernals.h @@ -86,17 +86,39 @@ struct _Termio double gesture_zoom_start_size; }; +typedef struct _Termio_Modifiers Termio_Modifiers; +struct _Termio_Modifiers +{ + unsigned char alt : 1; + unsigned char shift : 1; + unsigned char ctrl : 1; + unsigned char super : 1; + unsigned char meta : 1; + unsigned char hyper : 1; + unsigned char iso_level3_shift : 1; + unsigned char altgr : 1; +}; + + #define INT_SWAP(_a, _b) do { \ int _swap = _a; _a = _b; _b = _swap; \ } while (0) + void -termio_internal_mouse_down(Termio *sd, Evas_Event_Mouse_Down *ev); +termio_internal_mouse_down(Termio *sd, + Evas_Event_Mouse_Down *ev, + Termio_Modifiers modifiers); + void -termio_internal_mouse_up(Termio *sd, Evas_Event_Mouse_Up *ev); +termio_internal_mouse_up(Termio *sd, + Evas_Event_Mouse_Up *ev, + Termio_Modifiers modifiers); void -termio_internal_mouse_move(Termio *sd, Evas_Event_Mouse_Move *ev); +termio_internal_mouse_move(Termio *sd, + Evas_Event_Mouse_Move *ev, + Termio_Modifiers modifiers); void termio_selection_dbl_fix(Termio *sd); diff --git a/src/bin/termptyext.c b/src/bin/termptyext.c index 888e8403..592b6aba 100644 --- a/src/bin/termptyext.c +++ b/src/bin/termptyext.c @@ -1,7 +1,9 @@ #include "private.h" #include +#include "termio.h" #include "termpty.h" #include "termptyops.h" +#include "termiointernals.h" #include "tytest.h" #include @@ -17,6 +19,14 @@ #define INF(...) EINA_LOG_DOM_INFO(_termpty_log_dom, __VA_ARGS__) #define DBG(...) EINA_LOG_DOM_DBG(_termpty_log_dom, __VA_ARGS__) +#if defined(ENABLE_TESTS) + #define WITH_TESTS 1 +#else + #define WITH_TESTS 0 +#endif +// Uncomment following to enable testing escape codes within terminology +//#define WITH_TESTS 1 + //// extended terminology escape handling goes in here // // this is where escapes get handled *IF* the termpty layer needs to interpret @@ -36,7 +46,7 @@ static Eina_Bool _handle_op_a(Termpty *_ty EINA_UNUSED, const Eina_Unicode *buf EINA_UNUSED, - size_t blen) + size_t blen EINA_UNUSED) { switch (buf[0]) { @@ -49,6 +59,192 @@ _handle_op_a(Termpty *_ty EINA_UNUSED, return EINA_FALSE; } +#if WITH_TESTS + +static int +_tytest_arg_get(const Eina_Unicode *buf, int *value) +{ + int len = 0; + int sum = 0; + + if (*buf == ';') + { + len++; + } + + while (buf[len] >= '0' && buf[len] <= '9') + { + sum *= 10; + sum += buf[len] - '0'; + len++; + } + *value = sum; + return len; +} + +/** + * MODIFIERS is a bit field with the following values: + * - Alt + * - Shift + * - Ctrl + * - Super + * - Meta + * - Hyper + * - ISO_Level3_Shift + * - AltGr + */ + +/** + * FLAGS can be: + * - 0 + * - 1: SINGLE_CLICK + * - 2: DOUBLE_CLICK + * - 3: TRIPLE_CLICK + */ + +/* + * Format is td;X;Y;BUTTON;MODIFIERS;FLAGS + */ +static void +_handle_mouse_down(Termpty *ty, + const Eina_Unicode *buf) +{ + Evas_Event_Mouse_Down ev = {}; + Termio *sd = termio_get_from_obj(ty->obj); + Termio_Modifiers modifiers = {}; + int value; + + /* X */ + value = 0; + buf += _tytest_arg_get(buf, &value); + ev.canvas.x = value; + /* Y */ + value = 0; + buf += _tytest_arg_get(buf, &value); + ev.canvas.y = value; + /* BUTTON */ + value = 0; + buf += _tytest_arg_get(buf, &value); + ev.button = value; + /* MODIFIERS */ + value = 0; + buf += _tytest_arg_get(buf, &value); + union { + Termio_Modifiers m; + uint8_t u; + } u; + u.u = value; + modifiers = u.m; + /* FLAGS */ + value = 0; + buf +=_tytest_arg_get(buf, &value); + ev.flags = value; + + termio_internal_mouse_down(sd, &ev, modifiers); +} + +/* + * Format is tu;X;Y;BUTTON;MODIFIERS;FLAGS + */ +static void +_handle_mouse_up(Termpty *ty, + const Eina_Unicode *buf) +{ + Evas_Event_Mouse_Up ev = {}; + Termio *sd = termio_get_from_obj(ty->obj); + Termio_Modifiers modifiers = {}; + int value; + + /* X */ + value = 0; + buf += _tytest_arg_get(buf, &value); + ev.canvas.x = value; + /* Y */ + value = 0; + buf += _tytest_arg_get(buf, &value); + ev.canvas.y = value; + /* BUTTON */ + value = 0; + buf += _tytest_arg_get(buf, &value); + ev.button = value; + /* MODIFIERS */ + value = 0; + buf += _tytest_arg_get(buf, &value); + union { + Termio_Modifiers m; + uint8_t u; + } u; + u.u = value; + modifiers = u.m; + /* FLAGS */ + value = 0; + buf +=_tytest_arg_get(buf, &value); + ev.flags = value; + + termio_internal_mouse_up(sd, &ev, modifiers); +} + +/* + * Format is tm;X;Y;MODIFIERS + */ +static void +_handle_mouse_move(Termpty *ty, + const Eina_Unicode *buf) +{ + Evas_Event_Mouse_Move ev = {}; + Termio *sd = termio_get_from_obj(ty->obj); + Termio_Modifiers modifiers = {}; + int value; + + /* X */ + value = 0; + buf += _tytest_arg_get(buf, &value); + ev.cur.canvas.x = value; + /* Y */ + value = 0; + buf += _tytest_arg_get(buf, &value); + ev.cur.canvas.y = value; + /* MODIFIERS */ + value = 0; + buf += _tytest_arg_get(buf, &value); + union { + Termio_Modifiers m; + uint8_t u; + } u; + u.u = value; + modifiers = u.m; + + termio_internal_mouse_move(sd, &ev, modifiers); +} + +/* Testing escape codes that start with '\033}t' and end with '\0' + * Then, + * - 'd': mouse down: + * - 'u': mouse up; + * - 'm': mouse move; + */ +static void +tytest_handle_escape_codes(Termpty *ty, + const Eina_Unicode *buf) +{ + switch (buf[0]) + { + case 'd': + return _handle_mouse_down(ty, buf + 1); + break; + case 'm': + return _handle_mouse_move(ty, buf + 1); + break; + case 'u': + return _handle_mouse_up(ty, buf + 1); + break; + default: + break; + } +} +#endif + + Eina_Bool termpty_ext_handle(Termpty *ty, const Eina_Unicode *buf, @@ -60,9 +256,9 @@ termpty_ext_handle(Termpty *ty, return _handle_op_a(ty, buf + 1, blen - 1); break; // room here for more major opcode chars like 'b', 'c' etc. -#if defined(ENABLE_TESTS) +#if WITH_TESTS case 't': - tytest_handle_escape_codes(ty, buf + 1, blen - 1); + tytest_handle_escape_codes(ty, buf + 1); return EINA_FALSE; break; #endif diff --git a/src/bin/tytest.c b/src/bin/tytest.c index f33bb61b..9c907bf9 100644 --- a/src/bin/tytest.c +++ b/src/bin/tytest.c @@ -151,29 +151,3 @@ _tytest_checksum(Termpty *ty) md5out[2 * MD5_HASHBYTES] = '\0'; printf("%s", md5out); } - -static void -_handle_mouse_down(Termpty *ty EINA_UNUSED, - const Eina_Unicode *buf EINA_UNUSED, - size_t blen EINA_UNUSED) -{ -} - -/* Testing escape codes that start with '\033}t' and end with '\0' - * Then, - * - 'd': mouse down: - */ -void -tytest_handle_escape_codes(Termpty *ty, - const Eina_Unicode *buf, - size_t blen) -{ - switch (buf[0]) - { - case 'd': - return _handle_mouse_down(ty, buf + 1, blen - 1); - break; - default: - break; - } -} diff --git a/src/bin/tytest.h b/src/bin/tytest.h index 2164ff0e..e702cec5 100644 --- a/src/bin/tytest.h +++ b/src/bin/tytest.h @@ -11,9 +11,5 @@ test_textgrid_palette_get(const Evas_Object *obj, int *g, int *b, int *a); -void -tytest_handle_escape_codes(Termpty *ty, - const Eina_Unicode *buf, - size_t blen); #endif #endif