/*
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.dtv.lwuit;
import java.util.Vector;
import org.thenesis.lwuit.configuration.Configuration;
import org.thenesis.lwuit.configuration.ConfigurationProperties;
import org.thenesis.microbackend.ui.BackendEventListener;
import org.thenesis.microbackend.ui.UIBackend;
import org.thenesis.microbackend.ui.UIBackendFactory;
import org.thenesis.microbackend.ui.graphics.VirtualGraphics;
import org.thenesis.microbackend.ui.graphics.VirtualToolkit;
import com.sun.dtv.lwuit.animations.Animation;
import com.sun.dtv.lwuit.animations.Transition;
import com.sun.dtv.lwuit.geom.Rectangle;
import com.sun.dtv.lwuit.util.Log;
/**
* This class implements many of the implementation details related to Display
* that shouldn't be exposed by the API normally. It acts as the canvas, the
* thread for the events and a command listener which are 3 unrelated tasks. The
* purpose of using a single class for these 3 tasks is reduced class count and
* thus reduced overhead.
*
* @author Shai Almog
*/
public class VirtualImplementation implements Runnable {
private static final int POINTER_PRESSED = 1;
private static final int POINTER_RELEASED = 2;
private static final int POINTER_DRAGGED = 3;
private static final int KEY_PRESSED = 4;
private static final int KEY_RELEASED = 5;
private static final int SIZE_CHANGED = 7;
public static final int SYSTEM_KEY_BACKSPACE = -2;
public static final int SYSTEM_KEY_DELETE = -3;
/**
* The command used for accepting a text field change
*/
private static Command CONFIRM_COMMAND;
/**
* Indicates the maximum drawing speed of no more than 10 frames per second
* by defult (this can be increased or decreased) the advantage of limiting
* framerate is to allow the CPU to perform other tasks besides drawing.
* Notice that when no change is occuring on the screen no frame is drawn
* and so a high/low FPS will have no effect then.
*/
private int framerateLock = 30;
/**
* The command used for canceling a text field change
*/
private static Command CANCEL_COMMAND;
/**
* The currently edited text box used to input into text field, this is a
* MIDP implementation detail.
*/
// private TextBox currentTextBox;
/**
* The currently edited text component that will be updated after the
* dismissal of the text box
*/
private Component currentTextComponent;
private boolean flushGraphicsBug;
private int transitionDelay;
private Graphics wrapper;
/**
* Elements waiting for a paint
*/
// private Vector paintQueue = new Vector();
private Animation[] paintQueue = new Animation[50];
private Animation[] paintQueueTemp = new Animation[50];
private int paintQueueFill = 0;
/**
* Events to broadcast on the EDT
*/
private Vector inputEvents = new Vector();
// private static javax.microedition.lcdui.Display display;
private boolean keyRepeatCharged;
private long nextKeyRepeatEvent;
private int keyRepeatValue;
private int keyRepeatInitialIntervalTime = 800;
private int keyRepeatNextIntervalTime = 10;
private RunnableWrapper waitForEdit;
private boolean block = false;
private char lastKeyChar;
private int lastKeyPressed;
private EventMapper eventMapper = new GenericEventMapper();
private VirtualBackendEventListener backendEventListener = new VirtualBackendEventListener();
private VirtualToolkit virtualToolkit;
void init(Object m) {
//Copy LWUIT config in the MicroBackend config
ConfigurationProperties properties = Configuration.getAllProperties();
org.thenesis.microbackend.ui.Configuration microBackendConfig = new org.thenesis.microbackend.ui.Configuration();
for (int i = 0; i < properties.size(); i++) {
microBackendConfig.addParameter(properties.getKeyAt(i), properties.getValueAt(i));
}
virtualToolkit = VirtualToolkit.getToolkit();
virtualToolkit.initialize(m, microBackendConfig, backendEventListener);
wrapper = new Graphics();
wrapper.setGraphics(getGraphics());
setSoftKeyCodes();
}
/**
* Plays sound for the dialog
*/
void playDialogSound(final int type) {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.playDialogSound(): not implemented yet");
// TYPES[type - 1].playSound(display);
}
// void confirmControlsView() {
// if(display == null){
// throw new IllegalStateException(
// "First call Display.setDisplay(javax.microedition.lcdui.Display d) method"
// );
// }
// if(display.getCurrent() != this){
// setCurrent(this);
// }
// }
// private void setCurrent(Displayable d){
// if(display == null){
// throw new IllegalStateException(
// "First call Display.setDisplay(javax.microedition.lcdui.Display d) method"
// );
// }
// if(d instanceof Canvas){
// ((Canvas)d).setFullScreenMode(true);
// }
// display.setCurrent(d);
// }
/**
* Vibrates the device for the given length of time
*
* @param duration
* length of time to vibrate
*/
public void vibrate(int duration) {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.vibrate()");
// display.vibrate(duration);
}
/**
* Flash the backlight of the device for the given length of time
*
* @param duration
* length of time to flash the backlight
*/
public void flashBacklight(int duration) {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.flashBacklight()");
// display.flashBacklight(duration);
}
/**
* Indicates the maximum frames the API will try to draw every second by
* defult this is set to 10. The advantage of limiting framerate is to allow
* the CPU to perform other tasks besides drawing. Notice that when no
* change is occuring on the screen no frame is drawn and so a high/low FPS
* will have no effect then. 10FPS would be very reasonable for a business
* application.
*
* @param rate
* the frame rate
*/
public void setFramerate(int rate) {
framerateLock = 1000 / rate;
}
/**
* Indicates the maximum frames the API will try to draw every second
*
* @return the frame rate
*/
public int getFrameRate() {
return 1000 / framerateLock;
}
int getDisplayWidth() {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.getDisplayWidth(): " + getWidth());
return getWidth() - 1;
}
int getDisplayHeight() {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.getDisplayWidth(): " + getHeight());
return getHeight() - 1;
}
private void setSoftKeyCodes() {
// Initialy set known key codes
Form.leftSK = eventMapper.getSoftLeftKeyCode();
Form.rightSK = eventMapper.getSoftRightKeyCode();
Form.rightSK2 = eventMapper.getSoftRight2KeyCode();
Form.clearSK = eventMapper.getClearKeyCode();
Form.backSK = eventMapper.getBackKeyCode();
try {
// if the back key is assigned to a game action by mistake then
// workaround it implicitly
int game = getGameAction(Form.backSK);
if (game == Display.GAME_UP || game == Display.GAME_DOWN || game == Display.GAME_RIGHT || game == Display.GAME_LEFT
|| game == Display.GAME_FIRE) {
Form.backSK = -50000;
}
} catch (Exception ok) {
}
try {
// if the clear key is assigned to a game action by mistake then
// workaround it implicitly
int game = getGameAction(Form.clearSK);
if (game == Display.GAME_UP || game == Display.GAME_DOWN || game == Display.GAME_RIGHT || game == Display.GAME_LEFT
|| game == Display.GAME_FIRE) {
Form.clearSK = -50000;
}
} catch (Exception ok) {
}
}
public VirtualImplementation() {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.<init>()");
// super(false);
// setTitle(null);
// setFullScreenMode(true);
// // disable the flashGraphics bug on Nokia phones
// if(System.getProperty("microedition.platform").toUpperCase().indexOf(
// "NOKIA") >= 0) {
// flushGraphicsBug = false;
//
// // Symbian devices should yield a bit to let the paint thread
// complete its work
// // problem is we can't differentiate S40 from S60...
// transitionDelay = 1;
// } else {
// flushGraphicsBug = true;
// transitionDelay = -1;
// }
flushGraphicsBug = true;
transitionDelay = -1;
// TODO Remove
// wrapper.setGraphics(getGraphics());
}
/**
* Indicate to the implementation whether the flush graphics bug exists on
* this device. By default the flushGraphics bug is set to "true" and only
* disabled on handsets known 100% to be safe
*
* @param flushGraphicsBug
* true if the bug exists on this device (the safe choice) false
* for slightly higher performance.
*/
public void setFlashGraphicsBug(boolean flushGraphicsBug) {
this.flushGraphicsBug = flushGraphicsBug;
}
/**
* Indicates whether a delay should exist between calls to flush graphics
* during transition. In some devices flushGraphics is asynchronious causing
* it to be very slow with our background thread. The solution is to add a
* short wait allowing the implementation time to paint the screen. This
* value is set automatically by default but can be overriden for some
* devices.
*
* @param transitionDelay
* -1 for no delay otherwise delay in milliseconds
*/
public void setTransitionYield(int transitionDelay) {
this.transitionDelay = transitionDelay;
}
/**
* Encapsulates the editing code which is specific to the platform, some
* platforms would allow "in place editing" MIDP does not.
*
* @param cmp
* the {@link TextArea} component
*/
void editString(Component cmp, int maxSize, int constraint, String text) {
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.editString()");
EditForm editForm = new EditForm(this, Display.getInstance().getCurrent(), (TextArea) cmp);
Display.getInstance().setCurrent(editForm);
}
/**
* Returns the video control for the media player
*
* @param player
* the media player
* @return the video control for the media player
*/
Object getVideoControl(Object player) {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.getVideoControl()");
return null;
// VideoControl vidc =
// (VideoControl)((Player)player).getControl("VideoControl");
// vidc.initDisplayMode(vidc.USE_DIRECT_VIDEO, this);
// return vidc;
}
/**
* Return the number of alpha levels supported by the implementation.
*
* @return the number of alpha levels supported by the implementation
*/
public int numAlphaLevels() {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.numAlphaLevels()");
return 0;
// return display.numAlphaLevels();
}
/**
* Returns the number of colors applicable on the device, note that the API
* does not support gray scale devices.
*
* @return the number of colors applicable on the device
*/
public int numColors() {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.numColors()");
return 1 << 24;
// return display.numColors();
}
protected void showNotify() {
Form current = Display.getInstance().getCurrentInternal();
if (current != null) {
current.showNotify();
}
}
protected void hideNotify() {
Form current = Display.getInstance().getCurrentInternal();
if (current != null) {
current.hideNotify();
}
}
/**
* Invoked by the EDT to paint the dirty regions
*/
void paintDirty() {
int size = 0;
synchronized (Display.lock) {
size = paintQueueFill;
Animation[] array = paintQueue;
paintQueue = paintQueueTemp;
paintQueueTemp = array;
paintQueueFill = 0;
}
if (size > 0) {
wrapper.setGraphics(getGraphics());
int topX = getWidth();
int topY = getHeight();
int bottomX = 0;
int bottomY = 0;
for (int iter = 0; iter < size; iter++) {
Animation ani = paintQueueTemp[iter];
paintQueueTemp[iter] = null;
wrapper.translate(-wrapper.getTranslateX(), -wrapper.getTranslateY());
wrapper.setClip(0, 0, getWidth(), getHeight());
if (ani instanceof Component) {
Component cmp = (Component) ani;
System.out.println(cmp.getUIID() + " <- imprimido");
Rectangle dirty = cmp.getDirtyRegion();
//Rectangle dirty = new Rectangle(0, 0, cmp.getPreferredSize()) ;
if (dirty != null) {
System.out.println(cmp.getUIID() + " <- sujo");
wrapper.setClip(dirty.getX(), dirty.getY(), dirty.getSize().getWidth(), dirty.getSize().getHeight());
cmp.setDirtyRegion(null);
}
cmp.paintComponent(wrapper);
int cmpAbsX = cmp.getAbsoluteX() + cmp.getScrollX();
topX = Math.min(cmpAbsX, topX);
bottomX = Math.max(cmpAbsX + cmp.getWidth(), bottomX);
int cmpAbsY = cmp.getAbsoluteY() + cmp.getScrollY();
topY = Math.min(cmpAbsY, topY);
bottomY = Math.max(cmpAbsY + cmp.getHeight(), bottomY);
} else {
bottomX = getWidth();
bottomY = getHeight();
topX = 0;
topY = 0;
ani.paint(wrapper);
}
}
// disable flush graphics bug when media is playing to prevent the
// double buffer
// from clearing the media and producing flickering
Form current = Display.getInstance().getCurrentInternal();
if (!flushGraphicsBug || (current != null && current.hasMedia())) {
flushGraphics(topX, topY, bottomX - topX, bottomY - topY);
} else {
flushGraphics();
}
}
}
public void repaint(Animation cmp) {
synchronized (Display.lock) {
for (int iter = 0; iter < paintQueueFill; iter++) {
if (paintQueue[iter] == cmp) {
return;
}
}
// overcrowding the queue don't try to grow the array!
if (paintQueueFill >= paintQueue.length) {
System.out.println("Warning paint queue size exceeded, please watch the amount of repaint calls");
return;
}
paintQueue[paintQueueFill] = cmp;
paintQueueFill++;
Display.lock.notify();
}
}
private void addInputEvent(int[] ev) {
synchronized (Display.lock) {
inputEvents.addElement(ev);
Display.lock.notify();
}
}
private int[] createSizeChangedEvent(int w, int h) {
return new int[] { SIZE_CHANGED, w, h };
}
/**
* Creates a pointer event with the following properties
*/
private int[] createPointerEvent(int x, int y, boolean pressed) {
if (pressed) {
return new int[] { POINTER_PRESSED, x, y };
} else {
return new int[] { POINTER_RELEASED, x, y };
}
}
/**
* Creates a pointer event with the following properties
*/
private int[] createPointerDragEvent(int x, int y) {
return new int[] { POINTER_DRAGGED, x, y };
}
private int[] createKeyEvent(int keyCode, boolean pressed) {
if (pressed) {
return new int[] { KEY_PRESSED, keyCode };
} else {
return new int[] { KEY_RELEASED, keyCode };
}
}
protected void sizeChanged(int w, int h) {
Form current = Display.getInstance().getCurrentInternal();
if (current == null) {
return;
}
if (w == getDisplayWidth() && h == getDisplayHeight()) {
return;
}
addInputEvent(createSizeChangedEvent(w, h));
}
/**
* Used by the flush functionality which doesn't care much about component
* animations
*/
public boolean shouldEDTSleepNoFormAnimation() {
Display d = Display.getInstance();
Vector animationQueue = d.getAnimationQueue();
synchronized (Display.lock) {
return (animationQueue == null || animationQueue.size() == 0) && inputEvents.size() == 0 && paintQueueFill == 0
&& d.hasNoSerialCallsPending();
}
}
/**
* Returns true for a case where the EDT has nothing at all to do
*/
public boolean shouldEDTSleep() {
Display d = Display.getInstance();
Vector animationQueue = d.getAnimationQueue();
Form current = d.getCurrentInternal();
return (current == null || (!current.hasAnimations())) && (animationQueue == null || animationQueue.size() == 0)
&& inputEvents.size() == 0 && paintQueueFill == 0 && d.hasNoSerialCallsPending();
}
/**
* Run is used both to invoke the main EDT loop
*/
public void run() {
mainEDTLoop();
//TODO: Remove
System.exit(0);
}
public static boolean PARAR_DE_RODAR = false;
/**
* This method represents the event thread for the UI library on which all
* events are carried out. It differs from the MIDP event thread to prevent
* blocking of actual input and drawing operations. This also enables
* functionality such as "true" modal dialogs etc...
*/
private void mainEDTLoop() {
Vector animationQueue = Display.getInstance().getAnimationQueue();
try {
synchronized (Display.lock) {
// when there is no current form the EDT is useful only
// for features such as call serially
while (Display.getInstance().getCurrentInternal() == null) {
if (shouldEDTSleep()) {
Display.lock.wait();
}
// paint transition or intro animations and don't do
// anything else if such
// animations are in progress...
if (animationQueue != null && animationQueue.size() > 0) {
paintTransitionAnimation();
continue;
}
processSerialCalls();
}
}
} catch (Throwable err) {
err.printStackTrace();
Dialog.show("Error", "An internal application error occured: " + err.toString(), "OK", null);
}
//ADD BY CEBOLA
while (!PARAR_DE_RODAR) {
try {
// wait indefinetly but no more than the framerate if
// there are no animations... If animations exist then
// only wait for the framerate
if (shouldEDTSleep()) {
synchronized (Display.lock) {
Display.lock.wait();
}
}
edtLoopImpl();
} catch (Throwable err) {
err.printStackTrace();
Dialog.show("Error", "An internal application error occured: " + err.toString(), "OK", null);
}
}
}
/**
* Implementation of the event dispatch loop content
*/
public void edtLoopImpl() {
long time = System.currentTimeMillis();
try {
Vector animationQueue = Display.getInstance().getAnimationQueue();
// transitions shouldn't be bound by framerate
if (animationQueue == null || animationQueue.size() == 0) {
// prevents us from waking up the EDT too much and
// thus exhausting the systems resources. The + 1
// prevents us from ever waiting 0 milliseconds which
// is the same as waiting with no time limit
long currentTime = System.currentTimeMillis() + 1;
while (currentTime - time < framerateLock) {
synchronized (Display.lock) {
Display.lock.wait(Math.min(1, framerateLock - (currentTime - time)));
}
currentTime = System.currentTimeMillis() + 1;
}
} else {
// paint transition or intro animations and don't do anything
// else if such
// animations are in progress...
paintTransitionAnimation();
return;
}
} catch (InterruptedException ignor) {
}
while (inputEvents.size() > 0 && !block) {
int[] i = (int[]) inputEvents.elementAt(0);
inputEvents.removeElementAt(0);
handleEvent(i);
}
// draw the animations
Display.getInstance().getCurrentInternal().repaintAnimations();
paintDirty();
// check key repeat events
if (!block && keyRepeatCharged && nextKeyRepeatEvent <= System.currentTimeMillis()) {
Display.getInstance().getCurrentInternal().keyRepeated(keyRepeatValue);
nextKeyRepeatEvent = System.currentTimeMillis() + keyRepeatNextIntervalTime;
}
processSerialCalls();
}
/**
* Restores the menu in the given form
*/
private void restoreMenu(Form f) {
if (f != null) {
f.restoreMenu();
}
}
private void paintTransitionAnimation() {
Vector animationQueue = Display.getInstance().getAnimationQueue();
Animation ani = (Animation) animationQueue.elementAt(0);
if (!ani.animate()) {
animationQueue.removeElementAt(0);
if (ani instanceof Transition) {
Form current = Display.getInstance().getCurrentInternal();
Form source = (Form) ((Transition) ani).getSource();
restoreMenu(source);
Form f = (Form) ((Transition) ani).getDestination();
restoreMenu(f);
if (source == null || source == current || source == Display.getInstance().getCurrent()) {
Display.getInstance().setCurrentForm(f);
}
((Transition) ani).cleanup();
if (animationQueue.size() > 0) {
ani = (Animation) animationQueue.elementAt(0);
if (ani instanceof Transition) {
((Transition) ani).initTransition();
}
}
return;
}
}
ani.paint(wrapper);
flushGraphics();
if (transitionDelay > 0) {
// yield for a fraction, some devices don't "properly" implement
// flush and so require the painting thread to get CPU too.
try {
synchronized (Display.lock) {
Display.lock.wait(transitionDelay);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
/**
* Used by the EDT to process all the calls submitted via call serially
*/
private void processSerialCalls() {
Display.getInstance().processSerialCalls();
}
/**
* Invoked on the EDT to propagate the event
*/
private void handleEvent(int[] ev) {
switch (ev[0]) {
case KEY_PRESSED:
Display.getInstance().getCurrentInternal().keyPressed(ev[1]);
break;
case KEY_RELEASED:
Display.getInstance().getCurrentInternal().keyReleased(ev[1]);
break;
case POINTER_PRESSED:
Display.getInstance().getCurrentInternal().pointerPressed(ev[1], ev[2]);
break;
case POINTER_RELEASED:
Display.getInstance().getCurrentInternal().pointerReleased(ev[1], ev[2]);
break;
case POINTER_DRAGGED:
Display.getInstance().getCurrentInternal().pointerDragged(ev[1], ev[2]);
break;
case SIZE_CHANGED:
Display.getInstance().getCurrentInternal().sizeChanged(ev[1], ev[2]);
break;
}
}
void blockEvents(boolean block) {
this.block = block;
}
// /**
// * This method is used for text input purposes only
// */
// public void commandAction(Command c, Displayable d) {
// if (d == currentTextBox) {
// if (c == CONFIRM_COMMAND) {
// // confirm
// String text = currentTextBox.getString();
// currentTextComponent.onEditComplete(text);
// currentTextComponent.fireActionEvent();
// }
// currentTextBox = null;
//Display.getInstance().setCurrentForm(currentTextComponent.getComponentForm
// ());
// waitForEdit.setDone(true);
// }
// }
//
public void saveTextBox() {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.saveTextBox(): not implemented yet");
// String text = currentTextBox.getString();
// currentTextComponent.onEditComplete(text);
// currentTextComponent.fireActionEvent();
// currentTextBox = null;
// waitForEdit.setDone(true);
}
/* TODO Implement me */
private int getWidth() {
// TODO
//return 210;
return virtualToolkit.getWidth();
}
private int getHeight() {
// TODO
//return 640;
return virtualToolkit.getHeight();
}
private void flushGraphics() {
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.flushGraphics()");
virtualToolkit.flushGraphics(0, 0, getWidth(), getHeight());
}
private void flushGraphics(int topX, int topY, int i, int j) {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.flushGraphics(int topX, int topY, int i, int j): not implemented yet");
}
private VirtualGraphics getGraphics() {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.getGraphics()");
VirtualGraphics g = virtualToolkit.getRootGraphics();
return g;
}
public boolean hasPointerEvents() {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.hasPointerEvents(): not implemented yet");
return true;
}
public int getGameAction(int keyCode) {
// TODO
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualImplementation.getGameAction()");
return eventMapper.getGameAction(keyCode);
}
char getLastKeyChar() {
return lastKeyChar;
}
EventMapper getEventMapper() {
return eventMapper;
}
VirtualToolkit getVirtualToolkit() {
return virtualToolkit;
}
/**
* Listens events coming from the UIBackend and send it to the event queue
*/
private class VirtualBackendEventListener implements BackendEventListener {
private boolean dragEnabled = false;
public VirtualBackendEventListener() {
}
public void keyPressed(int keyCode, char c, int modifiers) {
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualBackendEventListener.keyPressed(): keyCode=" + keyCode + " c=" + c);
Form current = Display.getInstance().getCurrentInternal();
if (current == null) {
return;
}
addInputEvent(createKeyEvent(keyCode, true));
keyRepeatCharged = true;
keyRepeatValue = keyCode;
nextKeyRepeatEvent = System.currentTimeMillis() + keyRepeatInitialIntervalTime;
lastKeyPressed = keyCode;
lastKeyChar = c;
}
public void keyReleased(int keyCode, char c, int modifiers) {
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualBackendEventListener.keyReleased(): keyCode=" + keyCode + " c=" + c);
keyRepeatCharged = false;
Form current = Display.getInstance().getCurrentInternal();
if (current == null) {
return;
}
// this can happen when traversing from the native form to the
// current
// form
// caused by a keypress
if (keyCode != lastKeyPressed) {
return;
}
addInputEvent(createKeyEvent(keyCode, false));
}
public void mouseMoved(int x, int y, int modifiers) {
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualBackendEventListener.mouseMoved(): x=" + x + " y=" + y + " drag enabled ? "
+ dragEnabled);
if (dragEnabled) {
Form current = Display.getInstance().getCurrentInternal();
if (current == null) {
return;
}
addInputEvent(createPointerDragEvent(x, y));
}
}
public void mousePressed(int x, int y, int modifiers) {
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualBackendEventListener.mousePressed(): x=" + x + " y=" + y);
dragEnabled = true;
Form current = Display.getInstance().getCurrentInternal();
if (current == null) {
return;
}
addInputEvent(createPointerEvent(x, y, true));
}
public void mouseReleased(int x, int y, int modifiers) {
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualBackendEventListener.mouseReleased(): x=" + x + " y=" + y);
dragEnabled = false;
Form current = Display.getInstance().getCurrentInternal();
if (current == null) {
return;
}
addInputEvent(createPointerEvent(x, y, false));
}
public void windowClosed() {
if (Log.TRACE_ENABLED)
System.out.println("[DEBUG] VirtualBackendEventListener.windowClosed(): Window delete event received");
}
}
}