+++ /dev/null
-/*
- * Jexer - Java Text User Interface
- *
- * The MIT License (MIT)
- *
- * Copyright (C) 2017 Kevin Lamonte
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * @author Kevin Lamonte [kevin.lamonte@gmail.com]
- * @version 1
- */
-package jexer.backend;
-
-import java.util.LinkedList;
-import java.util.List;
-
-import jexer.bits.CellAttributes;
-import jexer.event.TInputEvent;
-import jexer.event.TKeypressEvent;
-import jexer.event.TMouseEvent;
-import jexer.TApplication;
-import jexer.TWindow;
-
-/**
- * TWindowBackend uses a window in one TApplication to provide a backend for
- * another TApplication.
- *
- * Note that TWindow has its own getScreen() and setTitle() functions.
- * Clients in TWindowBackend's application won't be able to use it to get at
- * the other application's screen. getOtherScreen() has been provided.
- */
-public class TWindowBackend extends TWindow implements Backend {
-
- /**
- * The listening object that run() wakes up on new input.
- */
- private Object listener;
-
- /**
- * The object to sync on in draw(). This is normally otherScreen, but it
- * could also be a MultiScreen.
- */
- private Object drawLock;
-
- /**
- * The event queue, filled up by a thread reading on input.
- */
- private List<TInputEvent> eventQueue;
-
- /**
- * The screen to use.
- */
- private Screen otherScreen;
-
- /**
- * The mouse X position as seen on the other screen.
- */
- private int otherMouseX = -1;
-
- /**
- * The mouse Y position as seen on the other screen.
- */
- private int otherMouseY = -1;
-
- /**
- * The session information.
- */
- private SessionInfo sessionInfo;
-
- /**
- * Set the object to sync to in draw().
- *
- * @param drawLock the object to synchronize on
- */
- public void setDrawLock(final Object drawLock) {
- this.drawLock = drawLock;
- }
-
- /**
- * Getter for the other application's screen.
- *
- * @return the Screen
- */
- public Screen getOtherScreen() {
- return otherScreen;
- }
-
- /**
- * Getter for sessionInfo.
- *
- * @return the SessionInfo
- */
- public final SessionInfo getSessionInfo() {
- return sessionInfo;
- }
-
- /**
- * Public constructor. Window will be located at (0, 0).
- *
- * @param listener the object this backend needs to wake up when new
- * input comes in
- * @param application TApplication that manages this window
- * @param title window title, will be centered along the top border
- * @param width width of window
- * @param height height of window
- */
- public TWindowBackend(final Object listener,
- final TApplication application, final String title,
- final int width, final int height) {
-
- super(application, title, width, height);
-
- this.listener = listener;
- eventQueue = new LinkedList<TInputEvent>();
- sessionInfo = new TSessionInfo(width, height);
- otherScreen = new LogicalScreen();
- otherScreen.setDimensions(width - 2, height - 2);
- drawLock = otherScreen;
- }
-
- /**
- * Public constructor. Window will be located at (0, 0).
- *
- * @param listener the object this backend needs to wake up when new
- * input comes in
- * @param application TApplication that manages this window
- * @param title window title, will be centered along the top border
- * @param width width of window
- * @param height height of window
- * @param flags bitmask of RESIZABLE, CENTERED, or MODAL
- */
- public TWindowBackend(final Object listener,
- final TApplication application, final String title,
- final int width, final int height, final int flags) {
-
- super(application, title, width, height, flags);
-
- this.listener = listener;
- eventQueue = new LinkedList<TInputEvent>();
- sessionInfo = new TSessionInfo(width, height);
- otherScreen = new LogicalScreen();
- otherScreen.setDimensions(width - 2, height - 2);
- drawLock = otherScreen;
- }
-
- /**
- * Public constructor.
- *
- * @param listener the object this backend needs to wake up when new
- * input comes in
- * @param application TApplication that manages this window
- * @param title window title, will be centered along the top border
- * @param x column relative to parent
- * @param y row relative to parent
- * @param width width of window
- * @param height height of window
- */
- public TWindowBackend(final Object listener,
- final TApplication application, final String title,
- final int x, final int y, final int width, final int height) {
-
- super(application, title, x, y, width, height);
-
- this.listener = listener;
- eventQueue = new LinkedList<TInputEvent>();
- sessionInfo = new TSessionInfo(width, height);
- otherScreen = new LogicalScreen();
- otherScreen.setDimensions(width - 2, height - 2);
- drawLock = otherScreen;
- }
-
- /**
- * Public constructor.
- *
- * @param listener the object this backend needs to wake up when new
- * input comes in
- * @param application TApplication that manages this window
- * @param title window title, will be centered along the top border
- * @param x column relative to parent
- * @param y row relative to parent
- * @param width width of window
- * @param height height of window
- * @param flags mask of RESIZABLE, CENTERED, or MODAL
- */
- public TWindowBackend(final Object listener,
- final TApplication application, final String title,
- final int x, final int y, final int width, final int height,
- final int flags) {
-
- super(application, title, x, y, width, height, flags);
-
- this.listener = listener;
- eventQueue = new LinkedList<TInputEvent>();
- sessionInfo = new TSessionInfo(width, height);
- otherScreen = new LogicalScreen();
- otherScreen.setDimensions(width - 2, height - 2);
- drawLock = otherScreen;
- }
-
- /**
- * Subclasses must provide an implementation that syncs the logical
- * screen to the physical device.
- */
- public void flushScreen() {
- // NOP
- }
-
- /**
- * Subclasses must provide an implementation to get keyboard, mouse, and
- * screen resize events.
- *
- * @param queue list to append new events to
- */
- public void getEvents(List<TInputEvent> queue) {
- synchronized (eventQueue) {
- if (eventQueue.size() > 0) {
- synchronized (queue) {
- queue.addAll(eventQueue);
- }
- eventQueue.clear();
- }
- }
- }
-
- /**
- * Subclasses must provide an implementation that closes sockets,
- * restores console, etc.
- */
- public void shutdown() {
- // NOP
- }
-
- /**
- * Set listener to a different Object.
- *
- * @param listener the new listening object that run() wakes up on new
- * input
- */
- public void setListener(final Object listener) {
- this.listener = listener;
- }
-
- /**
- * Draw the foreground colors grid.
- */
- @Override
- public void draw() {
-
- // Sync on other screen, so that we do not draw in the middle of
- // their screen update.
- synchronized (drawLock) {
- // Draw the box
- super.draw();
-
- // Draw every cell of the other screen
- for (int y = 0; y < otherScreen.getHeight(); y++) {
- for (int x = 0; x < otherScreen.getWidth(); x++) {
- putCharXY(x + 1, y + 1, otherScreen.getCharXY(x, y));
- }
- }
-
- // If the mouse pointer is over the other window, draw its
- // pointer again here. (Their TApplication drew it, then our
- // TApplication drew it again (undo-ing it), so now we draw it a
- // third time so that it is visible.)
- if ((otherMouseX != -1) && (otherMouseY != -1)) {
- CellAttributes attr = getAttrXY(otherMouseX, otherMouseY);
- attr.setForeColor(attr.getForeColor().invert());
- attr.setBackColor(attr.getBackColor().invert());
- putAttrXY(otherMouseX, otherMouseY, attr, false);
- }
-
- // If their cursor is visible, draw that here too.
- if (otherScreen.isCursorVisible()) {
- setCursorX(otherScreen.getCursorX() + 1);
- setCursorY(otherScreen.getCursorY() + 1);
- setCursorVisible(true);
- } else {
- setCursorVisible(false);
- }
- }
- }
-
- /**
- * Subclasses should override this method to cleanup resources. This is
- * called by application.closeWindow().
- */
- public void onClose() {
- // TODO: send a screen disconnect
- }
-
- /**
- * Returns true if the mouse is currently in the otherScreen window.
- *
- * @param mouse mouse event
- * @return true if mouse is currently in the otherScreen window.
- */
- protected boolean mouseOnOtherScreen(final TMouseEvent mouse) {
- if ((mouse.getY() >= 1)
- && (mouse.getY() <= otherScreen.getHeight())
- && (mouse.getX() >= 1)
- && (mouse.getX() <= otherScreen.getWidth())
- ) {
- return true;
- }
- return false;
- }
-
- /**
- * Handle mouse button presses.
- *
- * @param mouse mouse button event
- */
- @Override
- public void onMouseDown(final TMouseEvent mouse) {
- if (mouseOnOtherScreen(mouse)) {
- TMouseEvent event = mouse.dup();
- event.setX(mouse.getX() - 1);
- event.setY(mouse.getY() - 1);
- event.setAbsoluteX(event.getX());
- event.setAbsoluteY(event.getY());
- synchronized (eventQueue) {
- eventQueue.add(event);
- }
- synchronized (listener) {
- listener.notifyAll();
- }
- }
- super.onMouseDown(mouse);
- }
-
- /**
- * Handle mouse button releases.
- *
- * @param mouse mouse button release event
- */
- @Override
- public void onMouseUp(final TMouseEvent mouse) {
- if (mouseOnOtherScreen(mouse)) {
- TMouseEvent event = mouse.dup();
- event.setX(mouse.getX() - 1);
- event.setY(mouse.getY() - 1);
- event.setAbsoluteX(event.getX());
- event.setAbsoluteY(event.getY());
- synchronized (eventQueue) {
- eventQueue.add(event);
- }
- synchronized (listener) {
- listener.notifyAll();
- }
- }
- super.onMouseUp(mouse);
- }
-
- /**
- * Handle mouse movements.
- *
- * @param mouse mouse motion event
- */
- @Override
- public void onMouseMotion(final TMouseEvent mouse) {
- if (mouseOnOtherScreen(mouse)) {
- TMouseEvent event = mouse.dup();
- event.setX(mouse.getX() - 1);
- event.setY(mouse.getY() - 1);
- event.setAbsoluteX(event.getX());
- event.setAbsoluteY(event.getY());
- otherMouseX = event.getX() + 1;
- otherMouseY = event.getY() + 2;
- synchronized (eventQueue) {
- eventQueue.add(event);
- }
- synchronized (listener) {
- listener.notifyAll();
- }
- } else {
- otherMouseX = -1;
- otherMouseY = -1;
- }
- super.onMouseMotion(mouse);
- }
-
- /**
- * Handle keystrokes.
- *
- * @param keypress keystroke event
- */
- @Override
- public void onKeypress(final TKeypressEvent keypress) {
- TKeypressEvent event = keypress.dup();
- synchronized (eventQueue) {
- eventQueue.add(event);
- }
- synchronized (listener) {
- listener.notifyAll();
- }
- }
-
-}