1 #ifndef EL__TERMINAL_DRAW_H
2 #define EL__TERMINAL_DRAW_H
3 
4 struct color_pair;
5 struct box;
6 struct terminal;
7 
8 /* All attributes should fit inside an unsigned char. */
9 /* XXX: The bold mask is used as part of the color encoding. */
10 enum screen_char_attr {
11 	SCREEN_ATTR_UNSEARCHABLE = 0x01,
12 	SCREEN_ATTR_BOLD	= 0x08,
13 	SCREEN_ATTR_ITALIC	= 0x10,
14 	SCREEN_ATTR_UNDERLINE	= 0x20,
15 	SCREEN_ATTR_STANDOUT	= 0x40,
16 	SCREEN_ATTR_FRAME	= 0x80,
17 };
18 
19 /* One position in the terminal screen's image. */
20 struct screen_char {
21 	/* Contains either character value or frame data. */
22 	unsigned char data;
23 
24 	/* Attributes are screen_char_attr bits. */
25 	unsigned char attr;
26 
27 	/* The encoded fore- and background color. */
28 #if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS)
29 	unsigned char color[2];
30 #else
31 	unsigned char color[1];
32 #endif
33 };
34 
35 #define copy_screen_chars(to, from, amount) \
36 	do { memcpy(to, from, (amount) * sizeof(struct screen_char)); } while (0)
37 
38 /* Linux frame symbols table (it's magically converted to other terminals when
39  * needed). */
40 /* In the screen image, they have attribute SCREEN_ATTR_FRAME; you should drop them
41  * to the image using draw_border_char(). */
42 /* TODO: When we'll support internal Unicode, this should be changed to some
43  * Unicode sequences. --pasky */
44 
45 /* Codes extracted from twin-0.4.6 GPL project, a Textmode WINdow environment,
46  * by Massimiliano Ghilardi http://linuz.sns.it/~max/ */
47 
48 /* Not yet used
49 #define T_UTF_16_BOX_DRAWINGS_LIGHT_VERTICAL	0x2502
50 #define T_UTF_16_BOX_DRAWINGS_LIGHT_VERTICAL_AND_LEFT	0x2524
51 #define T_UTF_16_BOX_DRAWINGS_VERTICAL_SINGLE_AND_LEFT_DOUBLE	0x2561
52 #define T_UTF_16_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_LEFT_SINGLE	0x2562
53 #define T_UTF_16_BOX_DRAWINGS_DOWN_DOUBLE_AND_LEFT_SINGLE	0x2556
54 #define T_UTF_16_BOX_DRAWINGS_DOWN_SINGLE_AND_LEFT_DOUBLE	0x2555
55 #define T_UTF_16_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_LEFT	0x2563
56 #define T_UTF_16_BOX_DRAWINGS_DOUBLE_VERTICAL	0x2551
57 #define T_UTF_16_BOX_DRAWINGS_DOUBLE_DOWN_AND_LEFT	0x2557
58 #define T_UTF_16_BOX_DRAWINGS_DOUBLE_UP_AND_LEFT	0x255D
59 #define T_UTF_16_BOX_DRAWINGS_UP_DOUBLE_AND_LEFT_SINGLE	0x255C
60 #define T_UTF_16_BOX_DRAWINGS_UP_SINGLE_AND_LEFT_DOUBLE	0x255B
61 #define T_UTF_16_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT	0x2510
62 #define T_UTF_16_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT	0x2514
63 #define T_UTF_16_BOX_DRAWINGS_LIGHT_UP_AND_HORIZONTAL	0x2534
64 #define T_UTF_16_BOX_DRAWINGS_LIGHT_DOWN_AND_HORIZONTAL	0x252C
65 #define T_UTF_16_BOX_DRAWINGS_LIGHT_VERTICAL_AND_RIGHT	0x251C
66 #define T_UTF_16_BOX_DRAWINGS_LIGHT_HORIZONTAL	0x2500
67 #define T_UTF_16_BOX_DRAWINGS_LIGHT_VERTICAL_AND_HORIZONTAL	0x253C
68 #define T_UTF_16_BOX_DRAWINGS_VERTICAL_SINGLE_AND_RIGHT_DOUBLE	0x255E
69 #define T_UTF_16_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_RIGHT_SINGLE	0x255F
70 #define T_UTF_16_BOX_DRAWINGS_DOUBLE_UP_AND_RIGHT	0x255A
71 #define T_UTF_16_BOX_DRAWINGS_DOUBLE_DOWN_AND_RIGHT	0x2554
72 #define T_UTF_16_BOX_DRAWINGS_DOUBLE_UP_AND_HORIZONTAL	0x2569
73 #define T_UTF_16_BOX_DRAWINGS_DOUBLE_DOWN_AND_HORIZONTAL	0x2566
74 #define T_UTF_16_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_RIGHT	0x2560
75 #define T_UTF_16_BOX_DRAWINGS_DOUBLE_HORIZONTAL	0x2550
76 #define T_UTF_16_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_HORIZONTAL	0x256C
77 #define T_UTF_16_BOX_DRAWINGS_UP_SINGLE_AND_HORIZONTAL_DOUBLE	0x2567
78 #define T_UTF_16_BOX_DRAWINGS_UP_DOUBLE_AND_HORIZONTAL_SINGLE	0x2568
79 #define T_UTF_16_BOX_DRAWINGS_DOWN_SINGLE_AND_HORIZONTAL_DOUBLE	0x2564
80 #define T_UTF_16_BOX_DRAWINGS_DOWN_DOUBLE_AND_HORIZONTAL_SINGLE	0x2565
81 #define T_UTF_16_BOX_DRAWINGS_UP_DOUBLE_AND_RIGHT_SINGLE	0x2559
82 #define T_UTF_16_BOX_DRAWINGS_UP_SINGLE_AND_RIGHT_DOUBLE	0x2558
83 #define T_UTF_16_BOX_DRAWINGS_DOWN_SINGLE_AND_RIGHT_DOUBLE	0x2552
84 #define T_UTF_16_BOX_DRAWINGS_DOWN_DOUBLE_AND_RIGHT_SINGLE	0x2553
85 #define T_UTF_16_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE	0x256B
86 #define T_UTF_16_BOX_DRAWINGS_VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE	0x256A
87 #define T_UTF_16_BOX_DRAWINGS_LIGHT_UP_AND_LEFT	0x2518
88 #define T_UTF_16_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT	0x250C
89 */
90 
91 /* CP437 is used by default */
92 #define T_CP437_BOX_DRAWINGS_LIGHT_VERTICAL	0x00B3
93 #define T_CP437_BOX_DRAWINGS_LIGHT_VERTICAL_AND_LEFT	0x00B4
94 #define T_CP437_BOX_DRAWINGS_VERTICAL_SINGLE_AND_LEFT_DOUBLE	0x00B5
95 #define T_CP437_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_LEFT_SINGLE	0x00B6
96 #define T_CP437_BOX_DRAWINGS_DOWN_DOUBLE_AND_LEFT_SINGLE	0x00B7
97 #define T_CP437_BOX_DRAWINGS_DOWN_SINGLE_AND_LEFT_DOUBLE	0x00B8
98 #define T_CP437_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_LEFT	0x00B9
99 #define T_CP437_BOX_DRAWINGS_DOUBLE_VERTICAL	0x00BA
100 #define T_CP437_BOX_DRAWINGS_DOUBLE_DOWN_AND_LEFT	0x00BB
101 #define T_CP437_BOX_DRAWINGS_DOUBLE_UP_AND_LEFT	0x00BC
102 #define T_CP437_BOX_DRAWINGS_UP_DOUBLE_AND_LEFT_SINGLE	0x00BD
103 #define T_CP437_BOX_DRAWINGS_UP_SINGLE_AND_LEFT_DOUBLE	0x00BE
104 #define T_CP437_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT	0x00BF
105 #define T_CP437_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT	0x00C0
106 #define T_CP437_BOX_DRAWINGS_LIGHT_UP_AND_HORIZONTAL	0x00C1
107 #define T_CP437_BOX_DRAWINGS_LIGHT_DOWN_AND_HORIZONTAL	0x00C2
108 #define T_CP437_BOX_DRAWINGS_LIGHT_VERTICAL_AND_RIGHT	0x00C3
109 #define T_CP437_BOX_DRAWINGS_LIGHT_HORIZONTAL	0x00C4
110 #define T_CP437_BOX_DRAWINGS_LIGHT_VERTICAL_AND_HORIZONTAL	0x00C5
111 #define T_CP437_BOX_DRAWINGS_VERTICAL_SINGLE_AND_RIGHT_DOUBLE	0x00C6
112 #define T_CP437_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_RIGHT_SINGLE	0x00C7
113 #define T_CP437_BOX_DRAWINGS_DOUBLE_UP_AND_RIGHT	0x00C8
114 #define T_CP437_BOX_DRAWINGS_DOUBLE_DOWN_AND_RIGHT	0x00C9
115 #define T_CP437_BOX_DRAWINGS_DOUBLE_UP_AND_HORIZONTAL	0x00CA
116 #define T_CP437_BOX_DRAWINGS_DOUBLE_DOWN_AND_HORIZONTAL	0x00CB
117 #define T_CP437_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_RIGHT	0x00CC
118 #define T_CP437_BOX_DRAWINGS_DOUBLE_HORIZONTAL	0x00CD
119 #define T_CP437_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_HORIZONTAL	0x00CE
120 #define T_CP437_BOX_DRAWINGS_UP_SINGLE_AND_HORIZONTAL_DOUBLE	0x00CF
121 #define T_CP437_BOX_DRAWINGS_UP_DOUBLE_AND_HORIZONTAL_SINGLE	0x00D0
122 #define T_CP437_BOX_DRAWINGS_DOWN_SINGLE_AND_HORIZONTAL_DOUBLE	0x00D1
123 #define T_CP437_BOX_DRAWINGS_DOWN_DOUBLE_AND_HORIZONTAL_SINGLE	0x00D2
124 #define T_CP437_BOX_DRAWINGS_UP_DOUBLE_AND_RIGHT_SINGLE	0x00D3
125 #define T_CP437_BOX_DRAWINGS_UP_SINGLE_AND_RIGHT_DOUBLE	0x00D4
126 #define T_CP437_BOX_DRAWINGS_DOWN_SINGLE_AND_RIGHT_DOUBLE	0x00D5
127 #define T_CP437_BOX_DRAWINGS_DOWN_DOUBLE_AND_RIGHT_SINGLE	0x00D6
128 #define T_CP437_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE	0x00D7
129 #define T_CP437_BOX_DRAWINGS_VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE	0x00D8
130 #define T_CP437_BOX_DRAWINGS_LIGHT_UP_AND_LEFT	0x00D9
131 #define T_CP437_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT	0x00DA
132 
133 #define BD_LIGHT(XXX)  T_CP437_BOX_DRAWINGS_LIGHT_##XXX
134 #define BD_DOUBLE(XXX) T_CP437_BOX_DRAWINGS_DOUBLE_##XXX
135 #define BD_MIXED(XXX) 	T_CP437_BOX_DRAWINGS_##XXX
136 
137 enum border_char {
138 	BORDER_NONE	= 0x0000,
139 
140 	/* single-lined */
141 	BORDER_SULCORNER = BD_LIGHT(DOWN_AND_RIGHT),
142 	BORDER_SURCORNER = BD_LIGHT(DOWN_AND_LEFT),
143 	BORDER_SDLCORNER = BD_LIGHT(UP_AND_RIGHT),
144 	BORDER_SDRCORNER = BD_LIGHT(UP_AND_LEFT),
145 	BORDER_SLTEE	 = BD_LIGHT(VERTICAL_AND_LEFT), /* => the tee points to the left => -| */
146 	BORDER_SRTEE	 = BD_LIGHT(VERTICAL_AND_RIGHT),
147 	BORDER_SDTEE	 = BD_LIGHT(DOWN_AND_HORIZONTAL),
148 	BORDER_SUTEE	 = BD_LIGHT(UP_AND_HORIZONTAL),
149 	BORDER_SVLINE	 = BD_LIGHT(VERTICAL),
150 	BORDER_SHLINE	 = BD_LIGHT(HORIZONTAL),
151 	BORDER_SCROSS	 = BD_LIGHT(VERTICAL_AND_HORIZONTAL), /* + */
152 
153 	/* double-lined */
154 	BORDER_DULCORNER = BD_DOUBLE(DOWN_AND_RIGHT),
155 	BORDER_DURCORNER = BD_DOUBLE(DOWN_AND_LEFT),
156 	BORDER_DDLCORNER = BD_DOUBLE(UP_AND_RIGHT),
157 	BORDER_DDRCORNER = BD_DOUBLE(UP_AND_LEFT),
158 	BORDER_DLTEE	 = BD_DOUBLE(VERTICAL_AND_LEFT),
159 	BORDER_DRTEE	 = BD_DOUBLE(VERTICAL_AND_RIGHT),
160 	BORDER_DDTEE	 = BD_DOUBLE(DOWN_AND_HORIZONTAL),
161 	BORDER_DUTEE	 = BD_DOUBLE(UP_AND_HORIZONTAL),
162 	BORDER_DVLINE	 = BD_DOUBLE(VERTICAL),
163 	BORDER_DHLINE	 = BD_DOUBLE(HORIZONTAL),
164 	BORDER_DCROSS	 = BD_DOUBLE(VERTICAL_AND_HORIZONTAL),
165 
166 	/* Mixed single then double */
167 	BORDER_SDULCORNER = BD_MIXED(DOWN_SINGLE_AND_RIGHT_DOUBLE),
168 	BORDER_SDURCORNER = BD_MIXED(DOWN_SINGLE_AND_LEFT_DOUBLE),
169 	BORDER_SDDLCORNER = BD_MIXED(UP_SINGLE_AND_RIGHT_DOUBLE),
170 	BORDER_SDDRCORNER = BD_MIXED(UP_SINGLE_AND_LEFT_DOUBLE),
171 	BORDER_SDLTEE	  = BD_MIXED(VERTICAL_SINGLE_AND_LEFT_DOUBLE),
172 	BORDER_SDRTEE	  = BD_MIXED(VERTICAL_SINGLE_AND_RIGHT_DOUBLE),
173 	BORDER_SDDTEE	  = BD_MIXED(DOWN_SINGLE_AND_HORIZONTAL_DOUBLE),
174 	BORDER_SDUTEE	  = BD_MIXED(UP_SINGLE_AND_HORIZONTAL_DOUBLE),
175 	BORDER_SDCROSS	  = BD_MIXED(VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE),
176 
177 	/* Mixed double then single */
178 	BORDER_DSULCORNER = BD_MIXED(DOWN_DOUBLE_AND_RIGHT_SINGLE),
179 	BORDER_DSURCORNER = BD_MIXED(DOWN_DOUBLE_AND_LEFT_SINGLE),
180 	BORDER_DSDLCORNER = BD_MIXED(UP_DOUBLE_AND_RIGHT_SINGLE),
181 	BORDER_DSDRCORNER = BD_MIXED(UP_DOUBLE_AND_LEFT_SINGLE),
182 	BORDER_DSLTEE	  = BD_MIXED(VERTICAL_DOUBLE_AND_LEFT_SINGLE),
183 	BORDER_DSRTEE	  = BD_MIXED(VERTICAL_DOUBLE_AND_RIGHT_SINGLE),
184 	BORDER_DSDTEE	  = BD_MIXED(DOWN_DOUBLE_AND_HORIZONTAL_SINGLE),
185 	BORDER_DSUTEE	  = BD_MIXED(UP_DOUBLE_AND_HORIZONTAL_SINGLE),
186 	BORDER_DSCROSS	  = BD_MIXED(VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE),
187 };
188 
189 /* 0 -> 1 <- 2 v 3 ^ */
190 enum border_cross_direction {
191 	BORDER_X_RIGHT = 0,
192 	BORDER_X_LEFT,
193 	BORDER_X_DOWN,
194 	BORDER_X_UP
195 };
196 
197 /* Extracts a char from the screen. */
198 struct screen_char *get_char(struct terminal *, int x, int y);
199 
200 /* Sets the color of a screen position. */
201 void draw_char_color(struct terminal *term, int x, int y,
202 		     struct color_pair *color);
203 
204 /* Sets the data of a screen position. */
205 void draw_char_data(struct terminal *term, int x, int y, unsigned char data);
206 
207 /* Sets the data to @border and of a screen position. */
208 void draw_border_char(struct terminal *term, int x, int y,
209 		      enum border_char border, struct color_pair *color);
210 
211 /* Sets the cross position of two borders. */
212 void draw_border_cross(struct terminal *, int x, int y,
213 		       enum border_cross_direction, struct color_pair *color);
214 
215 /* Draws a char. */
216 void draw_char(struct terminal *term, int x, int y,
217 	       unsigned char data, enum screen_char_attr attr,
218 	       struct color_pair *color);
219 
220 /* Draws area defined by @box using the same colors and attributes. */
221 void draw_box(struct terminal *term, struct box *box,
222 	      unsigned char data, enum screen_char_attr attr,
223 	      struct color_pair *color);
224 
225 /* Draws a shadow of @width and @height with color @color around @box. */
226 void draw_shadow(struct terminal *term, struct box *box,
227 		 struct color_pair *color, int width, int height);
228 
229 /* Draw borders. */
230 void draw_border(struct terminal *term, struct box *box,
231 		 struct color_pair *color, int width);
232 
233 /* Draws @length chars from @text. */
234 void draw_text(struct terminal *term, int x, int y,
235 	       unsigned char *text, int length,
236 	       enum screen_char_attr attr,
237 	       struct color_pair *color);
238 
239 /* Draws @length chars from @line on the screen. */
240 /* Used by viewer to copy over a document. */
241 void draw_line(struct terminal *term, int x, int y, int length,
242 	       struct screen_char *line);
243 
244 /* Updates the terminals cursor position. When @blockable is set the
245  * block_cursor terminal option decides whether the cursor should be put at the
246  * bottom right corner of the screen. */
247 void set_cursor(struct terminal *term, int x, int y, int blockable);
248 
249 /* Blanks the screen. */
250 void clear_terminal(struct terminal *);
251 
252 #endif
253