blob: ac6d1ab73a70812f7d9807ff03905acd2623c141 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package vncclient.adapter;
import java.awt.event.KeyEvent;
import streamer.BaseElement;
import streamer.ByteBuffer;
import streamer.Link;
import vncclient.vnc.RfbConstants;
import common.KeyOrder;
public class AwtVncKeyboardAdapter extends BaseElement {
protected boolean sh = false;
protected boolean caps = false;
protected boolean num = false;
public AwtVncKeyboardAdapter(String id) {
super(id);
}
@Override
public void handleData(ByteBuffer buf, Link link) {
if (verbose)
System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
KeyOrder order = (KeyOrder)buf.getOrder();
buf.unref();
ByteBuffer outBuf = new ByteBuffer(8);
outBuf.writeByte(RfbConstants.CLIENT_KEYBOARD_EVENT);
outBuf.writeByte((order.pressed) ? RfbConstants.KEY_DOWN : RfbConstants.KEY_UP);
outBuf.writeShort(0); // padding
outBuf.writeInt(map_en_us(order));
pushDataToAllOuts(outBuf);
}
/**
* Return key scan code (in lower byte) and extended flags (in second byte).
*/
private int map_en_us(KeyOrder order) {
switch (order.event.getKeyCode()) {
// Functional keys
case KeyEvent.VK_ESCAPE:
return 0xff1b;
case KeyEvent.VK_F1:
return 0xffbe;
case KeyEvent.VK_F2:
return 0xffbf;
case KeyEvent.VK_F3:
return 0xffc0;
case KeyEvent.VK_F4:
return 0xffc1;
case KeyEvent.VK_F5:
return 0xffc2;
case KeyEvent.VK_F6:
return 0xffc3;
case KeyEvent.VK_F7:
return 0xffc4;
case KeyEvent.VK_F8:
return 0xffc5;
case KeyEvent.VK_F9:
return 0xffc6;
case KeyEvent.VK_F10:
return 0xffc7;
case KeyEvent.VK_F11:
return 0xffc8;
case KeyEvent.VK_F12:
return 0xffc9;
// Row #1
case KeyEvent.VK_BACK_QUOTE:
return (sh) ? '~' : '`';
case KeyEvent.VK_1:
return (sh) ? '!' : '1';
case KeyEvent.VK_2:
return (sh) ? '@' : '2';
case KeyEvent.VK_3:
return (sh) ? '#' : '3';
case KeyEvent.VK_4:
return (sh) ? '$' : '4';
case KeyEvent.VK_5:
return (sh) ? '%' : '5';
case KeyEvent.VK_6:
return (sh) ? '^' : '6';
case KeyEvent.VK_7:
return (sh) ? '&' : '7';
case KeyEvent.VK_8:
return (sh) ? '*' : '8';
case KeyEvent.VK_9:
return (sh) ? '(' : '9';
case KeyEvent.VK_0:
return (sh) ? ')' : '0';
case KeyEvent.VK_MINUS:
return (sh) ? '_' : '-';
case KeyEvent.VK_EQUALS:
return (sh) ? '+' : '=';
case KeyEvent.VK_BACK_SPACE:
return 0xff08;
// Row #2
case KeyEvent.VK_TAB:
return 0xff09;
case KeyEvent.VK_Q:
return (sh ^ caps) ? 'Q' : 'q';
case KeyEvent.VK_W:
return (sh ^ caps) ? 'W' : 'w';
case KeyEvent.VK_E:
return (sh ^ caps) ? 'E' : 'e';
case KeyEvent.VK_R:
return (sh ^ caps) ? 'R' : 'r';
case KeyEvent.VK_T:
return (sh ^ caps) ? 'T' : 't';
case KeyEvent.VK_Y:
return (sh ^ caps) ? 'Y' : 'y';
case KeyEvent.VK_U:
return (sh ^ caps) ? 'U' : 'u';
case KeyEvent.VK_I:
return (sh ^ caps) ? 'I' : 'i';
case KeyEvent.VK_O:
return (sh ^ caps) ? 'O' : 'o';
case KeyEvent.VK_P:
return (sh ^ caps) ? 'P' : 'p';
case KeyEvent.VK_OPEN_BRACKET:
return (sh) ? '{' : '[';
case KeyEvent.VK_CLOSE_BRACKET:
return (sh) ? '{' : ']';
case KeyEvent.VK_ENTER:
switch (order.event.getKeyLocation()) {
default:
case KeyEvent.KEY_LOCATION_STANDARD:
return 0xff0d;
case KeyEvent.KEY_LOCATION_NUMPAD:
return 0xff8d;
}
// Row #3
case KeyEvent.VK_CAPS_LOCK:
if (order.pressed)
caps = !caps;
return 0xFFE5;
case KeyEvent.VK_A:
return (sh ^ caps) ? 'A' : 'a';
case KeyEvent.VK_S:
return (sh ^ caps) ? 'S' : 's';
case KeyEvent.VK_D:
return (sh ^ caps) ? 'D' : 'd';
case KeyEvent.VK_F:
return (sh ^ caps) ? 'F' : 'f';
case KeyEvent.VK_G:
return (sh ^ caps) ? 'G' : 'g';
case KeyEvent.VK_H:
return (sh ^ caps) ? 'H' : 'h';
case KeyEvent.VK_J:
return (sh ^ caps) ? 'J' : 'j';
case KeyEvent.VK_K:
return (sh ^ caps) ? 'K' : 'k';
case KeyEvent.VK_L:
return (sh ^ caps) ? 'L' : 'l';
case KeyEvent.VK_SEMICOLON:
return (sh) ? ':' : ';';
case KeyEvent.VK_QUOTE:
return (sh) ? '"' : '\'';
// Row #4
case KeyEvent.VK_SHIFT:
sh = !sh;
switch (order.event.getKeyLocation()) {
default:
case KeyEvent.KEY_LOCATION_LEFT:
return 0xffe1;
case KeyEvent.KEY_LOCATION_RIGHT:
return 0xffe2;
}
case KeyEvent.VK_BACK_SLASH:
return (sh) ? '|' : '\\';
case KeyEvent.VK_Z:
return (sh ^ caps) ? 'Z' : 'z';
case KeyEvent.VK_X:
return (sh ^ caps) ? 'X' : 'x';
case KeyEvent.VK_C:
return (sh ^ caps) ? 'C' : 'c';
case KeyEvent.VK_V:
return (sh ^ caps) ? 'V' : 'v';
case KeyEvent.VK_B:
return (sh ^ caps) ? 'B' : 'b';
case KeyEvent.VK_N:
return (sh ^ caps) ? 'N' : 'n';
case KeyEvent.VK_M:
return (sh ^ caps) ? 'M' : 'm';
case KeyEvent.VK_COMMA:
return (sh) ? '<' : ',';
case KeyEvent.VK_PERIOD:
return (sh) ? '>' : '.';
case KeyEvent.VK_SLASH:
return (sh) ? '?' : '/';
//
// Bottom row
case KeyEvent.VK_CONTROL:
switch (order.event.getKeyLocation()) {
default:
case KeyEvent.KEY_LOCATION_LEFT:
return 0xFFE3;
case KeyEvent.KEY_LOCATION_RIGHT:
return 0xFFE4;
}
case KeyEvent.VK_WINDOWS:
switch (order.event.getKeyLocation()) {
default:
case KeyEvent.KEY_LOCATION_LEFT:
return 0xFFED; // HyperL
case KeyEvent.KEY_LOCATION_RIGHT:
return 0xFFEE; // HyperR
}
case KeyEvent.VK_META:
switch (order.event.getKeyLocation()) {
default:
case KeyEvent.KEY_LOCATION_LEFT:
return 0xFFE7; // MetaL
case KeyEvent.KEY_LOCATION_RIGHT:
return 0xFFE8; // MetaR
}
case KeyEvent.VK_ALT:
switch (order.event.getKeyLocation()) {
default:
case KeyEvent.KEY_LOCATION_LEFT:
return 0xFFE9;
case KeyEvent.KEY_LOCATION_RIGHT:
return 0xFFEA;
}
case KeyEvent.VK_ALT_GRAPH:
return 0xfe03;
case KeyEvent.VK_SPACE:
return ' ';
case KeyEvent.VK_CONTEXT_MENU:
return 0xff67;
//
// Special keys
case KeyEvent.VK_PRINTSCREEN:
return (sh) ? 0xFF15/* SysRq */: 0xFF61 /* Print */;
case KeyEvent.VK_SCROLL_LOCK:
return 0xFF14;
case KeyEvent.VK_PAUSE:
return (sh) ? 0xFF6B/* Break */: 0xFF13/* Pause */;
// Text navigation keys
case KeyEvent.VK_INSERT:
return 0xff63;
case KeyEvent.VK_DELETE:
return 0xffff;
case KeyEvent.VK_HOME:
return 0xff50;
case KeyEvent.VK_END:
return 0xff57;
case KeyEvent.VK_PAGE_UP:
return 0xff55;
case KeyEvent.VK_PAGE_DOWN:
return 0xff56;
// Cursor keys
case KeyEvent.VK_LEFT:
switch (order.event.getKeyLocation()) {
default:
case KeyEvent.KEY_LOCATION_LEFT:
return 0xff51;
case KeyEvent.KEY_LOCATION_NUMPAD:
return 0xFF96;
}
case KeyEvent.VK_UP:
switch (order.event.getKeyLocation()) {
default:
case KeyEvent.KEY_LOCATION_LEFT:
return 0xff52;
case KeyEvent.KEY_LOCATION_NUMPAD:
return 0xFF97;
}
case KeyEvent.VK_RIGHT:
switch (order.event.getKeyLocation()) {
default:
case KeyEvent.KEY_LOCATION_LEFT:
return 0xff53;
case KeyEvent.KEY_LOCATION_NUMPAD:
return 0xFF98;
}
case KeyEvent.VK_DOWN:
switch (order.event.getKeyLocation()) {
default:
case KeyEvent.KEY_LOCATION_LEFT:
return 0xff54;
case KeyEvent.KEY_LOCATION_NUMPAD:
return 0xFF99;
}
// Keypad
case KeyEvent.VK_NUM_LOCK:
if (order.pressed)
num = !num;
return 0xFF6F;
case KeyEvent.VK_DIVIDE:
return 0xFFAF;
case KeyEvent.VK_MULTIPLY:
return 0xFFAA;
case KeyEvent.VK_SUBTRACT:
return 0xFFAD;
case KeyEvent.VK_ADD:
return 0xFFAB;
case KeyEvent.VK_KP_LEFT:
return 0xFF96;
case KeyEvent.VK_KP_UP:
return 0xFF97;
case KeyEvent.VK_KP_RIGHT:
return 0xFF98;
case KeyEvent.VK_KP_DOWN:
return 0xFF99;
case KeyEvent.VK_NUMPAD0:
return 0xFFB0;
case KeyEvent.VK_NUMPAD1:
return 0xFFB1;
case KeyEvent.VK_NUMPAD2:
return 0xFFB2;
case KeyEvent.VK_NUMPAD3:
return 0xFFB3;
case KeyEvent.VK_NUMPAD4:
return 0xFFB4;
case KeyEvent.VK_NUMPAD5:
return 0xFFB5;
case KeyEvent.VK_NUMPAD6:
return 0xFFB6;
case KeyEvent.VK_NUMPAD7:
return 0xFFB7;
case KeyEvent.VK_NUMPAD8:
return 0xFFB8;
case KeyEvent.VK_NUMPAD9:
return 0xFFB9;
case KeyEvent.VK_DECIMAL:
return 0xFFAE;
default:
System.err.println("Key is not mapped: " + order + ".");
return ' '; // Space
}
}
}