public class ChuiWebSimulator extends EmulatedTerminalState implements WebClientMessageTypes, ClientProtocolHooks
IMPORTANT: Do not use logging anywhere inside this class. When an authentication plugin is running during session establishment with the P2J server using logging no messages are written into the log and the application is blocked.
Modifier and Type | Field and Description |
---|---|
private Cell[][] |
cache
Screen contents.
|
private static java.lang.String |
COLOR_PALETTE
Color palette message spec.
|
private java.lang.Object |
lock
Internal locking object which is also shared with the websock instance.
|
private java.lang.String |
paletteMessage
Color palette JSON message.
|
private VT100ProgressKeyboard |
vt100Keyboard
VT100 keyboard instance (only used for VT100 emulation in child processes).
|
private WebClientProtocol |
websock
Worker object to processing our WebSocket that connects us to the websock client.
|
cfgLock, cursorX, cursorY, data, dataLock, options, selLock, showCursor
CAPTURE_MOUSE, ENABLE_OS_EVENTS, MSG_ADD_WINDOW_MESSAGE_TEXT, MSG_BEEP, MSG_CLEAR, MSG_CLEAR_WINDOW_MESSAGES, MSG_CLIENT_READY, MSG_CLIPBOARD_CONTENTS, MSG_CLIPBOARD_PREPARE, MSG_CREATE_CHILD_WINDOW, MSG_CREATE_FONT, MSG_CREATE_WINDOW, MSG_CURRENT_SELECTION, MSG_CURSOR_POS, MSG_CURSOR_STATUS, MSG_DEREGISTER_WIDGET, MSG_DERIVE_FONT, MSG_DESKTOP_RESIZED, MSG_DESTROY_WINDOW, MSG_DONE_CREATE_FONT, MSG_DONE_DERIVE_FONT, MSG_DRAW, MSG_DRAW_HASH_REMOVED, MSG_DROP_FILE_NOTIFY, MSG_FILE_UPLOADING, MSG_GET_DESKTOP_DIMENSION, MSG_GET_FONT_HEIGHT, MSG_GET_FONT_WIDTHS, MSG_GET_MOUSE_POSITION, MSG_GET_PAR_HEIGHT, MSG_GET_TEXT_HEIGHT, MSG_GET_TEXT_WIDTH, MSG_GET_TEXT_WIDTHS, MSG_GET_TEXT_WIDTHS_BATCH, MSG_INVALIDATE_SELECTION, MSG_IS_FONT_INSTALLED, MSG_KEY, MSG_KEY_VT100, MSG_LOCK_MOUSE_PTR, MSG_MOUSE_EVENT, MSG_MOVE_TO_BOTTOM, MSG_MOVE_TO_TOP, MSG_OPEN_MIME_RESOURCE, MSG_P2J_APPLY_EVENT, MSG_P2J_CREATE_RESOURCE, MSG_P2J_DELETE_HANDLE, MSG_P2J_INVOKE, MSG_P2J_PUBLISH, MSG_P2J_SUBSCRIBE, MSG_P2J_UNSUBSCRIBE, MSG_PAGE_LOADED, MSG_PARSE_EDITOR_CONTENT, MSG_PARTIAL, MSG_PASTE, MSG_PING_PONG, MSG_QUIT, MSG_READ_CLIPBOARD, MSG_REGISTER_HOVERABLE_WIDGET, MSG_REMOTE_CALL, MSG_REMOVE_EXPIRED_HASH, MSG_RESTACK_WINDOWS, MSG_SENT_DESKTOP_DIMENSION, MSG_SENT_FONT_HEIGHT, MSG_SENT_FONT_WIDTHS, MSG_SENT_PAR_HEIGHT, MSG_SENT_TEXT_HEIGHT, MSG_SENT_TEXT_WIDTH, MSG_SENT_TEXT_WIDTHS, MSG_SENT_TEXT_WIDTHS_BATCH, MSG_SET_CURSOR_STYLE, MSG_SET_MOUSE_PTR, MSG_SET_UPLOAD_FILE_SIZE_LIMITS, MSG_SET_WAIT_STATE, MSG_SET_WINDOW_LOC, MSG_SET_WINDOW_STATUS_TEXT, MSG_VT100, MSG_WAIT_USER_INPUT, MSG_WINDOW_ACTIVATED, MSG_WINDOW_ICONIFY, MSG_WINDOW_RESIZED, MSG_WINDOW_SENSITIVITY, MSG_WINDOW_VISIBILITY, MSG_WRITE_CLIPBOARD, PROCESS_MOUSE_WIDGETS, SET_ICONIFICATION_STATE, SET_RESIZEABLE_WINDOW
Constructor and Description |
---|
ChuiWebSimulator(BootstrapConfig config)
Create a new chui web simulator.
|
Modifier and Type | Method and Description |
---|---|
private void |
addChunk(java.util.Map<Color,java.util.List<Chunk>> chunks,
java.io.ByteArrayOutputStream chunk,
Color color)
Add a chunk to the chunks map.
|
void |
beep()
Raise the bell on the remote terminal.
|
private byte[] |
buildDrawMessage(java.util.Map<Color,java.util.List<Chunk>> chunks,
int rows)
Build the screen drawing message from a given chunks map.
|
private java.lang.String |
buildPaletteMessage()
Build color palette message.
|
void |
clear()
Overwrite the entire 2-dimensional output buffer with the space character
to be rendered with the
Color.NORMAL color. |
private void |
clearCache()
Clear the cached screen.
|
void |
configure(TerminalOptions options)
Initialize the instance using the given configuration.
|
void |
desktopResized(int width,
int height)
Called when the desktop on the client has changed its dimensions.
|
WebClientProtocol |
getWebSocket()
Obtain the web client protocol instance that implements the web socket operations.
|
void |
initRemoteClient()
Called each time a connect occurs, this allows caller-controlled initialization of the
remote client.
|
void |
injectVT100Key(int keyCode,
char charCode)
Input key events when in VT100 mode.
|
private void |
putCellAttributes(java.io.ByteArrayOutputStream message,
Color cellColor)
Put cell attributes and character into the message buffer.
|
private void |
putCellCharacter(java.io.ByteArrayOutputStream message,
Cell cell)
Put cell character into the message buffer.
|
void |
quit()
Remote application is about to end.
|
void |
raiseMouseEvent(int windowId,
int mouseOp,
long tstamp,
int mouseX,
int mouseY,
int button,
int clickCount,
int modifiersMask,
int[] wheelParameters,
int widgetId)
Raise a mouse event.
|
int |
readKey()
Read the next key from the FIFO key input buffer.
|
private void |
sendColorPalette()
Send the color palette down to the javascript client.
|
private void |
sendSwitchMode()
Switch mode message.
|
boolean |
setCursor(int x,
int y)
Position the cursor.
|
boolean |
setCursorStatus(boolean on)
Set the cursor visibility.
|
void |
setVT100Keyboard(VT100ProgressKeyboard vt100Keyboard)
Assign the VT100 emulator keyboard instance.
|
void |
setWindowDimension(int windowId,
int width,
int height)
Set the dimension for the specified window.
|
void |
setWindowLocation(int windowId,
int x,
int y)
Set the location for the specified window.
|
void |
triggerRepaint(boolean full)
When data is prepared to send down to the websock JS code to be drawn, the data should be
optimized for drawing on a canvas.
|
void |
windowActivated(int deactivatingWindowId,
int activatingWindowId)
Raise an event as the window was activated.
|
void |
windowIconified(int windowId,
boolean state)
Raise an event as the window was (de)iconified.
|
append, getColumns, getCursorX, getCursorY, getRows, getScreenData, getTerminalOptions, replace
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
saveDropTargetFile, saveDropTargetFile, setNeedsNotificationOnWait, startDropTarget
private static final java.lang.String COLOR_PALETTE
private final java.lang.Object lock
private java.lang.String paletteMessage
private Cell[][] cache
private WebClientProtocol websock
private VT100ProgressKeyboard vt100Keyboard
public ChuiWebSimulator(BootstrapConfig config)
config
- Web socket timeout.public WebClientProtocol getWebSocket()
public void initRemoteClient()
Whenever the main page is loaded or re-loaded, the WebSocket will connect and we must put the virtual terminal into a known state.
initRemoteClient
in interface ClientProtocolHooks
public void injectVT100Key(int keyCode, char charCode)
injectVT100Key
in interface ClientProtocolHooks
keyCode
- The key code from the input event.charCode
- The character code from the input event.public void raiseMouseEvent(int windowId, int mouseOp, long tstamp, int mouseX, int mouseY, int button, int clickCount, int modifiersMask, int[] wheelParameters, int widgetId)
This is a no-op in ChUI.
raiseMouseEvent
in interface ClientProtocolHooks
windowId
- The window ID.mouseOp
- The mouse event code.tstamp
- The event timestamp.mouseX
- The absolute mouse X for this event.mouseY
- The absolute mouse Y for this event.button
- The button which was pressed.clickCount
- The click count.modifiersMask
- The bit mask that represents the modifiers keys are pressed. The 0-bit corresponds
to the shift key, the 1-bit to the ctrl key, the 2-bit to the meta key and
the 3-bit to the alt key.wheelParameters
- The array that represents the wheel rotation amount and its unit.widgetId
- The explicit widget ID to which this event needs to be posted.public void setWindowLocation(int windowId, int x, int y)
setWindowLocation
in interface ClientProtocolHooks
windowId
- The window ID.x
- The X coordinate of the top-left corner.y
- The Y coordinate of the top-left corner.public void setWindowDimension(int windowId, int width, int height)
setWindowDimension
in interface ClientProtocolHooks
windowId
- The window ID.width
- The window width.height
- The window height.public void windowActivated(int deactivatingWindowId, int activatingWindowId)
windowActivated
in interface ClientProtocolHooks
deactivatingWindowId
- Id of the window being deactivated, may be negative.activatingWindowId
- Id of the window being activated, always valid.public void windowIconified(int windowId, boolean state)
windowIconified
in interface ClientProtocolHooks
windowId
- The window ID.state
- true
if the window was iconified.public void desktopResized(int width, int height)
desktopResized
in interface ClientProtocolHooks
width
- New desktop width.height
- New desktop height.public void setVT100Keyboard(VT100ProgressKeyboard vt100Keyboard)
vt100Keyboard
- The keyboard instance.public int readKey()
public void configure(TerminalOptions options)
configure
in class EmulatedTerminalState
options
- The configuration for the terminal simulator.public void clear()
Color.NORMAL
color. Sets the cursor
Y and X positions to 0. Send INIT message down to JS client.clear
in class EmulatedTerminalState
public void beep()
public boolean setCursorStatus(boolean on) throws java.lang.IllegalStateException
setCursorStatus
in class EmulatedTerminalState
on
- true
to make the cursor visible (subsequent repaint
operations will then cause the cursor to be drawn).java.lang.IllegalStateException
public boolean setCursor(int x, int y)
setCursor
in class EmulatedTerminalState
x
- New X cursor position.y
- New Y cursor position.true
if cursor positioning succeeded.public void triggerRepaint(boolean full)
The video screen memory is composed of cells stored in a 2 dimensional matrix. The size of the matrix is rows x columns where rows are the number of rows in the screen and columns are the number of columns. For example, 24 x 80 for a screen having 24 rows and 80 columns. Each cell is a structure which holds cell attributes, color and character.
The state of the most recently updated screen is saved in a cache. Whenever a new screen should be sent to the websock, the new screen is compared with the cached screen and only the changed cells are sent. Then the cache is updated to reflect the latest changes. A cell is considered changed when at least one of the cell properties (attribute, color or the character) is different from the same cell in the cache.
Drawing text on the HTML5 canvas using JS code is done on two steps:
When a network message is constructed this is done on two steps by keeping in mind the performance constraints described above.
Chunk
structure. The chunks are stored in a
linked map structure having the cell Color (attribute and color) structure as a key
and a linked list of chunks as the value. Both the linked map and the linked list
preserve the insertion order.
triggerRepaint
in class EmulatedTerminalState
full
- Flag to force a the entire screen to repaint.public void quit()
private java.lang.String buildPaletteMessage()
private void sendColorPalette()
private void addChunk(java.util.Map<Color,java.util.List<Chunk>> chunks, java.io.ByteArrayOutputStream chunk, Color color)
chunks
- Chunks map.chunk
- Chunk to add.color
- Color attribute used as a keyprivate byte[] buildDrawMessage(java.util.Map<Color,java.util.List<Chunk>> chunks, int rows)
chunks
- Chunks map.rows
- The number of rows in the screen.private void sendSwitchMode()
private void putCellAttributes(java.io.ByteArrayOutputStream message, Color cellColor)
message
- Message buffer.cellColor
- Cell color object.private void putCellCharacter(java.io.ByteArrayOutputStream message, Cell cell)
message
- Message buffer.cell
- Cell object.private void clearCache()