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