aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demo-draw.c1
-rw-r--r--demo.c39
-rw-r--r--driver-ti.c77
-rw-r--r--termo-internal.h11
-rw-r--r--termo.c27
-rw-r--r--termo.h24
6 files changed, 102 insertions, 77 deletions
diff --git a/demo-draw.c b/demo-draw.c
index 10cbe3b..26b583f 100644
--- a/demo-draw.c
+++ b/demo-draw.c
@@ -165,7 +165,6 @@ main (int argc, char *argv[])
exit (EXIT_FAILURE);
}
- termo_set_mouse_proto (tk, termo_guess_mouse_proto (tk));
termo_set_mouse_tracking_mode (tk, TERMO_MOUSE_TRACKING_DRAG);
// Set up curses for our drawing needs
diff --git a/demo.c b/demo.c
index d74892c..bc416c0 100644
--- a/demo.c
+++ b/demo.c
@@ -5,6 +5,7 @@
#include <unistd.h>
#include <errno.h>
#include <locale.h>
+#include <strings.h>
#include "termo.h"
@@ -14,31 +15,33 @@ main(int argc, char *argv[])
TERMO_CHECK_VERSION;
setlocale (LC_CTYPE, "");
- int mouse = 0;
- int mouse_proto = 0;
+ termo_mouse_tracking_t mouse = TERMO_MOUSE_TRACKING_OFF;
termo_format_t format = TERMO_FORMAT_VIM;
char buffer[50];
termo_t *tk;
int opt;
- while ((opt = getopt (argc, argv, "m::p:")) != -1)
+ while ((opt = getopt (argc, argv, "m::")) != -1)
{
switch (opt)
{
case 'm':
- if (optarg)
- mouse = atoi (optarg);
- else
- mouse = 1000;
- break;
-
- case 'p':
- mouse_proto = atoi (optarg);
+ if (!optarg)
+ mouse = TERMO_MOUSE_TRACKING_DRAG;
+ else if (!strcasecmp (optarg, "off"))
+ mouse = TERMO_MOUSE_TRACKING_OFF;
+ else if (!strcasecmp (optarg, "click"))
+ mouse = TERMO_MOUSE_TRACKING_CLICK;
+ else if (!strcasecmp (optarg, "drag"))
+ mouse = TERMO_MOUSE_TRACKING_DRAG;
+ else if (!strcasecmp (optarg, "move"))
+ mouse = TERMO_MOUSE_TRACKING_MOVE;
break;
default:
- fprintf (stderr, "Usage: %s [-m]\n", argv[0]);
+ fprintf (stderr,
+ "Usage: %s [ -m [ off | click | drag | move ]]\n", argv[0]);
return 1;
}
}
@@ -59,12 +62,9 @@ main(int argc, char *argv[])
termo_result_t ret;
termo_key_t key;
- if (mouse)
- {
- printf ("\033[?%dhMouse mode active\n", mouse);
- if (mouse_proto)
- printf ("\033[?%dh", mouse_proto);
- }
+ termo_set_mouse_tracking_mode (tk, mouse);
+ if (mouse != TERMO_MOUSE_TRACKING_OFF)
+ printf ("Mouse mode active\n");
while ((ret = termo_waitkey (tk, &key)) != TERMO_RES_EOF)
{
@@ -130,8 +130,5 @@ main(int argc, char *argv[])
}
}
- if (mouse)
- printf ("\033[?%dlMouse mode deactivated\n", mouse);
-
termo_destroy (tk);
}
diff --git a/driver-ti.c b/driver-ti.c
index e31de47..6ac213f 100644
--- a/driver-ti.c
+++ b/driver-ti.c
@@ -58,7 +58,6 @@ typedef struct
char *start_string;
char *stop_string;
- bool have_mouse;
char *set_mouse_string;
}
termo_ti_t;
@@ -243,11 +242,12 @@ load_terminfo (termo_ti_t *ti, const char *term)
else
ti->set_mouse_string = strdup (set_mouse_string);
+ bool have_mouse = false;
if (!mouse_report_string && strstr (term, "xterm"))
mouse_report_string = "\x1b[M";
if (mouse_report_string)
{
- ti->have_mouse = true;
+ have_mouse = true;
trie_node_t *node = malloc (sizeof *node);
if (!node)
@@ -261,7 +261,7 @@ load_terminfo (termo_ti_t *ti, const char *term)
}
}
- if (!ti->have_mouse)
+ if (!have_mouse)
ti->tk->guessed_mouse_proto = TERMO_MOUSE_PROTO_NONE;
else if (strstr (term, "rxvt") == term)
// urxvt generally doesn't understand the SGR protocol.
@@ -276,6 +276,9 @@ load_terminfo (termo_ti_t *ti, const char *term)
// are illegal in the current locale's charset.
ti->tk->guessed_mouse_proto = TERMO_MOUSE_PROTO_SGR;
+ // Preset the active protocol to our wild guess
+ ti->tk->mouse_proto = ti->tk->guessed_mouse_proto;
+
// Take copies of these terminfo strings, in case we build multiple termo
// instances for multiple different termtypes, and it's different by the
// time we want to use it
@@ -346,39 +349,39 @@ mouse_reset (termo_ti_t *ti)
{
// Disable everything, a de-facto reset for all terminal mouse protocols
return set_mouse (ti, false)
- && write_string (ti->tk, "\E[?1002l")
- && write_string (ti->tk, "\E[?1003l")
+ && write_string (ti->tk, "\x1b[?1002l")
+ && write_string (ti->tk, "\x1b[?1003l")
- && write_string (ti->tk, "\E[?1005l")
- && write_string (ti->tk, "\E[?1006l")
- && write_string (ti->tk, "\E[?1015l");
+ && write_string (ti->tk, "\x1b[?1005l")
+ && write_string (ti->tk, "\x1b[?1006l")
+ && write_string (ti->tk, "\x1b[?1015l");
}
static bool
-mouse_set_proto (void *data, int proto, bool enable)
+mouse_set_tracking_mode (void *data,
+ termo_mouse_tracking_t tracking, bool enable)
{
termo_ti_t *ti = data;
- bool success = true;
- if (proto & TERMO_MOUSE_PROTO_VT200)
- success &= set_mouse (ti, enable);
- if (proto & TERMO_MOUSE_PROTO_UTF8)
- success &= write_string (ti->tk, enable ? "\E[?1005h" : "\E[?1005l");
- if (proto & TERMO_MOUSE_PROTO_SGR)
- success &= write_string (ti->tk, enable ? "\E[?1006h" : "\E[?1006l");
- if (proto & TERMO_MOUSE_PROTO_RXVT)
- success &= write_string (ti->tk, enable ? "\E[?1015h" : "\E[?1015l");
- return success;
+ if (tracking == TERMO_MOUSE_TRACKING_CLICK)
+ return set_mouse (ti, enable);
+ if (tracking == TERMO_MOUSE_TRACKING_DRAG)
+ return write_string (ti->tk, enable ? "\x1b[?1002h" : "\x1b[?1002l");
+ if (tracking == TERMO_MOUSE_TRACKING_MOVE)
+ return write_string (ti->tk, enable ? "\x1b[?1003h" : "\x1b[?1003l");
+ return true;
}
static bool
-mouse_set_tracking_mode (void *data,
- termo_mouse_tracking_t tracking, bool enable)
+mouse_set_proto (void *data, termo_mouse_proto_t proto, bool enable)
{
termo_ti_t *ti = data;
- if (tracking == TERMO_MOUSE_TRACKING_DRAG)
- return write_string (ti->tk, enable ? "\E[?1002h" : "\E[?1002l");
- if (tracking == TERMO_MOUSE_TRACKING_ANY)
- return write_string (ti->tk, enable ? "\E[?1003h" : "\E[?1003l");
+ // TERMO_MOUSE_PROTO_XTERM is ignored here; it is the default protocol
+ if (proto == TERMO_MOUSE_PROTO_UTF8)
+ return write_string (ti->tk, enable ? "\x1b[?1005h" : "\x1b[?1005l");
+ if (proto == TERMO_MOUSE_PROTO_SGR)
+ return write_string (ti->tk, enable ? "\x1b[?1006h" : "\x1b[?1006l");
+ if (proto == TERMO_MOUSE_PROTO_RXVT)
+ return write_string (ti->tk, enable ? "\x1b[?1015h" : "\x1b[?1015l");
return true;
}
@@ -386,10 +389,17 @@ static int
start_driver (termo_t *tk, void *info)
{
termo_ti_t *ti = info;
- return write_string (tk, ti->start_string)
- && ((!ti->have_mouse && tk->mouse_proto == TERMO_MOUSE_PROTO_NONE)
- || mouse_reset (ti)) // We can never be sure
- && mouse_set_proto (ti, tk->mouse_proto, true)
+ if (!write_string (tk, ti->start_string))
+ return false;
+
+ // If there's no protocol, it doesn't make sense to try anything else
+ if (tk->mouse_proto == TERMO_MOUSE_PROTO_NONE)
+ return true;
+
+ // Disable everything mouse-related first
+ if (!mouse_reset (ti))
+ return false;
+ return mouse_set_proto (ti, tk->mouse_proto, true)
&& mouse_set_tracking_mode (ti, tk->mouse_tracking, true);
}
@@ -397,8 +407,13 @@ static int
stop_driver (termo_t *tk, void *info)
{
termo_ti_t *ti = info;
- return write_string (tk, ti->stop_string)
- && mouse_set_proto (ti, tk->mouse_proto, false)
+ if (!write_string (tk, ti->stop_string))
+ return false;
+
+ // If there's no protocol, it doesn't make sense to try anything else
+ if (tk->mouse_proto == TERMO_MOUSE_PROTO_NONE)
+ return true;
+ return mouse_set_proto (ti, tk->mouse_proto, false)
&& mouse_set_tracking_mode (ti, tk->mouse_tracking, false);
}
diff --git a/termo-internal.h b/termo-internal.h
index b2b1c3a..adf3e8f 100644
--- a/termo-internal.h
+++ b/termo-internal.h
@@ -81,9 +81,12 @@ struct termo
}
method;
- int guessed_mouse_proto; // What we think should be the mouse protocol
- int mouse_proto; // The active mouse protocol
- termo_mouse_tracking_t mouse_tracking; // Mouse tracking mode
+ // What we think should be the mouse protocol
+ termo_mouse_proto_t guessed_mouse_proto;
+ // The active mouse protocol
+ termo_mouse_proto_t mouse_proto;
+ // Mouse tracking mode
+ termo_mouse_tracking_t mouse_tracking;
// The mouse unfortunately directly depends on the terminfo driver to let
// it handle changes in the mouse protocol.
@@ -92,7 +95,7 @@ struct termo
struct
{
- bool (*set_mouse_proto) (void *, int, bool);
+ bool (*set_mouse_proto) (void *, termo_mouse_proto_t, bool);
bool (*set_mouse_tracking_mode) (void *, termo_mouse_tracking_t, bool);
}
ti_method;
diff --git a/termo.c b/termo.c
index 063a5a7..e88e74d 100644
--- a/termo.c
+++ b/termo.c
@@ -315,7 +315,7 @@ termo_alloc (void)
tk->method.peekkey_mouse = &peekkey_mouse;
tk->mouse_proto = TERMO_MOUSE_PROTO_NONE;
- tk->mouse_tracking = TERMO_MOUSE_TRACKING_NORMAL;
+ tk->mouse_tracking = TERMO_MOUSE_TRACKING_CLICK;
tk->guessed_mouse_proto = TERMO_MOUSE_PROTO_NONE;
tk->ti_data = NULL;
@@ -638,28 +638,35 @@ termo_get_buffer_remaining (termo_t *tk)
return tk->buffsize - tk->buffcount;
}
-int
-termo_get_mouse_proto (termo_t *tk)
+termo_mouse_proto_t
+termo_get_mouse_proto(termo_t *tk)
{
return tk->mouse_proto;
}
-int
-termo_guess_mouse_proto (termo_t *tk)
+termo_mouse_proto_t
+termo_guess_mouse_proto(termo_t *tk)
{
return tk->guessed_mouse_proto;
}
int
-termo_set_mouse_proto (termo_t *tk, int proto)
+termo_set_mouse_proto (termo_t *tk, termo_mouse_proto_t proto)
{
- int old_proto = tk->mouse_proto;
+ termo_mouse_proto_t old_proto = tk->mouse_proto;
tk->mouse_proto = proto;
// Call the TI driver to apply the change if needed
- if (!tk->is_started
+ if (proto == old_proto
+ || !tk->is_started
|| !tk->ti_method.set_mouse_proto)
return true;
+
+ // Unsetting the protocol disables tracking; this is a bit hackish
+ if (!tk->ti_method.set_mouse_tracking_mode (tk->ti_data,
+ tk->mouse_tracking, proto != TERMO_MOUSE_PROTO_NONE))
+ return false;
+
return tk->ti_method.set_mouse_proto (tk->ti_data, old_proto, false)
&& tk->ti_method.set_mouse_proto (tk->ti_data, proto, true);
}
@@ -677,9 +684,11 @@ termo_set_mouse_tracking_mode (termo_t *tk, termo_mouse_tracking_t mode)
tk->mouse_tracking = mode;
// Call the TI driver to apply the change if needed
- if (!tk->is_started
+ if (mode == old_mode
+ || !tk->is_started
|| !tk->ti_method.set_mouse_tracking_mode)
return true;
+
return tk->ti_method.set_mouse_tracking_mode (tk->ti_data, old_mode, false)
&& tk->ti_method.set_mouse_tracking_mode (tk->ti_data, mode, true);
}
diff --git a/termo.h b/termo.h
index f6a82b1..9df3e73 100644
--- a/termo.h
+++ b/termo.h
@@ -124,21 +124,23 @@ enum termo_mouse_event
// You will want to handle GPM (incompatible license) and FreeBSD's sysmouse
// yourself. http://www.monkey.org/openbsd/archive/tech/0009/msg00018.html
-enum
+typedef enum termo_mouse_proto termo_mouse_proto_t;
+enum termo_mouse_proto
{
- TERMO_MOUSE_PROTO_NONE = 0,
- TERMO_MOUSE_PROTO_VT200 = 1 << 0,
- TERMO_MOUSE_PROTO_UTF8 = 1 << 1 | TERMO_MOUSE_PROTO_VT200,
- TERMO_MOUSE_PROTO_SGR = 1 << 2 | TERMO_MOUSE_PROTO_VT200,
- TERMO_MOUSE_PROTO_RXVT = 1 << 3 | TERMO_MOUSE_PROTO_VT200
+ TERMO_MOUSE_PROTO_NONE,
+ TERMO_MOUSE_PROTO_XTERM,
+ TERMO_MOUSE_PROTO_UTF8,
+ TERMO_MOUSE_PROTO_SGR,
+ TERMO_MOUSE_PROTO_RXVT
};
typedef enum termo_mouse_tracking termo_mouse_tracking_t;
enum termo_mouse_tracking
{
- TERMO_MOUSE_TRACKING_NORMAL,
+ TERMO_MOUSE_TRACKING_OFF,
+ TERMO_MOUSE_TRACKING_CLICK,
TERMO_MOUSE_TRACKING_DRAG,
- TERMO_MOUSE_TRACKING_ANY
+ TERMO_MOUSE_TRACKING_MOVE
};
enum
@@ -229,9 +231,9 @@ size_t termo_get_buffer_remaining (termo_t *tk);
void termo_canonicalise (termo_t *tk, termo_key_t *key);
-int termo_get_mouse_proto (termo_t *tk);
-int termo_set_mouse_proto (termo_t *tk, int proto);
-int termo_guess_mouse_proto (termo_t *tk);
+termo_mouse_proto_t termo_get_mouse_proto (termo_t *tk);
+int termo_set_mouse_proto (termo_t *tk, termo_mouse_proto_t proto);
+termo_mouse_proto_t termo_guess_mouse_proto (termo_t *tk);
termo_mouse_tracking_t termo_get_mouse_tracking_mode (termo_t *tk);
int termo_set_mouse_tracking_mode (termo_t *tk, termo_mouse_tracking_t mode);