summaryrefslogtreecommitdiff
path: root/lineset.c
diff options
context:
space:
mode:
authorKatolaZ <katolaz@freaknet.org>2019-07-30 12:15:54 +0100
committerKatolaZ <katolaz@freaknet.org>2019-07-30 12:15:54 +0100
commiteebc645dee0d15871d6cc46f156d424cd916b191 (patch)
tree82bb51d04d05a3cf1b4937e2cefb70cc282e9993 /lineset.c
parenta99759398841d86928c7ad4d8248f907765cbeb2 (diff)
yank buffer and initial copy/cut/paste support
Diffstat (limited to 'lineset.c')
-rw-r--r--lineset.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/lineset.c b/lineset.c
new file mode 100644
index 0000000..faabb30
--- /dev/null
+++ b/lineset.c
@@ -0,0 +1,117 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gramscii.h"
+
+static int LONG_STEP;
+
+/* line_t and lineset_t management */
+
+void ensure_line_length(line_t *l, int len){
+ char *tmp;
+
+ if (l->sz < len + 1){
+ tmp = realloc(l->s, (len+1) * 2 * sizeof(char));
+ if (!tmp){
+ fprintf(stderr, "Unable to allocate string\n");
+ exit(1);
+ }
+ l->s = tmp;
+ l->sz = (len + 1) * 2;
+ }
+}
+
+
+void alloc_line(line_t *l){
+ char *tmp;
+
+ l->sz = WIDTH+1;
+ tmp = malloc((l->sz) * sizeof(char));
+ if (tmp == NULL){
+ fprintf(stderr, "unable to allocate line\n");
+ exit(1);
+ }
+ l->s = tmp;
+ memset(l->s, BG, l->sz);
+ l->lst = -1;
+ l->s[0]='\0';
+}
+
+void ensure_num_lines(lineset_t *ls, int n){
+ line_t *tmp;
+
+ if (n > ls->sz){
+ if (ls->sz == 0)
+ ls->l=NULL;
+ tmp = realloc(ls->l, (n + LONG_STEP) * sizeof(line_t));
+ if (tmp == NULL){
+ fprintf(stderr, "Unable to allocate memory for more lines");
+ exit(1);
+ }
+ else {
+ ls->l = tmp;
+ while ( ls->sz < n + LONG_STEP){
+ alloc_line(&(ls->l[ls->sz]));
+ ls->sz ++;
+ }
+ }
+ }
+}
+
+void dump_lines(lineset_t ls, FILE *f){
+ int i;
+ for (i=0; i<ls.num ;i++){
+ fprintf(f, "%d:%s\n", i, ls.l[i].s);
+ }
+ fflush(f);
+}
+
+void pad_line_to_length(char *s, int W){
+
+ int i;
+
+ for (i=strlen(s); i<W; i++){
+ s[i] = BG;
+ }
+}
+
+/* cut/yank/paste/undo management */
+
+void yank_region(int x1, int y1, int x2, int y2){
+
+ int N, W, i;
+
+ N = y2 - y1 + 1;
+ W = x2 - x1 + 1;
+ ensure_num_lines(&cutbuf, N);
+
+ for (i=y1; i<=y2; i++){
+ ensure_line_length(&(cutbuf.l[i-y1]), W);
+ memcpy(cutbuf.l[i-y1].s, screen.l[i].s + x1, x2-x1+1);
+ if (strlen(cutbuf.l[i-y1].s) < W)
+ pad_line_to_length(cutbuf.l[i-y1].s, W);
+ cutbuf.l[i-y1].s[W] = '\0';
+ cutbuf.l[i-y1].n = i;
+ }
+ cutbuf.num = N;
+#ifdef DEBUG
+ dump_lines(cutbuf, stderr);
+#endif
+
+}
+
+
+void paste_region(int x1, int y1){
+ int i, curlen;
+
+ i = y1;
+ while( i < HEIGHT && i < y1 + cutbuf.num){
+ memcpy(screen.l[i].s + x1, cutbuf.l[i-y1].s, strlen(cutbuf.l[i-y1].s));
+ curlen = strlen(screen.l[i].s);
+ if (curlen <= x1)
+ /* double-check this line below */
+ pad_line_to_length(screen.l[i].s+curlen, x1 - curlen);
+ i += 1;
+ modified = 1;
+ }
+}