summaryrefslogtreecommitdiff
path: root/screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'screen.c')
-rw-r--r--screen.c138
1 files changed, 101 insertions, 37 deletions
diff --git a/screen.c b/screen.c
index 2e61acf..0c5f2d8 100644
--- a/screen.c
+++ b/screen.c
@@ -109,39 +109,64 @@ int is_yes(char c){
/*** Screen management ***/
-void show_cursor(){
- if (silent)
- return;
- printf("\033[%d;%df", y+1, x+1);
- fflush(stdout);
+void ensure_line_length(int i, int len){
+ char *tmp;
+
+ if (screen[i].sz < len + 1){
+ tmp = realloc(screen[i].s, (len+1) * 2 * sizeof(char));
+ if (!tmp){
+ fprintf(stderr, "Unable to allocate string\n");
+ exit(1);
+ }
+ screen[i].s = tmp;
+ screen[i].sz = (len + 1) * 2;
+ }
}
-void set_xy(int _x, int _y, char c){
+void alloc_line(int i){
+ char *tmp;
+
+ screen[i].sz = WIDTH+1;
+ tmp = malloc((screen[i].sz) * sizeof(char));
+ if (tmp == NULL){
+ fprintf(stderr, "unable to allocate line %d\n", i+1);
+ exit(1);
+ }
+ screen[i].s = tmp;
+ memset(screen[i].s, BG, screen[i].sz);
+ screen[i].lst = -1;
+ screen[i].s[0]='\0';
+}
+
+void ensure_num_lines(int n){
line_t *tmp;
- if (_y >= num_lines){
- tmp = realloc(screen, (_y + LONG_STEP)* sizeof(line_t));
+
+ if (n > num_lines){
+ tmp = realloc(screen, (n + LONG_STEP) * sizeof(line_t));
if (tmp == NULL){
fprintf(stderr, "Unable to allocate memory for more lines");
exit(1);
}
- else while ( num_lines < _y + LONG_STEP){
- screen[num_lines].sz = WIDTH+1;
- screen[num_lines].s = malloc((screen[num_lines].sz) * sizeof(char));
- if (screen[num_lines].s == NULL){
- perror("allocating screen[num_lines].s");
- exit(1);
- }
- memset(screen[num_lines].s, BG, screen[num_lines].sz);
- screen[num_lines].lst = 0;
- screen[num_lines].s[screen[num_lines].lst+1]='\0';
+ else while ( num_lines < n + LONG_STEP){
+ alloc_line(num_lines);
num_lines ++;
}
}
- if (screen[_y].sz < _x + 2){
- screen[_y].sz = (_x +2) * 2;
- screen[_y].s = realloc(screen[_y].s, screen[_y].sz * sizeof(char));
- }
+}
+
+
+void show_cursor(){
+ if (silent)
+ return;
+ printf("\033[%d;%df", y+1, x+1);
+ fflush(stdout);
+}
+
+
+void set_xy(int _x, int _y, char c){
+ ensure_num_lines(_y + 1);
+ ensure_line_length(_y, _x + 1);
while (screen[_y].lst<_x){
screen[_y].lst ++;
screen[_y].s[screen[_y].lst] = BG;
@@ -172,11 +197,9 @@ void update_current(){
fflush(stdout);
}
-void erase_line(char *s){
- while(*s){
- *s = BG;
- s++;
- }
+void erase_line(int i){
+ screen[i].lst = -1;
+ screen[i].s[0] = '\0';
}
void erase_box(int x1, int y1, char c){
@@ -196,7 +219,7 @@ void erase_box(int x1, int y1, char c){
void erase_screen(){
int i;
for(i=0;i<HEIGHT; i++)
- erase_line(screen[i].s);
+ erase_line(i);
}
void check_bound(){
@@ -399,15 +422,7 @@ void init_screen(){
exit(1);
}
for (i=0; i<HEIGHT; i++){
- screen[i].sz = WIDTH+1;
- screen[i].s = malloc((screen[i].sz) * sizeof(char));
- if (screen[i].s == NULL){
- perror("allocating screen[i].s");
- exit(1);
- }
- memset(screen[i].s, BG, screen[i].sz);
- screen[i].lst = 0;
- screen[i].s[screen[i].lst+1]='\0';
+ alloc_line(i);
}
hlines_sz= sizeof(hlines) -1;
vlines_sz= sizeof(vlines) -1;
@@ -417,3 +432,52 @@ void init_screen(){
reset_styles();
}
+void find_nonblank_rect(int *x1, int *y1, int *x2, int *y2){
+
+ int i, j;
+ int first;
+ *x1= WIDTH; /** FIXME: replace with num_cols **/
+ *y1 = num_lines;
+ *x2 = *y2 = 0;
+
+ for (i=0; i<num_lines; i++){
+ if (screen[i].lst < 0)
+ continue;
+ *y2 = i;
+ if (i < *y1)
+ *y1 = i;
+ if (screen[i].lst > *x2)
+ *x2 = screen[i].lst;
+ j = 0;
+ while(j <= screen[i].lst && isblank(first=screen[i].s[j]))
+ j++;
+ if (j < *x1)
+ *x1 = j;
+ }
+}
+
+void crop_to_rect(int x1, int y1, int x2, int y2){
+ int i;
+
+ for (i=0; i<= y2-y1; i ++){
+ ensure_line_length(i, screen[i+y1].lst);
+ sprintf(screen[i].s, "%s", screen[i+y1].s + x1);
+ screen[i].lst = screen[i+y1].lst - x1;
+ }
+ while (i<=y2){
+ screen[i].lst = -1;
+ screen[i].s[0]= '\0';
+ i ++;
+ }
+}
+
+void crop_to_nonblank(){
+ int x1, x2, y1, y2;
+ find_nonblank_rect(&x1, &y1, &x2, &y2);
+#ifdef DEBUG
+ fprintf(stderr, "crop rectangle: (%d, %d)-(%d, %d)\n", x1, y1, x2, y2);
+#endif
+ crop_to_rect(x1, y1, x2, y2);
+ redraw();
+}
+