6 * Copyright (C) 2002, 2003 Samuel Rydh (samuel@ibrium.se)
7 * Copyright (C) 2005 Stefan Reinauer <stepan@openbios.org>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation
16 #include "libopenbios/bindings.h"
17 #include "libopenbios/fontdata.h"
18 #include "libopenbios/console.h"
19 #include "packages/video.h"
21 #define FONT_ADJ_HEIGHT (FONT_HEIGHT + 2)
23 // Warning: will hang on purpose when encountering unknown codes
24 //#define DEBUG_CONSOLE
26 #define DPRINTF(fmt, args...) \
28 printk(fmt , ##args); \
32 #define DPRINTF(fmt, args...) do {} while(0)
36 ESnormal
, ESesc
, ESsquare
, ESgetpars
, ESgotpars
, ESfunckey
,
37 EShash
, ESsetG0
, ESsetG1
, ESpercent
, ESignore
, ESnonstd
,
52 unsigned int vc_npar
,vc_par
[NPAR
]; /* Parameters of current
57 get_conschar( int x
, int y
)
59 if( (unsigned int)x
< cons
.w
&& (unsigned int)y
< cons
.h
)
60 return cons
.buf
[y
*cons
.w
+ x
];
65 draw_char( unsigned int h
, unsigned int v
)
67 const unsigned char *c
= fontdata
;
68 int x
, y
, xx
, rskip
, m
;
69 int invert
= (h
==cons
.x
&& v
==cons
.y
&& cons
.cursor_on
);
70 int ch
= get_conschar( h
, v
);
72 while( h
>= cons
.w
|| v
>= cons
.h
)
78 rskip
= (FONT_WIDTH
> 8)? 2 : 1;
79 c
+= rskip
* (unsigned int)(ch
& 0xff) * FONT_HEIGHT
;
81 for( x
=0; x
<FONT_WIDTH
; x
++ ) {
86 for( y
=0; y
<FONT_HEIGHT
; y
++ ){
87 int col
= ((!(c
[rskip
*y
] & m
)) != invert
) ? 254 : 0;
88 draw_pixel( h
+x
, v
+y
+1, col
);
90 draw_pixel( h
+x
, v
, 254 );
91 draw_pixel( h
+x
, v
+FONT_HEIGHT
+1, 254 );
96 show_cursor( int show
)
98 if( cons
.cursor_on
== show
)
100 cons
.cursor_on
= show
;
101 draw_char( cons
.x
, cons
.y
);
110 if( n
>= cons
.h
|| n
< 0 )
112 for( i
=0; i
<cons
.w
; i
++ )
121 for( i
=0; i
<cons
.h
; i
++ )
129 if( video_get_res(&cons
.physw
,&cons
.physh
) < 0 )
134 cons
.w
= cons
.physw
/FONT_WIDTH
;
135 cons
.h
= cons
.physh
/FONT_ADJ_HEIGHT
;
136 cons
.buf
= malloc( cons
.w
* cons
.h
);
139 cons
.vc_state
= ESnormal
;
144 console_close( void )
153 rec_char( int ch
, int x
, int y
)
155 if( (unsigned int)x
< cons
.w
&& (unsigned int)y
< cons
.h
) {
156 cons
.buf
[y
*cons
.w
+ x
] = ch
;
166 video_scroll(FONT_ADJ_HEIGHT
);
168 for (y
= 1; y
< cons
.h
- 1; y
++) {
169 for (x
= 0; x
< cons
.w
; x
++)
170 cons
.buf
[(y
- 1) * cons
.w
+ x
] = cons
.buf
[y
* cons
.w
+ x
];
172 for (x
= 0; x
< cons
.w
; x
++)
173 cons
.buf
[(cons
.h
- 1) * cons
.w
+ x
] = ' ';
174 draw_line(cons
.h
- 1);
178 static void csi_at(unsigned int nr
)
182 if (nr
> cons
.w
- cons
.x
)
183 nr
= cons
.w
- cons
.x
;
187 for (x
= cons
.x
+ nr
; x
< cons
.w
- 1; x
++)
188 cons
.buf
[cons
.y
* cons
.w
+ x
- nr
] = cons
.buf
[cons
.y
* cons
.w
+ x
];
189 for (x
= cons
.x
; x
< cons
.x
+ nr
; x
++)
190 cons
.buf
[cons
.y
* cons
.w
+ x
] = ' ';
195 do_con_trol(unsigned char ch
)
210 cons
.x
= (cons
.x
+ 8) & ~7;
219 for (i
= 0; i
< cons
.h
; i
++) {
220 for (j
= 0; j
< cons
.w
; j
++)
221 cons
.buf
[i
* cons
.w
+ j
] = ' ';
235 cons
.vc_state
= ESnormal
;
239 cons
.vc_state
= ESesc
;
243 DPRINTF("Unhandled control char %d\n", ch
);
245 switch (cons
.vc_state
) {
247 cons
.vc_state
= ESnormal
;
250 cons
.vc_state
= ESsquare
;
256 DPRINTF("Unhandled basic escape code '%c'\n", ch
);
261 for(cons
.vc_npar
= 0; cons
.vc_npar
< NPAR
; cons
.vc_npar
++)
262 cons
.vc_par
[cons
.vc_npar
] = 0;
264 cons
.vc_state
= ESgetpars
;
267 if (ch
== ';' && cons
.vc_npar
< NPAR
- 1) {
270 } else if (ch
>= '0' && ch
<= '9') {
271 cons
.vc_par
[cons
.vc_npar
] *= 10;
272 cons
.vc_par
[cons
.vc_npar
] += ch
- '0';
275 cons
.vc_state
=ESgotpars
;
278 cons
.vc_state
= ESnormal
;
282 if (cons
.vc_par
[0] == 0)
284 if (cons
.y
- cons
.vc_par
[0] > 0)
285 cons
.y
-= cons
.vc_par
[0];
289 if (cons
.vc_par
[0] == 0)
291 if (cons
.y
+ cons
.vc_par
[0] < cons
.h
- 1)
292 cons
.y
+= cons
.vc_par
[0];
296 if (cons
.vc_par
[0] == 0)
298 if (cons
.x
+ cons
.vc_par
[0] < cons
.w
- 1)
299 cons
.x
+= cons
.vc_par
[0];
303 if (cons
.vc_par
[0] == 0)
305 if (cons
.x
- cons
.vc_par
[0] > 0)
306 cons
.x
-= cons
.vc_par
[0];
310 // Set cursor position
317 cons
.x
= cons
.vc_par
[1];
318 cons
.y
= cons
.vc_par
[0];
321 if (cons
.vc_par
[0] == 0 && (unsigned int)cons
.y
< (unsigned int)cons
.h
&&
322 (unsigned int)cons
.x
< (unsigned int)cons
.w
) {
323 // erase from cursor to end of display
324 for (i
= cons
.x
; i
< cons
.w
; i
++)
325 cons
.buf
[cons
.y
* cons
.w
+ i
] = ' ';
327 for (j
= cons
.y
+ 1; j
< cons
.h
; j
++) {
328 for (i
= 0; i
< cons
.w
; i
++)
329 cons
.buf
[j
* cons
.w
+ i
] = ' ';
333 DPRINTF("Unhandled CSI J code '%c'\n", cons
.vc_par
[0]);
337 switch (cons
.vc_par
[0]) {
338 case 0: /* erase from cursor to end of line */
339 for (i
= cons
.x
; i
< cons
.w
; i
++)
340 cons
.buf
[cons
.y
* cons
.w
+ i
] = ' ';
343 case 1: /* erase from start of line to cursor */
344 for (i
= 0; i
<= cons
.x
; i
++)
345 cons
.buf
[cons
.y
* cons
.w
+ i
] = ' ';
348 case 2: /* erase whole line */
349 for (i
= 0; i
< cons
.w
; i
++)
350 cons
.buf
[cons
.y
* cons
.w
+ i
] = ' ';
354 DPRINTF("Unhandled CSI K code '%c'\n", cons
.vc_par
[0]);
359 if (cons
.vc_par
[0] == 1)
362 DPRINTF("Unhandled CSI M %d\n", cons
.vc_par
[0]);
365 // Attributes are ignored
368 csi_at(cons
.vc_par
[0]);
371 DPRINTF("Unhandled escape code '%c', par[%d, %d, %d, %d, %d]\n",
372 ch
, cons
.vc_par
[0], cons
.vc_par
[1], cons
.vc_par
[2],
373 cons
.vc_par
[3], cons
.vc_par
[4]);
378 cons
.vc_state
= ESnormal
;
379 rec_char(ch
, cons
.x
++, cons
.y
);
385 console_draw_fstr(const char *str
, int len
)
390 if (!str
|| len
<= 0) {
394 if( !cons
.inited
&& console_init() )
398 while((ch
= *str
++) && len
--) {
401 if( cons
.x
>= cons
.w
) {
404 if( cons
.y
>= cons
.h
) {
405 for( y
=0; y
<cons
.h
-1; y
++ )
406 for( x
=0; x
<cons
.w
; x
++ )
407 cons
.buf
[y
*cons
.w
+ x
] = cons
.buf
[(y
+1)*cons
.w
+ x
];