compute refcount on hyper links

This commit is contained in:
Boris Faure 2018-10-12 18:12:15 +02:00
parent cc83e6b6f2
commit 05ee717fc0
5 changed files with 80 additions and 37 deletions

View File

@ -519,11 +519,16 @@ term_link_new(Termpty *ty)
} }
void void
term_link_free(Term_Link *link, Termpty *ty) term_link_free(Termpty *ty, Term_Link *link)
{ {
if (!link) if (!link || !ty)
return; return;
uint16_t id = (link - ty->hl.links); uint16_t id = (link - ty->hl.links);
free(link->key);
link->key = NULL;
free(link->url);
link->url = NULL;
/* Remove from bitmap */ /* Remove from bitmap */
hl_bitmap_clear_bit(ty, id); hl_bitmap_clear_bit(ty, id);

View File

@ -12,7 +12,12 @@ struct _Termlink
unsigned int refcount; unsigned int refcount;
}; };
typedef struct _Termpty Termpty;
char *termio_link_find(const Evas_Object *obj, int cx, int cy, int *x1r, int *y1r, int *x2r, int *y2r); char *termio_link_find(const Evas_Object *obj, int cx, int cy, int *x1r, int *y1r, int *x2r, int *y2r);
Term_Link * term_link_new(Termpty *ty);
void term_link_free(Termpty *ty, Term_Link *link);
#endif #endif

View File

@ -830,8 +830,7 @@ termpty_free(Termpty *ty)
{ {
Term_Link *l = ty->hl.links + i; Term_Link *l = ty->hl.links + i;
free(l->key); term_link_free(ty, l);
free(l->url);
} }
free(ty->hl.links); free(ty->hl.links);
} }
@ -1635,29 +1634,6 @@ termpty_screen_swap(Termpty *ty)
ty->cb.cancel_sel.func(ty->cb.cancel_sel.data); ty->cb.cancel_sel.func(ty->cb.cancel_sel.data);
} }
void
termpty_cell_fill(Termpty *ty, Termcell *src, Termcell *dst, int n)
{
int i;
if (src)
{
for (i = 0; i < n; i++)
{
HANDLE_BLOCK_CODEPOINT_OVERWRITE(ty, dst[i].codepoint, src[0].codepoint);
dst[i] = src[0];
}
}
else
{
for (i = 0; i < n; i++)
{
HANDLE_BLOCK_CODEPOINT_OVERWRITE(ty, dst[i].codepoint, 0);
memset(&(dst[i]), 0, sizeof(*dst));
}
}
}
void void
termpty_cells_set_content(Termpty *ty, Termcell *cells, termpty_cells_set_content(Termpty *ty, Termcell *cells,
Eina_Unicode codepoint, int count) Eina_Unicode codepoint, int count)
@ -1681,6 +1657,9 @@ termpty_cells_att_fill_preserve_colors(Termpty *ty, Termcell *cells,
{ {
Termatt att = cells[i].att; Termatt att = cells[i].att;
HANDLE_BLOCK_CODEPOINT_OVERWRITE(ty, cells[i].codepoint, codepoint); HANDLE_BLOCK_CODEPOINT_OVERWRITE(ty, cells[i].codepoint, codepoint);
if (EINA_UNLIKELY(cells[i].att.link_id))
term_link_refcount_dec(ty, cells[i].att.link_id, 1);
cells[i] = local; cells[i] = local;
if (ty->termstate.att.fg == 0 && ty->termstate.att.bg == 0) if (ty->termstate.att.fg == 0 && ty->termstate.att.bg == 0)
{ {
@ -1693,6 +1672,8 @@ termpty_cells_att_fill_preserve_colors(Termpty *ty, Termcell *cells,
cells[i].att.bgintense = att.bgintense; cells[i].att.bgintense = att.bgintense;
} }
} }
if (EINA_UNLIKELY(local.att.link_id))
term_link_refcount_inc(ty, local.att.link_id, count);
} }
@ -1706,8 +1687,13 @@ termpty_cell_codepoint_att_fill(Termpty *ty, Eina_Unicode codepoint,
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
HANDLE_BLOCK_CODEPOINT_OVERWRITE(ty, dst[i].codepoint, codepoint); HANDLE_BLOCK_CODEPOINT_OVERWRITE(ty, dst[i].codepoint, codepoint);
if (EINA_UNLIKELY(dst[i].att.link_id))
term_link_refcount_dec(ty, dst[i].att.link_id, 1);
dst[i] = local; dst[i] = local;
} }
if (EINA_UNLIKELY(local.att.link_id))
term_link_refcount_inc(ty, local.att.link_id, n);
} }
Config * Config *

View File

@ -5,7 +5,6 @@
#include "media.h" #include "media.h"
#include "termiolink.h" #include "termiolink.h"
typedef struct _Termpty Termpty;
typedef struct _Termcell Termcell; typedef struct _Termcell Termcell;
typedef struct _Termatt Termatt; typedef struct _Termatt Termatt;
typedef struct _Termsave Termsave; typedef struct _Termsave Termsave;
@ -180,7 +179,7 @@ struct _Termpty
struct { struct {
Term_Link *links; Term_Link *links;
uint8_t *bitmap; uint8_t *bitmap;
uint16_t size; uint32_t size;
} hl; } hl;
}; };
@ -240,6 +239,7 @@ struct _Termexp
int x, y, w, h; int x, y, w, h;
}; };
void termpty_init(void); void termpty_init(void);
void termpty_shutdown(void); void termpty_shutdown(void);
@ -270,7 +270,6 @@ Termblock *termpty_block_get(const Termpty *ty, int id);
void termpty_block_chid_update(Termpty *ty, Termblock *blk); void termpty_block_chid_update(Termpty *ty, Termblock *blk);
Termblock *termpty_block_chid_get(const Termpty *ty, const char *chid); Termblock *termpty_block_chid_get(const Termpty *ty, const char *chid);
void termpty_cell_fill(Termpty *ty, Termcell *src, Termcell *dst, int n);
void termpty_cell_codepoint_att_fill(Termpty *ty, Eina_Unicode codepoint, Termatt att, Termcell *dst, int n); void termpty_cell_codepoint_att_fill(Termpty *ty, Eina_Unicode codepoint, Termatt att, Termcell *dst, int n);
void termpty_cells_set_content(Termpty *ty, Termcell *cells, void termpty_cells_set_content(Termpty *ty, Termcell *cells,
Eina_Unicode codepoint, int count); Eina_Unicode codepoint, int count);
@ -311,15 +310,63 @@ do { \
HANDLE_BLOCK_CODEPOINT_OVERWRITE(Tpty, \ HANDLE_BLOCK_CODEPOINT_OVERWRITE(Tpty, \
(Tdst)[__i].codepoint, \ (Tdst)[__i].codepoint, \
(Tsrc)[__i].codepoint); \ (Tsrc)[__i].codepoint); \
if (EINA_UNLIKELY((Tsrc)[__i].att.link_id)) \
term_link_refcount_dec(ty, (Tsrc)[__i].att.link_id, 1); \
if (EINA_UNLIKELY((Tdst)[__i].att.link_id)) \
term_link_refcount_inc(ty, (Tdst)[__i].att.link_id, 1); \
} \ } \
memcpy(Tdst, Tsrc, N * sizeof(Termcell)); \ memcpy(Tdst, Tsrc, N * sizeof(Termcell)); \
} while (0) } while (0)
Term_Link * static inline void
term_link_new(Termpty *ty); term_link_refcount_inc(Termpty *ty, uint16_t link_id, uint16_t count)
{
Term_Link *link;
void link = &ty->hl.links[link_id];
term_link_free(Term_Link *link, Termpty *ty); link->refcount += count;
}
static inline void
term_link_refcount_dec(Termpty *ty, uint16_t link_id, uint16_t count)
{
Term_Link *link;
link = &ty->hl.links[link_id];
link->refcount -= count;
if (EINA_UNLIKELY(link->refcount == 0))
term_link_free(ty, link);
}
static inline void
termpty_cell_fill(Termpty *ty, Termcell *src, Termcell *dst, int n)
{
int i;
if (src)
{
for (i = 0; i < n; i++)
{
HANDLE_BLOCK_CODEPOINT_OVERWRITE(ty, dst[i].codepoint, src[0].codepoint);
if (EINA_UNLIKELY(dst[i].att.link_id))
term_link_refcount_dec(ty, dst[i].att.link_id, 1);
dst[i] = src[0];
}
if (src[0].att.link_id)
term_link_refcount_inc(ty, dst[i].att.link_id, n);
}
else
{
for (i = 0; i < n; i++)
{
HANDLE_BLOCK_CODEPOINT_OVERWRITE(ty, dst[i].codepoint, 0);
if (EINA_UNLIKELY(dst[i].att.link_id))
term_link_refcount_dec(ty, dst[i].att.link_id, 1);
memset(&(dst[i]), 0, sizeof(*dst));
}
}
}
#endif #endif

View File

@ -1884,7 +1884,7 @@ _handle_hyperlink(Termpty *ty,
hl = NULL; hl = NULL;
end: end:
term_link_free(hl, ty); term_link_free(ty, hl);
free(url); free(url);
free(key); free(key);
} }