Import from old repository commit 61ef2b42a9c4ba8e1600f15bb0236765edc2ad45.
[openvswitch] / extras / ezio / ezio.c
1 /* Copyright (c) 2008, 2009 Nicira Networks, Inc.
2  *
3  * This program is free software: you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation, either version 3 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  *
16  * In addition, as a special exception, Nicira Networks gives permission
17  * to link the code of its release of vswitchd with the OpenSSL project's
18  * "OpenSSL" library (or with modified versions of it that use the same
19  * license as the "OpenSSL" library), and distribute the linked
20  * executables.  You must obey the GNU General Public License in all
21  * respects for all of the code used other than "OpenSSL".  If you modify
22  * this file, you may extend this exception to your version of the file,
23  * but you are not obligated to do so.  If you do not wish to do so,
24  * delete this exception statement from your version.
25  *
26  */
27
28 #include <config.h>
29 #include "ezio.h"
30 #include <assert.h>
31 #include <stddef.h>
32 #include <string.h>
33 #include "util.h"
34
35 static void remove_elements(uint8_t *p, size_t n_elems, size_t elem_size,
36                             int pos, int n_del);
37 static void insert_elements(uint8_t *p, size_t n_elems, size_t elem_size,
38                             int pos, int n_insert);
39 static int range(int value, int min, int max);
40
41 void
42 ezio_init(struct ezio *e)
43 {
44     memset(e->icons, 0, sizeof e->icons);
45     ezio_clear(e);
46     e->x_ofs = 0;
47     e->show_cursor = true;
48     e->blink_cursor = false;
49 }
50
51 void
52 ezio_set_icon(struct ezio *e, int idx,
53               int row0, int row1, int row2, int row3,
54               int row4, int row5, int row6, int row7)
55 {
56     e->icons[idx][0] = row0;
57     e->icons[idx][1] = row1;
58     e->icons[idx][2] = row2;
59     e->icons[idx][3] = row3;
60     e->icons[idx][4] = row4;
61     e->icons[idx][5] = row5;
62     e->icons[idx][6] = row6;
63     e->icons[idx][7] = row7;
64 }
65
66 void
67 ezio_set_default_icon(struct ezio *e, int idx)
68 {
69     uint8_t *icon;
70
71     assert(idx >= 0 && idx < 8);
72     icon = e->icons[idx];
73     if (idx == 6) {
74         ezio_set_icon(e, idx,
75                       e_____,
76                       eX____,
77                       e_X___,
78                       e__X__,
79                       e___X_,
80                       e____X,
81                       e_____,
82                       e_____);
83     } else if (idx == 7) {
84         ezio_set_icon(e, idx,
85                       e_____,
86                       e_____,
87                       e_X___,
88                       eX_X_X,
89                       eX_X_X,
90                       e___X_,
91                       e_____,
92                       e_____);
93     } else {
94         ezio_set_icon(e, idx,
95                       e_____,
96                       e_____,
97                       e_____,
98                       e_____,
99                       e_____,
100                       e_____,
101                       e_____,
102                       e_____);
103     }
104 }
105
106 void
107 ezio_clear(struct ezio *e)
108 {
109     memset(e->chars, ' ', sizeof e->chars);
110     e->x = e->y = 0;
111 }
112
113 void
114 ezio_put_char(struct ezio *e, int x, int y, uint8_t c)
115 {
116     assert(x >= 0 && x <= 39);
117     assert(y >= 0 && y <= 1);
118     e->chars[y][x] = c != 0xfe ? c : 0xff;
119 }
120
121 void
122 ezio_line_feed(struct ezio *e)
123 {
124     if (++e->y >= 2) {
125         e->y = 1;
126         ezio_scroll_up(e, 1);
127     }
128 }
129
130 void
131 ezio_newline(struct ezio *e)
132 {
133     e->x = 0;
134     ezio_line_feed(e);
135 }
136
137 void
138 ezio_delete_char(struct ezio *e, int x, int y, int n)
139 {
140     remove_elements(&e->chars[y][0], 40, 1, x, n);
141 }
142
143 void
144 ezio_delete_line(struct ezio *e, int y, int n)
145 {
146     remove_elements(e->chars[0], 2, 40, y, n);
147 }
148
149 void
150 ezio_insert_char(struct ezio *e, int x, int y, int n)
151 {
152     insert_elements(&e->chars[y][0], 40, 1, x, n);
153 }
154
155 void
156 ezio_insert_line(struct ezio *e, int y, int n)
157 {
158     insert_elements(&e->chars[0][0], 2, 40, y, n);
159 }
160
161 void
162 ezio_scroll_left(struct ezio *e, int n)
163 {
164     int y;
165     for (y = 0; y < 2; y++) {
166         ezio_delete_char(e, 0, y, n);
167     }
168 }
169
170 void
171 ezio_scroll_right(struct ezio *e, int n)
172 {
173     int y;
174
175     for (y = 0; y < 2; y++) {
176         ezio_insert_char(e, 0, y, n);
177     }
178 }
179
180 void
181 ezio_scroll_up(struct ezio *e, int n)
182 {
183     ezio_delete_line(e, 0, n);
184 }
185
186 void
187 ezio_scroll_down(struct ezio *e, int n)
188 {
189     ezio_insert_line(e, 0, n);
190 }
191
192 bool
193 ezio_chars_differ(const struct ezio *a, const struct ezio *b, int x0, int x1,
194                   int *xp, int *yp)
195 {
196     int x, y;
197
198     x0 = range(x0, 0, 39);
199     x1 = range(x1, 1, 40);
200     for (y = 0; y < 2; y++) {
201         for (x = x0; x < x1; x++) {
202             if (a->chars[y][x] != b->chars[y][x]) {
203                 *xp = x;
204                 *yp = y;
205                 return true;
206             }
207         }
208     }
209     return false;
210 }
211
212 static void
213 remove_elements(uint8_t *p, size_t n_elems, size_t elem_size,
214                 int pos, int n_del)
215 {
216     if (pos >= 0 && pos < n_elems) {
217         n_del = MIN(n_del, n_elems - pos);
218         memmove(p + elem_size * pos,
219                 p + elem_size * (pos + n_del),
220                 elem_size * (n_elems - pos - n_del));
221         memset(p + elem_size * (n_elems - n_del), ' ', n_del * elem_size);
222     }
223 }
224
225 static void
226 insert_elements(uint8_t *p, size_t n_elems, size_t elem_size,
227                 int pos, int n_insert)
228 {
229     if (pos >= 0 && pos < n_elems) {
230         n_insert = MIN(n_insert, n_elems - pos);
231         memmove(p + elem_size * (pos + n_insert),
232                 p + elem_size * pos,
233                 elem_size * (n_elems - pos - n_insert));
234         memset(p + elem_size * pos, ' ', n_insert * elem_size);
235     }
236 }
237
238 static int
239 range(int value, int min, int max)
240 {
241     return value < min ? min : value > max ? max : value;
242 }
243