GameCanvasImplementation.java
上传用户:haobig99
上传日期:2022-06-15
资源大小:369k
文件大小:42k
源码类别:

J2ME

开发平台:

Java

  1. /*
  2.  * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
  3.  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4.  *
  5.  * This code is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License version 2 only, as
  7.  * published by the Free Software Foundation.  Sun designates this
  8.  * particular file as subject to the "Classpath" exception as provided
  9.  * by Sun in the LICENSE file that accompanied this code.
  10.  *
  11.  * This code is distributed in the hope that it will be useful, but WITHOUT
  12.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14.  * version 2 for more details (a copy is included in the LICENSE file that
  15.  * accompanied this code).
  16.  *
  17.  * You should have received a copy of the GNU General Public License version
  18.  * 2 along with this work; if not, write to the Free Software Foundation,
  19.  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20.  *
  21.  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22.  * CA 95054 USA or visit www.sun.com if you need additional information or
  23.  * have any questions.
  24.  */
  25. package com.sun.lwuit.impl.midp;
  26. import com.sun.lwuit.Component;
  27. import com.sun.lwuit.Display;
  28. import com.sun.lwuit.Form;
  29. import com.sun.lwuit.TextArea;
  30. import com.sun.lwuit.impl.LWUITImplementation;
  31. import com.sun.lwuit.plaf.UIManager;
  32. import java.io.IOException;
  33. import java.io.InputStream;
  34. import javax.microedition.lcdui.AlertType;
  35. import javax.microedition.lcdui.Canvas;
  36. import javax.microedition.lcdui.Command;
  37. import javax.microedition.lcdui.CommandListener;
  38. import javax.microedition.lcdui.Displayable;
  39. import javax.microedition.lcdui.TextBox;
  40. import javax.microedition.lcdui.game.GameCanvas;
  41. import javax.microedition.lcdui.game.Sprite;
  42. import javax.microedition.media.MediaException;
  43. import javax.microedition.media.Player;
  44. import javax.microedition.midlet.MIDlet;
  45. import javax.microedition.media.control.VideoControl;
  46. /**
  47.  * An implementation of LWUIT based on game canvas, this is the default implementation
  48.  * class for LWUIT which most customizers should extend to enhance.
  49.  *
  50.  * @author Shai Almog
  51.  */
  52. public class GameCanvasImplementation extends LWUITImplementation {
  53.     private static boolean NOKIA = false;
  54.     private boolean minimized;
  55.     /**
  56.      * On some devices getKeyCode returns numeric values for game actions,
  57.      * this breaks the code since we filter these values. We pick unused 
  58.      * negative values for game keys and assign them to game keys for getKeyCode.
  59.      */
  60.     private static int[] portableKeyCodes;
  61.     private static int[] portableKeyCodeValues;
  62.     private int alpha = 255;
  63.     private int[] rgbArr;
  64.     private Canvas canvas;
  65.     private class C extends GameCanvas implements CommandListener, Runnable {
  66.         private boolean done;
  67.         public void run() {
  68.             while (!done) {
  69.                 synchronized (getDisplayLock()) {
  70.                     try {
  71.                         getDisplayLock().wait(50);
  72.                     } catch (InterruptedException ex) {
  73.                         ex.printStackTrace();
  74.                     }
  75.                 }
  76.             }
  77.         }
  78.         public void setDone(boolean done) {
  79.             this.done = done;
  80.             synchronized (getDisplayLock()) {
  81.                 getDisplayLock().notify();
  82.             }
  83.         }
  84.         public void commandAction(Command c, Displayable d) {
  85.             if (d == currentTextBox) {
  86.                 display.setCurrent(canvas);
  87.                 if (c == CONFIRM_COMMAND) {
  88.                     // confirm
  89.                     String text = currentTextBox.getString();
  90.                     Display.getInstance().onEditingComplete(currentTextComponent, text);
  91.                 }
  92.                 currentTextBox = null;
  93.                 ((C)canvas).setDone(true);
  94.             }
  95.         }
  96.         private javax.microedition.lcdui.Graphics gfx;
  97.         C() {
  98.             super(false);
  99.         }
  100.         public javax.microedition.lcdui.Graphics getGraphics() {
  101.             if (gfx == null) {
  102.                 gfx = super.getGraphics();
  103.             }
  104.             return gfx;
  105.         }
  106.         protected void keyPressed(final int keyCode) {
  107.             GameCanvasImplementation.this.keyPressed(keyCode);
  108.         }
  109.         protected void keyReleased(final int keyCode) {
  110.             GameCanvasImplementation.this.keyReleased(keyCode);
  111.         }
  112.         protected void pointerDragged(final int x, final int y) {
  113.             GameCanvasImplementation.this.pointerDragged(x, y);
  114.         }
  115.         protected void pointerPressed(final int x, final int y) {
  116.             GameCanvasImplementation.this.pointerPressed(x, y);
  117.         }
  118.         protected void pointerReleased(final int x, final int y) {
  119.             GameCanvasImplementation.this.pointerReleased(x, y);
  120.         }
  121.         protected void sizeChanged(int w, int h) {
  122.             GameCanvasImplementation.this.sizeChanged(w, h);
  123.         }
  124.         protected void hideNotify() {
  125.             GameCanvasImplementation.this.hideNotify();
  126.         }
  127.         protected void showNotify() {
  128.             GameCanvasImplementation.this.showNotify();
  129.         }
  130.         
  131.         
  132.     }
  133.     private static final AlertType[] TYPES = new AlertType[]{
  134.         AlertType.ALARM, AlertType.CONFIRMATION, AlertType.ERROR,
  135.         AlertType.INFO, AlertType.WARNING
  136.     };
  137.     /**
  138.      * The command used for accepting a text field change
  139.      */
  140.     static Command CONFIRM_COMMAND;
  141.     /**
  142.      * The command used for canceling a text field change
  143.      */
  144.     static Command CANCEL_COMMAND;
  145.     /**
  146.      * The currently edited text box used to input into text field, this is a MIDP implementation
  147.      * detail.
  148.      */
  149.     TextBox currentTextBox;
  150.     /**
  151.      * The currently edited text component that will be updated after the dismissal
  152.      * of the text box
  153.      */
  154.     Component currentTextComponent;
  155.     private boolean flushGraphicsBug;
  156.     static javax.microedition.lcdui.Display display;
  157.     /**
  158.      * This member holds the left soft key value
  159.      */
  160.     static int[] leftSK = new int[]{-6};
  161.     /**
  162.      * This member holds the right soft key value
  163.      */
  164.     static int[] rightSK = new int[]{-7};
  165.     /**
  166.      * This member holds the back command key value
  167.      */
  168.     static int backSK = -11;
  169.     /**
  170.      * This member holds the clear command key value
  171.      */
  172.     static int clearSK = -8;
  173.     static int backspaceSK = -8;
  174.     /**
  175.      * This flag indicates if the drawRGB method is able to draw negative x and y
  176.      * In drawRGB method, some devices such as BlackBerry throw exceptions if you
  177.      * try to give negative values to drawRGB method.
  178.      */
  179.     private static boolean drawNegativeOffsetsInRGB = true;
  180.     /**
  181.      * Allows a subclass to create its own canvas implemention
  182.      * 
  183.      * @return the canvas implementation
  184.      */
  185.     protected Canvas createCanvas() {
  186.         return new C();
  187.     }
  188.     public GameCanvasImplementation() {
  189.         // code should be in the init to allow assignment into implementation first
  190.     }
  191.     /**
  192.      * @inheritDoc
  193.      */
  194.     public int getKeyboardType() {
  195.         // See http://wiki.forum.nokia.com/index.php/How_to_utilize_different_keyboards_in_Java_ME for details on
  196.         // Nokia keyboard types
  197.         String keyboardType = System.getProperty("com.nokia.keyboard.type");
  198.         if(keyboardType != null) {
  199.             if("None".equalsIgnoreCase(keyboardType)) {
  200.                 return Display.KEYBOARD_TYPE_VIRTUAL;
  201.             }
  202.             if("PhoneKeypad".equalsIgnoreCase(keyboardType)) {
  203.                 return Display.KEYBOARD_TYPE_NUMERIC;
  204.             }
  205.             if("HalfKeyboard".equalsIgnoreCase(keyboardType)) {
  206.                 return Display.KEYBOARD_TYPE_HALF_QWERTY;
  207.             }
  208.             if("FullKeyboard".equalsIgnoreCase(keyboardType)) {
  209.                 return Display.KEYBOARD_TYPE_QWERTY;
  210.             }
  211.             if("LimitedKeyboard4x10".equalsIgnoreCase(keyboardType)) {
  212.                 return Display.KEYBOARD_TYPE_QWERTY;
  213.             }
  214.             if("LimitedKeyboard3x11".equalsIgnoreCase(keyboardType)) {
  215.                 return Display.KEYBOARD_TYPE_QWERTY;
  216.             }
  217.         }
  218.         return super.getKeyboardType();
  219.     }
  220.     /**
  221.      * @inheritDoc
  222.      */
  223.     public void init(Object m) {
  224.         canvas = createCanvas();
  225.         canvas.setTitle(null);
  226.         canvas.setFullScreenMode(true);
  227.         // disable the flashGraphics bug on Nokia phones
  228.         String platform = System.getProperty("microedition.platform");
  229.         if (platform != null && platform.toUpperCase().indexOf("NOKIA") >= 0) {
  230.             flushGraphicsBug = false;
  231.             NOKIA = true;
  232.             // Symbian devices should yield a bit to let the paint thread complete its work
  233.             // problem is we can't differentiate S40 from S60...
  234.             Display.getInstance().setTransitionYield(1);
  235.         } else {
  236.             flushGraphicsBug = true;
  237.             Display.getInstance().setTransitionYield(-1);
  238.         }
  239.         display = javax.microedition.lcdui.Display.getDisplay((MIDlet) m);
  240.         setSoftKeyCodes((MIDlet) m);
  241.     }
  242.     private void setSoftKeyCodes(MIDlet m) {
  243.         // initialy set known key codes
  244.         setKnownSoftKeyCodes();
  245.         try {
  246.             // if the back key is assigned to a game action by mistake then
  247.             // workaround it implicitly
  248.             int game = getGameAction(backSK);
  249.             if (game == GameCanvas.UP || game == GameCanvas.DOWN || game == GameCanvas.RIGHT ||
  250.                     game == GameCanvas.LEFT || game == GameCanvas.FIRE) {
  251.                 backSK = -50000;
  252.             }
  253.         } catch (Exception ok) {
  254.         }
  255.         try {
  256.             // if the clear key is assigned to a game action by mistake then
  257.             // workaround it implicitly
  258.             int game = getGameAction(clearSK);
  259.             if (game == GameCanvas.UP || game == GameCanvas.DOWN || game == GameCanvas.RIGHT ||
  260.                     game == GameCanvas.LEFT || game == GameCanvas.FIRE) {
  261.                 clearSK = -50000;
  262.             }
  263.             game = getGameAction(backspaceSK);
  264.             if (game == GameCanvas.UP || game == GameCanvas.DOWN || game == GameCanvas.RIGHT ||
  265.                     game == GameCanvas.LEFT || game == GameCanvas.FIRE) {
  266.                 backspaceSK = -50000;
  267.             }
  268.         } catch (Exception ok) {
  269.         }
  270.         // Then Check JAD file for overide specific key mapping
  271.         String tmpSoftKey = m.getAppProperty("SoftKey-Right");
  272.         if (tmpSoftKey != null && !"".equals(tmpSoftKey)) {
  273.             rightSK[0] = Integer.valueOf(tmpSoftKey).intValue();
  274.         }
  275.         tmpSoftKey = m.getAppProperty("SoftKey-Right2");
  276.         if (tmpSoftKey != null && !"".equals(tmpSoftKey)) {
  277.             rightSK = new int[]{rightSK[0], Integer.valueOf(tmpSoftKey).intValue()};
  278.         }
  279.         tmpSoftKey = m.getAppProperty("SoftKey-Left");
  280.         if (tmpSoftKey != null && !"".equals(tmpSoftKey)) {
  281.             leftSK[0] = Integer.valueOf(tmpSoftKey).intValue();
  282.         }
  283.         tmpSoftKey = m.getAppProperty("SoftKey-Back");
  284.         if (tmpSoftKey != null && !"".equals(tmpSoftKey)) {
  285.             backSK = Integer.valueOf(tmpSoftKey).intValue();
  286.         }
  287.         tmpSoftKey = m.getAppProperty("SoftKey-Clear");
  288.         if (tmpSoftKey != null && !"".equals(tmpSoftKey)) {
  289.             clearSK = Integer.valueOf(tmpSoftKey).intValue();
  290.         }
  291.         tmpSoftKey = m.getAppProperty("SoftKey-Backspace");
  292.         if (tmpSoftKey != null && !"".equals(tmpSoftKey)) {
  293.             backspaceSK = Integer.valueOf(tmpSoftKey).intValue();
  294.         }
  295. // Check Third Soft Button is supported        
  296.         tmpSoftKey = m.getAppProperty("isThirdSoftButtonSupported");
  297.         if (tmpSoftKey != null && "true".equals(tmpSoftKey.toLowerCase().trim())) {
  298.             Display.getInstance().setThirdSoftButton(true);
  299.         }
  300.     }
  301.     private void setKnownSoftKeyCodes() {
  302.         try {
  303.             Class.forName("com.siemens.mp.game.Light");
  304.             leftSK[0] = -1;
  305.             rightSK[0] = -4;
  306.             clearSK = -12;
  307.             backspaceSK = -12;
  308.             return;
  309.         } catch (ClassNotFoundException _ex) {
  310.         }
  311.         try {
  312.             Class.forName("com.motorola.phonebook.PhoneBookRecord");
  313.             leftSK[0] = -21;
  314.             rightSK[0] = -22;
  315.             return;
  316.         //maybe Motorola A1000 has different keyCodes
  317.         //Left soft key: Key code -10,
  318.         //Right soft key: Key code -11,
  319.         } catch (ClassNotFoundException _ex) {
  320.         }
  321.         try {
  322.             Class.forName("com.nokia.mid.ui.FullCanvas");
  323.             leftSK[0] = -6;
  324.             rightSK[0] = -7;
  325.             clearSK = -8;
  326.             backspaceSK = -8;
  327.             // prevent this from breaking Sony Ericsson devices
  328.             String p = System.getProperty("microedition.platform");
  329.             if (p != null && p.toUpperCase().indexOf("NOKIA") >= 0) {
  330.                 backspaceSK = 8;
  331.             }
  332.             return;
  333.         } catch (Throwable ex) {
  334.         }
  335.         try {
  336.             Class.forName("net.rim.device.api.system.Application");
  337.             //there are no soft keys on the Blackberry
  338.             //instead use the Q and P keys
  339.             leftSK[0] = 113;
  340.             //some BB devices use O as the most right key
  341.             rightSK = new int[]{112, 111};
  342.             clearSK = 8;
  343.             backspaceSK = 8;
  344.             return;
  345.         } catch (ClassNotFoundException ex) {
  346.         }
  347.         // detecting LG  
  348.         try {
  349.             // iden device
  350.             Class.forName("com.mot.iden.util.Base64");
  351.             clearSK = -5000;
  352.             backspaceSK = -5000;
  353.             leftSK[0] = -20;
  354.             rightSK[0] = -21;
  355.             setFireValue(-23);
  356.             return;
  357.         } catch (Throwable ex) {
  358.         }
  359.         try {
  360.             Class.forName("mmpp.media.MediaPlayer");
  361.             clearSK = -204;
  362.             backspaceSK = -204;
  363.         } catch (ClassNotFoundException ex) {
  364.         }
  365.         try {
  366.             if (canvas.getKeyName(-6).toUpperCase().indexOf("SOFT") >= 0) {
  367.                 leftSK[0] = -6;
  368.                 rightSK[0] = -7;
  369.                 return;
  370.             }
  371.             if (canvas.getKeyName(21).toUpperCase().indexOf("SOFT") >= 0) {
  372.                 leftSK[0] = 21;
  373.                 rightSK[0] = 22;
  374.                 return;
  375.             }
  376.         } catch (Exception ex) {
  377.         }
  378.         boolean leftInit = false;
  379.         boolean rightInit = false;
  380.         for (int i = -127; i < 127; i++) {
  381.             if (leftInit && rightInit) {  //I have added this if to avoid unnecessary loops
  382.                 return; //but the main reason is that sometimes after the correct negative values were initialized also positive
  383.             }          // keycodes had "soft" in the name.
  384.             try {
  385.                 if (canvas.getKeyName(i).toUpperCase().indexOf("SOFT") < 0) {
  386.                     continue;
  387.                 }
  388.                 if (canvas.getKeyName(i).indexOf("1") >= 0) {
  389.                     leftSK[0] = i;
  390.                     leftInit = true;
  391.                 }
  392.                 if (canvas.getKeyName(i).indexOf("2") >= 0) {
  393.                     rightSK[0] = i;
  394.                     rightInit = true;
  395.                 }
  396.                 continue;
  397.             } catch (Exception ex) {
  398.             }
  399.         }
  400.     }
  401.     /**
  402.      * Some devices (iden) map the fire key incorrectly, this method allows
  403.      * us to add another button as fire for specific devices.
  404.      * 
  405.      * @param key keyCode to react as fire
  406.      */
  407.     void setFireValue(int key) {
  408.         try {
  409.             getKeyCode(0);
  410.         } catch (Exception ignor) {
  411.         }
  412.         portableKeyCodeValues[4] = key;
  413.     }
  414.     /**
  415.      * @inheritDoc
  416.      */
  417.     public void vibrate(int duration) {
  418.         display.vibrate(duration);
  419.     }
  420.     /**
  421.      * @inheritDoc
  422.      */
  423.     public void flashBacklight(int duration) {
  424.         display.flashBacklight(duration);
  425.     }
  426.     /**
  427.      * @inheritDoc
  428.      */
  429.     public int getDisplayWidth() {
  430.         return canvas.getWidth();
  431.     }
  432.     /**
  433.      * @inheritDoc
  434.      */
  435.     public int getDisplayHeight() {
  436.         return canvas.getHeight();
  437.     }
  438.     /**
  439.      * @inheritDoc
  440.      */
  441.     public void editString(Component cmp, int maxSize, int constraint, String text) {
  442.         UIManager m = UIManager.getInstance();
  443.         CONFIRM_COMMAND = new Command(m.localize("ok", "OK"), Command.OK, 1);
  444.         CANCEL_COMMAND = new Command(m.localize("cancel", "Cancel"), Command.CANCEL, 2);
  445.         currentTextBox = new TextBox("", "", maxSize, TextArea.ANY);
  446.         currentTextBox.setCommandListener((CommandListener)canvas);
  447.         currentTextBox.addCommand(CONFIRM_COMMAND);
  448.         currentTextBox.addCommand(CANCEL_COMMAND);
  449.         currentTextComponent = cmp;
  450.         currentTextBox.setMaxSize(maxSize);
  451.         currentTextBox.setString(text);
  452.         currentTextBox.setConstraints(constraint);
  453.         display.setCurrent(currentTextBox);
  454.         ((C)canvas).setDone(false);
  455.         Display.getInstance().invokeAndBlock(((C)canvas));
  456.     }
  457.     /**
  458.      * @inheritDoc
  459.      */
  460.     public void saveTextEditingState() {
  461.         String text = currentTextBox.getString();
  462.         Display.getInstance().onEditingComplete(currentTextComponent, text);
  463.         currentTextBox = null;
  464.         ((C)canvas).setDone(true);
  465.     }
  466.     /**
  467.      * Indicate to the implementation whether the flush graphics bug exists on this
  468.      * device. By default the flushGraphics bug is set to "true" and only disabled
  469.      * on handsets known 100% to be safe
  470.      * 
  471.      * @param flushGraphicsBug true if the bug exists on this device (the safe choice)
  472.      * false for slightly higher performance.
  473.      */
  474.     public void setFlashGraphicsBug(boolean flushGraphicsBug) {
  475.         this.flushGraphicsBug = flushGraphicsBug;
  476.     }
  477.     /**
  478.      * Allows subclasses to access the canvas
  479.      * 
  480.      * @returns the canvas instance
  481.      */
  482.     protected final Canvas getCanvas() {
  483.         return canvas;
  484.     }
  485.     /**
  486.      * @inheritDoc
  487.      */
  488.     public void flushGraphics(int x, int y, int width, int height) {
  489.         // disable flush graphics bug when media is playing to prevent the double buffer
  490.         // from clearing the media and producing flickering
  491.         Form current = getCurrentForm();
  492.         if (!flushGraphicsBug || (current != null && current.hasMedia())) {
  493.             ((C) canvas).flushGraphics(x, y, width, height);
  494.         } else {
  495.             ((C) canvas).flushGraphics();
  496.         }
  497.     }
  498.     /**
  499.      * @inheritDoc
  500.      */
  501.     public void flushGraphics() {
  502.         ((C) canvas).flushGraphics();
  503.     }
  504.     /**
  505.      * @inheritDoc
  506.      */
  507.     public void getRGB(Object nativeImage, int[] arr, int offset, int x, int y, int width, int height) {
  508.         ((javax.microedition.lcdui.Image) nativeImage).getRGB(arr, offset, width, x, y, width, height);
  509.     }
  510.     /**
  511.      * @inheritDoc
  512.      */
  513.     public Object createImage(
  514.             int[] rgb, int width, int height) {
  515.         return javax.microedition.lcdui.Image.createRGBImage(rgb, width, height, true);
  516.     }
  517.     /**
  518.      * @inheritDoc
  519.      */
  520.     public Object createImage(
  521.             String path) throws IOException {
  522.         return javax.microedition.lcdui.Image.createImage(path);
  523.     }
  524.     /**
  525.      * @inheritDoc
  526.      */
  527.     public Object createImage(
  528.             InputStream i) throws IOException {
  529.         return javax.microedition.lcdui.Image.createImage(i);
  530.     }
  531.     /**
  532.      * @inheritDoc
  533.      */
  534.     public Object createMutableImage(
  535.             int width, int height, int fillColor) {
  536.         javax.microedition.lcdui.Image i = javax.microedition.lcdui.Image.createImage(width, height);
  537.         if (fillColor != 0xffffffff) {
  538.             javax.microedition.lcdui.Graphics g = i.getGraphics();
  539.             g.setColor(fillColor);
  540.             g.fillRect(0, 0, width, height);
  541.             g.drawRect(0, 0, width-1, height-1);
  542.         }
  543.         return i;
  544.     }
  545.     /**
  546.      * @inheritDoc
  547.      */
  548.     public Object createImage(
  549.             byte[] bytes, int offset, int len) {
  550.         return javax.microedition.lcdui.Image.createImage(bytes, offset, len);
  551.     }
  552.     /**
  553.      * @inheritDoc
  554.      */
  555.     public int getImageWidth(Object i) {
  556.         return ((javax.microedition.lcdui.Image) i).getWidth();
  557.     }
  558.     /**
  559.      * @inheritDoc
  560.      */
  561.     public int getImageHeight(Object i) {
  562.         return ((javax.microedition.lcdui.Image) i).getHeight();
  563.     }
  564.     /**
  565.      * @inheritDoc
  566.      */
  567.     public Object scale(
  568.             Object nativeImage, int width, int height) {
  569.         javax.microedition.lcdui.Image image = (javax.microedition.lcdui.Image) nativeImage;
  570.         int srcWidth = image.getWidth();
  571.         int srcHeight = image.getHeight();
  572.         // no need to scale
  573.         if (srcWidth == width && srcHeight == height) {
  574.             return image;
  575.         }
  576.         int[] currentArray = new int[srcWidth];
  577.         int[] destinationArray = new int[width * height];
  578.         scaleArray(image, srcWidth, srcHeight, height, width, currentArray, destinationArray);
  579.         return createImage(destinationArray, width, height);
  580.     }
  581.     private void scaleArray(javax.microedition.lcdui.Image currentImage, int srcWidth, int srcHeight, int height, int width, int[] currentArray, int[] destinationArray) {
  582.         // Horizontal Resize
  583.         int yRatio = (srcHeight << 16) / height;
  584.         int xRatio = (srcWidth << 16) / width;
  585.         int xPos = xRatio / 2;
  586.         int yPos = yRatio / 2;
  587.         // if there is more than 16bit color there is no point in using mutable
  588.         // images since they won't save any memory
  589.         for (int y = 0; y <
  590.                 height; y++) {
  591.             int srcY = yPos >> 16;
  592.             getRGB(currentImage, currentArray, 0, 0, srcY, srcWidth, 1);
  593.             for (int x = 0; x <
  594.                     width; x++) {
  595.                 int srcX = xPos >> 16;
  596.                 int destPixel = x + y * width;
  597.                 if ((destPixel >= 0 && destPixel < destinationArray.length) && (srcX < currentArray.length)) {
  598.                     destinationArray[destPixel] = currentArray[srcX];
  599.                 }
  600.                 xPos += xRatio;
  601.             }
  602.             yPos += yRatio;
  603.             xPos =
  604.                     xRatio / 2;
  605.         }
  606.     }
  607.     /**
  608.      * @inheritDoc
  609.      */
  610.     public void drawImageRotated(Object graphics, Object img, int x, int y, int degrees) {
  611.         javax.microedition.lcdui.Image i = (javax.microedition.lcdui.Image) img;
  612.         int t;
  613.         switch (degrees % 360) {
  614.             case 0:
  615.                 drawImage(graphics, img, x, y);
  616.                 return;
  617.             case 90:
  618.                 t = Sprite.TRANS_ROT90;
  619.                 break;
  620.             case 180:
  621.                 t = Sprite.TRANS_ROT180;
  622.                 break;
  623.             case 270:
  624.                 t = Sprite.TRANS_ROT270;
  625.                 break;
  626.             default:
  627.                 throw new IllegalArgumentException("Unsupported value for drawImageRotated: " + degrees);
  628.         }
  629.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  630.         nativeGraphics.drawRegion(i, 0, 0, i.getWidth(),
  631.                 i.getHeight(), t, x, y,
  632.                 javax.microedition.lcdui.Graphics.TOP | javax.microedition.lcdui.Graphics.LEFT);
  633.     }
  634.     /**
  635.      * @inheritDoc
  636.      */
  637.     public boolean isRotationDrawingSupported() {
  638.         return true;
  639.     }
  640.     /**
  641.      * @inheritDoc
  642.      */
  643.     public int getSoftkeyCount() {
  644.         return 2;
  645.     }
  646.     /**
  647.      * @inheritDoc
  648.      */
  649.     public int[] getSoftkeyCode(int index) {
  650.         if (index == 0) {
  651.             return leftSK;
  652.         }
  653.         if (index == 1) {
  654.             return rightSK;
  655.         }
  656.         return null;
  657.     }
  658.     /**
  659.      * @inheritDoc
  660.      */
  661.     public int getClearKeyCode() {
  662.         return clearSK;
  663.     }
  664.     /**
  665.      * @inheritDoc
  666.      */
  667.     public int getBackspaceKeyCode() {
  668.         return backspaceSK;
  669.     }
  670.     /**
  671.      * @inheritDoc
  672.      */
  673.     public int getBackKeyCode() {
  674.         return backSK;
  675.     }
  676.     /**
  677.      * @inheritDoc
  678.      */
  679.     public int getGameAction(int keyCode) {
  680.         try {
  681.             // prevent game actions from being returned by numeric keypad thus screwing up
  682.             // keypad based navigation and text input
  683.             if (keyCode >= '0' && keyCode <= '9') {
  684.                 return 0;
  685.             }
  686.             if (portableKeyCodes != null) {
  687.                 for (int iter = 0; iter <
  688.                         portableKeyCodeValues.length; iter++) {
  689.                     if (portableKeyCodeValues[iter] == keyCode) {
  690.                         return portableKeyCodes[iter];
  691.                     }
  692.                 }
  693.             }
  694.             return canvas.getGameAction(keyCode);
  695.         } catch (IllegalArgumentException err) {
  696.             // this is a stupid MIDP requirement some implementations throw this
  697.             // exception for some keys
  698.             return 0;
  699.         }
  700.     }
  701.     /**
  702.      * @inheritDoc
  703.      */
  704.     public int getKeyCode(int gameAction) {
  705.         if (portableKeyCodes == null) {
  706.             portableKeyCodes = new int[]{Display.GAME_DOWN, Display.GAME_LEFT, Display.GAME_RIGHT, Display.GAME_UP, Display.GAME_FIRE};
  707.             portableKeyCodeValues = new int[5];
  708.             int currentValue = -500;
  709.             int offset = 0;
  710.             while (offset < portableKeyCodeValues.length) {
  711.                 currentValue--;
  712.                 try {
  713.                     if (canvas.getGameAction(currentValue) != 0) {
  714.                         continue;
  715.                     }
  716.                 } catch (IllegalArgumentException ignor) {
  717.                     // this is good, the game key is unassigned
  718.                 }
  719.                 portableKeyCodeValues[offset] = currentValue;
  720.                 offset++;
  721.             }
  722.         }
  723.         for (int iter = 0; iter <
  724.                 portableKeyCodes.length; iter++) {
  725.             if (portableKeyCodes[iter] == gameAction) {
  726.                 return portableKeyCodeValues[iter];
  727.             }
  728.         }
  729.         return 0;
  730.     }
  731.     /**
  732.      * @inheritDoc
  733.      */
  734.     public boolean isTouchDevice() {
  735.         return canvas.hasPointerEvents();
  736.     }
  737.     /**
  738.      * @inheritDoc
  739.      */
  740.     public void setNativeFont(Object graphics, Object font) {
  741.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  742.         nativeGraphics.setFont(font(font));
  743.     }
  744.     /**
  745.      * @inheritDoc
  746.      */
  747.     public int getClipX(Object graphics) {
  748.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  749.         return nativeGraphics.getClipX();
  750.     }
  751.     /**
  752.      * @inheritDoc
  753.      */
  754.     public int getClipY(Object graphics) {
  755.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  756.         return nativeGraphics.getClipY();
  757.     }
  758.     /**
  759.      * @inheritDoc
  760.      */
  761.     public int getClipWidth(Object graphics) {
  762.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  763.         return nativeGraphics.getClipWidth();
  764.     }
  765.     /**
  766.      * @inheritDoc
  767.      */
  768.     public int getClipHeight(Object graphics) {
  769.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  770.         return nativeGraphics.getClipHeight();
  771.     }
  772.     /**
  773.      * @inheritDoc
  774.      */
  775.     public void setClip(Object graphics, int x, int y, int width, int height) {
  776.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  777.         nativeGraphics.setClip(x, y, width, height);
  778.     }
  779.     /**
  780.      * @inheritDoc
  781.      */
  782.     public void clipRect(Object graphics, int x, int y, int width, int height) {
  783.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  784.         nativeGraphics.clipRect(x, y, width, height);
  785.     }
  786.     /**
  787.      * @inheritDoc
  788.      */
  789.     public void drawLine(Object graphics, int x1, int y1, int x2, int y2) {
  790.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  791.         nativeGraphics.drawLine(x1, y1, x2, y2);
  792.     }
  793.     /**
  794.      * @inheritDoc
  795.      */
  796.     public void fillRect(Object graphics, int x, int y, int w, int h) {
  797.         if (isAlphaGlobal()) {
  798.             javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  799.             nativeGraphics.fillRect(x, y, w, h);
  800.             nativeGraphics.drawRect(x, y, w-1, h-1);
  801.             return;
  802.         }
  803.         if (alpha == 0) {
  804.             return;
  805.         }
  806.         if (alpha == 0xff) {
  807.             javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  808.             nativeGraphics.fillRect(x, y, w, h);
  809.             nativeGraphics.drawRect(x, y, w-1, h-1);
  810.         } else {
  811.             int transparencyLevel = alpha << 24;
  812.             int color = (getColor(graphics) & 0x00FFFFFF);
  813.             color = (color | transparencyLevel);
  814.             if (rgbArr == null || rgbArr.length < w) {
  815.                 rgbArr = new int[w];
  816.             }
  817.             for (int i = 0; i <
  818.                     w; i++) {
  819.                 rgbArr[i] = color;
  820.             }
  821.             int rgbX = x;
  822.             int rgbY = y;
  823.             if (rgbX < 0 && rgbX + w > 0) {
  824.                 w = rgbX + w;
  825.                 rgbX = 0;
  826.             }
  827.             if (w < 0) {
  828.                 return;
  829.             }
  830.             int clipY = getClipY(graphics);
  831.             int clipHeight = getClipHeight(graphics);
  832.             int clipBottomY = clipHeight + clipY;
  833.             for (int i = 0; i < h; i++) {
  834.                 if (rgbX >= 0 && rgbY + i >= 0) {
  835.                     int currentY = rgbY + i;
  836.                     if(currentY >= clipY && currentY <= clipBottomY) {
  837.                         drawRGB(graphics, rgbArr, 0, rgbX, currentY, w, 1, true);
  838.                     }
  839.                 }
  840.             }
  841.         }
  842.     }
  843.     /**
  844.      * @inheritDoc
  845.      */
  846.     public void drawRect(Object graphics, int x, int y, int width, int height) {
  847.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  848.         nativeGraphics.drawRect(x, y, width, height);
  849.     }
  850.     /**
  851.      * @inheritDoc
  852.      */
  853.     public void drawRoundRect(Object graphics, int x, int y, int width, int height, int arcWidth, int arcHeight) {
  854.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  855.         nativeGraphics.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
  856.     }
  857.     /**
  858.      * @inheritDoc
  859.      */
  860.     public void fillRoundRect(Object graphics, int x, int y, int width, int height, int arcWidth, int arcHeight) {
  861.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  862.         nativeGraphics.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
  863.     }
  864.     /**
  865.      * @inheritDoc
  866.      */
  867.     public void fillArc(Object graphics, int x, int y, int width, int height, int startAngle, int arcAngle) {
  868.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  869.         nativeGraphics.fillArc(x, y, width, height, startAngle, arcAngle);
  870.     }
  871.     /**
  872.      * @inheritDoc
  873.      */
  874.     public void drawArc(Object graphics, int x, int y, int width, int height, int startAngle, int arcAngle) {
  875.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  876.         nativeGraphics.drawArc(x, y, width, height, startAngle, arcAngle);
  877.     }
  878.     /**
  879.      * @inheritDoc
  880.      */
  881.     public void setColor(Object graphics, int RGB) {
  882.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  883.         nativeGraphics.setColor(RGB);
  884.     }
  885.     /**
  886.      * @inheritDoc
  887.      */
  888.     public int getColor(Object graphics) {
  889.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  890.         return nativeGraphics.getColor();
  891.     }
  892.     /**
  893.      * @inheritDoc
  894.      */
  895.     public void setAlpha(Object graphics, int alpha) {
  896.         this.alpha = alpha;
  897.     }
  898.     /**
  899.      * @inheritDoc
  900.      */
  901.     public int getAlpha(Object graphics) {
  902.         return alpha;
  903.     }
  904.     /**
  905.      * @inheritDoc
  906.      */
  907.     public void drawString(Object graphics, String str, int x, int y) {
  908.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  909.         nativeGraphics.drawString(str, x, y, javax.microedition.lcdui.Graphics.TOP | javax.microedition.lcdui.Graphics.LEFT);
  910.     }
  911.     /**
  912.      * @inheritDoc
  913.      */
  914.     public void drawImage(Object graphics, Object img, int x, int y) {
  915.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  916.         nativeGraphics.drawImage((javax.microedition.lcdui.Image) img, x, y, javax.microedition.lcdui.Graphics.TOP | javax.microedition.lcdui.Graphics.LEFT);
  917.     }
  918.     /**
  919.      * @inheritDoc
  920.      */
  921.     public void fillTriangle(Object graphics, int x1, int y1, int x2, int y2, int x3, int y3) {
  922.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  923.         nativeGraphics.fillTriangle(x1, y1, x2, y2, x3, y3);
  924.     }
  925.     /**
  926.      * @inheritDoc
  927.      */
  928.     public void drawRGB(Object graphics, int[] rgbData, int offset, int x, int y, int w, int h, boolean processAlpha) {
  929.         javax.microedition.lcdui.Graphics nativeGraphics = (javax.microedition.lcdui.Graphics) graphics;
  930.         int rgbX = x;
  931.         int rgbY = y;
  932.         //if the x or y are positive simply redirect the call to midp Graphics
  933.         if (rgbX >= 0 && rgbY >= 0) {
  934.             nativeGraphics.drawRGB(rgbData, offset, w, rgbX, rgbY, w, h, processAlpha);
  935.             return;
  936.         }
  937.         //first time try to draw with negative indexes
  938.         if (drawNegativeOffsetsInRGB) {
  939.             try {
  940.                 nativeGraphics.drawRGB(rgbData, offset, w, rgbX, rgbY, w, h, processAlpha);
  941.                 return;
  942.             } catch (RuntimeException e) {
  943.                 //if you failed it might be because you tried to paint with negative
  944.                 //indexes
  945.                 drawNegativeOffsetsInRGB = false;
  946.             }
  947.         }
  948.         //if the translate causes us to paint out of the bounds
  949.         //we will paint only the relevant rows row by row to avoid some devices bugs
  950.         //such as BB that fails to paint if the coordinates are negative.
  951.         if (rgbX < 0 && rgbX + w > 0) {
  952.             if (w < rgbData.length) {
  953.                 for (int i = 1; i <=
  954.                         rgbData.length / w; i++) {
  955.                     offset = -rgbX + (w * (i - 1));
  956.                     rgbY++;
  957.                     if (rgbY >= 0) {
  958.                         nativeGraphics.drawRGB(rgbData, offset, (w + rgbX), 0, rgbY, w + rgbX, 1, processAlpha);
  959.                     }
  960.                 }
  961.             }
  962.         }
  963.     }
  964.     /**
  965.      * @inheritDoc
  966.      */
  967.     public Object getVideoControl(
  968.             Object player) {
  969.         VideoControl vidc = (VideoControl) ((Player) player).getControl("VideoControl");
  970.         vidc.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, canvas);
  971.         return vidc;
  972.     }
  973.     /**
  974.      * @inheritDoc
  975.      */
  976.     public int numAlphaLevels() {
  977.         return display.numAlphaLevels();
  978.     }
  979.     /**
  980.      * @inheritDoc
  981.      */
  982.     public int numColors() {
  983.         return display.numColors();
  984.     }
  985.     /**
  986.      * @inheritDoc
  987.      */
  988.     public void playDialogSound(final int type) {
  989.         TYPES[type - 1].playSound(display);
  990.     }
  991.     /**
  992.      * @inheritDoc
  993.      */
  994.     public void confirmControlView() {
  995.         if (display == null) {
  996.             throw new IllegalStateException("First call Display.setDisplay(javax.microedition.lcdui.Display d) method");
  997.         }
  998.         if (display.getCurrent() != canvas || !canvas.isShown()) {
  999.             setCurrent(canvas);
  1000.         }
  1001.     }
  1002.     /**
  1003.      * @inheritDoc
  1004.      */
  1005.     private void setCurrent(Displayable d) {
  1006.         if (display == null) {
  1007.             throw new IllegalStateException("First call Display.setDisplay(javax.microedition.lcdui.Display d) method");
  1008.         }
  1009.         if(!minimized) {
  1010.             if (d instanceof Canvas) {
  1011.                 ((Canvas) d).setFullScreenMode(true);
  1012.             }
  1013.             display.setCurrent(d);
  1014.         }
  1015.     }
  1016.     /**
  1017.      * @inheritDoc
  1018.      */
  1019.     public Object getNativeGraphics() {
  1020.         return ((C) canvas).getGraphics();
  1021.     }
  1022.     /**
  1023.      * @inheritDoc
  1024.      */
  1025.     public Object getNativeGraphics(
  1026.             Object image) {
  1027.         return ((javax.microedition.lcdui.Image) image).getGraphics();
  1028.     }
  1029.     /**
  1030.      * @inheritDoc
  1031.      */
  1032.     public void translate(Object graphics, int x, int y) {
  1033.         // does nothing, we expect translate to occur in the graphics for
  1034.         // better device portability
  1035.     }
  1036.     /**
  1037.      * @inheritDoc
  1038.      */
  1039.     public int getTranslateX(Object graphics) {
  1040.         return 0;
  1041.     }
  1042.     /**
  1043.      * @inheritDoc
  1044.      */
  1045.     public int getTranslateY(Object graphics) {
  1046.         return 0;
  1047.     }
  1048.     /**
  1049.      * @inheritDoc
  1050.      */
  1051.     public int charsWidth(Object nativeFont, char[] ch, int offset, int length) {
  1052.         if(NOKIA) {
  1053.             // charsWidth is MUCH MUCH MUCH slower on S40 devices than stringWidth.
  1054.             return font(nativeFont).stringWidth(new String(ch, offset, length));
  1055.         }
  1056.         return font(nativeFont).charsWidth(ch, offset, length);
  1057.     }
  1058.     /**
  1059.      * @inheritDoc
  1060.      */
  1061.     public int stringWidth(Object nativeFont, String str) {
  1062.         return font(nativeFont).stringWidth(str);
  1063.     }
  1064.     /**
  1065.      * @inheritDoc
  1066.      */
  1067.     public int charWidth(Object nativeFont, char ch) {
  1068.         return font(nativeFont).charWidth(ch);
  1069.     }
  1070.     /**
  1071.      * @inheritDoc
  1072.      */
  1073.     public int getHeight(Object nativeFont) {
  1074.         return font(nativeFont).getHeight();
  1075.     }
  1076.     /**
  1077.      * @inheritDoc
  1078.      */
  1079.     public Object createFont(
  1080.             int face, int style, int size) {
  1081.         return javax.microedition.lcdui.Font.getFont(face, style, size);
  1082.     }
  1083.     /**
  1084.      * @inheritDoc
  1085.      */
  1086.     public Object getDefaultFont() {
  1087.         return javax.microedition.lcdui.Font.getDefaultFont();
  1088.     }
  1089.     /**
  1090.      * @inheritDoc
  1091.      */
  1092.     public int getFace(Object nativeFont) {
  1093.         return font(nativeFont).getFace();
  1094.     }
  1095.     /**
  1096.      * @inheritDoc
  1097.      */
  1098.     public int getSize(Object nativeFont) {
  1099.         return font(nativeFont).getSize();
  1100.     }
  1101.     /**
  1102.      * @inheritDoc
  1103.      */
  1104.     public int getStyle(Object nativeFont) {
  1105.         return font(nativeFont).getStyle();
  1106.     }
  1107.     private javax.microedition.lcdui.Font font(Object f) {
  1108.         if (f == null) {
  1109.             return (javax.microedition.lcdui.Font) getDefaultFont();
  1110.         }
  1111.         return (javax.microedition.lcdui.Font) f;
  1112.     }
  1113.     /**
  1114.      * @inheritDoc
  1115.      */
  1116.     public Object createVideoComponent(
  1117.             Object player) {
  1118.         if (((Player) player).getState() < Player.REALIZED) {
  1119.             throw new IllegalArgumentException("player must be in a realized state");
  1120.         }
  1121.         return getVideoControl(player);
  1122.     }
  1123.     /**
  1124.      * @inheritDoc
  1125.      */
  1126.     public int getVideoWidth(Object videoControl) {
  1127.         return ((VideoControl) videoControl).getSourceWidth();
  1128.     }
  1129.     /**
  1130.      * @inheritDoc
  1131.      */
  1132.     public int getVideoHeight(Object videoControl) {
  1133.         return ((VideoControl) videoControl).getSourceHeight();
  1134.     }
  1135.     /**
  1136.      * @inheritDoc
  1137.      */
  1138.     public void setVideoVisible(Object vc, boolean visible) {
  1139.         ((VideoControl) vc).setVisible(visible);
  1140.     }
  1141.     /**
  1142.      * @inheritDoc
  1143.      */
  1144.     public void startVideo(Object player, Object videoControl) {
  1145.         try {
  1146.             ((VideoControl) videoControl).setVisible(true);
  1147.             ((Player) player).start();
  1148.         } catch (MediaException ex) {
  1149.             ex.printStackTrace();
  1150.         }
  1151.     }
  1152.     /**
  1153.      * @inheritDoc
  1154.      */
  1155.     public void stopVideo(Object player, Object videoControl) {
  1156.         try {
  1157.             ((Player) player).stop();
  1158.         } catch (MediaException ex) {
  1159.             ex.printStackTrace();
  1160.         }
  1161.     }
  1162.     /**
  1163.      * @inheritDoc
  1164.      */
  1165.     public void setVideoLoopCount(Object player, int count) {
  1166.         ((Player) player).setLoopCount(count);
  1167.     }
  1168.     /**
  1169.      * @inheritDoc
  1170.      */
  1171.     public long getMediaTime(Object player) {
  1172.         return ((Player) player).getMediaTime();
  1173.     }
  1174.     /**
  1175.      * @inheritDoc
  1176.      */
  1177.     public long setMediaTime(Object player, long now) {
  1178.         try {
  1179.             return ((Player) player).setMediaTime(now);
  1180.         } catch (MediaException ex) {
  1181.             ex.printStackTrace();
  1182.             throw new RuntimeException(ex.toString());
  1183.         }
  1184.     }
  1185.     /**
  1186.      * @inheritDoc
  1187.      */
  1188.     public void paintVideo(Component cmp, boolean fullScreen, Object nativeGraphics, Object video,
  1189.             Object player) {
  1190.         try {
  1191.             VideoControl vidc = (VideoControl) video;
  1192.             if (fullScreen) {
  1193.                 vidc.setDisplayLocation(0, 0);
  1194.                 vidc.setDisplaySize(Display.getInstance().getDisplayWidth(), Display.getInstance().getDisplayHeight());
  1195.             } else {
  1196.                 vidc.setDisplayLocation(cmp.getAbsoluteX(), cmp.getAbsoluteY());
  1197.                 int w = cmp.getWidth();
  1198.                 int h = cmp.getHeight();
  1199.                 if (vidc.getDisplayWidth() != w || vidc.getDisplayHeight() != h) {
  1200.                     vidc.setDisplaySize(w, h);
  1201.                 }
  1202.             }
  1203.         } catch (MediaException ex) {
  1204.             ex.printStackTrace();
  1205.         }
  1206.     }
  1207.     /**
  1208.      * @inheritDoc
  1209.      */
  1210.     public boolean minimizeApplication() {
  1211.         try {
  1212.             minimized = true;
  1213.             display.setCurrent(null);
  1214.         } catch(Throwable t) {
  1215.             t.printStackTrace();
  1216.         }
  1217.         return false;
  1218.     }
  1219.     /**
  1220.      * @inheritDoc
  1221.      */
  1222.     public void restoreMinimizedApplication() {
  1223.         try {
  1224.             minimized = false;
  1225.             display.setCurrent(canvas);
  1226.         } catch(Throwable t) {
  1227.             t.printStackTrace();
  1228.         }
  1229.     }
  1230.     /**
  1231.      * @inheritDoc
  1232.      */
  1233.     public boolean isMinimized() {
  1234.         return display.getCurrent() == null;
  1235.     }
  1236. }