/*------------------------------------------------------------------------------ -- This file is a part of the libuc, microcontroler library -- Copyright (C) 2013, Alexis Jeandet -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------------- -- Author : Alexis Jeandet -- Mail : alexis.jeandet@gmail.com -------------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #define CHARXPOS(terminal,charwidth) (((terminal)->column * charwidth) + (terminal)->Xpos) #define CHARYPOS(terminal,charheight) ((terminal)->line * charheight + (terminal)->Ypos+charheight) streamdevice_ops TERMINAL_OPS= { .write = &terminal_write, .read = &terminal_read, .setpos= &terminal_setpos, .close = NULL }; int terminal_init(terminal_t* terminal,LCD_t* LCD,sFONT* font,streamdevice* strdev) { if((LCD!=NULL) && (font!=NULL) && (strdev!=NULL) && (terminal!=NULL)) { terminal->LCD=LCD; terminal->font=font; terminal->line = 0; terminal->column = 0; terminal->horizontalSpace = 0; terminal->verticalSpace = 0; int charw=terminal->font->Width + terminal->horizontalSpace; int charh=terminal->font->Height + terminal->verticalSpace; terminal->textColor=0xFFFF; terminal->backgroundColor=0x0000; terminal_setgeometry(terminal,5,5,terminal->LCD->width-(10),terminal->LCD->height-(10)); strdev->_stream = (UHANDLE)terminal; strdev->ops = &TERMINAL_OPS; strdev->streamPt = 0; terminal_clear(terminal); terminal->LCD->paintFilRect(terminal->LCD,CHARXPOS(terminal, charw),CHARYPOS(terminal, charh)-charh,charw,charh,terminal->backgroundColor,0,terminal->backgroundColor); terminal->buffer = (char*)malloc(terminal->lineCount*(terminal->columnCount + 1)); terminal->firstLine = 0; terminal->lastLine = 0; terminal->empty = 1; for(int i=1;i<=terminal->lineCount;i++) { terminal->buffer[i * terminal->columnCount]='\n'; } return 1; } return 0; } void terminal_setgeometry(terminal_t* terminal,uint16_t Xpos,uint16_t Ypos,uint16_t width,uint16_t height) { int charw=terminal->font->Width + terminal->horizontalSpace; int charh=terminal->font->Height + terminal->verticalSpace; if(terminal->LCD->height<(Ypos+height)) return; if(terminal->LCD->width<(Xpos+width)) return; terminal->Xpos = Xpos; terminal->Ypos = Ypos; terminal->height = height; terminal->width = width; terminal->lineCount = terminal->height/charh; terminal->columnCount = (terminal->width/charw)-1; terminal_clear(terminal); } void terminal_clear(terminal_t* terminal) { terminal->firstLine = 0; terminal->lastLine = 0; terminal->empty = 1; terminal->line =0; terminal->column=0; terminal->LCD->paintFilRect(terminal->LCD,terminal->Xpos,terminal->Ypos,terminal->width,terminal->height,terminal->backgroundColor,0,terminal->backgroundColor); } void terminal_setbackgroundColor(terminal_t* terminal, uint32_t backgrooundColor) { terminal->backgroundColor = backgrooundColor; } void terminal_settextColor(terminal_t* terminal, uint32_t textColor) { terminal->textColor = textColor; } void terminal_movecursor(terminal_t* terminal,int n) { int charw=terminal->font->Width + terminal->horizontalSpace; int charh=terminal->font->Height + terminal->verticalSpace; terminal->column += n; if(terminal->column>(terminal->columnCount)) { terminal->line += (terminal->column)/terminal->columnCount; terminal->line = terminal->line % terminal->lineCount; terminal->column = (terminal->column % terminal->columnCount)-1; int x=CHARXPOS(terminal, charw); int y=CHARYPOS(terminal,charh)-charh; int w=charw*(terminal->columnCount-terminal->column); int h=charh; terminal->LCD->paintFilRect(terminal->LCD,CHARXPOS(terminal, charw),CHARYPOS(terminal,charh)-charh,charw*(terminal->columnCount-terminal->column-1),charh,terminal->backgroundColor,0,terminal->backgroundColor); } terminal->LCD->paintFilRect(terminal->LCD,CHARXPOS(terminal,charw),CHARYPOS(terminal,charh)-charh,charw,charh,terminal->backgroundColor,0,terminal->backgroundColor); } void terminal_clearCurentLine(terminal_t* terminal) { int charw=terminal->font->Width + terminal->horizontalSpace; int charh=terminal->font->Height + terminal->verticalSpace; terminal->LCD->paintFilRect(terminal->LCD,terminal->Xpos,CHARYPOS(terminal, charh)-charh,terminal->width,charh,terminal->backgroundColor,0,terminal->backgroundColor); } int terminal_writenc(terminal_t* terminal,char* data, int n) { int charw=terminal->font->Width + terminal->horizontalSpace; int charh=terminal->font->Height + terminal->verticalSpace; int l=0; char buffer[2]=" "; while(lline= (terminal->line+1) % terminal->lineCount; terminal->column = 0; if(terminal->line==0) terminal_clear(terminal); else terminal_clearCurentLine(terminal); }else { if(buffer[0]=='\t') { for(int i=0;i<1;i++)terminal_movecursor(terminal,1); }else if(terminal->column==0)terminal_clearCurentLine(terminal); if(buffer[0]!='\r'){ terminal->LCD->paintFilRect(terminal->LCD,CHARXPOS(terminal,charw),CHARYPOS(terminal, charh)-charh,charw,charh,terminal->backgroundColor,0,terminal->backgroundColor); terminal->LCD->paintText(terminal->LCD,buffer,CHARXPOS(terminal,charw),CHARYPOS(terminal, charh),terminal->font,terminal->textColor); terminal_movecursor(terminal,1); } } l++; } return n; } void terminal_print_line(terminal_t* terminal,int line) { int charw=terminal->font->Width + terminal->horizontalSpace; int charh=terminal->font->Height + terminal->verticalSpace; terminal_clearCurentLine(terminal); terminal->LCD->paintText(terminal->LCD,terminal->buffer+(line*(terminal->columnCount + 1)),CHARXPOS(terminal,charw),CHARYPOS(terminal, charh),terminal->font,terminal->textColor); } int terminal_writenc2(terminal_t* terminal,char* data, int n) { int charw=terminal->font->Width + terminal->horizontalSpace; int charh=terminal->font->Height + terminal->verticalSpace; /* First copy to buffer*/ int offset = (terminal->lastLine*(terminal->columnCount + 1)) + terminal->column; for(int i=0;iempty=0; terminal->buffer[offset] = data[i]; if(data[i]=='\n') { offset = ((offset/(terminal->columnCount + 1) + 1) * (terminal->columnCount + 1)); } else { offset++; } } if(!terminal->empty) { for(int i=terminal->firstLine;i<=terminal->lastLine;i++) { terminal_print_line(terminal,i); } } return n; } int terminal_write(streamdevice* device,void* data,int size, int n) { return terminal_writenc((terminal_t*)device->_stream,(char*) data,size*n); } int terminal_read(streamdevice* device,void* data,int size, int n) { return n*size; } int terminal_setpos(streamdevice* device,int pos) { return 1; } int terminal_close( streamdevice* device) { return 1; }