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
29void Display::Output(const char * buf)
30{
31	printf("%s", buf);
32}
33
34// ansi console
35AnsiConsole::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
45AnsiConsole::~AnsiConsole()
46{
47	delete [] m_buf;
48}
49
50void 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
68void 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
99void AnsiConsole::Clear()
100{
101	printf("%c[2J", ESC);
102}
103
104void 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