1 /* -*- c-basic-offset:2; tab-width:2; indent-tabs-mode:nil -*- */
2
3 #include "vt_model.h"
4
5 #include <pobl/bl_mem.h> /* malloc/free */
6 #include <pobl/bl_debug.h>
7 #include <pobl/bl_util.h>
8
9 /* --- global functions --- */
10
vt_model_init(vt_model_t * model,u_int num_cols,u_int num_rows)11 int vt_model_init(vt_model_t *model, u_int num_cols, u_int num_rows) {
12 u_int count;
13
14 if (num_rows == 0 || num_cols == 0) {
15 return 0;
16 }
17
18 model->num_rows = num_rows;
19 model->num_cols = num_cols;
20
21 if ((model->lines = calloc(sizeof(vt_line_t), model->num_rows)) == NULL) {
22 #ifdef DEBUG
23 bl_warn_printf(BL_DEBUG_TAG "calloc() failed.\n");
24 #endif
25
26 return 0;
27 }
28
29 for (count = 0; count < model->num_rows; count++) {
30 if (!vt_line_init(&model->lines[count], model->num_cols)) {
31 return 0;
32 }
33 }
34
35 model->beg_row = 0;
36
37 return 1;
38 }
39
vt_model_final(vt_model_t * model)40 void vt_model_final(vt_model_t *model) {
41 u_int count;
42
43 for (count = 0; count < model->num_rows; count++) {
44 vt_line_final(&model->lines[count]);
45 }
46
47 free(model->lines);
48 }
49
vt_model_reset(vt_model_t * model)50 void vt_model_reset(vt_model_t *model) {
51 u_int count;
52
53 for (count = 0; count < model->num_rows; count++) {
54 vt_line_reset(&model->lines[count]);
55 vt_line_set_updated(&model->lines[count]);
56 }
57 }
58
vt_model_resize(vt_model_t * model,u_int num_cols,u_int num_rows,u_int slide)59 int vt_model_resize(vt_model_t *model, u_int num_cols, u_int num_rows, u_int slide) {
60 int new_row;
61 u_int count;
62 u_int copy_rows;
63 vt_line_t *lines_p;
64
65 if (num_cols == 0 || num_rows == 0) {
66 return 0;
67 }
68
69 if (num_cols == model->num_cols && num_rows == model->num_rows) {
70 /* not resized */
71
72 return 0;
73 }
74
75 if ((lines_p = calloc(sizeof(vt_line_t), num_rows)) == NULL) {
76 return 0;
77 }
78
79 if (model->num_rows - slide > num_rows) {
80 copy_rows = num_rows;
81 } else {
82 copy_rows = model->num_rows - slide;
83 }
84
85 /* updating existing lines. */
86 for (new_row = 0; new_row < copy_rows; new_row++) {
87 vt_line_init(&lines_p[new_row], num_cols);
88 vt_line_copy(&lines_p[new_row], vt_model_get_line(model, slide));
89 slide++;
90 vt_line_set_modified_all(&lines_p[new_row]);
91 lines_p[new_row].is_modified = 2; /* XXX See set_real_modified() in vt_line.c */
92 }
93
94 /* freeing old data. */
95 for (count = 0; count < model->num_rows; count++) {
96 vt_line_final(&model->lines[count]);
97 }
98 free(model->lines);
99 model->lines = lines_p;
100
101 /* update empty lines. */
102 for (; new_row < num_rows; new_row++) {
103 vt_line_init(&lines_p[new_row], num_cols);
104 vt_line_set_modified_all(&lines_p[new_row]);
105 }
106
107 model->num_rows = num_rows;
108 model->num_cols = num_cols;
109
110 model->beg_row = 0;
111
112 return 1;
113 }
114
vt_model_get_num_filled_rows(vt_model_t * model)115 u_int vt_model_get_num_filled_rows(vt_model_t *model) {
116 u_int filled_rows;
117
118 for (filled_rows = model->num_rows; filled_rows > 0; filled_rows--) {
119 #if 1
120 /*
121 * XXX
122 * This is problematic, since the value of 'slide' can be incorrect when
123 * cursor is located at the line which contains white spaces alone.
124 */
125 if (vt_line_get_num_filled_chars_except_sp(vt_model_get_line(model, filled_rows - 1)) > 0)
126 #else
127 if (!vt_line_is_empty(vt_model_get_line(model, filled_rows - 1)))
128 #endif
129 {
130 break;
131 }
132 }
133
134 return filled_rows;
135 }
136
vt_model_end_row(vt_model_t * model)137 int vt_model_end_row(vt_model_t *model) { return model->num_rows - 1; }
138
vt_model_get_line(vt_model_t * model,int row)139 vt_line_t *vt_model_get_line(vt_model_t *model, int row) {
140 if (row < 0 || model->num_rows <= row) {
141 #ifdef __DEBUG
142 bl_debug_printf(BL_DEBUG_TAG " row %d is out of range.\n", row);
143 #endif
144
145 return NULL;
146 }
147
148 if (model->beg_row + row < model->num_rows) {
149 return &model->lines[model->beg_row + row];
150 } else {
151 return &model->lines[model->beg_row + row - model->num_rows];
152 }
153 }
154
vt_model_scroll_upward(vt_model_t * model,u_int size)155 void vt_model_scroll_upward(vt_model_t *model, u_int size) {
156 if (size > model->num_rows) {
157 size = model->num_rows;
158 }
159
160 if (model->beg_row + size >= model->num_rows) {
161 model->beg_row = model->beg_row + size - model->num_rows;
162 } else {
163 model->beg_row += size;
164 }
165 }
166
vt_model_scroll_downward(vt_model_t * model,u_int size)167 void vt_model_scroll_downward(vt_model_t *model, u_int size) {
168 if (size > model->num_rows) {
169 size = model->num_rows;
170 }
171
172 if (model->beg_row < size) {
173 model->beg_row = model->num_rows - (size - model->beg_row);
174 } else {
175 model->beg_row -= size;
176 }
177 }
178
179 #ifdef DEBUG
180
vt_model_dump(vt_model_t * model)181 void vt_model_dump(vt_model_t *model) {
182 int row;
183 vt_line_t *line;
184
185 for (row = 0; row < model->num_rows; row++) {
186 line = vt_model_get_line(model, row);
187
188 if (vt_line_is_modified(line)) {
189 bl_msg_printf("!%.2d-%.2d", vt_line_get_beg_of_modified(line),
190 vt_line_get_end_of_modified(line));
191 } else {
192 bl_msg_printf(" ");
193 }
194
195 bl_msg_printf("[%.2d %.2d]", line->num_filled_chars, vt_line_get_num_filled_cols(line));
196
197 vt_str_dump(line->chars, line->num_filled_chars);
198 }
199 }
200
201 #endif
202