2012-07-13 02:12:01 -07:00
|
|
|
|
#include "private.h"
|
|
|
|
|
#include <Elementary.h>
|
2019-11-23 14:31:21 -08:00
|
|
|
|
#include "termpty.h"
|
|
|
|
|
#include "backlog.h"
|
2018-09-26 10:59:33 -07:00
|
|
|
|
#include "termiolink.h"
|
2012-07-13 02:12:01 -07:00
|
|
|
|
#include "termio.h"
|
2016-11-06 10:45:46 -08:00
|
|
|
|
#include "sb.h"
|
|
|
|
|
#include "utf8.h"
|
2012-10-09 08:11:09 -07:00
|
|
|
|
#include "utils.h"
|
2012-07-13 02:12:01 -07:00
|
|
|
|
|
2020-05-31 13:27:28 -07:00
|
|
|
|
__attribute__((const))
|
2020-04-02 12:52:04 -07:00
|
|
|
|
static Eina_Bool
|
|
|
|
|
_isspace_unicode(const int codepoint)
|
|
|
|
|
{
|
|
|
|
|
switch (codepoint)
|
|
|
|
|
{
|
|
|
|
|
case 9: // character tabulation
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 10: // line feed
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 11: // line tabulation
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 12: // form feed
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 13: // carriage return
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 32: // space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 133: // next line
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 160: // no-break space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 5760: // ogham space mark
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 6158: // mongolian vowel separator
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8192: // en quad
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8193: // em quad
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8194: // en space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8195: // em space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8196: // three-per-em space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8197: // four-per-em space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8198: // six-per-em space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8199: // figure space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8200: // puncturation space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8201: // thin space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8202: // hair space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8203: // zero width space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8204: // zero width non-joiner
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8205: // zero width joiner
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8232: // line separator
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8233: // paragraph separator
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8239: // narrow no-break space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8287: // medium mathematical space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 8288: // word joiner
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 12288: // ideographic space
|
2020-06-04 13:44:39 -07:00
|
|
|
|
return EINA_TRUE;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
case 65279: // zero width non-breaking space
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
}
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-10-09 10:09:26 -07:00
|
|
|
|
static char *
|
|
|
|
|
_cwd_path_get(const Evas_Object *obj, const char *relpath)
|
|
|
|
|
{
|
2012-10-09 10:32:29 -07:00
|
|
|
|
char cwdpath[PATH_MAX], tmppath[PATH_MAX];
|
2012-10-09 10:09:26 -07:00
|
|
|
|
|
2012-10-09 10:32:29 -07:00
|
|
|
|
if (!termio_cwd_get(obj, cwdpath, sizeof(cwdpath)))
|
|
|
|
|
return NULL;
|
2012-10-09 10:09:26 -07:00
|
|
|
|
|
|
|
|
|
eina_str_join(tmppath, sizeof(tmppath), '/', cwdpath, relpath);
|
|
|
|
|
return strdup(tmppath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *
|
2016-10-05 13:00:22 -07:00
|
|
|
|
_home_path_get(const Evas_Object *_obj EINA_UNUSED,
|
|
|
|
|
const char *relpath)
|
2012-10-09 10:09:26 -07:00
|
|
|
|
{
|
2012-10-09 10:20:27 -07:00
|
|
|
|
char tmppath[PATH_MAX], homepath[PATH_MAX];
|
|
|
|
|
|
|
|
|
|
if (!homedir_get(homepath, sizeof(homepath)))
|
|
|
|
|
return NULL;
|
2012-10-09 10:09:26 -07:00
|
|
|
|
|
2012-10-09 10:20:27 -07:00
|
|
|
|
eina_str_join(tmppath, sizeof(tmppath), '/', homepath, relpath);
|
2012-10-09 10:09:26 -07:00
|
|
|
|
return strdup(tmppath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
_local_path_get(const Evas_Object *obj, const char *relpath)
|
|
|
|
|
{
|
|
|
|
|
if (relpath[0] == '/')
|
|
|
|
|
return strdup(relpath);
|
|
|
|
|
else if (eina_str_has_prefix(relpath, "~/"))
|
|
|
|
|
return _home_path_get(obj, relpath + 2);
|
|
|
|
|
else
|
|
|
|
|
return _cwd_path_get(obj, relpath);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-15 04:18:56 -07:00
|
|
|
|
/* isalpha() may produce unsigned-integer-overflow
|
|
|
|
|
* runtime error: unsigned integer overflow: 32 - 97 cannot be represented in
|
|
|
|
|
* type 'unsigned int'
|
|
|
|
|
* int isalpha(int c)
|
|
|
|
|
* {
|
|
|
|
|
* return ((unsigned)c|32)-'a' < 26;
|
|
|
|
|
* }
|
|
|
|
|
*/
|
|
|
|
|
#if defined(__clang__)
|
|
|
|
|
__attribute__((no_sanitize("unsigned-integer-overflow")))
|
|
|
|
|
#endif
|
2019-09-15 08:47:07 -07:00
|
|
|
|
Eina_Bool
|
|
|
|
|
link_is_protocol(const char *str)
|
|
|
|
|
{
|
|
|
|
|
const char *p = str;
|
2020-04-19 14:23:57 -07:00
|
|
|
|
int c;
|
2019-09-15 08:47:07 -07:00
|
|
|
|
|
2020-04-19 14:23:57 -07:00
|
|
|
|
if (!str)
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
|
|
c = *p;
|
2019-09-15 08:47:07 -07:00
|
|
|
|
if (!isalpha(c))
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
|
|
/* Try to follow RFC3986 a bit
|
|
|
|
|
* URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
|
|
|
|
|
* hier-part = "//" authority path-abempty
|
|
|
|
|
* [...] other stuff not taken into account
|
|
|
|
|
* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
p++;
|
|
|
|
|
c = *p;
|
|
|
|
|
}
|
|
|
|
|
while (isalpha(c) || (c == '.') || (c == '-') || (c == '+'));
|
|
|
|
|
|
|
|
|
|
return (p[0] == ':') && (p[1] == '/') && (p[2] == '/');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Eina_Bool
|
|
|
|
|
link_is_url(const char *str)
|
|
|
|
|
{
|
2020-04-19 14:23:57 -07:00
|
|
|
|
if (!str)
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
2019-09-15 08:47:07 -07:00
|
|
|
|
if (link_is_protocol(str) ||
|
|
|
|
|
casestartswith(str, "www.") ||
|
|
|
|
|
casestartswith(str, "ftp."))
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Eina_Bool
|
|
|
|
|
link_is_email(const char *str)
|
|
|
|
|
{
|
2020-04-19 14:23:57 -07:00
|
|
|
|
const char *at;
|
|
|
|
|
|
|
|
|
|
if (!str)
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
|
|
at = strchr(str, '@');
|
2019-09-15 08:47:07 -07:00
|
|
|
|
if (at && strchr(at + 1, '.'))
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
if (casestartswith(str, "mailto:"))
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Eina_Bool
|
|
|
|
|
link_is_file(const char *str)
|
2012-10-09 10:09:26 -07:00
|
|
|
|
{
|
2020-04-19 14:23:57 -07:00
|
|
|
|
if (!str)
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
2012-10-09 10:09:26 -07:00
|
|
|
|
switch (str[0])
|
|
|
|
|
{
|
|
|
|
|
case '/':
|
2012-12-24 17:15:56 -08:00
|
|
|
|
return EINA_TRUE;
|
2012-10-09 10:09:26 -07:00
|
|
|
|
case '~':
|
2012-12-24 17:15:56 -08:00
|
|
|
|
if (str[1] == '/')
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
return EINA_FALSE;
|
2012-10-09 10:09:26 -07:00
|
|
|
|
case '.':
|
2012-12-24 17:15:56 -08:00
|
|
|
|
if (str[1] == '/')
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
else if ((str[1] == '.') && (str[2] == '/'))
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
return EINA_FALSE;
|
2012-10-09 10:09:26 -07:00
|
|
|
|
default:
|
2012-12-24 17:15:56 -08:00
|
|
|
|
return EINA_FALSE;
|
2012-10-09 10:09:26 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-06 10:45:46 -08:00
|
|
|
|
static int
|
2020-04-01 15:09:47 -07:00
|
|
|
|
_txt_at(Termpty *ty, int *x, int *y, char *txt, int *txtlenp, int *codepointp)
|
2016-11-06 10:45:46 -08:00
|
|
|
|
{
|
|
|
|
|
Termcell *cells = NULL;
|
|
|
|
|
Termcell cell;
|
|
|
|
|
ssize_t w;
|
|
|
|
|
|
|
|
|
|
cells = termpty_cellrow_get(ty, *y, &w);
|
|
|
|
|
if (!cells || !w)
|
|
|
|
|
goto bad;
|
2016-11-15 13:28:27 -08:00
|
|
|
|
if ((*x >= w))
|
2016-11-17 14:30:57 -08:00
|
|
|
|
goto empty;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
cell = cells[*x];
|
|
|
|
|
if ((cell.codepoint == 0) && (cell.att.dblwidth))
|
|
|
|
|
{
|
|
|
|
|
(*x)--;
|
|
|
|
|
if (*x < 0)
|
|
|
|
|
goto bad;
|
|
|
|
|
cell = cells[*x];
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-13 10:15:57 -07:00
|
|
|
|
if ((cell.codepoint == 0) || (cell.att.link_id))
|
2016-11-17 14:30:57 -08:00
|
|
|
|
goto empty;
|
|
|
|
|
|
|
|
|
|
*txtlenp = codepoint_to_utf8(cell.codepoint, txt);
|
2020-04-01 15:09:47 -07:00
|
|
|
|
*codepointp = cell.codepoint;
|
2016-11-17 14:30:57 -08:00
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
empty:
|
2016-11-06 10:45:46 -08:00
|
|
|
|
txt[0] = '\0';
|
|
|
|
|
*txtlenp = 0;
|
2020-04-01 15:09:47 -07:00
|
|
|
|
*codepointp = 0;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
bad:
|
|
|
|
|
*txtlenp = 0;
|
|
|
|
|
txt[0] = '\0';
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2020-04-01 15:09:47 -07:00
|
|
|
|
_txt_prev_at(Termpty *ty, int *x, int *y, char *txt, int *txtlenp,
|
|
|
|
|
int *codepointp)
|
2016-11-06 10:45:46 -08:00
|
|
|
|
{
|
|
|
|
|
Termcell *cells = NULL;
|
|
|
|
|
Termcell cell;
|
|
|
|
|
ssize_t w;
|
|
|
|
|
|
|
|
|
|
(*x)--;
|
|
|
|
|
if ((*x) < 0)
|
2016-11-17 14:30:57 -08:00
|
|
|
|
{
|
2016-11-06 10:45:46 -08:00
|
|
|
|
(*y)--;
|
2016-11-17 14:30:57 -08:00
|
|
|
|
*x = ty->w-1;
|
|
|
|
|
cells = termpty_cellrow_get(ty, *y, &w);
|
|
|
|
|
if (!cells || !w)
|
|
|
|
|
goto bad;
|
|
|
|
|
if ((*x) >= w)
|
|
|
|
|
goto empty;
|
|
|
|
|
cell = cells[*x];
|
|
|
|
|
/* Either the cell is in the normal screen and needs to have
|
|
|
|
|
* autowrapped flag or is in the backlog and its length is larger than
|
|
|
|
|
* the screen, spanning multiple lines */
|
|
|
|
|
if (((!cell.att.autowrapped) && (*y) >= 0)
|
|
|
|
|
|| (w < ty->w))
|
|
|
|
|
goto empty;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
cells = termpty_cellrow_get(ty, *y, &w);
|
|
|
|
|
if (!cells || !w)
|
|
|
|
|
goto bad;
|
|
|
|
|
if ((*x) >= w)
|
|
|
|
|
goto empty;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
|
2016-11-17 14:30:57 -08:00
|
|
|
|
cell = cells[*x];
|
|
|
|
|
}
|
2016-11-06 10:45:46 -08:00
|
|
|
|
if ((cell.codepoint == 0) && (cell.att.dblwidth))
|
|
|
|
|
{
|
|
|
|
|
(*x)--;
|
|
|
|
|
if (*x < 0)
|
|
|
|
|
goto bad;
|
|
|
|
|
cell = cells[*x];
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-13 10:15:57 -07:00
|
|
|
|
if ((cell.codepoint == 0) || (cell.att.link_id))
|
2016-11-17 14:30:57 -08:00
|
|
|
|
goto empty;
|
|
|
|
|
|
|
|
|
|
*txtlenp = codepoint_to_utf8(cell.codepoint, txt);
|
2020-04-01 15:09:47 -07:00
|
|
|
|
*codepointp = cell.codepoint;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
2016-11-17 14:30:57 -08:00
|
|
|
|
empty:
|
|
|
|
|
txt[0] = '\0';
|
|
|
|
|
*txtlenp = 0;
|
2020-04-01 15:09:47 -07:00
|
|
|
|
*codepointp = 0;
|
2016-11-17 14:30:57 -08:00
|
|
|
|
return 0;
|
|
|
|
|
|
2016-11-06 10:45:46 -08:00
|
|
|
|
bad:
|
|
|
|
|
*txtlenp = 0;
|
|
|
|
|
txt[0] = '\0';
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2020-04-01 15:09:47 -07:00
|
|
|
|
_txt_next_at(Termpty *ty, int *x, int *y, char *txt, int *txtlenp,
|
|
|
|
|
int *codepointp)
|
2016-11-06 10:45:46 -08:00
|
|
|
|
{
|
|
|
|
|
Termcell *cells = NULL;
|
|
|
|
|
Termcell cell;
|
|
|
|
|
ssize_t w;
|
|
|
|
|
|
|
|
|
|
(*x)++;
|
|
|
|
|
cells = termpty_cellrow_get(ty, *y, &w);
|
|
|
|
|
if (!cells || !w)
|
|
|
|
|
goto bad;
|
2016-11-17 14:30:57 -08:00
|
|
|
|
if ((*x) >= w)
|
2016-11-06 10:45:46 -08:00
|
|
|
|
{
|
|
|
|
|
(*y)++;
|
2016-11-17 14:30:57 -08:00
|
|
|
|
if ((*x) <= ty->w)
|
|
|
|
|
{
|
|
|
|
|
cell = cells[w-1];
|
|
|
|
|
if (!cell.att.autowrapped)
|
|
|
|
|
goto empty;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-06 10:45:46 -08:00
|
|
|
|
*x = 0;
|
|
|
|
|
cells = termpty_cellrow_get(ty, *y, &w);
|
|
|
|
|
if (!cells || !w)
|
|
|
|
|
goto bad;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cell = cells[*x];
|
|
|
|
|
if ((cell.codepoint == 0) && (cell.att.dblwidth))
|
|
|
|
|
{
|
|
|
|
|
(*x)++;
|
|
|
|
|
if (*x >= w)
|
|
|
|
|
{
|
2016-11-17 14:30:57 -08:00
|
|
|
|
cell = cells[w-1];
|
|
|
|
|
if (!cell.att.autowrapped && w == ty->w)
|
|
|
|
|
goto empty;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
(*y)++;
|
|
|
|
|
*x = 0;
|
|
|
|
|
cells = termpty_cellrow_get(ty, *y, &w);
|
|
|
|
|
if (!cells || !w)
|
|
|
|
|
goto bad;
|
|
|
|
|
}
|
|
|
|
|
goto bad;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cell = cells[*x];
|
2018-10-13 10:15:57 -07:00
|
|
|
|
if ((cell.codepoint == 0) || (cell.att.link_id))
|
2016-11-17 14:30:57 -08:00
|
|
|
|
goto empty;
|
|
|
|
|
|
|
|
|
|
*txtlenp = codepoint_to_utf8(cell.codepoint, txt);
|
2020-04-01 15:09:47 -07:00
|
|
|
|
*codepointp = cell.codepoint;
|
2016-11-17 14:30:57 -08:00
|
|
|
|
|
|
|
|
|
return 0;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
|
2016-11-17 14:30:57 -08:00
|
|
|
|
empty:
|
|
|
|
|
txt[0] = '\0';
|
|
|
|
|
*txtlenp = 0;
|
2020-04-01 15:09:47 -07:00
|
|
|
|
*codepointp = 0;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
bad:
|
|
|
|
|
*txtlenp = 0;
|
|
|
|
|
txt[0] = '\0';
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-18 15:02:36 -07:00
|
|
|
|
/* returned string must be freed */
|
2012-07-13 02:12:01 -07:00
|
|
|
|
char *
|
2017-07-06 11:55:02 -07:00
|
|
|
|
termio_link_find(const Evas_Object *obj, int cx, int cy,
|
2016-11-06 04:03:19 -08:00
|
|
|
|
int *x1r, int *y1r, int *x2r, int *y2r)
|
2012-07-13 02:12:01 -07:00
|
|
|
|
{
|
2016-11-06 10:45:46 -08:00
|
|
|
|
char *s = NULL;
|
2020-04-01 15:09:47 -07:00
|
|
|
|
int endmatch1 = 0, endmatch2 = 0;
|
2013-05-20 08:39:25 -07:00
|
|
|
|
int x1, x2, y1, y2, w = 0, h = 0, sc;
|
2018-10-13 10:15:57 -07:00
|
|
|
|
Eina_Bool goback = EINA_TRUE,
|
|
|
|
|
goforward = EINA_FALSE,
|
|
|
|
|
escaped = EINA_FALSE;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
struct ty_sb sb = {.buf = NULL, .gap = 0, .len = 0, .alloc = 0};
|
|
|
|
|
Termpty *ty = termio_pty_get(obj);
|
|
|
|
|
int res;
|
|
|
|
|
char txt[8];
|
|
|
|
|
int txtlen = 0;
|
2020-04-01 15:09:47 -07:00
|
|
|
|
int codepoint = 0;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
Eina_Bool was_protocol = EINA_FALSE;
|
2013-05-20 08:39:25 -07:00
|
|
|
|
|
2016-11-08 12:17:48 -08:00
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(ty, NULL);
|
|
|
|
|
|
2012-07-13 02:12:01 -07:00
|
|
|
|
x1 = x2 = cx;
|
|
|
|
|
y1 = y2 = cy;
|
|
|
|
|
termio_size_get(obj, &w, &h);
|
2016-11-06 10:45:46 -08:00
|
|
|
|
if ((w <= 0) || (h <= 0)) goto end;
|
|
|
|
|
|
2013-06-04 14:08:05 -07:00
|
|
|
|
sc = termio_scroll_get(obj);
|
2016-11-06 10:45:46 -08:00
|
|
|
|
|
|
|
|
|
termpty_backlog_lock();
|
|
|
|
|
|
|
|
|
|
y1 -= sc;
|
|
|
|
|
y2 -= sc;
|
|
|
|
|
|
2020-04-01 15:09:47 -07:00
|
|
|
|
res = _txt_at(ty, &x1, &y1, txt, &txtlen, &codepoint);
|
2016-11-06 10:45:46 -08:00
|
|
|
|
if ((res != 0) || (txtlen == 0)) goto end;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
if (_isspace_unicode(codepoint))
|
2019-09-15 11:58:52 -07:00
|
|
|
|
goto end;
|
2016-11-08 12:13:21 -08:00
|
|
|
|
res = ty_sb_add(&sb, txt, txtlen);
|
|
|
|
|
if (res < 0) goto end;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
|
|
|
|
|
while (goback)
|
2012-07-13 02:12:01 -07:00
|
|
|
|
{
|
2016-11-06 10:45:46 -08:00
|
|
|
|
int new_x1 = x1, new_y1 = y1;
|
|
|
|
|
|
2020-04-01 15:09:47 -07:00
|
|
|
|
res = _txt_prev_at(ty, &new_x1, &new_y1, txt, &txtlen, &codepoint);
|
2016-11-06 10:45:46 -08:00
|
|
|
|
if ((res != 0) || (txtlen == 0))
|
|
|
|
|
{
|
|
|
|
|
goback = EINA_FALSE;
|
|
|
|
|
goforward = EINA_TRUE;
|
2016-11-11 03:38:54 -08:00
|
|
|
|
break;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
}
|
2016-11-08 12:15:42 -08:00
|
|
|
|
res = ty_sb_prepend(&sb, txt, txtlen);
|
|
|
|
|
if (res < 0) goto end;
|
2020-04-02 12:52:04 -07:00
|
|
|
|
if (_isspace_unicode(codepoint))
|
2012-07-13 02:12:01 -07:00
|
|
|
|
{
|
2016-11-06 10:45:46 -08:00
|
|
|
|
int old_txtlen = txtlen;
|
2020-04-01 15:09:47 -07:00
|
|
|
|
res = _txt_prev_at(ty, &new_x1, &new_y1, txt, &txtlen, &codepoint);
|
|
|
|
|
if ((res != 0) || (txtlen == 0) || (codepoint != '\\'))
|
2012-07-13 02:12:01 -07:00
|
|
|
|
{
|
2016-11-06 10:45:46 -08:00
|
|
|
|
ty_sb_lskip(&sb, old_txtlen);
|
|
|
|
|
goback = EINA_FALSE;
|
|
|
|
|
goforward = EINA_TRUE;
|
|
|
|
|
break;
|
2012-07-13 02:12:01 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-04-01 15:09:47 -07:00
|
|
|
|
switch (codepoint)
|
2016-11-06 10:45:46 -08:00
|
|
|
|
{
|
2020-04-01 15:09:47 -07:00
|
|
|
|
case '"': endmatch1 = endmatch2 = '"'; break;
|
|
|
|
|
case '\'': endmatch1 = endmatch2 = '\''; break;
|
|
|
|
|
case '`': endmatch1 = endmatch2 = '`'; break;
|
|
|
|
|
case '<': endmatch1 = endmatch2 = '>'; break;
|
|
|
|
|
case '[': endmatch1 = endmatch2 = ']'; break;
|
|
|
|
|
case ']': endmatch1 = endmatch2 = '['; break;
|
|
|
|
|
case '{': endmatch1 = endmatch2 = '}'; break;
|
|
|
|
|
case '(': endmatch1 = endmatch2 = ')'; break;
|
|
|
|
|
case '|': endmatch1 = endmatch2 = '|'; break;
|
|
|
|
|
case 0xab: endmatch1 = endmatch2 = 0xbb; break; // french « »
|
|
|
|
|
case 0xbb: endmatch1 = endmatch2 = 0xab; break; // swedish » «
|
|
|
|
|
case 0x2018: endmatch1 = endmatch2 = 0x2019; break; // ‘ ’
|
|
|
|
|
case 0x201b: endmatch1 = endmatch2 = 0x2019; break; // ‛ ’
|
|
|
|
|
case 0x201c: endmatch1 = endmatch2 = 0x201d; break; // “ ”
|
|
|
|
|
case 0x201e: endmatch1 = 0x201c; endmatch2 = 0x201d; break; // „ “”
|
|
|
|
|
case 0x2039: endmatch1 = endmatch2 = 0x203a; break; // ‹›
|
|
|
|
|
case 0x27e6: endmatch1 = endmatch2 = 0x27e7; break; // ⟦ ⟧
|
|
|
|
|
case 0x27e8: endmatch1 = endmatch2 = 0x27e9; break; // ⟨ ⟩
|
|
|
|
|
case 0x2329: endmatch1 = endmatch2 = 0x232a; break; // 〈 〉
|
|
|
|
|
case 0x231c: endmatch1 = 0x231d; endmatch2 = 0x231f; break; // ⌜⌝⌟
|
|
|
|
|
case 0x231e: endmatch1 = 0x231d; endmatch2 = 0x231f; break; // ⌞⌝⌟
|
|
|
|
|
case 0x2308: endmatch1 = 0x2309; endmatch2 = 0x230b; break; // ⌈⌉⌋
|
|
|
|
|
case 0x230a: endmatch1 = 0x2309; endmatch2 = 0x230b; break; // ⌊⌉⌋
|
2016-11-06 10:45:46 -08:00
|
|
|
|
}
|
2020-04-01 15:09:47 -07:00
|
|
|
|
if (endmatch1)
|
2012-07-13 02:12:01 -07:00
|
|
|
|
{
|
2016-11-06 10:45:46 -08:00
|
|
|
|
ty_sb_lskip(&sb, txtlen);
|
|
|
|
|
goback = EINA_FALSE;
|
|
|
|
|
goforward = EINA_TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2013-06-06 13:51:32 -07:00
|
|
|
|
|
2016-11-06 10:45:46 -08:00
|
|
|
|
if (!link_is_protocol(sb.buf))
|
|
|
|
|
{
|
|
|
|
|
if (was_protocol)
|
2012-07-13 02:12:01 -07:00
|
|
|
|
{
|
2020-04-02 12:52:04 -07:00
|
|
|
|
if (!_isspace_unicode(codepoint))
|
2020-04-01 15:09:47 -07:00
|
|
|
|
endmatch1 = endmatch2 = codepoint;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
ty_sb_lskip(&sb, txtlen);
|
|
|
|
|
goback = EINA_FALSE;
|
|
|
|
|
goforward = EINA_TRUE;
|
|
|
|
|
break;
|
2012-07-13 02:12:01 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-06 10:45:46 -08:00
|
|
|
|
else
|
2012-07-13 02:12:01 -07:00
|
|
|
|
{
|
2016-11-06 10:45:46 -08:00
|
|
|
|
was_protocol = EINA_TRUE;
|
2012-07-13 02:12:01 -07:00
|
|
|
|
}
|
2016-11-06 10:45:46 -08:00
|
|
|
|
x1 = new_x1;
|
|
|
|
|
y1 = new_y1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (goforward)
|
|
|
|
|
{
|
|
|
|
|
int new_x2 = x2, new_y2 = y2;
|
|
|
|
|
/* Check if the previous char is a delimiter */
|
2020-04-01 15:09:47 -07:00
|
|
|
|
res = _txt_next_at(ty, &new_x2, &new_y2, txt, &txtlen, &codepoint);
|
2016-11-06 10:45:46 -08:00
|
|
|
|
if ((res != 0) || (txtlen == 0))
|
2012-07-13 02:12:01 -07:00
|
|
|
|
{
|
2013-06-06 13:51:32 -07:00
|
|
|
|
goforward = EINA_FALSE;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
/* escaping */
|
2020-04-01 15:09:47 -07:00
|
|
|
|
if (codepoint == '\\')
|
2016-11-06 10:45:46 -08:00
|
|
|
|
{
|
|
|
|
|
x2 = new_x2;
|
|
|
|
|
y2 = new_y2;
|
|
|
|
|
escaped = EINA_TRUE;
|
|
|
|
|
continue;
|
2012-07-13 02:12:01 -07:00
|
|
|
|
}
|
2016-11-06 10:45:46 -08:00
|
|
|
|
if (escaped)
|
2012-07-13 02:12:01 -07:00
|
|
|
|
{
|
2016-11-06 10:45:46 -08:00
|
|
|
|
x2 = new_x2;
|
|
|
|
|
y2 = new_y2;
|
|
|
|
|
escaped = EINA_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-02 12:52:04 -07:00
|
|
|
|
if (_isspace_unicode(codepoint) || (codepoint == endmatch1)
|
2020-04-01 15:09:47 -07:00
|
|
|
|
|| (codepoint == endmatch2))
|
2016-11-06 10:45:46 -08:00
|
|
|
|
{
|
|
|
|
|
goforward = EINA_FALSE;
|
2012-07-13 02:12:01 -07:00
|
|
|
|
break;
|
|
|
|
|
}
|
2020-04-01 15:09:47 -07:00
|
|
|
|
switch (codepoint)
|
2016-12-25 09:18:16 -08:00
|
|
|
|
{
|
2020-05-31 13:27:28 -07:00
|
|
|
|
case '"': goto out;
|
|
|
|
|
case '\'': goto out;
|
|
|
|
|
case '`': goto out;
|
|
|
|
|
case '<': goto out;
|
|
|
|
|
case '>': goto out;
|
|
|
|
|
case '[': goto out;
|
|
|
|
|
case ']': goto out;
|
|
|
|
|
case '{': goto out;
|
|
|
|
|
case '}': goto out;
|
|
|
|
|
case '|': goto out;
|
|
|
|
|
case 0xab: goto out;
|
|
|
|
|
case 0xbb: goto out;
|
|
|
|
|
case 0x2018: goto out;
|
|
|
|
|
case 0x2019: goto out;
|
|
|
|
|
case 0x201b: goto out;
|
|
|
|
|
case 0x201c: goto out;
|
|
|
|
|
case 0x201d: goto out;
|
|
|
|
|
case 0x201e: goto out;
|
|
|
|
|
case 0x2039: goto out;
|
|
|
|
|
case 0x203a: goto out;
|
|
|
|
|
case 0x2308: goto out;
|
|
|
|
|
case 0x2309: goto out;
|
|
|
|
|
case 0x230a: goto out;
|
|
|
|
|
case 0x230b: goto out;
|
|
|
|
|
case 0x231c: goto out;
|
|
|
|
|
case 0x231d: goto out;
|
|
|
|
|
case 0x231e: goto out;
|
|
|
|
|
case 0x231f: goto out;
|
|
|
|
|
case 0x2329: goto out;
|
|
|
|
|
case 0x232a: goto out;
|
|
|
|
|
case 0x27e6: goto out;
|
|
|
|
|
case 0x27e7: goto out;
|
|
|
|
|
case 0x27e8: goto out;
|
|
|
|
|
case 0x27e9: goto out;
|
2016-12-25 09:18:16 -08:00
|
|
|
|
}
|
2016-11-06 10:45:46 -08:00
|
|
|
|
|
2016-11-08 12:13:21 -08:00
|
|
|
|
res = ty_sb_add(&sb, txt, txtlen);
|
|
|
|
|
if (res < 0) goto end;
|
2016-11-06 10:45:46 -08:00
|
|
|
|
|
|
|
|
|
if (!link_is_protocol(sb.buf))
|
|
|
|
|
{
|
|
|
|
|
if (was_protocol)
|
|
|
|
|
{
|
|
|
|
|
ty_sb_rskip(&sb, txtlen);
|
|
|
|
|
goback = EINA_FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
was_protocol = EINA_TRUE;
|
|
|
|
|
}
|
|
|
|
|
x2 = new_x2;
|
|
|
|
|
y2 = new_y2;
|
2012-07-13 02:12:01 -07:00
|
|
|
|
}
|
2016-11-06 10:45:46 -08:00
|
|
|
|
|
2016-12-25 09:18:16 -08:00
|
|
|
|
out:
|
2016-11-06 10:45:46 -08:00
|
|
|
|
if (sb.len)
|
2012-07-13 02:12:01 -07:00
|
|
|
|
{
|
2019-09-15 08:47:07 -07:00
|
|
|
|
Eina_Bool is_file = link_is_file(sb.buf);
|
2016-11-06 10:45:46 -08:00
|
|
|
|
|
|
|
|
|
if (is_file ||
|
|
|
|
|
link_is_email(sb.buf) ||
|
|
|
|
|
link_is_url(sb.buf))
|
2012-07-13 02:12:01 -07:00
|
|
|
|
{
|
2016-11-06 10:45:46 -08:00
|
|
|
|
if (x1r) *x1r = x1;
|
|
|
|
|
if (y1r) *y1r = y1 + sc;
|
|
|
|
|
if (x2r) *x2r = x2;
|
|
|
|
|
if (y2r) *y2r = y2 + sc;
|
2013-06-15 14:37:10 -07:00
|
|
|
|
|
2016-11-06 10:45:46 -08:00
|
|
|
|
if (is_file && (sb.buf[0] != '/'))
|
2012-07-13 02:12:01 -07:00
|
|
|
|
{
|
2016-11-06 10:45:46 -08:00
|
|
|
|
char *local= _local_path_get(obj, (const char*)sb.buf);
|
|
|
|
|
ty_sb_free(&sb);
|
|
|
|
|
s = local;
|
|
|
|
|
goto end;
|
2012-07-13 02:12:01 -07:00
|
|
|
|
}
|
2016-11-06 10:45:46 -08:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
s = ty_sb_steal_buf(&sb);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
goto end;
|
2012-07-13 02:12:01 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-06 10:45:46 -08:00
|
|
|
|
end:
|
|
|
|
|
termpty_backlog_unlock();
|
|
|
|
|
ty_sb_free(&sb);
|
|
|
|
|
return s;
|
2012-07-13 02:12:01 -07:00
|
|
|
|
}
|
2020-04-20 12:20:21 -07:00
|
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
|
_is_authorized_in_color(const int codepoint)
|
|
|
|
|
{
|
|
|
|
|
switch (codepoint)
|
|
|
|
|
{
|
|
|
|
|
case '#': EINA_FALLTHROUGH;
|
|
|
|
|
case '0': EINA_FALLTHROUGH;
|
|
|
|
|
case '1': EINA_FALLTHROUGH;
|
|
|
|
|
case '2': EINA_FALLTHROUGH;
|
|
|
|
|
case '3': EINA_FALLTHROUGH;
|
|
|
|
|
case '4': EINA_FALLTHROUGH;
|
|
|
|
|
case '5': EINA_FALLTHROUGH;
|
|
|
|
|
case '6': EINA_FALLTHROUGH;
|
|
|
|
|
case '7': EINA_FALLTHROUGH;
|
|
|
|
|
case '8': EINA_FALLTHROUGH;
|
|
|
|
|
case '9': EINA_FALLTHROUGH;
|
|
|
|
|
case 'a': EINA_FALLTHROUGH;
|
|
|
|
|
case 'A': EINA_FALLTHROUGH;
|
|
|
|
|
case 'b': EINA_FALLTHROUGH;
|
|
|
|
|
case 'B': EINA_FALLTHROUGH;
|
|
|
|
|
case 'c': EINA_FALLTHROUGH;
|
|
|
|
|
case 'C': EINA_FALLTHROUGH;
|
|
|
|
|
case 'd': EINA_FALLTHROUGH;
|
|
|
|
|
case 'D': EINA_FALLTHROUGH;
|
|
|
|
|
case 'e': EINA_FALLTHROUGH;
|
|
|
|
|
case 'E': EINA_FALLTHROUGH;
|
|
|
|
|
case 'f': EINA_FALLTHROUGH;
|
|
|
|
|
case 'F':
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
}
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Eina_Bool
|
2020-05-12 14:52:13 -07:00
|
|
|
|
_parse_hex(const char c, uint8_t *v)
|
2020-04-20 12:20:21 -07:00
|
|
|
|
{
|
|
|
|
|
if (c < '0')
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
if (c <= '9')
|
|
|
|
|
{
|
|
|
|
|
*v = c - '0';
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
}
|
|
|
|
|
if (c < 'A')
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
if (c <= 'F')
|
|
|
|
|
{
|
|
|
|
|
*v = 10 + c - 'A';
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
}
|
|
|
|
|
if (c < 'a')
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
if (c <= 'f')
|
|
|
|
|
{
|
|
|
|
|
*v = 10 + c - 'a';
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
}
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Eina_Bool
|
2020-05-12 14:52:13 -07:00
|
|
|
|
_parse_2hex(const char *s, uint8_t *v)
|
2020-04-20 12:20:21 -07:00
|
|
|
|
{
|
|
|
|
|
uint8_t v0, v1;
|
|
|
|
|
if (!_parse_hex(s[0], &v0))
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
if (!_parse_hex(s[1], &v1))
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
*v = v0 << 4 | v1;
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Eina_Bool
|
|
|
|
|
termio_color_find(const Evas_Object *obj, int cx, int cy,
|
|
|
|
|
int *x1r, int *y1r, int *x2r, int *y2r,
|
|
|
|
|
uint8_t *rp, uint8_t *gp, uint8_t *bp, uint8_t *ap)
|
|
|
|
|
{
|
|
|
|
|
int x1, x2, y1, y2, w = 0, h = 0, sc;
|
|
|
|
|
//const char authorized[] = "#0123456789aAbBcCdDeEfFrghsoltun() ,+/";
|
|
|
|
|
Eina_Bool goback = EINA_TRUE,
|
|
|
|
|
goforward = EINA_FALSE;
|
|
|
|
|
struct ty_sb sb = {.buf = NULL, .gap = 0, .len = 0, .alloc = 0};
|
|
|
|
|
Termpty *ty = termio_pty_get(obj);
|
|
|
|
|
int res;
|
|
|
|
|
char txt[8];
|
|
|
|
|
int txtlen = 0;
|
|
|
|
|
Eina_Bool found = EINA_FALSE;
|
|
|
|
|
int codepoint;
|
|
|
|
|
uint8_t r, g, b, a = 255;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(ty, EINA_FALSE);
|
|
|
|
|
|
|
|
|
|
x1 = x2 = cx;
|
|
|
|
|
y1 = y2 = cy;
|
|
|
|
|
termio_size_get(obj, &w, &h);
|
|
|
|
|
if ((w <= 0) || (h <= 0)) goto end;
|
|
|
|
|
|
|
|
|
|
sc = termio_scroll_get(obj);
|
|
|
|
|
|
|
|
|
|
termpty_backlog_lock();
|
|
|
|
|
|
|
|
|
|
y1 -= sc;
|
|
|
|
|
y2 -= sc;
|
|
|
|
|
|
|
|
|
|
/* TODO: boris */
|
|
|
|
|
res = _txt_at(ty, &x1, &y1, txt, &txtlen, &codepoint);
|
|
|
|
|
if ((res != 0) || (txtlen == 0))
|
|
|
|
|
goto end;
|
|
|
|
|
if (!_is_authorized_in_color(codepoint))
|
|
|
|
|
goto end;
|
|
|
|
|
res = ty_sb_add(&sb, txt, txtlen);
|
|
|
|
|
if (res < 0) goto end;
|
|
|
|
|
|
|
|
|
|
while (goback)
|
|
|
|
|
{
|
|
|
|
|
int new_x1 = x1, new_y1 = y1;
|
|
|
|
|
|
|
|
|
|
res = _txt_prev_at(ty, &new_x1, &new_y1, txt, &txtlen, &codepoint);
|
|
|
|
|
if ((res != 0) || (txtlen == 0))
|
|
|
|
|
{
|
|
|
|
|
goback = EINA_FALSE;
|
|
|
|
|
goforward = EINA_TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
res = ty_sb_prepend(&sb, txt, txtlen);
|
|
|
|
|
if (res < 0) goto end;
|
|
|
|
|
if (!_is_authorized_in_color(codepoint))
|
|
|
|
|
{
|
|
|
|
|
ty_sb_lskip(&sb, txtlen);
|
|
|
|
|
goback = EINA_FALSE;
|
|
|
|
|
goforward = EINA_TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
x1 = new_x1;
|
|
|
|
|
y1 = new_y1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (goforward)
|
|
|
|
|
{
|
|
|
|
|
int new_x2 = x2, new_y2 = y2;
|
|
|
|
|
|
|
|
|
|
/* Check if the previous char is a delimiter */
|
|
|
|
|
res = _txt_next_at(ty, &new_x2, &new_y2, txt, &txtlen, &codepoint);
|
|
|
|
|
if ((res != 0) || (txtlen == 0))
|
|
|
|
|
{
|
|
|
|
|
goforward = EINA_FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!_is_authorized_in_color(codepoint))
|
|
|
|
|
{
|
|
|
|
|
goforward = EINA_FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res = ty_sb_add(&sb, txt, txtlen);
|
|
|
|
|
if (res < 0) goto end;
|
|
|
|
|
|
|
|
|
|
x2 = new_x2;
|
|
|
|
|
y2 = new_y2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!sb.len)
|
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
|
|
if (sb.buf[0] == '#')
|
|
|
|
|
{
|
|
|
|
|
ty_sb_lskip(&sb, 1);
|
|
|
|
|
switch (sb.len)
|
|
|
|
|
{
|
|
|
|
|
case 3:
|
|
|
|
|
if ((!_parse_hex(sb.buf[0], &r)) ||
|
|
|
|
|
(!_parse_hex(sb.buf[1], &g)) ||
|
|
|
|
|
(!_parse_hex(sb.buf[2], &b)))
|
|
|
|
|
goto end;
|
|
|
|
|
r <<= 4;
|
|
|
|
|
g <<= 4;
|
|
|
|
|
b <<= 4;
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
if ((!_parse_hex(sb.buf[0], &r)) ||
|
|
|
|
|
(!_parse_hex(sb.buf[1], &g)) ||
|
|
|
|
|
(!_parse_hex(sb.buf[2], &b)) ||
|
|
|
|
|
(!_parse_hex(sb.buf[3], &a)))
|
|
|
|
|
goto end;
|
|
|
|
|
r <<= 4;
|
|
|
|
|
g <<= 4;
|
|
|
|
|
b <<= 4;
|
|
|
|
|
a <<= 4;
|
|
|
|
|
break;
|
|
|
|
|
case 6:
|
|
|
|
|
if ((!_parse_2hex(&sb.buf[0], &r)) ||
|
|
|
|
|
(!_parse_2hex(&sb.buf[2], &g)) ||
|
|
|
|
|
(!_parse_2hex(&sb.buf[4], &b)))
|
|
|
|
|
goto end;
|
|
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
if ((!_parse_2hex(&sb.buf[0], &r)) ||
|
|
|
|
|
(!_parse_2hex(&sb.buf[2], &g)) ||
|
|
|
|
|
(!_parse_2hex(&sb.buf[4], &b)) ||
|
|
|
|
|
(!_parse_2hex(&sb.buf[6], &a)))
|
|
|
|
|
goto end;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
goto end;
|
|
|
|
|
}
|
|
|
|
|
found = EINA_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
end:
|
|
|
|
|
termpty_backlog_unlock();
|
|
|
|
|
ty_sb_free(&sb);
|
|
|
|
|
if (found)
|
|
|
|
|
{
|
|
|
|
|
if (rp) *rp = r;
|
|
|
|
|
if (gp) *gp = g;
|
|
|
|
|
if (bp) *bp = b;
|
|
|
|
|
if (ap) *ap = a;
|
|
|
|
|
if (x1r) *x1r = x1;
|
|
|
|
|
if (y1r) *y1r = y1 + sc;
|
|
|
|
|
if (x2r) *x2r = x2;
|
|
|
|
|
if (y2r) *y2r = y2 + sc;
|
|
|
|
|
}
|
|
|
|
|
return found;
|
|
|
|
|
}
|