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
term_link_free(Term_Link *link, Termpty *ty)
term_link_free(Termpty *ty, Term_Link *link)
{
if (!link)
return;
uint16_t id = (link - ty->hl.links);
if (!link || !ty)
return;
uint16_t id = (link - ty->hl.links);
free(link->key);
link->key = NULL;
free(link->url);
link->url = NULL;
/* Remove from bitmap */
hl_bitmap_clear_bit(ty, id);

View File

@ -12,7 +12,12 @@ struct _Termlink
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);
Term_Link * term_link_new(Termpty *ty);
void term_link_free(Termpty *ty, Term_Link *link);
#endif

View File

@ -830,8 +830,7 @@ termpty_free(Termpty *ty)
{
Term_Link *l = ty->hl.links + i;
free(l->key);
free(l->url);
term_link_free(ty, l);
}
free(ty->hl.links);
}
@ -1635,29 +1634,6 @@ termpty_screen_swap(Termpty *ty)
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
termpty_cells_set_content(Termpty *ty, Termcell *cells,
Eina_Unicode codepoint, int count)
@ -1681,6 +1657,9 @@ termpty_cells_att_fill_preserve_colors(Termpty *ty, Termcell *cells,
{
Termatt att = cells[i].att;
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;
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;
}
}
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++)
{
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;
}
if (EINA_UNLIKELY(local.att.link_id))
term_link_refcount_inc(ty, local.att.link_id, n);
}
Config *

View File

@ -5,7 +5,6 @@
#include "media.h"
#include "termiolink.h"
typedef struct _Termpty Termpty;
typedef struct _Termcell Termcell;
typedef struct _Termatt Termatt;
typedef struct _Termsave Termsave;
@ -180,7 +179,7 @@ struct _Termpty
struct {
Term_Link *links;
uint8_t *bitmap;
uint16_t size;
uint32_t size;
} hl;
};
@ -240,6 +239,7 @@ struct _Termexp
int x, y, w, h;
};
void termpty_init(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);
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_cells_set_content(Termpty *ty, Termcell *cells,
Eina_Unicode codepoint, int count);
@ -311,15 +310,63 @@ do { \
HANDLE_BLOCK_CODEPOINT_OVERWRITE(Tpty, \
(Tdst)[__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)); \
} while (0)
Term_Link *
term_link_new(Termpty *ty);
static inline void
term_link_refcount_inc(Termpty *ty, uint16_t link_id, uint16_t count)
{
Term_Link *link;
void
term_link_free(Term_Link *link, Termpty *ty);
link = &ty->hl.links[link_id];
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

View File

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