diff -r 4320db4aa0c1 .classpath --- a/.classpath Mon Oct 17 13:46:01 2011 -0700 +++ b/.classpath Tue Oct 18 00:01:56 2011 -0400 @@ -68,6 +68,7 @@ + diff -r 4320db4aa0c1 javafx-ui-common/project.properties --- a/javafx-ui-common/project.properties Mon Oct 17 13:46:01 2011 -0700 +++ b/javafx-ui-common/project.properties Tue Oct 18 00:01:56 2011 -0400 @@ -10,6 +10,7 @@ ${runtime.deps.dir}/plugin_exports.jar:\ ${runtime.dist.root.dir}/aria/dist/aria.jar:\ ${import.lombok.jar}:\ + ${import.swt.jar}:\ ${jfx.checkstyle.jar} javac.test.additional.classpath=\ ${runtime.dist.root.dir}/prism-common/dist/prism-common.jar diff -r 4320db4aa0c1 javafx-ui-common/src/javafx/embed/swt/FXCanvas.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javafx-ui-common/src/javafx/embed/swt/FXCanvas.java Tue Oct 18 00:01:56 2011 -0400 @@ -0,0 +1,512 @@ +package javafx.embed.swt; + +import java.nio.IntBuffer; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +import com.sun.javafx.cursor.CursorFrame; +import javafx.scene.Scene; + +import com.sun.javafx.application.PlatformImpl; +import com.sun.javafx.embed.AbstractEvents; +import com.sun.javafx.embed.EmbeddedSceneInterface; +import com.sun.javafx.embed.EmbeddedStageInterface; +import com.sun.javafx.embed.HostInterface; +import com.sun.javafx.stage.EmbeddedWindow; + +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; + +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.graphics.Point; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.MouseWheelListener; + +/** + * {@code FXCanvas} is a component to embed JavaFX content into + * SWT applications. The content to be displayed is specified + * with the {@link #setScene} method that accepts an instance of + * JavaFX {@code Scene}. After the scene is assigned, it gets + * repainted automatically. All the input and focus events are + * forwarded to the scene transparently to the developer. + *

+ * Here is a typical pattern how {@code FXCanvas} can used: + *

+ *    public class Test {
+ *        private static Scene createScene() {
+ *            Group group = new Group();
+ *            Scene scene = new Scene(group);
+ *            Button button = new Button("JFX Button");
+ *            group.getChildren().add(button);
+ *            return scene;
+ *        }
+ *    
+ *        public static void main(String[] args) {
+ *            Display display = new Display();
+ *            Shell shell = new Shell(display);
+ *            shell.setLayout(new FillLayout());
+ *            FXCanvas canvas = new FXCanvas(shell, SWT.NONE);
+ *            Scene scene = createScene();
+ *            canvas.setScene(scene);
+ *            shell.open();
+ *            while (!shell.isDisposed()) {
+ *                if (!display.readAndDispatch()) display.sleep();
+ *            }
+ *            display.dispose();
+ *        }
+ *    }
+ * 
+ * + * @author Dmitry Cherepanov + * @author Artem Ananiev + * + */ +public class FXCanvas extends Canvas { + + private HostContainer hostContainer; + private volatile EmbeddedWindow stage; + private volatile Scene scene; + private EmbeddedStageInterface stagePeer; + private EmbeddedSceneInterface scenePeer; + + private int pWidth = 0; + private int pHeight = 0; + + private volatile int pPreferredWidth = -1; + private volatile int pPreferredHeight = -1; + + private IntBuffer pixelsBuf = null; + + /** + * {@inheritDoc} + */ + public FXCanvas(Composite parent, int style) { + super(parent, style | SWT.NO_BACKGROUND); + initFx(); + hostContainer = new HostContainer(); + registerEventListeners(); + } + + private static void initFx() { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + System.setProperty("javafx.macosx.embedded", "true"); + System.setProperty("javafx.embed.isEventThread", "true"); + return null; + } + }); + // Note that calling PlatformImpl.startup more than once is OK + PlatformImpl.startup(new Runnable() { + @Override + public void run() { + } + }); + } + + /** + * {@inheritDoc} + */ + public Point computeSize (int wHint, int hHint, boolean changed) { + checkWidget(); + if (pPreferredWidth != -1 && pPreferredHeight != -1) { + return new Point (pPreferredWidth, pPreferredHeight); + } + return super.computeSize(wHint, hHint, changed); + } + + /** + * Returns the JavaFX scene attached to this {@code FXCanvas}. + * + * @return the {@code Scene} attached to this {@code FXCanvas} + */ + public Scene getScene() { + checkWidget(); + return scene; + } + + /** + * Attaches a {@code Scene} object to display in this {@code + * FXCanvas}. This method must called either on the JavaFX + * JavaFX application thread (which is the same as the SWT + * event dispatch thread). + * + * @param newScene a scene to display in this {@code FXCanvas} + * + * @see javafx.application.Platform#isFxApplicationThread() + */ + public void setScene(final Scene newScene) { + checkWidget(); + + if ((stage == null) && (newScene != null)) { + stage = new EmbeddedWindow(hostContainer); + stage.show(); + } + scene = newScene; + if (stage != null) { + stage.setScene(newScene); + } + if ((stage != null) && (newScene == null)) { + stage.hide(); + stage = null; + } + } + + // Note that removing the listeners is unnecessary + private void registerEventListeners() { + addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent de) { + FXCanvas.this.widgetDisposed(de); + } + }); + + addPaintListener(new PaintListener() { + @Override + public void paintControl(PaintEvent pe) { + FXCanvas.this.paintControl(pe); + } + }); + + addMouseListener(new MouseListener() { + @Override + public void mouseDoubleClick(MouseEvent me) { + // TODO + } + @Override + public void mouseDown(MouseEvent me) { + FXCanvas.this.sendMouseEventToFX(me, AbstractEvents.MOUSEEVENT_PRESSED); + } + @Override + public void mouseUp(MouseEvent me) { + FXCanvas.this.sendMouseEventToFX(me, AbstractEvents.MOUSEEVENT_RELEASED); + } + }); + + addMouseMoveListener(new MouseMoveListener() { + @Override + public void mouseMove(MouseEvent me) { + if ((me.stateMask & SWT.BUTTON_MASK) != 0) { + FXCanvas.this.sendMouseEventToFX(me, AbstractEvents.MOUSEEVENT_DRAGGED); + } else { + FXCanvas.this.sendMouseEventToFX(me, AbstractEvents.MOUSEEVENT_MOVED); + } + } + }); + + addMouseWheelListener(new MouseWheelListener() { + @Override + public void mouseScrolled(MouseEvent me) { + FXCanvas.this.sendMouseEventToFX(me, AbstractEvents.MOUSEEVENT_WHEEL); + } + }); + + addMouseTrackListener(new MouseTrackListener() { + @Override + public void mouseEnter(MouseEvent me) { + FXCanvas.this.sendMouseEventToFX(me, AbstractEvents.MOUSEEVENT_ENTERED); + } + @Override + public void mouseExit(MouseEvent me) { + FXCanvas.this.sendMouseEventToFX(me, AbstractEvents.MOUSEEVENT_EXITED); + } + @Override + public void mouseHover(MouseEvent me) { + //TODO - implement mouse hover + } + }); + + addControlListener(new ControlListener() { + @Override + public void controlMoved(ControlEvent ce) { + FXCanvas.this.sendMoveEventToFX(); + } + @Override + public void controlResized(ControlEvent ce) { + FXCanvas.this.sendResizeEventToFX(); + } + }); + + addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent fe) { + FXCanvas.this.sendFocusEventToFX(fe, true); + } + @Override + public void focusLost(FocusEvent fe) { + FXCanvas.this.sendFocusEventToFX(fe, false); + } + }); + + addKeyListener(new KeyListener() { + @Override + public void keyPressed(KeyEvent e) { + FXCanvas.this.sendKeyEventToFX(e, SWT.KeyDown); + + } + @Override + public void keyReleased(KeyEvent e) { + FXCanvas.this.sendKeyEventToFX(e, SWT.KeyUp); + } + }); + } + + private void widgetDisposed(DisposeEvent de) { + if (stage != null) { + stage.hide(); + } + } + + int lastWidth, lastHeight; + IntBuffer lastPixelsBuf = null; + private void paintControl(PaintEvent pe) { + if ((scenePeer == null) || (pixelsBuf == null)) { + return; + } + + // if we can't get the pixels, draw the bits that were there before + IntBuffer buffer = pixelsBuf; + int width = pWidth, height = pHeight; + if (scenePeer.getPixels(pixelsBuf, pWidth, pHeight)) { + width = lastWidth = pWidth; + height = lastHeight = pHeight; + buffer = lastPixelsBuf = pixelsBuf; + } else { + if (lastPixelsBuf == null) return; + width = lastWidth; + height = lastHeight; + buffer = lastPixelsBuf; + } + + // TODO: consider optimizing this + PaletteData palette = new PaletteData(0x00ff0000, 0x0000ff00, 0x000000ff); + ImageData imageData = new ImageData(width, height, 32, palette); + imageData.setPixels(0, 0,width * height, buffer.array(), 0); + + Image image = new Image(Display.getDefault(), imageData); + pe.gc.drawImage(image, 0, 0); + image.dispose(); + } + + private void sendMoveEventToFX() { + if ((stagePeer == null) /*|| !isShowing()*/) { + return; + } + Point los = toDisplay(getLocation()); + stagePeer.setLocation(los.x, los.y); + } + + private void sendMouseEventToFX(MouseEvent me, int embedMouseType) { + if (scenePeer == null) { + return; + } + + Point los = toDisplay(me.x, me.y); + boolean primaryBtnDown = false, middleBtnDown = false, secondaryBtnDown = false; + switch (embedMouseType) { + case AbstractEvents.MOUSEEVENT_PRESSED: + primaryBtnDown = (me.stateMask & SWT.BUTTON1) != 0 || me.button == 1; + middleBtnDown = (me.stateMask & SWT.BUTTON2) != 0 || me.button == 2; + secondaryBtnDown = (me.stateMask & SWT.BUTTON3) != 0 || me.button == 3; + break; + case AbstractEvents.MOUSEEVENT_RELEASED: + primaryBtnDown = (me.stateMask & SWT.BUTTON1) != 0 && me.button != 1; + middleBtnDown = (me.stateMask & SWT.BUTTON2) != 0 && me.button != 2; + secondaryBtnDown = (me.stateMask & SWT.BUTTON3) != 0 && me.button != 3; + break; + } + scenePeer.mouseEvent( + embedMouseType, + SWTEvents.mouseButtonToEmbedMouseButton(me.button, me.stateMask), + primaryBtnDown, middleBtnDown, secondaryBtnDown, + me.count, + me.x, me.y, + los.x, los.y, + SWTEvents.getWheelRotation(me), false); // TODO: wheel rotation, popup trigger + } + + private void sendKeyEventToFX(final KeyEvent e, int type) { + if (scenePeer == null /*|| !isFxEnabled()*/) { + return; + } + int stateMask = e.stateMask; + if (type == SWT.KeyDown) { + if (e.keyCode == SWT.SHIFT) stateMask |= SWT.SHIFT; + if (e.keyCode == SWT.CONTROL) stateMask |= SWT.CONTROL; + if (e.keyCode == SWT.ALT) stateMask |= SWT.ALT; + if (e.keyCode == SWT.COMMAND) stateMask |= SWT.COMMAND; + } else { + if (e.keyCode == SWT.SHIFT) stateMask &= ~SWT.SHIFT; + if (e.keyCode == SWT.CONTROL) stateMask &= ~SWT.CONTROL; + if (e.keyCode == SWT.ALT) stateMask &= ~SWT.ALT; + if (e.keyCode == SWT.COMMAND) stateMask &= ~SWT.COMMAND; + } + int keyCode = SWTEvents.keyCodeToEmbedKeyCode(e.keyCode); + scenePeer.keyEvent( + SWTEvents.keyIDToEmbedKeyType(type), + keyCode, null, + SWTEvents.keyModifiersToEmbedKeyModifiers(stateMask)); + if (e.character != '\0' && type == SWT.KeyDown) { + char[] chars = new char[] { e.character }; + scenePeer.keyEvent( + AbstractEvents.KEYEVENT_TYPED, + e.keyCode, chars, + SWTEvents.keyModifiersToEmbedKeyModifiers(stateMask)); + } + } + + private void sendResizeEventToFX() { + + // force the panel to draw right away (avoid black rectangle) + redraw(); + update(); + + pWidth = getSize().x; + pHeight = getSize().y; + + if ((pWidth <= 0) || (pHeight <= 0)) { + pixelsBuf = lastPixelsBuf = null; + } else { + pixelsBuf = IntBuffer.allocate(pWidth * pHeight); + } + + if (scenePeer == null) { + return; + } + + stagePeer.setSize(pWidth, pHeight); + scenePeer.setSize(pWidth, pHeight); + } + + private void sendFocusEventToFX(FocusEvent fe, boolean focused) { + if ((stage == null) || (stagePeer == null)) { + return; + } + int focusCause = (focused ? + AbstractEvents.FOCUSEVENT_ACTIVATED : + AbstractEvents.FOCUSEVENT_DEACTIVATED); + stagePeer.setFocused(focused, focusCause); + } + + private class HostContainer implements HostInterface { + + @Override + public void setEmbeddedStage(EmbeddedStageInterface embeddedStage) { + stagePeer = embeddedStage; + if (stagePeer == null) { + return; + } + if (pWidth > 0 && pHeight > 0) { + stagePeer.setSize(pWidth, pHeight); + } + if (FXCanvas.this.isFocusControl()) { + stagePeer.setFocused(true, AbstractEvents.FOCUSEVENT_ACTIVATED); + } + sendMoveEventToFX(); + sendResizeEventToFX(); + } + + @Override + public void setEmbeddedScene(EmbeddedSceneInterface embeddedScene) { + scenePeer = embeddedScene; + if (scenePeer == null) { + return; + } + if (pWidth > 0 && pHeight > 0) { + scenePeer.setSize(pWidth, pHeight); + } + } + + @Override + public boolean requestFocus() { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if (isDisposed()) return; + FXCanvas.this.forceFocus(); + } + }); + return true; + } + + @Override + public boolean traverseFocusOut(boolean bln) { + // TODO - not implemented + return true; + } + + Object lock = new Object(); + boolean queued = false; + public void repaint() { + synchronized (lock) { + if (queued) return; + queued = true; + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + try { + if (isDisposed()) return; + FXCanvas.this.redraw(); + } finally { + synchronized (lock) { + queued = false; + } + } + } + }); + } + } + + @Override + public void setPreferredSize(int width, int height) { + FXCanvas.this.pPreferredWidth = width; + FXCanvas.this.pPreferredHeight = height; + //FXCanvas.this.getShell().layout(new Control []{FXCanvas.this}, SWT.DEFER); + } + + @Override + public void setEnabled(boolean bln) { + FXCanvas.this.setEnabled(bln); + } + + @Override + public void setCursor(CursorFrame cursorFrame) { + FXCanvas.this.setCursor(getPlatformCursor(cursorFrame)); + } + + private org.eclipse.swt.graphics.Cursor getPlatformCursor(final CursorFrame cursorFrame) { + final org.eclipse.swt.graphics.Cursor cachedPlatformCursor = + cursorFrame.getPlatformCursor(org.eclipse.swt.graphics.Cursor.class); + if (cachedPlatformCursor != null) { + // platform cursor already cached + return cachedPlatformCursor; + } + + // platform cursor not cached yet + final org.eclipse.swt.graphics.Cursor platformCursor = + SWTCursors.embedCursorToCursor(cursorFrame); + cursorFrame.setPlatforCursor(org.eclipse.swt.graphics.Cursor.class, platformCursor); + + return platformCursor; + } + } +} diff -r 4320db4aa0c1 javafx-ui-common/src/javafx/embed/swt/SWTCursors.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javafx-ui-common/src/javafx/embed/swt/SWTCursors.java Tue Oct 18 00:01:56 2011 -0400 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + */ + +package javafx.embed.swt; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.widgets.Display; + +import com.sun.javafx.cursor.CursorFrame; +import com.sun.javafx.cursor.ImageCursorFrame; + +/** + * An utility class to translate cursor types between embedded + * application and SWT. + * + */ +class SWTCursors { + + private static Cursor createCustomCursor(ImageCursorFrame cursorFrame) { + //TODO - implement custom cursors + /* + Toolkit awtToolkit = Toolkit.getDefaultToolkit(); + + double imageWidth = cursorFrame.getWidth(); + double imageHeight = cursorFrame.getHeight(); + Dimension nativeSize = awtToolkit.getBestCursorSize((int)imageWidth, (int)imageHeight); + + double scaledHotspotX = cursorFrame.getHotspotX() * nativeSize.getWidth() / imageWidth; + double scaledHotspotY = cursorFrame.getHotspotY() * nativeSize.getHeight() / imageHeight; + Point hotspot = new Point((int)scaledHotspotX, (int)scaledHotspotY); + + final com.sun.javafx.tk.Toolkit fxToolkit = + com.sun.javafx.tk.Toolkit.getToolkit(); + BufferedImage awtImage = + (BufferedImage) fxToolkit.toExternalImage( + cursorFrame.getPlatformImage(), + BufferedImage.class); + + return awtToolkit.createCustomCursor(awtImage, hotspot, null); + */ + return null; + } + + static Cursor embedCursorToCursor(CursorFrame cursorFrame) { + int id = SWT.CURSOR_ARROW; + switch (cursorFrame.getCursorType()) { + case DEFAULT: id = SWT.CURSOR_ARROW; break; + case CROSSHAIR: id = SWT.CURSOR_CROSS; break; + case TEXT: id = SWT.CURSOR_IBEAM; break; + case WAIT: id = SWT.CURSOR_WAIT; break; + case SW_RESIZE: id = SWT.CURSOR_SIZESW; break; + case SE_RESIZE: id = SWT.CURSOR_SIZESE; break; + case NW_RESIZE: id = SWT.CURSOR_SIZENW; break; + case NE_RESIZE: id = SWT.CURSOR_SIZENE; break; + case N_RESIZE: id = SWT.CURSOR_SIZEN; break; + case S_RESIZE: id = SWT.CURSOR_SIZES; break; + case W_RESIZE: id = SWT.CURSOR_SIZEW; break; + case E_RESIZE: id = SWT.CURSOR_SIZEE; break; + case OPEN_HAND: + case CLOSED_HAND: + case HAND: id = SWT.CURSOR_HAND; break; + case MOVE: id = SWT.CURSOR_SIZEALL; break; + case DISAPPEAR: + //TODO - Not implemented + break; + case H_RESIZE: id = SWT.CURSOR_SIZEWE; break; + case V_RESIZE: id = SWT.CURSOR_SIZENS; break; + case NONE: + return null; + case IMAGE: + //TODO - Not implemented +// return createCustomCursor((ImageCursorFrame) cursorFrame); + } + Display display = Display.getCurrent(); + return display != null ? display.getSystemCursor(id) : null; + } +} \ No newline at end of file diff -r 4320db4aa0c1 javafx-ui-common/src/javafx/embed/swt/SWTEvents.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javafx-ui-common/src/javafx/embed/swt/SWTEvents.java Tue Oct 18 00:01:56 2011 -0400 @@ -0,0 +1,256 @@ +package javafx.embed.swt; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseEvent; + +//import com.sun.glass.events.KeyEvent; +import com.sun.javafx.embed.AbstractEvents; + +/** + * An utility class to translate event types between embedded + * application and SWT. + * + * @author Dmitry Cherepanov + */ +class SWTEvents { + +/* + static int mouseIDToEmbedMouseType(int id) { + switch (id) { + case MouseEvent.MOUSE_PRESSED: + return AbstractEvents.MOUSEEVENT_PRESSED; + case MouseEvent.MOUSE_RELEASED: + return AbstractEvents.MOUSEEVENT_RELEASED; + case MouseEvent.MOUSE_CLICKED: + return AbstractEvents.MOUSEEVENT_CLICKED; + case MouseEvent.MOUSE_MOVED: + return AbstractEvents.MOUSEEVENT_MOVED; + case MouseEvent.MOUSE_DRAGGED: + return AbstractEvents.MOUSEEVENT_DRAGGED; + case MouseEvent.MOUSE_ENTERED: + return AbstractEvents.MOUSEEVENT_ENTERED; + case MouseEvent.MOUSE_EXITED: + return AbstractEvents.MOUSEEVENT_EXITED; + case MouseWheelEvent.MOUSE_WHEEL: + return AbstractEvents.MOUSEEVENT_WHEEL; + } + return 0; + } +*/ + //TODO - not tested (are masked needed?) + static int mouseButtonToEmbedMouseButton(int button, int extModifiers) { + int embedMouseButton = AbstractEvents.MOUSEEVENT_NONE_BUTTON; + if ((button == 1) || (extModifiers & SWT.BUTTON1) != 0) { + embedMouseButton |= AbstractEvents.MOUSEEVENT_PRIMARY_BUTTON; + } + if ((button == 2) || (extModifiers & SWT.BUTTON2) != 0) { + embedMouseButton |= AbstractEvents.MOUSEEVENT_MIDDLE_BUTTON; + } + if ((button == 3) || (extModifiers & SWT.BUTTON3) != 0) { + embedMouseButton |= AbstractEvents.MOUSEEVENT_SECONDARY_BUTTON; + } + return embedMouseButton; + } + + static int getWheelRotation(MouseEvent e) { + //TODO - not implemented +// if (e instanceof MouseWheelEvent) { +// return ((MouseWheelEvent)e).getWheelRotation(); +// } + return 0; + } + + static int keyIDToEmbedKeyType(int id) { + switch (id) { + case SWT.KeyDown: + return AbstractEvents.KEYEVENT_PRESSED; + case SWT.KeyUp: + return AbstractEvents.KEYEVENT_RELEASED; +// case KeyEvent.KEY_TYPED: +// return AbstractEvents.KEYEVENT_TYPED; + } + return 0; + } + + static final int [] [] KeyTable = { + + {0x0 /*KeyEvent.VK_UNDEFINED*/, SWT.NULL}, + + // SWT only + {'\n' /*KeyEvent.VK_?????*/, SWT.CR}, + + // Misc + {'\n' /*KeyEvent.VK_ENTER*/, SWT.LF}, + {'\b' /*KeyEvent.VK_BACKSPACE*/, SWT.BS}, + {'\t' /*KeyEvent.VK_TAB*/, SWT.TAB}, +// {KeyEvent.VK_CANCEL SWT.???}, +// {KeyEvent.VK_CLEAR SWT.???}, +// {KeyEvent.VK_PAUSE SWT.???}, + {0x1B /*KeyEvent.VK_ESCAPE*/, SWT.ESC}, + {0x20 /*KeyEvent.VK_SPACE*/, 0x20}, + {0x7F /*KeyEvent.VK_DELETE*/, SWT.DEL}, +// {KeyEvent.VK_PRINTSCREEN SWT.???; + {0x9B /*KeyEvent.VK_INSERT*/, SWT.INSERT}, + {0x9C /*KeyEvent.VK_HELP*/, SWT.HELP}, + + // Modifiers + {0x10 /*KeyEvent.VK_SHIFT*/, SWT.SHIFT}, + {0x11 /*KeyEvent.VK_CONTROL*/, SWT.CONTROL}, + {0x12 /*KeyEvent.VK_ALT*/, SWT.ALT}, + {0x020C /*(KeyEvent.VK_WINDOWS*/, SWT.COMMAND}, + // {KeyEvent.VK_CONTEXT_MENU, SWT.???}, + {0x14 /*KeyEvent.VK_CAPS_LOCK*/, SWT.CAPS_LOCK}, + {0x90 /*KeyEvent.VK_NUM_LOCK*/, SWT.NUM_LOCK}, + {0x91 /*KeyEvent.VK_SCROLL_LOCK*/, SWT.SCROLL_LOCK}, + + // Navigation keys + {0x21 /*KeyEvent.VK_PAGE_UP*/, SWT.PAGE_UP}, + {0x22 /*KeyEvent.VK_PAGE_DOWN*/, SWT.PAGE_DOWN}, + {0x23 /*KeyEvent.VK_END*/, SWT.END}, + {0x24 /*KeyEvent.VK_HOME*/, SWT.HOME}, + {0x25 /*KeyEvent.VK_LEFT*/, SWT.ARROW_LEFT}, + {0x26 /*KeyEvent.VK_UP*/, SWT.ARROW_UP}, + {0x27 /*KeyEvent.VK_RIGHT*/, SWT.ARROW_RIGHT}, + {0x28 /*KeyEvent.VK_DOWN*/, SWT.ARROW_DOWN}, + + //TODO - how are these mapped? (SWT uses the unaffected key)? + // Misc 2 +// {KeyEvent.VK_COMMA = 0x2C; // ',' +// {KeyEvent.VK_MINUS = 0x2D; // '-' +// {KeyEvent.VK_PERIOD = 0x2E; // '.' +// {KeyEvent.VK_SLASH = 0x2F; // '/' +// {KeyEvent.VK_SEMICOLON = 0x3B; // ';' +// {KeyEvent.VK_EQUALS = 0x3D; // '=' +// {KeyEvent.VK_OPEN_BRACKET = 0x5B; // '[' +// {KeyEvent.VK_BACK_SLASH = 0x5C; // '\' +// {KeyEvent.VK_CLOSE_BRACKET = 0x5D; // ']' +// {KeyEvent.VK_MULTIPLY = 0x6A; // '*' +// {KeyEvent.VK_ADD = 0x6B; // '+' +// {KeyEvent.VK_SEPARATOR = 0x6C; +// {KeyEvent.VK_SUBTRACT = 0x6D; +// {KeyEvent.VK_DECIMAL = 0x6E; +// {KeyEvent.VK_DIVIDE = 0x6F; +// {KeyEvent.VK_AMPERSAND = 0x96; +// {KeyEvent.VK_ASTERISK = 0x97; +// {KeyEvent.VK_DOUBLE_QUOTE = 0x98; // '"' +// {KeyEvent.VK_LESS = 0x99; // '<' +// {KeyEvent.VK_GREATER = 0xa0; // '>' +// {KeyEvent.VK_BRACELEFT = 0xa1; // '{' +// {KeyEvent.VK_BRACERIGHT = 0xa2; // '}' +// {KeyEvent.VK_BACK_QUOTE = 0xC0; // '`' +// {KeyEvent.VK_QUOTE = 0xDE; // ''' +// {KeyEvent.VK_AT = 0x0200; // '@' +// {KeyEvent.VK_COLON = 0x0201; // ':' +// {KeyEvent.VK_CIRCUMFLEX = 0x0202; // '^' +// {KeyEvent.VK_DOLLAR = 0x0203; // '$' +// {KeyEvent.VK_EURO_SIGN = 0x0204; +// {KeyEvent.VK_EXCLAMATION = 0x0205; // '!' +// {KeyEvent.VK_INV_EXCLAMATION = 0x0206; +// {KeyEvent.VK_LEFT_PARENTHESIS = 0x0207; // '(' +// {KeyEvent.VK_NUMBER_SIGN = 0x0208; // '#' +// {KeyEvent.VK_PLUS = 0x0209; // '+' +// {KeyEvent.VK_RIGHT_PARENTHESIS = 0x020A; // ')' +// {KeyEvent.VK_UNDERSCORE = 0x020B; // '_' +// +// // Numeric keys +// {KeyEvent.VK_0 = 0x30; // '0' +// {KeyEvent.VK_1 = 0x31; // '1' +// {KeyEvent.VK_2 = 0x32; // '2' +// {KeyEvent.VK_3 = 0x33; // '3' +// {KeyEvent.VK_4 = 0x34; // '4' +// {KeyEvent.VK_5 = 0x35; // '5' +// {KeyEvent.VK_6 = 0x36; // '6' +// {KeyEvent.VK_7 = 0x37; // '7' +// {KeyEvent.VK_8 = 0x38; // '8' +// {KeyEvent.VK_9 = 0x39; // '9' +// +// // Alpha keys +// {KeyEvent.VK_A = 0x41; // 'A' +// {KeyEvent.VK_B = 0x42; // 'B' +// {KeyEvent.VK_C = 0x43; // 'C' +// {KeyEvent.VK_D = 0x44; // 'D' +// {KeyEvent.VK_E = 0x45; // 'E' +// {KeyEvent.VK_F = 0x46; // 'F' +// {KeyEvent.VK_G = 0x47; // 'G' +// {KeyEvent.VK_H = 0x48; // 'H' +// {KeyEvent.VK_I = 0x49; // 'I' +// {KeyEvent.VK_J = 0x4A; // 'J' +// {KeyEvent.VK_K = 0x4B; // 'K' +// {KeyEvent.VK_L = 0x4C; // 'L' +// {KeyEvent.VK_M = 0x4D; // 'M' +// {KeyEvent.VK_N = 0x4E; // 'N' +// {KeyEvent.VK_O = 0x4F; // 'O' +// {KeyEvent.VK_P = 0x50; // 'P' +// {KeyEvent.VK_Q = 0x51; // 'Q' +// {KeyEvent.VK_R = 0x52; // 'R' +// {KeyEvent.VK_S = 0x53; // 'S' +// {KeyEvent.VK_T = 0x54; // 'T' +// {KeyEvent.VK_U = 0x55; // 'U' +// {KeyEvent.VK_V = 0x56; // 'V' +// {KeyEvent.VK_W = 0x57; // 'W' +// {KeyEvent.VK_X = 0x58; // 'X' +// {KeyEvent.VK_Y = 0x59; // 'Y' +// {KeyEvent.VK_Z = 0x5A; // 'Z' + + // Numpad keys + {0x60 /*KeyEvent.VK_NUMPAD0*/, SWT.KEYPAD_0}, + {0x61 /*KeyEvent.VK_NUMPAD1*/, SWT.KEYPAD_1}, + {0x62 /*KeyEvent.VK_NUMPAD2*/, SWT.KEYPAD_2}, + {0x63 /*KeyEvent.VK_NUMPAD3*/, SWT.KEYPAD_3}, + {0x64 /*KeyEvent.VK_NUMPAD4*/, SWT.KEYPAD_4}, + {0x65 /*KeyEvent.VK_NUMPAD5*/, SWT.KEYPAD_5}, + {0x66 /*KeyEvent.VK_NUMPAD6*/, SWT.KEYPAD_6}, + {0x67 /*KeyEvent.VK_NUMPAD7*/, SWT.KEYPAD_7}, + {0x68 /*KeyEvent.VK_NUMPAD8*/, SWT.KEYPAD_8}, + {0x69 /*KeyEvent.VK_NUMPAD9*/, SWT.KEYPAD_9}, + + // Function keys + {0x70 /*KeyEvent.VK_F1*/, SWT.F1}, + {0x71 /*KeyEvent.VK_F2*/, SWT.F2}, + {0x72 /*KeyEvent.VK_F3*/, SWT.F3}, + {0x73 /*KeyEvent.VK_F4*/, SWT.F4}, + {0x74 /*KeyEvent.VK_F5*/, SWT.F5}, + {0x75 /*KeyEvent.VK_F6*/, SWT.F6}, + {0x76 /*KeyEvent.VK_F7*/, SWT.F7}, + {0x77 /*KeyEvent.VK_F8*/, SWT.F8}, + {0x78 /*KeyEvent.VK_F9*/, SWT.F9}, + {0x79 /*KeyEvent.VK_F10*/, SWT.F10}, + {0x7A /*KeyEvent.VK_F11*/, SWT.F11}, + {0x7B /*KeyEvent.VK_F12*/, SWT.F12}, + }; + + //TODO - map these to Fx keys +// /* Numeric Keypad Keys */ +// {KeyEvent.VK_MULTIPLY, SWT.KEYPAD_MULTIPLY}, +// {KeyEvent.VK_ADD, SWT.KEYPAD_ADD}, +// {KeyEvent.VK_RETURN, SWT.KEYPAD_CR}, +// {KeyEvent.VK_SUBTRACT, SWT.KEYPAD_SUBTRACT}, +// {KeyEvent.VK_DECIMAL, SWT.KEYPAD_DECIMAL}, +// {KeyEvent.VK_DIVIDE, SWT.KEYPAD_DIVIDE}, +//// {KeyEvent.VK_????, SWT.KEYPAD_EQUAL}, + + static int keyCodeToEmbedKeyCode(int keyCode) { + for (int i=0; i