Terminal emulator with all the bells and whistles https://www.enlightenment.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

226 lines
4.5 KiB

#include "private.h"
#include <Elementary.h>
#include "termpty.h"
#include "backlog.h"
static int ts_comp = 0;
static int ts_uncomp = 0;
static int ts_freeops = 0;
static Eina_List *ptys = NULL;
static int64_t _mem_used = 0;
static void
_accounting_change(int64_t diff)
{
if (diff > 0)
{
diff = DIV_ROUND_UP(diff, 16) * 16;
}
else
{
diff = DIV_ROUND_UP(-1 * diff, 16) * -16;
}
_mem_used += diff;
}
int64_t
termpty_backlog_memory_get(void)
{
return _mem_used;
}
void
termpty_save_register(Termpty *ty)
{
termpty_backlog_lock();
ptys = eina_list_append(ptys, ty);
termpty_backlog_unlock();
}
void
termpty_save_unregister(Termpty *ty)
{
termpty_backlog_lock();
ptys = eina_list_remove(ptys, ty);
termpty_backlog_unlock();
}
Termsave *
termpty_save_extract(Termsave *ts)
{
if (!ts) return NULL;
return ts;
}
Termsave *
termpty_save_new(Termpty *ty, Termsave *ts, int w)
{
termpty_save_free(ty, ts);
Termcell *cells = calloc(1, w * sizeof(Termcell));
if (!cells ) return NULL;
ts->cells = cells;
ts->w = w;
_accounting_change(w * sizeof(Termcell));
return ts;
}
Termsave *
termpty_save_expand(Termpty *ty, Termsave *ts, Termcell *cells, size_t delta)
{
Termcell *newcells;
newcells = realloc(ts->cells, (ts->w + delta) * sizeof(Termcell));
if (!newcells)
return NULL;
memset(newcells + ts->w,
0, delta * sizeof(Termcell));
TERMPTY_CELL_COPY(ty, cells, &newcells[ts->w], (int)delta);
_accounting_change((-1) * (int64_t)(ts->w * sizeof(Termcell)));
ts->w += delta;
_accounting_change(ts->w * sizeof(Termcell));
ts->cells = newcells;
return ts;
}
void
termpty_save_free(Termpty *ty, Termsave *ts)
{
unsigned int i;
if (!ts) return;
if (ts->comp) ts_comp--;
else ts_uncomp--;
ts_freeops++;
for (i = 0; i < ts->w; i++)
{
if (EINA_UNLIKELY(ts->cells[i].att.link_id))
term_link_refcount_dec(ty, ts->cells[i].att.link_id, 1);
}
free(ts->cells);
ts->cells = NULL;
_accounting_change((-1) * (int64_t)(ts->w * sizeof(Termcell)));
ts->w = 0;
}
void
termpty_backlog_lock(void)
{
}
void
termpty_backlog_unlock(void)
{
}
void
termpty_backlog_free(Termpty *ty)
{
size_t i;
if (!ty || !ty->back)
return;
for (i = 0; i < ty->backsize; i++)
termpty_save_free(ty, &ty->back[i]);
_accounting_change((-1) * (int64_t)(sizeof(Termsave) * ty->backsize));
free(ty->back);
ty->back = NULL;
}
void
termpty_clear_backlog(Termpty *ty)
{
int backsize;
ty->backlog_beacon.screen_y = 0;
ty->backlog_beacon.backlog_y = 0;
termpty_backlog_lock();
termpty_backlog_free(ty);
ty->backpos = 0;
backsize = ty->backsize;
ty->backsize = 0;
termpty_backlog_size_set(ty, backsize);
termpty_backlog_unlock();
}
ssize_t
termpty_backlog_length(Termpty *ty)
{
int backlog_y = ty->backlog_beacon.backlog_y;
int screen_y = ty->backlog_beacon.screen_y;
if (!ty->backsize)
return 0;
for (backlog_y++; backlog_y < (int)ty->backsize; backlog_y++)
{
int nb_lines;
const Termsave *ts;
ts = BACKLOG_ROW_GET(ty, backlog_y);
if (!ts->cells)
goto end;
nb_lines = (ts->w == 0) ? 1 : DIV_ROUND_UP(ts->w, ty->w);
screen_y += nb_lines;
ty->backlog_beacon.screen_y = screen_y;
ty->backlog_beacon.backlog_y = backlog_y;
}
end:
return ty->backlog_beacon.screen_y;
}
void
termpty_backlog_size_set(Termpty *ty, size_t size)
{
Termsave *new_back;
size_t i;
if (ty->backsize == size)
return;
termpty_backlog_lock();
if (size == 0)
{
termpty_backlog_free(ty);
goto end;
}
if (size > ty->backsize)
{
new_back = realloc(ty->back, sizeof(Termsave) * size);
if (!new_back)
return;
memset(new_back + ty->backsize, 0,
sizeof(Termsave) * (size - ty->backsize));
ty->back = new_back;
}
else
{
new_back = calloc(1, sizeof(Termsave) * size);
if (!new_back)
return;
for (i = 0; i < size; i++)
new_back[i] = ty->back[i];
for (i = size; i < ty->backsize; i++)
termpty_save_free(ty, &ty->back[i]);
free(ty->back);
ty->back = new_back;
}
_accounting_change((size - ty->backsize) * (int64_t)sizeof(Termsave));
end:
ty->backpos = 0;
ty->backsize = size;
/* Reset beacon */
ty->backlog_beacon.screen_y = 0;
ty->backlog_beacon.backlog_y = 0;
termpty_backlog_unlock();
}