Diffstat (limited to 'noncore/apps/opie-console/emulation_layer.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/apps/opie-console/emulation_layer.cpp | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/noncore/apps/opie-console/emulation_layer.cpp b/noncore/apps/opie-console/emulation_layer.cpp index 2bef801..fd30ad7 100644 --- a/noncore/apps/opie-console/emulation_layer.cpp +++ b/noncore/apps/opie-console/emulation_layer.cpp | |||
@@ -13,204 +13,204 @@ | |||
13 | /* Ported Konsole to Qt/Embedded */ | 13 | /* Ported Konsole to Qt/Embedded */ |
14 | /* */ | 14 | /* */ |
15 | /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ | 15 | /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ |
16 | /* */ | 16 | /* */ |
17 | /* -------------------------------------------------------------------------- */ | 17 | /* -------------------------------------------------------------------------- */ |
18 | /* */ | 18 | /* */ |
19 | /* Modified to suit opie-console */ | 19 | /* Modified to suit opie-console */ |
20 | /* */ | 20 | /* */ |
21 | /* Copyright (C) 2002 by opie developers <opie@handhelds.org> */ | 21 | /* Copyright (C) 2002 by opie developers <opie@handhelds.org> */ |
22 | /* */ | 22 | /* */ |
23 | /* -------------------------------------------------------------------------- */ | 23 | /* -------------------------------------------------------------------------- */ |
24 | 24 | ||
25 | /*! \class EmulationLayer | 25 | /*! \class EmulationLayer |
26 | 26 | ||
27 | \brief Mediator between Widget and Screen. | 27 | \brief Mediator between Widget and Screen. |
28 | 28 | ||
29 | This class is responsible to scan the escapes sequences of the terminal | 29 | This class is responsible to scan the escapes sequences of the terminal |
30 | emulation and to map it to their corresponding semantic complements. | 30 | emulation and to map it to their corresponding semantic complements. |
31 | Thus this module knows mainly about decoding escapes sequences and | 31 | Thus this module knows mainly about decoding escapes sequences and |
32 | is a stateless device w.r.t. the semantics. | 32 | is a stateless device w.r.t. the semantics. |
33 | 33 | ||
34 | It is also responsible to refresh the Widget by certain rules. | 34 | It is also responsible to refresh the Widget by certain rules. |
35 | 35 | ||
36 | \sa Widget \sa Screen | 36 | \sa Widget \sa Screen |
37 | 37 | ||
38 | \par A note on refreshing | 38 | \par A note on refreshing |
39 | 39 | ||
40 | Although the modifications to the current screen image could immediately | 40 | Although the modifications to the current screen image could immediately |
41 | be propagated via `Widget' to the graphical surface, we have chosen | 41 | be propagated via `Widget' to the graphical surface, we have chosen |
42 | another way here. | 42 | another way here. |
43 | 43 | ||
44 | The reason for doing so is twofold. | 44 | The reason for doing so is twofold. |
45 | 45 | ||
46 | First, experiments show that directly displaying the operation results | 46 | First, experiments show that directly displaying the operation results |
47 | in slowing down the overall performance of emulations. Displaying | 47 | in slowing down the overall performance of emulations. Displaying |
48 | individual characters using X11 creates a lot of overhead. | 48 | individual characters using X11 creates a lot of overhead. |
49 | 49 | ||
50 | Second, by using the following refreshing method, the screen operations | 50 | Second, by using the following refreshing method, the screen operations |
51 | can be completely separated from the displaying. This greatly simplifies | 51 | can be completely separated from the displaying. This greatly simplifies |
52 | the programmer's task of coding and maintaining the screen operations, | 52 | the programmer's task of coding and maintaining the screen operations, |
53 | since one need not worry about differential modifications on the | 53 | since one need not worry about differential modifications on the |
54 | display affecting the operation of concern. | 54 | display affecting the operation of concern. |
55 | 55 | ||
56 | We use a refreshing algorithm here that has been adoped from rxvt/kvt. | 56 | We use a refreshing algorithm here that has been adoped from rxvt/kvt. |
57 | 57 | ||
58 | By this, refreshing is driven by a timer, which is (re)started whenever | 58 | By this, refreshing is driven by a timer, which is (re)started whenever |
59 | a new bunch of data to be interpreted by the emulation arives at `onRcvBlock'. | 59 | a new bunch of data to be interpreted by the emulation arives at `onRcvBlock'. |
60 | As soon as no more data arrive for `BULK_TIMEOUT' milliseconds, we trigger | 60 | As soon as no more data arrive for `BULK_TIMEOUT' milliseconds, we trigger |
61 | refresh. This rule suits both bulk display operation as done by curses as | 61 | refresh. This rule suits both bulk display operation as done by curses as |
62 | well as individual characters typed. | 62 | well as individual characters typed. |
63 | (BULK_TIMEOUT < 1000 / max characters received from keyboard per second). | 63 | (BULK_TIMEOUT < 1000 / max characters received from keyboard per second). |
64 | 64 | ||
65 | Additionally, we trigger refreshing by newlines comming in to make visual | 65 | Additionally, we trigger refreshing by newlines comming in to make visual |
66 | snapshots of lists as produced by `cat', `ls' and likely programs, thereby | 66 | snapshots of lists as produced by `cat', `ls' and likely programs, thereby |
67 | producing the illusion of a permanent and immediate display operation. | 67 | producing the illusion of a permanent and immediate display operation. |
68 | 68 | ||
69 | As a sort of catch-all needed for cases where none of the above | 69 | As a sort of catch-all needed for cases where none of the above |
70 | conditions catch, the screen refresh is also triggered by a count | 70 | conditions catch, the screen refresh is also triggered by a count |
71 | of incoming bulks (`bulk_incnt'). | 71 | of incoming bulks (`bulk_incnt'). |
72 | */ | 72 | */ |
73 | 73 | ||
74 | /* FIXME | 74 | /* FIXME |
75 | - evtl. the bulk operations could be made more transparent. | 75 | - evtl. the bulk operations could be made more transparent. |
76 | */ | 76 | */ |
77 | 77 | ||
78 | #include "emulation_layer.h" | 78 | #include "emulation_layer.h" |
79 | #include <stdio.h> | 79 | #include <stdio.h> |
80 | #include <stdlib.h> | 80 | #include <stdlib.h> |
81 | #include <unistd.h> | 81 | #include <unistd.h> |
82 | 82 | ||
83 | 83 | ||
84 | /* ------------------------------------------------------------------------- */ | 84 | /* ------------------------------------------------------------------------- */ |
85 | /* */ | 85 | /* */ |
86 | /* EmulationLayer */ | 86 | /* EmulationLayer */ |
87 | /* */ | 87 | /* */ |
88 | /* ------------------------------------------------------------------------- */ | 88 | /* ------------------------------------------------------------------------- */ |
89 | 89 | ||
90 | #define CNTL(c) ((c)-'@') | 90 | #define CNTL(c) ((c)-'@') |
91 | 91 | ||
92 | /*! | 92 | /*! |
93 | */ | 93 | */ |
94 | 94 | ||
95 | EmulationLayer::EmulationLayer( WidgetLayer* gui ) | 95 | EmulationLayer::EmulationLayer( WidgetLayer* gui ) |
96 | : decoder((QTextDecoder*)NULL) | 96 | : decoder((QTextDecoder*)NULL) |
97 | { | 97 | { |
98 | this->gui = gui; | 98 | this->gui = gui; |
99 | 99 | ||
100 | screen[0] = new Screen(gui->lines(),gui->columns()); | 100 | screen[0] = new Screen(gui->lines(),gui->columns()); |
101 | screen[1] = new Screen(gui->lines(),gui->columns()); | 101 | screen[1] = new Screen(gui->lines(),gui->columns()); |
102 | scr = screen[0]; | 102 | scr = screen[0]; |
103 | 103 | ||
104 | bulk_nlcnt = 0; // reset bulk newline counter | 104 | bulk_nlcnt = 0; // reset bulk newline counter |
105 | bulk_incnt = 0; // reset bulk counter | 105 | bulk_incnt = 0; // reset bulk counter |
106 | connected = FALSE; | 106 | connected = FALSE; |
107 | 107 | ||
108 | QObject::connect(&bulk_timer, SIGNAL( timeout() ), this, SLOT( showBulk() ) ); | 108 | QObject::connect(&bulk_timer, SIGNAL( timeout() ), this, SLOT( showBulk() ) ); |
109 | QObject::connect(gui,SIGNAL( imageSizeChanged( int, int ) ), | 109 | QObject::connect(gui,SIGNAL( imageSizeChanged(int,int) ), |
110 | this,SLOT( onImageSizeChange( int, int ) ) ); | 110 | this,SLOT( onImageSizeChange(int,int) ) ); |
111 | QObject::connect(gui,SIGNAL( changedHistoryCursor( int ) ), | 111 | QObject::connect(gui,SIGNAL( changedHistoryCursor(int) ), |
112 | this,SLOT( historyCursorChange( int ) ) ); | 112 | this,SLOT( historyCursorChange(int) ) ); |
113 | QObject::connect(gui,SIGNAL( keyPressed( QKeyEvent* ) ), | 113 | QObject::connect(gui,SIGNAL( keyPressed(QKeyEvent*) ), |
114 | this,SLOT( onKeyPress( QKeyEvent* ) ) ); | 114 | this,SLOT( onKeyPress(QKeyEvent*) ) ); |
115 | QObject::connect(gui,SIGNAL( selectionBegin( const int, const int) ), | 115 | QObject::connect(gui,SIGNAL( selectionBegin(const int,const int) ), |
116 | this,SLOT( onSelectionBegin( const int, const int ) ) ); | 116 | this,SLOT( onSelectionBegin(const int,const int) ) ); |
117 | QObject::connect(gui,SIGNAL( selectionExtended( const int, const int ) ), | 117 | QObject::connect(gui,SIGNAL( selectionExtended(const int,const int) ), |
118 | this,SLOT( onSelectionExtend( const int,const int ) ) ); | 118 | this,SLOT( onSelectionExtend(const int,const int) ) ); |
119 | QObject::connect(gui,SIGNAL( selectionEnd( const bool ) ), | 119 | QObject::connect(gui,SIGNAL( selectionEnd(const bool) ), |
120 | this,SLOT( setSelection( const bool ) ) ); | 120 | this,SLOT( setSelection(const bool) ) ); |
121 | QObject::connect(gui,SIGNAL( selectionCleared() ), | 121 | QObject::connect(gui,SIGNAL( selectionCleared() ), |
122 | this,SLOT( clearSelection() ) ); | 122 | this,SLOT( clearSelection() ) ); |
123 | } | 123 | } |
124 | 124 | ||
125 | /*! | 125 | /*! |
126 | */ | 126 | */ |
127 | 127 | ||
128 | EmulationLayer::~EmulationLayer() | 128 | EmulationLayer::~EmulationLayer() |
129 | { | 129 | { |
130 | delete screen[0]; | 130 | delete screen[0]; |
131 | delete screen[1]; | 131 | delete screen[1]; |
132 | bulk_timer.stop(); | 132 | bulk_timer.stop(); |
133 | } | 133 | } |
134 | 134 | ||
135 | /*! change between primary and alternate screen | 135 | /*! change between primary and alternate screen |
136 | */ | 136 | */ |
137 | 137 | ||
138 | void EmulationLayer::setScreen(int n) | 138 | void EmulationLayer::setScreen(int n) |
139 | { | 139 | { |
140 | scr = screen[n&1]; | 140 | scr = screen[n&1]; |
141 | } | 141 | } |
142 | 142 | ||
143 | void EmulationLayer::setHistory(bool on) | 143 | void EmulationLayer::setHistory(bool on) |
144 | { | 144 | { |
145 | screen[0]->setScroll(on); | 145 | screen[0]->setScroll(on); |
146 | if (!connected) return; | 146 | if (!connected) return; |
147 | showBulk(); | 147 | showBulk(); |
148 | } | 148 | } |
149 | 149 | ||
150 | bool EmulationLayer::history() | 150 | bool EmulationLayer::history() |
151 | { | 151 | { |
152 | return screen[0]->hasScroll(); | 152 | return screen[0]->hasScroll(); |
153 | } | 153 | } |
154 | 154 | ||
155 | void EmulationLayer::setCodec(int c) | 155 | void EmulationLayer::setCodec(int c) |
156 | { | 156 | { |
157 | //FIXME: check whether we have to free codec | 157 | //FIXME: check whether we have to free codec |
158 | codec = c ? QTextCodec::codecForName("utf8") | 158 | codec = c ? QTextCodec::codecForName("utf8") |
159 | : QTextCodec::codecForLocale(); | 159 | : QTextCodec::codecForLocale(); |
160 | if (decoder) delete decoder; | 160 | if (decoder) delete decoder; |
161 | decoder = codec->makeDecoder(); | 161 | decoder = codec->makeDecoder(); |
162 | } | 162 | } |
163 | 163 | ||
164 | void EmulationLayer::setKeytrans(int no) | 164 | void EmulationLayer::setKeytrans(int no) |
165 | { | 165 | { |
166 | keytrans = KeyTrans::find(no); | 166 | keytrans = KeyTrans::find(no); |
167 | } | 167 | } |
168 | 168 | ||
169 | void EmulationLayer::setKeytrans(const char * no) | 169 | void EmulationLayer::setKeytrans(const char * no) |
170 | { | 170 | { |
171 | keytrans = KeyTrans::find(no); | 171 | keytrans = KeyTrans::find(no); |
172 | } | 172 | } |
173 | 173 | ||
174 | // Interpreting Codes --------------------------------------------------------- | 174 | // Interpreting Codes --------------------------------------------------------- |
175 | 175 | ||
176 | /* | 176 | /* |
177 | This section deals with decoding the incoming character stream. | 177 | This section deals with decoding the incoming character stream. |
178 | Decoding means here, that the stream is first seperated into `tokens' | 178 | Decoding means here, that the stream is first seperated into `tokens' |
179 | which are then mapped to a `meaning' provided as operations by the | 179 | which are then mapped to a `meaning' provided as operations by the |
180 | `Screen' class. | 180 | `Screen' class. |
181 | */ | 181 | */ |
182 | 182 | ||
183 | /*! | 183 | /*! |
184 | */ | 184 | */ |
185 | 185 | ||
186 | void EmulationLayer::onRcvChar(int c) | 186 | void EmulationLayer::onRcvChar(int c) |
187 | // process application unicode input to terminal | 187 | // process application unicode input to terminal |
188 | // this is a trivial scanner | 188 | // this is a trivial scanner |
189 | { | 189 | { |
190 | c &= 0xff; | 190 | c &= 0xff; |
191 | switch (c) | 191 | switch (c) |
192 | { | 192 | { |
193 | case '\b' : scr->BackSpace(); break; | 193 | case '\b' : scr->BackSpace(); break; |
194 | case '\t' : scr->Tabulate(); break; | 194 | case '\t' : scr->Tabulate(); break; |
195 | case '\n' : scr->NewLine(); break; | 195 | case '\n' : scr->NewLine(); break; |
196 | case '\r' : scr->Return(); break; | 196 | case '\r' : scr->Return(); break; |
197 | case 0x07 : gui->bell(); break; | 197 | case 0x07 : gui->bell(); break; |
198 | default : scr->ShowCharacter(c); break; | 198 | default : scr->ShowCharacter(c); break; |
199 | }; | 199 | }; |
200 | } | 200 | } |
201 | 201 | ||
202 | /* ------------------------------------------------------------------------- */ | 202 | /* ------------------------------------------------------------------------- */ |
203 | /* */ | 203 | /* */ |
204 | /* Keyboard Handling */ | 204 | /* Keyboard Handling */ |
205 | /* */ | 205 | /* */ |
206 | /* ------------------------------------------------------------------------- */ | 206 | /* ------------------------------------------------------------------------- */ |
207 | 207 | ||
208 | /*! | 208 | /*! |
209 | */ | 209 | */ |
210 | 210 | ||
211 | void EmulationLayer::onKeyPress( QKeyEvent* ev ) | 211 | void EmulationLayer::onKeyPress( QKeyEvent* ev ) |
212 | { | 212 | { |
213 | if (!connected) return; // someone else gets the keys | 213 | if (!connected) return; // someone else gets the keys |
214 | if (scr->getHistCursor() != scr->getHistLines()); | 214 | if (scr->getHistCursor() != scr->getHistLines()); |
215 | scr->setHistCursor(scr->getHistLines()); | 215 | scr->setHistCursor(scr->getHistLines()); |
216 | if (!ev->text().isEmpty()) | 216 | if (!ev->text().isEmpty()) |