Mercurial > 510Connectbot
comparison src/com/five_ten_sg/connectbot/transport/TN5250.java @ 49:8887bff45dee tn5250
start tn5250 integration
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Wed, 11 Jun 2014 11:28:31 -0700 |
parents | a3fd10a8c0de |
children | 2cd3d8091e37 |
comparison
equal
deleted
inserted
replaced
48:1e931ef5f776 | 49:8887bff45dee |
---|---|
69 public void debug(String s) { | 69 public void debug(String s) { |
70 Log.d(TAG, s); | 70 Log.d(TAG, s); |
71 } | 71 } |
72 @Override | 72 @Override |
73 public void write(byte[] b) { | 73 public void write(byte[] b) { |
74 screen52.sendKeys(new String(b)); | |
74 } | 75 } |
75 @Override | 76 @Override |
76 public void write(int b) { | 77 public void write(int b) { |
78 screen52.sendKeys(new String(new byte[] {b})); | |
77 } | 79 } |
78 // bridge.monitor placement of new characters | 80 // bridge.monitor placement of new characters |
79 @Override | 81 @Override |
80 public void putChar(int c, int l, char ch, int attributes) { | 82 public void putChar(int c, int l, char ch, int attributes) { |
81 if (bridge.monitor != null) bridge.monitor.screenChanged(l, c); | 83 if (bridge.monitor != null) bridge.monitor.screenChanged(l, c); |
94 TerminalBridge bridge, | 96 TerminalBridge bridge, |
95 vt320 buffer, | 97 vt320 buffer, |
96 String encoding) { | 98 String encoding) { |
97 super(manager, bridge, buffer, encoding); | 99 super(manager, bridge, buffer, encoding); |
98 } | 100 } |
101 | |
102 /** | |
103 * Handle onKey() events coming down from a {@link com.five_ten_sg.connectbot.TerminalView} above us. | |
104 * Modify the keys to make more sense to a host then pass it to the 5250. | |
105 */ | |
106 public boolean onKey(View v, int keyCode, KeyEvent event) { | |
107 try { | |
108 // skip keys if we aren't connected yet or have been disconnected | |
109 if (bridge.isDisconnected() || bridge.transport == null) | |
110 return false; | |
111 | |
112 final boolean hardKeyboardHidden = manager.hardKeyboardHidden; | |
113 | |
114 // Ignore all key-up events except for the special keys | |
115 if (event.getAction() == KeyEvent.ACTION_UP) { | |
116 // There's nothing here for virtual keyboard users. | |
117 if (!hardKeyboard || (hardKeyboard && hardKeyboardHidden)) | |
118 return false; | |
119 | |
120 // if keycode debugging enabled, log and print the pressed key | |
121 if (prefs.getBoolean(PreferenceConstants.DEBUG_KEYCODES, false)) { | |
122 String keyCodeString = String.format(": %d", keyCode); | |
123 String toastText = v.getContext().getString(R.string.keycode_pressed) + keyCodeString; | |
124 Log.d(TAG, toastText); | |
125 } | |
126 | |
127 if (fullKeyboard()) { | |
128 switch (keyCode) { | |
129 case KeyEvent.KEYCODE_CTRL_LEFT: | |
130 case KeyEvent.KEYCODE_CTRL_RIGHT: | |
131 metaKeyUp(META_CTRL_ON); | |
132 return true; | |
133 | |
134 case KeyEvent.KEYCODE_ALT_LEFT: | |
135 case KeyEvent.KEYCODE_ALT_RIGHT: | |
136 metaKeyUp(META_ALT_ON); | |
137 return true; | |
138 | |
139 case KeyEvent.KEYCODE_SHIFT_LEFT: | |
140 case KeyEvent.KEYCODE_SHIFT_RIGHT: | |
141 metaKeyUp(META_SHIFT_ON); | |
142 return true; | |
143 | |
144 default: | |
145 } | |
146 } | |
147 else if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) { | |
148 if (keyCode == KeyEvent.KEYCODE_ALT_RIGHT | |
149 && (metaState & META_SLASH) != 0) { | |
150 metaState &= ~(META_SLASH | META_TRANSIENT); | |
151 buffer.write('/'); | |
152 return true; | |
153 } | |
154 else if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT | |
155 && (metaState & META_TAB) != 0) { | |
156 metaState &= ~(META_TAB | META_TRANSIENT); | |
157 buffer.write("[tab]"); | |
158 return true; | |
159 } | |
160 } | |
161 else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) { | |
162 if (keyCode == KeyEvent.KEYCODE_ALT_LEFT | |
163 && (metaState & META_SLASH) != 0) { | |
164 metaState &= ~(META_SLASH | META_TRANSIENT); | |
165 buffer.write('/'); | |
166 return true; | |
167 } | |
168 else if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT | |
169 && (metaState & META_TAB) != 0) { | |
170 metaState &= ~(META_TAB | META_TRANSIENT); | |
171 buffer.write("[tab]"); | |
172 return true; | |
173 } | |
174 } | |
175 | |
176 return false; | |
177 } | |
178 | |
179 bridge.resetScrollPosition(); | |
180 | |
181 if (keyCode == KeyEvent.KEYCODE_UNKNOWN && | |
182 event.getAction() == KeyEvent.ACTION_MULTIPLE) { | |
183 byte[] input = event.getCharacters().getBytes(encoding); | |
184 buffer.write(input); | |
185 return true; | |
186 } | |
187 | |
188 int curMetaState = event.getMetaState(); | |
189 final int orgMetaState = curMetaState; | |
190 | |
191 if ((metaState & META_SHIFT_MASK) != 0) { | |
192 curMetaState |= KeyEvent.META_SHIFT_ON; | |
193 } | |
194 | |
195 if ((metaState & META_ALT_MASK) != 0) { | |
196 curMetaState |= KeyEvent.META_ALT_ON; | |
197 } | |
198 | |
199 int uchar = event.getUnicodeChar(curMetaState); | |
200 | |
201 // no hard keyboard? ALT-k should pass through to below | |
202 if ((orgMetaState & KeyEvent.META_ALT_ON) != 0 && | |
203 (!hardKeyboard || hardKeyboardHidden)) { | |
204 uchar = 0; | |
205 } | |
206 | |
207 if ((uchar & KeyCharacterMap.COMBINING_ACCENT) != 0) { | |
208 mDeadKey = uchar & KeyCharacterMap.COMBINING_ACCENT_MASK; | |
209 return true; | |
210 } | |
211 | |
212 if (mDeadKey != 0 && uchar != 0) { | |
213 uchar = KeyCharacterMap.getDeadChar(mDeadKey, uchar); | |
214 mDeadKey = 0; | |
215 } | |
216 | |
217 // handle customized keymaps | |
218 if (customKeymapAction(v, keyCode, event)) | |
219 return true; | |
220 | |
221 if (v != null) { | |
222 //Show up the CharacterPickerDialog when the SYM key is pressed | |
223 if ((isSymKey(keyCode) || uchar == KeyCharacterMap.PICKER_DIALOG_INPUT)) { | |
224 bridge.showCharPickerDialog(); | |
225 | |
226 if (metaState == 4) { // reset fn-key state | |
227 metaState = 0; | |
228 bridge.redraw(); | |
229 } | |
230 | |
231 return true; | |
232 } | |
233 else if (keyCode == KeyEvent.KEYCODE_SEARCH) { | |
234 //Show up the URL scan dialog when the search key is pressed | |
235 urlScan(v); | |
236 return true; | |
237 } | |
238 } | |
239 | |
240 // otherwise pass through to existing session | |
241 // print normal keys | |
242 if (uchar > 0x00 && keyCode != KeyEvent.KEYCODE_ENTER) { | |
243 metaState &= ~(META_SLASH | META_TAB); | |
244 // Remove shift and alt modifiers | |
245 final int lastMetaState = metaState; | |
246 metaState &= ~(META_SHIFT_ON | META_ALT_ON); | |
247 | |
248 if (metaState != lastMetaState) { | |
249 bridge.redraw(); | |
250 } | |
251 | |
252 if ((metaState & META_CTRL_MASK) != 0) { | |
253 metaState &= ~META_CTRL_ON; | |
254 bridge.redraw(); | |
255 | |
256 // If there is no hard keyboard or there is a hard keyboard currently hidden, | |
257 // CTRL-1 through CTRL-9 will send F1 through F9 | |
258 if ((!hardKeyboard || (hardKeyboard && hardKeyboardHidden)) | |
259 && sendFunctionKey(keyCode)) | |
260 return true; | |
261 | |
262 uchar = keyAsControl(uchar); | |
263 } | |
264 | |
265 // handle pressing f-keys | |
266 if ((hardKeyboard && !hardKeyboardHidden) | |
267 && (curMetaState & KeyEvent.META_ALT_ON) != 0 | |
268 && (curMetaState & KeyEvent.META_SHIFT_ON) != 0 | |
269 && sendFunctionKey(keyCode)) | |
270 return true; | |
271 | |
272 if (uchar < 0x80) | |
273 buffer.write(uchar); | |
274 else | |
275 buffer.write(new String(Character.toChars(uchar)).getBytes(encoding)); | |
276 | |
277 return true; | |
278 } | |
279 | |
280 // send ctrl and meta-keys as appropriate | |
281 if (!hardKeyboard || hardKeyboardHidden) { | |
282 int k = event.getUnicodeChar(0); | |
283 int k0 = k; | |
284 boolean sendCtrl = false; | |
285 boolean sendMeta = false; | |
286 | |
287 if (k != 0) { | |
288 if ((orgMetaState & HC_META_CTRL_ON) != 0) { | |
289 k = keyAsControl(k); | |
290 | |
291 if (k != k0) | |
292 sendCtrl = true; | |
293 | |
294 // send F1-F10 via CTRL-1 through CTRL-0 | |
295 if (!sendCtrl && sendFunctionKey(keyCode)) | |
296 return true; | |
297 } | |
298 else if ((orgMetaState & KeyEvent.META_ALT_ON) != 0) { | |
299 sendMeta = true; | |
300 buffer.write(0x1b); | |
301 } | |
302 | |
303 if (sendMeta || sendCtrl) { | |
304 buffer.write(k); | |
305 return true; | |
306 } | |
307 } | |
308 } | |
309 | |
310 // handle meta and f-keys for full hardware keyboard | |
311 if (hardKeyboard && !hardKeyboardHidden && fullKeyboard()) { | |
312 int k = event.getUnicodeChar(orgMetaState & KeyEvent.META_SHIFT_ON); | |
313 int k0 = k; | |
314 | |
315 if (k != 0) { | |
316 if ((orgMetaState & HC_META_CTRL_ON) != 0) { | |
317 k = keyAsControl(k); | |
318 | |
319 if (k != k0) | |
320 buffer.write(k); | |
321 | |
322 return true; | |
323 } | |
324 else if ((orgMetaState & KeyEvent.META_ALT_ON) != 0) { | |
325 buffer.write(0x1b); | |
326 buffer.write(k); | |
327 return true; | |
328 } | |
329 } | |
330 | |
331 if (sendFullSpecialKey(keyCode)) | |
332 return true; | |
333 } | |
334 | |
335 // try handling keymode shortcuts | |
336 if (hardKeyboard && !hardKeyboardHidden && | |
337 event.getRepeatCount() == 0) { | |
338 if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) { | |
339 switch (keyCode) { | |
340 case KeyEvent.KEYCODE_ALT_RIGHT: | |
341 metaState |= META_SLASH; | |
342 return true; | |
343 | |
344 case KeyEvent.KEYCODE_SHIFT_RIGHT: | |
345 metaState |= META_TAB; | |
346 return true; | |
347 | |
348 case KeyEvent.KEYCODE_SHIFT_LEFT: | |
349 metaPress(META_SHIFT_ON); | |
350 return true; | |
351 | |
352 case KeyEvent.KEYCODE_ALT_LEFT: | |
353 metaPress(META_ALT_ON); | |
354 return true; | |
355 } | |
356 } | |
357 else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) { | |
358 switch (keyCode) { | |
359 case KeyEvent.KEYCODE_ALT_LEFT: | |
360 metaState |= META_SLASH; | |
361 return true; | |
362 | |
363 case KeyEvent.KEYCODE_SHIFT_LEFT: | |
364 metaState |= META_TAB; | |
365 return true; | |
366 | |
367 case KeyEvent.KEYCODE_SHIFT_RIGHT: | |
368 metaPress(META_SHIFT_ON); | |
369 return true; | |
370 | |
371 case KeyEvent.KEYCODE_ALT_RIGHT: | |
372 metaPress(META_ALT_ON); | |
373 return true; | |
374 } | |
375 } | |
376 else { | |
377 switch (keyCode) { | |
378 case KeyEvent.KEYCODE_ALT_RIGHT: | |
379 case KeyEvent.KEYCODE_ALT_LEFT: | |
380 metaPress(META_ALT_ON); | |
381 return true; | |
382 | |
383 case KeyEvent.KEYCODE_SHIFT_LEFT: | |
384 case KeyEvent.KEYCODE_SHIFT_RIGHT: | |
385 metaPress(META_SHIFT_ON); | |
386 return true; | |
387 } | |
388 } | |
389 | |
390 // Handle hardware CTRL keys | |
391 if (keyCode == KeyEvent.KEYCODE_CTRL_LEFT || | |
392 keyCode == KeyEvent.KEYCODE_CTRL_RIGHT) { | |
393 ctrlKeySpecial(); | |
394 return true; | |
395 } | |
396 } | |
397 | |
398 // look for special chars | |
399 switch (keyCode) { | |
400 case KEYCODE_ESCAPE: | |
401 buffer.write(0x1b); | |
402 return true; | |
403 | |
404 case KeyEvent.KEYCODE_TAB: | |
405 buffer.write("[tab]"); | |
406 return true; | |
407 | |
408 case KEYCODE_PAGE_DOWN: | |
409 buffer.write("[pgdown]"); | |
410 metaState &= ~META_TRANSIENT; | |
411 bridge.tryKeyVibrate(); | |
412 return true; | |
413 | |
414 case KEYCODE_PAGE_UP: | |
415 buffer.write("[pgup]"); | |
416 metaState &= ~META_TRANSIENT; | |
417 bridge.tryKeyVibrate(); | |
418 return true; | |
419 | |
420 case KeyEvent.KEYCODE_MOVE_HOME: | |
421 buffer.write("[home]"); | |
422 metaState &= ~META_TRANSIENT; | |
423 bridge.tryKeyVibrate(); | |
424 return true; | |
425 | |
426 case KeyEvent.KEYCODE_MOVE_END: | |
427 buffer.write("[end]"); // does not exist!! | |
428 metaState &= ~META_TRANSIENT; | |
429 bridge.tryKeyVibrate(); | |
430 return true; | |
431 | |
432 case KeyEvent.KEYCODE_CAMERA: | |
433 // check to see which shortcut the camera button triggers | |
434 String hwbuttonShortcut = manager.prefs.getString( | |
435 PreferenceConstants.CAMERA, | |
436 PreferenceConstants.HWBUTTON_SCREEN_CAPTURE); | |
437 return (handleShortcut(v, hwbuttonShortcut)); | |
438 | |
439 case KeyEvent.KEYCODE_VOLUME_UP: | |
440 // check to see which shortcut the volume button triggers | |
441 hwbuttonShortcut = manager.prefs.getString( | |
442 PreferenceConstants.VOLUP, | |
443 PreferenceConstants.HWBUTTON_CTRL); | |
444 return (handleShortcut(v, hwbuttonShortcut)); | |
445 | |
446 case KeyEvent.KEYCODE_VOLUME_DOWN: | |
447 // check to see which shortcut the camera button triggers | |
448 hwbuttonShortcut = manager.prefs.getString( | |
449 PreferenceConstants.VOLDN, | |
450 PreferenceConstants.HWBUTTON_TAB); | |
451 return (handleShortcut(v, hwbuttonShortcut)); | |
452 | |
453 case KeyEvent.KEYCODE_SEARCH: | |
454 // check to see which shortcut the search button triggers | |
455 hwbuttonShortcut = manager.prefs.getString( | |
456 PreferenceConstants.SEARCH, | |
457 PreferenceConstants.HWBUTTON_ESC); | |
458 return (handleShortcut(v, hwbuttonShortcut)); | |
459 | |
460 case KeyEvent.KEYCODE_DEL: | |
461 if ((metaState & META_ALT_MASK) != 0) { | |
462 buffer.write("[insert]"); | |
463 } | |
464 else { | |
465 buffer.write("[backspace]"); | |
466 } | |
467 | |
468 metaState &= ~META_TRANSIENT; | |
469 return true; | |
470 | |
471 case KeyEvent.KEYCODE_ENTER: | |
472 buffer.write("[enter]"); | |
473 metaState &= ~META_TRANSIENT; | |
474 return true; | |
475 | |
476 case KeyEvent.KEYCODE_DPAD_LEFT: | |
477 if (selectingForCopy) { | |
478 selectionArea.decrementColumn(); | |
479 bridge.redraw(); | |
480 } | |
481 else { | |
482 if ((metaState & META_ALT_MASK) != 0) { | |
483 buffer.write("[home]"); | |
484 } | |
485 else { | |
486 buffer.write("[left]"); | |
487 } | |
488 | |
489 metaState &= ~META_TRANSIENT; | |
490 bridge.tryKeyVibrate(); | |
491 } | |
492 | |
493 return true; | |
494 | |
495 case KeyEvent.KEYCODE_DPAD_UP: | |
496 if (selectingForCopy) { | |
497 selectionArea.decrementRow(); | |
498 bridge.redraw(); | |
499 } | |
500 else { | |
501 if ((metaState & META_ALT_MASK) != 0) { | |
502 buffer.write("[pgup]"); | |
503 } | |
504 else { | |
505 buffer.write("[up]"); | |
506 } | |
507 | |
508 metaState &= ~META_TRANSIENT; | |
509 bridge.tryKeyVibrate(); | |
510 } | |
511 | |
512 return true; | |
513 | |
514 case KeyEvent.KEYCODE_DPAD_DOWN: | |
515 if (selectingForCopy) { | |
516 selectionArea.incrementRow(); | |
517 bridge.redraw(); | |
518 } | |
519 else { | |
520 if ((metaState & META_ALT_MASK) != 0) { | |
521 buffer.write("[pgdown]"); | |
522 } | |
523 else { | |
524 buffer.write("[down]"); | |
525 } | |
526 | |
527 metaState &= ~META_TRANSIENT; | |
528 bridge.tryKeyVibrate(); | |
529 } | |
530 | |
531 return true; | |
532 | |
533 case KeyEvent.KEYCODE_DPAD_RIGHT: | |
534 if (selectingForCopy) { | |
535 selectionArea.incrementColumn(); | |
536 bridge.redraw(); | |
537 } | |
538 else { | |
539 if ((metaState & META_ALT_MASK) != 0) { | |
540 buffer.write("[end]"); | |
541 } | |
542 else { | |
543 buffer.write("[right]"); | |
544 } | |
545 | |
546 metaState &= ~META_TRANSIENT; | |
547 bridge.tryKeyVibrate(); | |
548 } | |
549 | |
550 return true; | |
551 | |
552 case KeyEvent.KEYCODE_DPAD_CENTER: | |
553 ctrlKeySpecial(); | |
554 return true; | |
555 } | |
556 } | |
557 catch (IOException e) { | |
558 Log.e(TAG, "Problem while trying to handle an onKey() event", e); | |
559 | |
560 try { | |
561 bridge.transport.flush(); | |
562 } | |
563 catch (IOException ioe) { | |
564 Log.d(TAG, "Our transport was closed, dispatching disconnect event"); | |
565 bridge.dispatchDisconnect(false); | |
566 } | |
567 } | |
568 catch (NullPointerException npe) { | |
569 Log.d(TAG, "Input before connection established ignored."); | |
570 return true; | |
571 } | |
572 } | |
573 | |
99 }; | 574 }; |
575 | |
100 | 576 |
101 public TN5250() { | 577 public TN5250() { |
102 super(); | 578 super(); |
103 } | 579 } |
104 | 580 |