2013-05-03 19:44:20 -07:00
|
|
|
#include "private.h"
|
|
|
|
#include <Elementary.h>
|
|
|
|
#include "termpty.h"
|
2019-11-23 09:31:23 -08:00
|
|
|
#include "backlog.h"
|
2013-05-05 07:10:44 -07:00
|
|
|
|
|
|
|
|
|
|
|
static int ts_comp = 0;
|
2013-05-03 19:44:20 -07:00
|
|
|
static int ts_uncomp = 0;
|
2013-05-05 07:10:44 -07:00
|
|
|
static int ts_freeops = 0;
|
2013-05-03 19:44:20 -07:00
|
|
|
static Eina_List *ptys = NULL;
|
|
|
|
|
2019-11-24 09:06:21 -08:00
|
|
|
static int64_t _mem_used = 0;
|
2019-11-23 14:06:34 -08:00
|
|
|
|
|
|
|
static void
|
|
|
|
_accounting_change(int64_t diff)
|
|
|
|
{
|
2019-11-24 10:00:31 -08:00
|
|
|
if (diff > 0)
|
|
|
|
{
|
|
|
|
diff = ((diff + 16-1) / 16) * 16;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
diff = ((-1 * diff + 16-1) / 16) * -16;
|
|
|
|
}
|
2019-11-24 09:06:21 -08:00
|
|
|
_mem_used += diff;
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t
|
|
|
|
termpty_backlog_memory_get(void)
|
|
|
|
{
|
|
|
|
return _mem_used;
|
2019-11-23 14:06:34 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-05-03 19:44:20 -07:00
|
|
|
void
|
|
|
|
termpty_save_register(Termpty *ty)
|
|
|
|
{
|
2015-08-01 09:37:35 -07:00
|
|
|
termpty_backlog_lock();
|
2013-05-03 19:44:20 -07:00
|
|
|
ptys = eina_list_append(ptys, ty);
|
2015-08-01 09:37:35 -07:00
|
|
|
termpty_backlog_unlock();
|
2013-05-03 19:44:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
termpty_save_unregister(Termpty *ty)
|
|
|
|
{
|
2015-08-01 09:37:35 -07:00
|
|
|
termpty_backlog_lock();
|
2013-05-03 19:44:20 -07:00
|
|
|
ptys = eina_list_remove(ptys, ty);
|
2015-08-01 09:37:35 -07:00
|
|
|
termpty_backlog_unlock();
|
2013-05-03 19:44:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Termsave *
|
|
|
|
termpty_save_extract(Termsave *ts)
|
|
|
|
{
|
|
|
|
if (!ts) return NULL;
|
|
|
|
return ts;
|
|
|
|
}
|
|
|
|
|
|
|
|
Termsave *
|
2018-10-13 10:15:57 -07:00
|
|
|
termpty_save_new(Termpty *ty, Termsave *ts, int w)
|
2013-05-03 19:44:20 -07:00
|
|
|
{
|
2018-10-13 10:15:57 -07:00
|
|
|
termpty_save_free(ty, ts);
|
2015-04-06 09:08:23 -07:00
|
|
|
|
|
|
|
Termcell *cells = calloc(1, w * sizeof(Termcell));
|
|
|
|
if (!cells ) return NULL;
|
|
|
|
ts->cells = cells;
|
2013-05-03 19:44:20 -07:00
|
|
|
ts->w = w;
|
2019-11-23 14:06:34 -08:00
|
|
|
_accounting_change(w * sizeof(Termcell));
|
2013-05-03 19:44:20 -07:00
|
|
|
return ts;
|
|
|
|
}
|
|
|
|
|
2015-04-06 09:08:23 -07:00
|
|
|
Termsave *
|
2018-10-13 10:15:57 -07:00
|
|
|
termpty_save_expand(Termpty *ty, Termsave *ts, Termcell *cells, size_t delta)
|
2015-04-06 09:08:23 -07:00
|
|
|
{
|
|
|
|
Termcell *newcells;
|
|
|
|
|
|
|
|
newcells = realloc(ts->cells, (ts->w + delta) * sizeof(Termcell));
|
|
|
|
if (!newcells)
|
|
|
|
return NULL;
|
2017-08-26 09:51:22 -07:00
|
|
|
|
2018-10-13 10:15:57 -07:00
|
|
|
memset(newcells + ts->w,
|
|
|
|
0, delta * sizeof(Termcell));
|
|
|
|
TERMPTY_CELL_COPY(ty, cells, &newcells[ts->w], (int)delta);
|
|
|
|
|
2020-04-16 15:00:46 -07:00
|
|
|
_accounting_change((-1) * (int64_t)(ts->w * sizeof(Termcell)));
|
2015-04-06 09:08:23 -07:00
|
|
|
ts->w += delta;
|
2019-11-23 14:06:34 -08:00
|
|
|
_accounting_change(ts->w * sizeof(Termcell));
|
2015-04-06 09:08:23 -07:00
|
|
|
ts->cells = newcells;
|
|
|
|
return ts;
|
|
|
|
}
|
|
|
|
|
2013-05-03 19:44:20 -07:00
|
|
|
void
|
2018-10-13 10:15:57 -07:00
|
|
|
termpty_save_free(Termpty *ty, Termsave *ts)
|
2013-05-03 19:44:20 -07:00
|
|
|
{
|
2018-10-13 10:15:57 -07:00
|
|
|
unsigned int i;
|
2013-05-03 19:44:20 -07:00
|
|
|
if (!ts) return;
|
2018-09-12 22:40:39 -07:00
|
|
|
if (ts->comp) ts_comp--;
|
|
|
|
else ts_uncomp--;
|
|
|
|
ts_freeops++;
|
2018-10-13 10:15:57 -07:00
|
|
|
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);
|
2015-04-06 09:08:23 -07:00
|
|
|
ts->cells = NULL;
|
2020-04-16 15:00:46 -07:00
|
|
|
_accounting_change((-1) * (int64_t)(ts->w * sizeof(Termcell)));
|
2015-04-06 09:08:23 -07:00
|
|
|
ts->w = 0;
|
2013-05-03 19:44:20 -07:00
|
|
|
}
|
2015-08-01 09:37:35 -07:00
|
|
|
|
|
|
|
void
|
|
|
|
termpty_backlog_lock(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
termpty_backlog_unlock(void)
|
|
|
|
{
|
|
|
|
}
|
2019-11-23 14:31:21 -08:00
|
|
|
|
|
|
|
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]);
|
2020-04-16 15:00:46 -07:00
|
|
|
_accounting_change((-1) * (int64_t)(sizeof(Termsave) * ty->backsize));
|
2019-11-23 14:31:21 -08:00
|
|
|
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 : (ts->w + ty->w - 1) / 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)
|
|
|
|
{
|
2019-11-24 07:14:00 -08:00
|
|
|
Termsave *new_back;
|
2019-11-24 10:50:08 -08:00
|
|
|
size_t i;
|
2019-11-24 07:14:00 -08:00
|
|
|
|
2019-11-23 14:31:21 -08:00
|
|
|
if (ty->backsize == size)
|
|
|
|
return;
|
|
|
|
|
|
|
|
termpty_backlog_lock();
|
|
|
|
|
2019-11-24 07:14:00 -08:00
|
|
|
if (size == 0)
|
|
|
|
{
|
|
|
|
termpty_backlog_free(ty);
|
|
|
|
goto end;
|
|
|
|
}
|
2019-11-24 10:50:08 -08:00
|
|
|
if (size > ty->backsize)
|
2019-11-23 14:31:21 -08:00
|
|
|
{
|
2019-11-24 10:50:08 -08:00
|
|
|
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;
|
2019-11-23 14:31:21 -08:00
|
|
|
}
|
|
|
|
else
|
2019-11-24 10:50:08 -08:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
2020-04-16 15:00:46 -07:00
|
|
|
_accounting_change((size - ty->backsize) * (int64_t)sizeof(Termsave));
|
2019-11-24 07:14:00 -08:00
|
|
|
end:
|
2019-11-23 14:31:21 -08:00
|
|
|
ty->backpos = 0;
|
|
|
|
ty->backsize = size;
|
2019-11-24 07:14:00 -08:00
|
|
|
/* Reset beacon */
|
|
|
|
ty->backlog_beacon.screen_y = 0;
|
|
|
|
ty->backlog_beacon.backlog_y = 0;
|
|
|
|
|
2019-11-23 14:31:21 -08:00
|
|
|
termpty_backlog_unlock();
|
|
|
|
}
|