aboutsummaryrefslogtreecommitdiff
path: root/lib/driver/rcconsole.cpp
blob: 7a625ffcfdc7312ca5bf22d9faacc03d07404517 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <lib/base/init.h>
#include <lib/base/init_num.h>
#include <lib/base/eerror.h>
#include <lib/driver/rcconsole.h>
#include <stdio.h>
#include <fcntl.h>

eRCConsoleDriver::eRCConsoleDriver(const char *filename): eRCDriver(eRCInput::getInstance())
{
	handle=open(filename, O_RDONLY|O_NONBLOCK);
	if (handle<0)
	{
		eDebug("failed to open %s", filename);
		sn=0;
	} else
	{
		sn=new eSocketNotifier(eApp, handle, eSocketNotifier::Read);
		CONNECT(sn->activated, eRCConsoleDriver::keyPressed);
		eRCInput::getInstance()->setFile(handle);
	}
	
		/* set console mode */
	struct termios t;
	tcgetattr(handle, &t);
	ot = t;
	t.c_lflag &= ~(ECHO | ICANON | ECHOK | ECHOE | ECHONL);
	tcsetattr(handle, TCSANOW,&t);
}

eRCConsoleDriver::~eRCConsoleDriver()
{
	tcsetattr(handle,TCSANOW, &ot);
 	if (handle>=0)
		close(handle);
	if (sn)
		delete sn;
}

void eRCConsoleDriver::keyPressed(int)
{
	unsigned char data[16];
	unsigned char *d = data;
	int num = read(handle, data, 16);
	int code=-1;
	
	int km = input->getKeyboardMode();

	if (km == eRCInput::kmNone)
		return;

	while (num--)
	{
//		eDebug("console code %08x\n", *d);
		if (km == eRCInput::kmAll)
			code = *d++;
		else
		{
			if (*d == 27) // escape code
			{
				while (num)
				{
					num--;
					if (*++d != '[')
						break;
				}
				code = -1;
			} else
				code = *d;
			++d;

			if (code < 32)			/* control characters */
				code = -1;
			else switch(code)
			{
			case 0x35:  // mute
			case 0x7E:  // mute, einfg, entf
			case 0x7F:  // backspace
			code = -1;
			default:
				break;
			}
		}

		if (code != -1)
			for (std::list<eRCDevice*>::iterator i(listeners.begin()); i!=listeners.end(); ++i)
			{
//				eDebug("ascii %08x", code);
				(*i)->handleCode(code);
			}
	}
}

void eRCConsole::handleCode(int code)
{
	input->keyPressed(eRCKey(this, code, eRCKey::flagAscii));
}

eRCConsole::eRCConsole(eRCDriver *driver)
			: eRCDevice("Console", driver)
{
}

const char *eRCConsole::getDescription() const
{
	return "Console";
}

const char *eRCConsole::getKeyDescription(const eRCKey &key) const
{
	return 0;
}

int eRCConsole::getKeyCompatibleCode(const eRCKey &key) const
{
	return key.code;
}

class eRCConsoleInit
{
	eRCConsoleDriver driver;
	eRCConsole device;
public:
	eRCConsoleInit(): driver("/dev/vc/0"), device(&driver)
	{
	}
};

eAutoInitP0<eRCConsoleInit> init_rcconsole(eAutoInitNumbers::rc+1, "Console RC Driver");