source: trunk/src/curses/curses_terminal.cc @ 513

Last change on this file since 513 was 487, checked in by epyon, 9 years ago
File size: 4.4 KB
Line 
1// Copyright (C) 2013-2015 ChaosForge Ltd
2// http://chaosforge.org/
3//
4// This file is part of Nova libraries.
5// For conditions of distribution and use, see copying.txt file in root folder.
6
7#include "nv/curses/curses_terminal.hh"
8
9#include "nv/core/time.hh"
10#include "nv/lib/curses.hh"
11
12using namespace nv;
13
14curses_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  ( static_cast<WINDOW*>( m_screen ), true );
23        intrflush( static_cast<WINDOW*>( m_screen ), false );
24        keypad   ( static_cast<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
46void curses_terminal::update()
47{
48        if (m_update_needed)
49        {
50                refresh();
51                m_update_needed = false;
52        }
53}
54
55void curses_terminal::print( position p, uint32 color, 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, chtype(ch) );
67        ::move( m_cursor.y-1, m_cursor.x-1 );
68}
69
70void 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
78void curses_terminal::clear()
79{
80        m_update_needed = true;
81        ::clear();
82        ::move( m_cursor.y-1, m_cursor.x-1 );
83}
84
85bool 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( static_cast<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
159void curses_terminal::set_cursor( position p )
160{
161        terminal::set_cursor( p );
162        ::move( m_cursor.y-1, m_cursor.x-1 );
163}
164
165void curses_terminal::show_cursor()
166{
167        curs_set(1);
168}
169
170void curses_terminal::hide_cursor()
171{
172        curs_set(0);
173}
174
175curses_terminal::~curses_terminal()
176{
177        endwin();
178}
Note: See TracBrowser for help on using the repository browser.