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
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(); |
|
}
|
|
|