218 lines
4.1 KiB
C
218 lines
4.1 KiB
C
|
/*
|
||
|
Copyright (C) 2015-2019 The University of Notre Dame
|
||
|
This software is distributed under the GNU General Public License.
|
||
|
See the file LICENSE for details.
|
||
|
*/
|
||
|
|
||
|
#include "console.h"
|
||
|
#include "serial.h"
|
||
|
#include "graphics.h"
|
||
|
#include "kmalloc.h"
|
||
|
#include "string.h"
|
||
|
|
||
|
struct console {
|
||
|
struct window *window;
|
||
|
struct graphics *gx;
|
||
|
int xsize;
|
||
|
int ysize;
|
||
|
int xpos;
|
||
|
int ypos;
|
||
|
int onoff;
|
||
|
int refcount;
|
||
|
};
|
||
|
|
||
|
struct console console_root = {0};
|
||
|
|
||
|
static struct graphics_color bgcolor = { 0, 0, 0 };
|
||
|
static struct graphics_color fgcolor = { 255, 255, 255 };
|
||
|
|
||
|
struct console * console_create_root()
|
||
|
{
|
||
|
console_root.window = window_create_root();
|
||
|
console_root.gx = window_graphics(console_root.window);
|
||
|
console_reset(&console_root);
|
||
|
console_putstring(&console_root,"\nconsole: initialized\n");
|
||
|
return &console_root;
|
||
|
}
|
||
|
|
||
|
void console_reset( struct console *d )
|
||
|
{
|
||
|
if(!d || !d->gx) return;
|
||
|
d->xpos = d->ypos = 0;
|
||
|
d->xsize = graphics_width(d->gx) / 8;
|
||
|
d->ysize = graphics_height(d->gx) / 8;
|
||
|
d->onoff = 0;
|
||
|
graphics_fgcolor(d->gx, fgcolor);
|
||
|
graphics_bgcolor(d->gx, bgcolor);
|
||
|
graphics_clear(d->gx, 0, 0, graphics_width(d->gx), graphics_height(d->gx));
|
||
|
}
|
||
|
|
||
|
void console_heartbeat( struct console *d )
|
||
|
{
|
||
|
char c = d->onoff ? ' ' : '_';
|
||
|
graphics_char(d->gx, d->xpos * 8, d->ypos * 8, c );
|
||
|
d->onoff = !d->onoff;
|
||
|
}
|
||
|
|
||
|
int console_post( struct console *c, const char *data, int size )
|
||
|
{
|
||
|
int total = 0;
|
||
|
|
||
|
struct event e;
|
||
|
e.type = EVENT_KEY_DOWN;
|
||
|
e.x = 0;
|
||
|
e.y = 0;
|
||
|
|
||
|
while(size>0) {
|
||
|
e.code = *data;
|
||
|
window_post_events(c->window,&e,sizeof(e));
|
||
|
size--;
|
||
|
data++;
|
||
|
total++;
|
||
|
}
|
||
|
|
||
|
return total;
|
||
|
}
|
||
|
|
||
|
int console_write( struct console *d, const char *data, int size )
|
||
|
{
|
||
|
graphics_char(d->gx, d->xpos * 8, d->ypos * 8, ' ');
|
||
|
|
||
|
int i;
|
||
|
for(i = 0; i < size; i++) {
|
||
|
char c = data[i];
|
||
|
switch (c) {
|
||
|
case 13:
|
||
|
case 10:
|
||
|
d->xpos = 0;
|
||
|
d->ypos++;
|
||
|
break;
|
||
|
case '\f':
|
||
|
d->xpos = d->ypos = 0;
|
||
|
d->xsize = graphics_width(d->gx) / 8;
|
||
|
d->ysize = graphics_height(d->gx) / 8;
|
||
|
graphics_fgcolor(d->gx, fgcolor);
|
||
|
graphics_bgcolor(d->gx, bgcolor);
|
||
|
graphics_clear(d->gx, 0, 0, graphics_width(d->gx), graphics_height(d->gx));
|
||
|
break;
|
||
|
case '\b':
|
||
|
d->xpos--;
|
||
|
break;
|
||
|
default:
|
||
|
graphics_char(d->gx, d->xpos * 8, d->ypos * 8, c);
|
||
|
d->xpos++;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(d->xpos < 0) {
|
||
|
d->xpos = d->xsize - 1;
|
||
|
d->ypos--;
|
||
|
}
|
||
|
|
||
|
if(d->xpos >= d->xsize) {
|
||
|
d->xpos = 0;
|
||
|
d->ypos++;
|
||
|
}
|
||
|
|
||
|
if(d->ypos >= d->ysize) {
|
||
|
d->xpos = d->ypos = 0;
|
||
|
d->xsize = graphics_width(d->gx) / 8;
|
||
|
d->ysize = graphics_height(d->gx) / 8;
|
||
|
graphics_fgcolor(d->gx, fgcolor);
|
||
|
graphics_bgcolor(d->gx, bgcolor);
|
||
|
graphics_clear(d->gx, 0, 0, graphics_width(d->gx), graphics_height(d->gx));
|
||
|
}
|
||
|
|
||
|
}
|
||
|
graphics_char(d->gx, d->xpos * 8, d->ypos * 8, '_');
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
int console_read( struct console *c, char *data, int length )
|
||
|
{
|
||
|
int total=0;
|
||
|
|
||
|
struct event e;
|
||
|
while(length>0 && window_read_events(c->window,&e,sizeof(e))) {
|
||
|
if(e.type==EVENT_KEY_DOWN) {
|
||
|
*data = e.code;
|
||
|
length--;
|
||
|
total++;
|
||
|
data++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return total;
|
||
|
}
|
||
|
|
||
|
int console_read_nonblock( struct console *c, char *data, int length )
|
||
|
{
|
||
|
int total=0;
|
||
|
|
||
|
struct event e;
|
||
|
while(length>0 && window_read_events_nonblock(c->window,&e,sizeof(e))) {
|
||
|
if(e.type==EVENT_KEY_DOWN) {
|
||
|
*data = e.code;
|
||
|
length--;
|
||
|
total++;
|
||
|
data++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return total;
|
||
|
}
|
||
|
|
||
|
int console_getchar( struct console *c )
|
||
|
{
|
||
|
char ch;
|
||
|
if(console_read(c,&ch,1)>0) {
|
||
|
return ch;
|
||
|
} else {
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void console_putchar( struct console *c, char ch )
|
||
|
{
|
||
|
console_write(c,&ch,1);
|
||
|
}
|
||
|
|
||
|
void console_putstring( struct console *c, const char *str)
|
||
|
{
|
||
|
console_write(c,str,strlen(str));
|
||
|
}
|
||
|
|
||
|
struct console *console_create( struct window *w )
|
||
|
{
|
||
|
struct console *c = kmalloc(sizeof(*c));
|
||
|
c->window = window_addref(w);
|
||
|
c->gx = window_graphics(w);
|
||
|
c->refcount = 1;
|
||
|
console_reset(c);
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
struct console *console_addref( struct console *c )
|
||
|
{
|
||
|
c->refcount++;
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
void console_delete( struct console *c )
|
||
|
{
|
||
|
if(c==&console_root) return;
|
||
|
|
||
|
c->refcount--;
|
||
|
if(c->refcount==0) {
|
||
|
window_delete(c->window);
|
||
|
kfree(c);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void console_size( struct console *c, int *xsize, int *ysize )
|
||
|
{
|
||
|
*xsize = c->xsize;
|
||
|
*ysize = c->ysize;
|
||
|
}
|
||
|
|