1 /*
2  * Copyright (C) 2014 Satoshi Noguchi
3  * Copyright (C) 2014 Synaptics Inc
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <stdio.h>
19 #include <sys/ioctl.h>
20 #include <termios.h>
21 #include <unistd.h>
22 #include <string.h>
23 
24 #include "display.h"
25 
26 #define ESC 0x1B
27 
28 // default display
Output(const char * buf)29 void Display::Output(const char * buf)
30 {
31 	printf("%s", buf);
32 }
33 
34 // ansi console
AnsiConsole()35 AnsiConsole::AnsiConsole() : Display()
36 {
37 	m_buf = NULL;
38 	GetWindowSize();
39 	m_curX = 0;
40 	m_curY = 0;
41 	m_maxCurX = 0;
42 	m_maxCurY = 0;
43 }
44 
~AnsiConsole()45 AnsiConsole::~AnsiConsole()
46 {
47 	delete [] m_buf;
48 }
49 
GetWindowSize()50 void AnsiConsole::GetWindowSize()
51 {
52 	struct winsize winsz;
53 	ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsz);
54 	if (m_numRows != winsz.ws_row || m_numCols != winsz.ws_col)
55 	{
56 		m_numRows = winsz.ws_row;
57 		m_numCols = winsz.ws_col;
58 		if (m_buf != NULL)
59 		{
60 			delete [] m_buf;
61 		}
62 		m_buf = new char[m_numRows * m_numCols];
63 
64 		Clear();
65 	}
66 }
67 
Output(const char * buf)68 void AnsiConsole::Output(const char * buf)
69 {
70 	char * p;
71 
72 	while (m_curY < m_numRows &&
73 		m_numCols * m_curY + m_curX < m_numRows * m_numCols)
74 	{
75 		p = &(m_buf[m_numCols * m_curY + m_curX]);
76 
77 		if (*buf == '\0')
78 		{
79 			break;
80 		}
81 		else if (*buf == '\n')
82 		{
83 			memset(p, ' ', m_numCols - m_curX);
84 			m_curX = 0;
85 			m_curY++;
86 		}
87 		else if (m_curX < m_numCols)
88 		{
89 			*p = *buf;
90 			m_curX++;
91 		}
92 		buf++;
93 
94 		if (m_maxCurX < m_curX) m_maxCurX = m_curX;
95 		if (m_maxCurY < m_curY) m_maxCurY = m_curY;
96 	}
97 }
98 
Clear()99 void AnsiConsole::Clear()
100 {
101 	printf("%c[2J", ESC);
102 }
103 
Reflesh()104 void AnsiConsole::Reflesh()
105 {
106 	int i;
107 	int j;
108 	char * p;
109 
110 	printf("%c[%d;%dH", ESC, 0, 0);
111 
112 	for (j = 0; j < m_maxCurY; j++)
113 	{
114 		p = &(m_buf[m_numCols * j]);
115 
116 		for (i = 0; i < m_maxCurX; i++)
117 		{
118 			putc(*p, stdout);
119 			p++;
120 		}
121 
122 		putc('\n', stdout);
123 	}
124 
125 	GetWindowSize();
126 	m_curX = 0;
127 	m_curY = 0;
128 	m_maxCurX = 0;
129 	m_maxCurY = 0;
130 }
131