1 | // Copyright (C) 2013-2014 ChaosForge Ltd
|
---|
2 | // http://chaosforge.org/
|
---|
3 | //
|
---|
4 | // This file is part of NV Libraries.
|
---|
5 | // For conditions of distribution and use, see copyright notice in nv.hh
|
---|
6 |
|
---|
7 | #include "nv/curses/curses_terminal.hh"
|
---|
8 |
|
---|
9 | #include "nv/core/time.hh"
|
---|
10 | #include "nv/lib/curses.hh"
|
---|
11 |
|
---|
12 | using namespace nv;
|
---|
13 |
|
---|
14 | curses_terminal::curses_terminal( dimension size ) : terminal( size )
|
---|
15 | {
|
---|
16 | load_curses_library();
|
---|
17 | m_screen = initscr();
|
---|
18 | raw();
|
---|
19 | cbreak();
|
---|
20 | noecho();
|
---|
21 |
|
---|
22 | nodelay ( (WINDOW*)m_screen, true );
|
---|
23 | intrflush( (WINDOW*)m_screen, false );
|
---|
24 | keypad ( (WINDOW*)m_screen, true );
|
---|
25 |
|
---|
26 | start_color();
|
---|
27 | resize_term( size.y, size.x );
|
---|
28 | PDC_save_key_modifiers( true );
|
---|
29 |
|
---|
30 | init_pair( 1, 0, 0 );
|
---|
31 | init_pair( 2, 1, 0 );
|
---|
32 | init_pair( 3, 2, 0 );
|
---|
33 | init_pair( 4, 3, 0 );
|
---|
34 | init_pair( 5, 4, 0 );
|
---|
35 | init_pair( 6, 5, 0 );
|
---|
36 | init_pair( 7, 6, 0 );
|
---|
37 | init_pair( 8, 7, 0 );
|
---|
38 |
|
---|
39 | clear();
|
---|
40 | refresh();
|
---|
41 | curs_set(1);
|
---|
42 |
|
---|
43 | m_update_needed = false;
|
---|
44 | }
|
---|
45 |
|
---|
46 | void curses_terminal::update()
|
---|
47 | {
|
---|
48 | if (m_update_needed)
|
---|
49 | {
|
---|
50 | refresh();
|
---|
51 | m_update_needed = false;
|
---|
52 | }
|
---|
53 | }
|
---|
54 |
|
---|
55 | void curses_terminal::print( position p, uint32 color, unsigned char ch )
|
---|
56 | {
|
---|
57 | m_update_needed = true;
|
---|
58 | if ( color > 7 )
|
---|
59 | {
|
---|
60 | attrset(((static_cast<uint32>(color-7) << 24) & 0xff000000ul ) | 0x00800000ul);
|
---|
61 | }
|
---|
62 | else
|
---|
63 | {
|
---|
64 | attrset((static_cast<uint32>(color+1) << 24) & 0xff000000ul);
|
---|
65 | }
|
---|
66 | mvaddch( p.y-1, p.x-1, ch );
|
---|
67 | ::move( m_cursor.y-1, m_cursor.x-1 );
|
---|
68 | }
|
---|
69 |
|
---|
70 | void curses_terminal::clear( rectangle r )
|
---|
71 | {
|
---|
72 | attrset( 0x00000000ul | 0x00800000ul );
|
---|
73 | for ( int x = r.ul.x-1; x <= r.lr.x-1; ++x )
|
---|
74 | for ( int y = r.ul.y-1; y <= r.lr.y-1; ++y )
|
---|
75 | mvaddch( y, x, ' ' );
|
---|
76 | }
|
---|
77 |
|
---|
78 | void curses_terminal::clear()
|
---|
79 | {
|
---|
80 | m_update_needed = true;
|
---|
81 | ::clear();
|
---|
82 | ::move( m_cursor.y-1, m_cursor.x-1 );
|
---|
83 | }
|
---|
84 |
|
---|
85 | bool curses_terminal::poll( io_event& kevent )
|
---|
86 | {
|
---|
87 | // Sleep so we don't get 100% processor usage
|
---|
88 | sleep(10);
|
---|
89 |
|
---|
90 | // Get value from curses
|
---|
91 | int result = wgetch((WINDOW*)m_screen);
|
---|
92 |
|
---|
93 | // If value is err, return none event
|
---|
94 | if ( result == -1 )
|
---|
95 | {
|
---|
96 | return false;
|
---|
97 | }
|
---|
98 |
|
---|
99 | // Zero the fields
|
---|
100 | kevent.type = EV_KEY;
|
---|
101 | kevent.key.pressed = true;
|
---|
102 | kevent.key.ascii = 0;
|
---|
103 | kevent.key.code = nv::KEY_NONE;
|
---|
104 | kevent.key.control = false;
|
---|
105 | kevent.key.shift = false;
|
---|
106 |
|
---|
107 | // if result is a typable char place it into the structure
|
---|
108 | if ( result >= 32 && result < 128 )
|
---|
109 | {
|
---|
110 | kevent.key.ascii = static_cast<nv::uchar8>(result);
|
---|
111 | }
|
---|
112 |
|
---|
113 | // Check the control and shift states
|
---|
114 | // TODO: obviously there is an ERROR here :P
|
---|
115 | kevent.key.control = (PDC_get_key_modifiers() & 2) != 0;
|
---|
116 | kevent.key.shift = (PDC_get_key_modifiers() & 2) != 0;
|
---|
117 |
|
---|
118 | // if result is a typable char from the directly transformable ranges
|
---|
119 | if ( (result >= nv::KEY_A && result <= nv::KEY_Z) ||
|
---|
120 | (result >= nv::KEY_0 && result <= nv::KEY_9) ||
|
---|
121 | result == ' ' )
|
---|
122 | {
|
---|
123 | kevent.key.code = static_cast<nv::key_code>(result);
|
---|
124 | }
|
---|
125 |
|
---|
126 | // if result is a typable char from the a..z range
|
---|
127 | if ( result >= nv::KEY_A + 32 && result <= nv::KEY_Z + 32 )
|
---|
128 | {
|
---|
129 | kevent.key.code = static_cast<nv::key_code>(result - 32);
|
---|
130 | }
|
---|
131 |
|
---|
132 | // if result is a typable char from the 0..9 range
|
---|
133 | if ( result >= nv::KEY_0 && result <= nv::KEY_9 )
|
---|
134 | {
|
---|
135 | kevent.key.code = static_cast<nv::key_code>(result);
|
---|
136 | }
|
---|
137 |
|
---|
138 | // other recognized codes
|
---|
139 | switch ( result )
|
---|
140 | {
|
---|
141 | case 8 : kevent.key.code = nv::KEY_BACK; break;
|
---|
142 | case 9 : kevent.key.code = nv::KEY_TAB; break;
|
---|
143 | case 13 : kevent.key.code = nv::KEY_ENTER; break;
|
---|
144 | case 27 : kevent.key.code = nv::KEY_ESCAPE; break;
|
---|
145 | case 0x103 : kevent.key.code = nv::KEY_UP; break;
|
---|
146 | case 0x102 : kevent.key.code = nv::KEY_DOWN; break;
|
---|
147 | case 0x104 : kevent.key.code = nv::KEY_LEFT; break;
|
---|
148 | case 0x105 : kevent.key.code = nv::KEY_RIGHT; break;
|
---|
149 | case 0x153 : kevent.key.code = nv::KEY_PGUP; break;
|
---|
150 | case 0x152 : kevent.key.code = nv::KEY_PGDOWN; break;
|
---|
151 | case 0x106 : kevent.key.code = nv::KEY_HOME; break;
|
---|
152 | case 0x166 : kevent.key.code = nv::KEY_END; break;
|
---|
153 | }
|
---|
154 |
|
---|
155 | // If key was understood by nv, then it's valid, otherwise ignored
|
---|
156 | return kevent.key.ascii != 0 || kevent.key.code != 0;
|
---|
157 | }
|
---|
158 |
|
---|
159 | void curses_terminal::set_cursor( position p )
|
---|
160 | {
|
---|
161 | terminal::set_cursor( p );
|
---|
162 | ::move( m_cursor.y-1, m_cursor.x-1 );
|
---|
163 | }
|
---|
164 |
|
---|
165 | void curses_terminal::show_cursor()
|
---|
166 | {
|
---|
167 | curs_set(1);
|
---|
168 | }
|
---|
169 |
|
---|
170 | void curses_terminal::hide_cursor()
|
---|
171 | {
|
---|
172 | curs_set(0);
|
---|
173 | }
|
---|
174 |
|
---|
175 | curses_terminal::~curses_terminal()
|
---|
176 | {
|
---|
177 | endwin();
|
---|
178 | }
|
---|