2 * Emulator Skin Process
4 * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
7 * GiWoong Kim <giwoong.kim@samsung.com>
8 * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 package org.tizen.emulator.skin;
33 import java.io.IOException;
34 import java.util.ArrayList;
35 import java.util.Iterator;
36 import java.util.LinkedList;
37 import java.util.List;
38 import java.util.Map.Entry;
39 import java.util.logging.Level;
40 import java.util.logging.Logger;
42 import org.eclipse.swt.SWT;
43 import org.eclipse.swt.events.FocusEvent;
44 import org.eclipse.swt.events.FocusListener;
45 import org.eclipse.swt.events.KeyEvent;
46 import org.eclipse.swt.events.KeyListener;
47 import org.eclipse.swt.events.MenuDetectEvent;
48 import org.eclipse.swt.events.MenuDetectListener;
49 import org.eclipse.swt.events.MouseEvent;
50 import org.eclipse.swt.events.MouseListener;
51 import org.eclipse.swt.events.MouseMoveListener;
52 import org.eclipse.swt.events.MouseWheelListener;
53 import org.eclipse.swt.events.SelectionAdapter;
54 import org.eclipse.swt.events.SelectionEvent;
55 import org.eclipse.swt.events.ShellEvent;
56 import org.eclipse.swt.events.ShellListener;
57 import org.eclipse.swt.graphics.Color;
58 import org.eclipse.swt.graphics.Point;
59 import org.eclipse.swt.graphics.RGB;
60 import org.eclipse.swt.graphics.Rectangle;
61 import org.eclipse.swt.widgets.Canvas;
62 import org.eclipse.swt.widgets.Display;
63 import org.eclipse.swt.widgets.Menu;
64 import org.eclipse.swt.widgets.MenuItem;
65 import org.eclipse.swt.widgets.Shell;
66 import org.tizen.emulator.skin.comm.ICommunicator.KeyEventType;
67 import org.tizen.emulator.skin.comm.ICommunicator.MouseButtonType;
68 import org.tizen.emulator.skin.comm.ICommunicator.MouseEventType;
69 import org.tizen.emulator.skin.comm.ICommunicator.RotationInfo;
70 import org.tizen.emulator.skin.comm.ICommunicator.Scale;
71 import org.tizen.emulator.skin.comm.ICommunicator.SendCommand;
72 import org.tizen.emulator.skin.comm.sock.SocketCommunicator;
73 import org.tizen.emulator.skin.comm.sock.data.BooleanData;
74 import org.tizen.emulator.skin.comm.sock.data.DisplayStateData;
75 import org.tizen.emulator.skin.comm.sock.data.KeyEventData;
76 import org.tizen.emulator.skin.comm.sock.data.MouseEventData;
77 import org.tizen.emulator.skin.config.EmulatorConfig;
78 import org.tizen.emulator.skin.config.EmulatorConfig.ArgsConstants;
79 import org.tizen.emulator.skin.config.EmulatorConfig.SkinPropertiesConstants;
80 import org.tizen.emulator.skin.custom.ColorTag;
81 import org.tizen.emulator.skin.custom.CustomProgressBar;
82 import org.tizen.emulator.skin.custom.KeyWindow;
83 import org.tizen.emulator.skin.dbi.ColorsType;
84 import org.tizen.emulator.skin.dbi.KeyMapType;
85 import org.tizen.emulator.skin.dbi.RgbType;
86 import org.tizen.emulator.skin.dbi.RotationType;
87 import org.tizen.emulator.skin.dialog.AboutDialog;
88 import org.tizen.emulator.skin.dialog.DetailInfoDialog;
89 import org.tizen.emulator.skin.dialog.RamdumpDialog;
90 import org.tizen.emulator.skin.image.ImageRegistry;
91 import org.tizen.emulator.skin.image.ImageRegistry.IconName;
92 import org.tizen.emulator.skin.info.SkinInformation;
93 import org.tizen.emulator.skin.layout.GeneralPurposeSkinComposer;
94 import org.tizen.emulator.skin.layout.ISkinComposer;
95 import org.tizen.emulator.skin.layout.PhoneShapeSkinComposer;
96 import org.tizen.emulator.skin.log.SkinLogger;
97 import org.tizen.emulator.skin.screenshot.ScreenShotDialog;
98 import org.tizen.emulator.skin.util.SkinRotation;
99 import org.tizen.emulator.skin.util.SkinUtil;
100 import org.tizen.emulator.skin.util.SwtUtil;
106 public class EmulatorSkin {
108 public class SkinReopenPolicy {
110 private EmulatorSkin reopenSkin;
111 private boolean reopen;
113 private SkinReopenPolicy( EmulatorSkin reopenSkin, boolean reopen ) {
114 this.reopenSkin = reopenSkin;
115 this.reopen = reopen;
118 public EmulatorSkin getReopenSkin() {
122 public boolean isReopen() {
128 public enum SkinBasicColor {
132 VIOLET(168, 43, 255),
134 MAGENTA(245, 48, 233),
140 private int channelRed;
141 private int channelGreen;
142 private int channelBlue;
144 SkinBasicColor(int r, int g, int b) {
151 return new RGB(channelRed, channelGreen, channelBlue);
155 private static Logger logger =
156 SkinLogger.getSkinLogger(EmulatorSkin.class).getLogger();
158 protected EmulatorConfig config;
159 protected EmulatorFingers finger;
160 protected Shell shell;
161 protected ImageRegistry imageRegistry;
162 protected Canvas lcdCanvas;
163 private int displayCanvasStyle;
164 protected SkinInformation skinInfo;
165 protected ISkinComposer skinComposer;
167 protected EmulatorSkinState currentState;
169 private boolean isDragStartedInLCD;
170 private boolean isShutdownRequested;
171 private boolean isAboutToReopen;
172 private boolean isOnTop;
173 private boolean isKeyWindow;
174 private boolean isOnKbd;
176 private Menu contextMenu;
177 public Color colorVM;
178 private MenuItem keyWindowItem; /* key window menu */
179 public KeyWindow keyWindow;
180 public int recentlyDocked;
181 public ColorTag pairTag;
182 public CustomProgressBar bootingProgress;
183 public ScreenShotDialog screenShotDialog;
185 public SocketCommunicator communicator;
186 private ShellListener shellListener;
187 private MenuDetectListener shellMenuDetectListener;
189 //private DragDetectListener canvasDragDetectListener;
190 private MouseMoveListener canvasMouseMoveListener;
191 private MouseListener canvasMouseListener;
192 private MouseWheelListener canvasMouseWheelListener;
193 private KeyListener canvasKeyListener;
194 private MenuDetectListener canvasMenuDetectListener;
195 private FocusListener canvasFocusListener;
197 private LinkedList<KeyEventData> pressedKeyEventList;
200 private static int pressingX = -1, pressingY = -1;
201 private static int pressingOriginX = -1, pressingOriginY = -1;
204 private EmulatorSkin reopenSkin;
208 * @param config : configuration of emulator skin
209 * @param isOnTop : always on top flag
211 protected EmulatorSkin(EmulatorSkinState state, EmulatorFingers finger,
212 EmulatorConfig config, SkinInformation skinInfo,
213 int displayCanvasStyle, boolean isOnTop) {
214 this.finger = finger;
215 this.config = config;
216 this.skinInfo = skinInfo;
218 this.screenShotDialog = null;
219 this.keyWindow = null;
220 this.pressedKeyEventList = new LinkedList<KeyEventData>();
222 this.isOnTop = isOnTop;
223 this.isKeyWindow = false;
224 this.recentlyDocked = SWT.NONE;
226 int style = SWT.NO_TRIM | SWT.DOUBLE_BUFFERED;
227 // if (skinInfo.isPhoneShape() == false) {
228 // style = SWT.TITLE | SWT.CLOSE | SWT.MIN | SWT.BORDER;
230 this.shell = new Shell(Display.getDefault(), style);
231 if (isOnTop == true) {
232 SkinUtil.setTopMost(shell, true);
235 this.displayCanvasStyle = displayCanvasStyle;
237 /* generate a pair tag color of key window */
240 this.currentState = state;
243 public void setCommunicator(SocketCommunicator communicator) {
244 this.communicator = communicator;
245 this.finger.setCommunicator(this.communicator);
248 private void setColorVM() {
249 int portNumber = config.getArgInt(ArgsConstants.NET_BASE_PORT) % 100;
251 if (portNumber >= 26200) {
252 int red = (int) (Math.random() * 256);
253 int green = (int) (Math.random() * 256);
254 int blue = (int) (Math.random() * 256);
255 this.colorVM = new Color(shell.getDisplay(), new RGB(red, green, blue));
257 int vmIndex = (portNumber % 100) / 10;
259 SkinBasicColor colors[] = SkinBasicColor.values();
260 this.colorVM = new Color(shell.getDisplay(), colors[vmIndex].color());
264 public long initLayout() {
265 imageRegistry = ImageRegistry.getInstance();
267 if (skinInfo.isPhoneShape() == true) { /* phone shape skin */
268 skinComposer = new PhoneShapeSkinComposer(config, this,
269 shell, currentState, imageRegistry, communicator);
271 ((PhoneShapeSkinComposer) skinComposer).addPhoneShapeListener(shell);
272 } else { /* general purpose skin */
273 skinComposer = new GeneralPurposeSkinComposer(config, this,
274 shell, currentState, imageRegistry);
276 ((GeneralPurposeSkinComposer) skinComposer).addGeneralPurposeListener(shell);
279 lcdCanvas = skinComposer.compose(displayCanvasStyle);
281 /* load a hover color */
282 currentState.setHoverColor(loadHoverColor());
284 /* added event handlers */
285 addMainWindowListener(shell);
286 addCanvasListener(shell, lcdCanvas);
291 this.isOnKbd = false;
297 private void setMenu() {
298 contextMenu = new Menu(shell);
300 addMenuItems(shell, contextMenu);
302 shell.setMenu(contextMenu);
305 // private void readyToReopen( EmulatorSkin sourceSkin, boolean isOnTop ) {
307 // logger.info( "Start Changing AlwaysOnTop status" );
309 // sourceSkin.reopenSkin = new EmulatorSkin( sourceSkin.config, isOnTop );
311 // sourceSkin.reopenSkin.lcdCanvas = sourceSkin.lcdCanvas;
312 // Point previousLocation = sourceSkin.shell.getLocation();
314 // sourceSkin.reopenSkin.composeInternal( sourceSkin.lcdCanvas, previousLocation.x, previousLocation.y,
315 // sourceSkin.currentLcdWidth, sourceSkin.currentLcdHeight, sourceSkin.currentScale,
316 // sourceSkin.currentRotationId, sourceSkin.isOnKbd );
318 // sourceSkin.reopenSkin.windowHandleId = sourceSkin.windowHandleId;
320 // sourceSkin.reopenSkin.communicator = sourceSkin.communicator;
321 // sourceSkin.reopenSkin.communicator.resetSkin( reopenSkin );
323 // sourceSkin.isAboutToReopen = true;
324 // sourceSkin.isShutdownRequested = true;
326 // if ( sourceSkin.isScreenShotOpened && ( null != sourceSkin.screenShotDialog ) ) {
327 // sourceSkin.screenShotDialog.setReserveImage( true );
328 // sourceSkin.screenShotDialog.setEmulatorSkin( reopenSkin );
329 // reopenSkin.isScreenShotOpened = true;
330 // reopenSkin.screenShotDialog = sourceSkin.screenShotDialog;
331 // // see open() method to know next logic for screenshot dialog.
334 // sourceSkin.lcdCanvas.setParent( reopenSkin.shell );
335 // sourceSkin.shell.close();
339 private Color loadHoverColor() {
340 ColorsType colors = config.getDbiContents().getColors();
342 if (null != colors) {
343 RgbType hoverRgb = colors.getHoverColor();
344 if (null != hoverRgb) {
345 Long r = hoverRgb.getR();
346 Long g = hoverRgb.getG();
347 Long b = hoverRgb.getB();
349 if (null != r && null != g && null != b) {
350 Color hoverColor = new Color(shell.getDisplay(),
351 new RGB(r.intValue(), g.intValue(), b.intValue()));
359 return (new Color(shell.getDisplay(), new RGB(255, 255, 255)));
362 public Color getColorVM() {
366 public ImageRegistry getImageRegistry() {
367 return imageRegistry;
370 public SkinReopenPolicy open() {
371 if (null == this.communicator) {
372 logger.severe("communicator is null.");
376 Display display = this.shell.getDisplay();
380 // logic only for reopen case ///////
381 // if ( isScreenShotOpened && ( null != screenShotDialog ) ) {
383 // screenShotDialog.setReserveImage( false );
384 // screenShotDialog.open();
386 // isScreenShotOpened = false;
389 // ///////////////////////////////////
391 while (!shell.isDisposed()) {
392 if (!display.readAndDispatch()) {
397 return new SkinReopenPolicy(reopenSkin, isAboutToReopen);
400 protected void skinFinalize() {
401 skinComposer.composerFinalize();
404 private void addMainWindowListener(final Shell shell) {
406 shellListener = new ShellListener() {
408 public void shellClosed(ShellEvent event) {
409 logger.info("Main Window is closed");
411 if (isShutdownRequested) {
412 removeShellListeners();
413 removeCanvasListeners();
415 if (!isAboutToReopen) {
416 /* close the screen shot window */
417 if (null != screenShotDialog) {
418 Shell scShell = screenShotDialog.getShell();
419 if (!scShell.isDisposed()) {
422 screenShotDialog = null;
425 /* save config only for emulator close */
426 config.setSkinProperty(
427 SkinPropertiesConstants.WINDOW_X, shell.getLocation().x);
428 config.setSkinProperty(
429 SkinPropertiesConstants.WINDOW_Y, shell.getLocation().y);
430 config.setSkinProperty(
431 SkinPropertiesConstants.WINDOW_SCALE, currentState.getCurrentScale());
432 config.setSkinProperty(
433 SkinPropertiesConstants.WINDOW_ROTATION, currentState.getCurrentRotationId());
434 config.setSkinProperty(
435 SkinPropertiesConstants.WINDOW_ONTOP, Boolean.toString(isOnTop));
438 if (keyWindow != null && keyWindow.getShell().isVisible()) {
439 dockValue = keyWindow.getDockPosition();
441 config.setSkinProperty(
442 SkinPropertiesConstants.KEYWINDOW_POSITION, dockValue);
444 config.saveSkinProperties();
446 /* close the Key Window */
447 if (skinInfo.isPhoneShape() == false) {
451 /* dispose the color */
452 if (colorVM != null) {
457 if (currentState.getCurrentImage() != null) {
458 currentState.getCurrentImage().dispose();
460 if (currentState.getCurrentKeyPressedImage() != null) {
461 currentState.getCurrentKeyPressedImage().dispose();
464 if (currentState.getHoverColor() != null) {
465 currentState.getHoverColor().dispose();
471 /* Skin have to be alive until
472 * receiving shutdown request from qemu */
475 if (null != communicator) {
476 communicator.sendToQEMU(SendCommand.CLOSE, null);
482 public void shellActivated(ShellEvent event) {
483 logger.info("activate");
485 if (keyWindow != null && isKeyWindow == true) {
486 if (isOnTop == false) {
487 keyWindow.getShell().moveAbove(shell);
489 if (keyWindow.getDockPosition() != SWT.NONE) {
490 shell.moveAbove(keyWindow.getShell());
493 if (keyWindow.getDockPosition() == SWT.NONE) {
494 keyWindow.getShell().moveAbove(shell);
501 public void shellDeactivated(ShellEvent event) {
502 //logger.info("deactivate");
508 public void shellIconified(ShellEvent event) {
509 logger.info("iconified");
511 /* synchronization of minimization */
512 shell.getDisplay().asyncExec(new Runnable() {
515 if (isKeyWindow == true && keyWindow != null) {
516 if (keyWindow.getShell().getMinimized() == false) {
517 keyWindow.getShell().setVisible(false);
518 /* the tool style window is exposed
519 when even it was minimized */
520 keyWindow.getShell().setMinimized(true);
528 public void shellDeiconified(ShellEvent event) {
529 logger.info("deiconified");
531 if (isKeyWindow == true && keyWindow != null) {
532 if (keyWindow.getShell().getMinimized() == true) {
533 keyWindow.getShell().setMinimized(false);
534 keyWindow.getShell().setVisible(true);
538 DisplayStateData lcdStateData = new DisplayStateData(
539 currentState.getCurrentScale(), currentState.getCurrentRotationId());
540 communicator.sendToQEMU(SendCommand.CHANGE_LCD_STATE, lcdStateData);
544 shell.addShellListener(shellListener);
547 shellMenuDetectListener = new MenuDetectListener() {
549 public void menuDetected(MenuDetectEvent e) {
550 Menu menu = EmulatorSkin.this.contextMenu;
554 menu.setVisible(true);
563 shell.addMenuDetectListener(shellMenuDetectListener);
566 private void removeShellListeners() {
567 if (null != shellListener) {
568 shell.removeShellListener(shellListener);
571 if (null != shellMenuDetectListener) {
572 shell.removeMenuDetectListener(shellMenuDetectListener);
576 private void addCanvasListener(final Shell shell, final Canvas canvas) {
578 canvasMenuDetectListener = new MenuDetectListener() {
580 public void menuDetected(MenuDetectEvent e) {
581 Menu menu = EmulatorSkin.this.contextMenu;
582 keyForceRelease(true);
584 if (menu != null && EmulatorSkin.this.isDragStartedInLCD == false) {
585 lcdCanvas.setMenu(menu);
586 menu.setVisible(true);
589 lcdCanvas.setMenu(null);
594 /* remove 'input method' menu item (avoid bug) */
595 canvas.addMenuDetectListener(canvasMenuDetectListener);
598 canvasFocusListener = new FocusListener() {
600 public void focusGained(FocusEvent event) {
601 //logger.info("gain focus");
607 public void focusLost(FocusEvent event) {
608 logger.info("lost focus");
609 keyForceRelease(false);
613 lcdCanvas.addFocusListener(canvasFocusListener);
616 /*canvasDragDetectListener = new DragDetectListener() {
619 public void dragDetected( DragDetectEvent e ) {
620 if ( logger.isLoggable( Level.FINE ) ) {
621 logger.fine( "dragDetected e.button:" + e.button );
623 if ( 1 == e.button && // left button
624 e.x > 0 && e.x < canvas.getSize().x && e.y > 0 && e.y < canvas.getSize().y ) {
626 if ( logger.isLoggable( Level.FINE ) ) {
627 logger.fine( "dragDetected in display" );
629 EmulatorSkin.this.isDragStartedInLCD = true;
635 canvas.addDragDetectListener(canvasDragDetectListener);*/
637 canvasMouseMoveListener = new MouseMoveListener() {
640 public void mouseMove( MouseEvent e ) {
641 if ( true == EmulatorSkin.this.isDragStartedInLCD ) { //true = mouse down
642 int eventType = MouseEventType.DRAG.value();
643 Point canvasSize = canvas.getSize();
647 eventType = MouseEventType.RELEASE.value();
648 EmulatorSkin.this.isDragStartedInLCD = false;
649 } else if ( e.x >= canvasSize.x ) {
650 e.x = canvasSize.x - 1;
651 eventType = MouseEventType.RELEASE.value();
652 EmulatorSkin.this.isDragStartedInLCD = false;
657 eventType = MouseEventType.RELEASE.value();
658 EmulatorSkin.this.isDragStartedInLCD = false;
659 } else if ( e.y >= canvasSize.y ) {
660 e.y = canvasSize.y - 1;
661 eventType = MouseEventType.RELEASE.value();
662 EmulatorSkin.this.isDragStartedInLCD = false;
665 int[] geometry = SkinUtil.convertMouseGeometry(e.x, e.y,
666 currentState.getCurrentResolutionWidth(),
667 currentState.getCurrentResolutionHeight(),
668 currentState.getCurrentScale(), currentState.getCurrentAngle());
670 if (SwtUtil.isMacPlatform()) {
671 //eventType = MouseEventType.DRAG.value();
672 if (finger.getMultiTouchEnable() == 1) {
673 finger.maruFingerProcessing1(eventType,
674 e.x, e.y, geometry[0], geometry[1]);
677 else if (finger.getMultiTouchEnable() == 2) {
678 finger.maruFingerProcessing2(eventType,
679 e.x, e.y, geometry[0], geometry[1]);
684 MouseEventData mouseEventData = new MouseEventData(
685 MouseButtonType.LEFT.value(), eventType,
686 e.x, e.y, geometry[0], geometry[1], 0);
688 communicator.sendToQEMU(SendCommand.SEND_MOUSE_EVENT, mouseEventData);
693 canvas.addMouseMoveListener(canvasMouseMoveListener);
695 canvasMouseListener = new MouseListener() {
698 public void mouseUp(MouseEvent e) {
699 if (1 == e.button) { /* left button */
701 int[] geometry = SkinUtil.convertMouseGeometry(e.x, e.y,
702 currentState.getCurrentResolutionWidth(),
703 currentState.getCurrentResolutionHeight(),
704 currentState.getCurrentScale(), currentState.getCurrentAngle());
705 logger.info("mouseUp in display" +
706 " x:" + geometry[0] + " y:" + geometry[1]);
708 if (true == EmulatorSkin.this.isDragStartedInLCD) {
709 EmulatorSkin.this.isDragStartedInLCD = false;
712 if (SwtUtil.isMacPlatform()) {
713 pressingX = pressingY = -1;
714 pressingOriginX = pressingOriginY = -1;
715 if (finger.getMultiTouchEnable() == 1) {
716 logger.info("maruFingerProcessing1");
717 finger.maruFingerProcessing1(MouseEventType.RELEASE.value(),
718 e.x, e.y, geometry[0], geometry[1]);
721 else if (finger.getMultiTouchEnable() == 2) {
722 logger.info("maruFingerProcessing2");
723 finger.maruFingerProcessing2(MouseEventType.RELEASE.value(),
724 e.x, e.y, geometry[0], geometry[1]);
729 MouseEventData mouseEventData = new MouseEventData(
730 MouseButtonType.LEFT.value(), MouseEventType.RELEASE.value(),
731 e.x, e.y, geometry[0], geometry[1], 0);
733 communicator.sendToQEMU(SendCommand.SEND_MOUSE_EVENT, mouseEventData);
734 } else if (2 == e.button) { /* wheel button */
735 logger.info("wheelUp in display");
740 public void mouseDown(MouseEvent e) {
741 if (1 == e.button) { /* left button */
743 int[] geometry = SkinUtil.convertMouseGeometry(e.x, e.y,
744 currentState.getCurrentResolutionWidth(),
745 currentState.getCurrentResolutionHeight(),
746 currentState.getCurrentScale(), currentState.getCurrentAngle());
747 logger.info("mouseDown in display" +
748 " x:" + geometry[0] + " y:" + geometry[1]);
750 if (false == EmulatorSkin.this.isDragStartedInLCD) {
751 EmulatorSkin.this.isDragStartedInLCD = true;
754 if (SwtUtil.isMacPlatform()) {
755 pressingX = geometry[0];
756 pressingY = geometry[1];
757 pressingOriginX = e.x;
758 pressingOriginY = e.y;
760 if (finger.getMultiTouchEnable() == 1) {
761 logger.info("maruFingerProcessing1");
762 finger.maruFingerProcessing1(MouseEventType.PRESS.value(),
763 e.x, e.y, geometry[0], geometry[1]);
766 else if (finger.getMultiTouchEnable() == 2) {
767 logger.info("maruFingerProcessing2");
768 finger.maruFingerProcessing2(MouseEventType.PRESS.value(),
769 e.x, e.y, geometry[0], geometry[1]);
774 MouseEventData mouseEventData = new MouseEventData(
775 MouseButtonType.LEFT.value(), MouseEventType.PRESS.value(),
776 e.x, e.y, geometry[0], geometry[1], 0);
778 communicator.sendToQEMU(SendCommand.SEND_MOUSE_EVENT, mouseEventData);
783 public void mouseDoubleClick(MouseEvent e) {
788 canvas.addMouseListener(canvasMouseListener);
790 canvasMouseWheelListener = new MouseWheelListener() {
793 public void mouseScrolled(MouseEvent e) {
794 int[] geometry = SkinUtil.convertMouseGeometry(e.x, e.y,
795 currentState.getCurrentResolutionWidth(),
796 currentState.getCurrentResolutionHeight(),
797 currentState.getCurrentScale(), currentState.getCurrentAngle());
798 logger.info("mousewheel in display" +
799 " x:" + geometry[0] + " y:" + geometry[1] + " value:" + e.count);
803 eventType = MouseEventType.WHEELDOWN.value();
805 eventType = MouseEventType.WHEELUP.value();
808 MouseEventData mouseEventData = new MouseEventData(
809 MouseButtonType.WHEEL.value(), eventType,
810 e.x, e.y, geometry[0], geometry[1], e.count);
812 communicator.sendToQEMU(SendCommand.SEND_MOUSE_EVENT, mouseEventData);
816 canvas.addMouseWheelListener(canvasMouseWheelListener);
819 canvasKeyListener = new KeyListener() {
821 private KeyEvent previous;
822 private boolean disappearEvent = false;
823 private int disappearKeycode = 0;
824 private int disappearStateMask = 0;
825 private int disappearKeyLocation = 0;
828 public void keyReleased(KeyEvent e) {
829 if (logger.isLoggable(Level.INFO)) {
830 logger.info("'" + e.character + "':" +
831 e.keyCode + ":" + e.stateMask + ":" + e.keyLocation);
832 } else if (logger.isLoggable(Level.FINE)) {
833 logger.fine(e.toString());
836 int keyCode = e.keyCode;
837 int stateMask = e.stateMask;
841 /* generate a disappeared key event in Windows */
842 if (SwtUtil.isWindowsPlatform() && disappearEvent) {
843 disappearEvent = false;
844 if (isMetaKey(e.keyCode) && e.character != '\0') {
845 logger.info("send disappear release : keycode=" + disappearKeycode +
846 ", stateMask=" + disappearStateMask +
847 ", keyLocation=" + disappearKeyLocation);
849 KeyEventData keyEventData = new KeyEventData(
850 KeyEventType.RELEASED.value(),
851 disappearKeycode, disappearStateMask, disappearKeyLocation);
852 communicator.sendToQEMU(SendCommand.SEND_KEY_EVENT, keyEventData);
854 removePressedKey(keyEventData);
856 disappearKeycode = 0;
857 disappearStateMask = 0;
858 disappearKeyLocation = 0;
861 else if (SwtUtil.isMacPlatform()) {
862 /* check multi-touch */
863 if (keyCode == SWT.SHIFT || keyCode == SWT.COMMAND) {
864 int tempStateMask = stateMask & ~SWT.BUTTON1;
865 if (tempStateMask == (SWT.SHIFT | SWT.COMMAND)) {
866 finger.setMultiTouchEnable(1);
867 logger.info("enable multi-touch = mode1");
870 finger.setMultiTouchEnable(0);
871 finger.clearFingerSlot();
872 logger.info("disable multi-touch");
877 KeyEventData keyEventData = new KeyEventData(
878 KeyEventType.RELEASED.value(), keyCode, stateMask, e.keyLocation);
879 communicator.sendToQEMU(SendCommand.SEND_KEY_EVENT, keyEventData);
881 removePressedKey(keyEventData);
885 public void keyPressed(KeyEvent e) {
886 int keyCode = e.keyCode;
887 int stateMask = e.stateMask;
889 /* When the pressed key event is overwritten by next key event,
890 * the release event of previous key does not occur in Windows.
891 * So, we generate a release key event by ourselves
892 * that had been disappeared. */
893 if (SwtUtil.isWindowsPlatform()) {
894 if (null != previous) {
895 if (previous.keyCode != e.keyCode) {
897 if (isMetaKey(previous.keyCode)) {
898 disappearEvent = true;
899 disappearKeycode = keyCode;
900 disappearStateMask = stateMask;
901 disappearKeyLocation = e.keyLocation;
903 /* three or more keys were pressed
905 if (disappearEvent == true) {
906 logger.info("replace the disappearEvent : " +
907 disappearKeycode + "->" + keyCode);
909 disappearKeycode = keyCode;
910 disappearStateMask = stateMask;
911 disappearKeyLocation = e.keyLocation;
914 int previousKeyCode = previous.keyCode;
915 int previousStateMask = previous.stateMask;
917 if (logger.isLoggable(Level.INFO)) {
918 logger.info("send previous release : '" +
919 previous.character + "':" + previous.keyCode + ":" +
920 previous.stateMask + ":" + previous.keyLocation);
921 } else if (logger.isLoggable(Level.FINE)) {
922 logger.fine("send previous release :" + previous.toString());
925 KeyEventData keyEventData = new KeyEventData(KeyEventType.RELEASED.value(),
926 previousKeyCode, previousStateMask, previous.keyLocation);
927 communicator.sendToQEMU(SendCommand.SEND_KEY_EVENT, keyEventData);
929 removePressedKey(keyEventData);
934 } //end isWindowsPlatform
935 else if (SwtUtil.isMacPlatform()) {
936 // if(finger.getMaxTouchPoint() > 1) {
937 int tempStateMask = stateMask & ~SWT.BUTTON1;
938 if ((keyCode == SWT.SHIFT && (tempStateMask & SWT.COMMAND) != 0) ||
939 (keyCode == SWT.COMMAND && (tempStateMask & SWT.SHIFT) != 0))
941 finger.setMultiTouchEnable(2);
942 /* add a finger before start the multi-touch processing
943 if already exist the pressed touch in display */
944 if (pressingX != -1 && pressingY != -1 &&
945 pressingOriginX != -1 && pressingOriginY != -1) {
946 finger.addFingerPoint(
947 pressingOriginX, pressingOriginY,
948 pressingX, pressingY);
949 pressingX = pressingY = -1;
950 pressingOriginX = pressingOriginY = -1;
952 logger.info("enable multi-touch = mode2");
954 else if (keyCode == SWT.SHIFT || keyCode == SWT.COMMAND) {
955 finger.setMultiTouchEnable(1);
956 /* add a finger before start the multi-touch processing
957 * if already exist the pressed touch in display */
958 if (pressingX != -1 && pressingY != -1 &&
959 pressingOriginX != -1 && pressingOriginY != -1) {
960 finger.addFingerPoint(
961 pressingOriginX, pressingOriginY,
962 pressingX, pressingY);
963 pressingX = pressingY = -1;
964 pressingOriginX = pressingOriginY = -1;
966 logger.info("enable multi-touch = mode1");
973 if (logger.isLoggable(Level.INFO)) {
974 logger.info("'" + e.character + "':" +
975 e.keyCode + ":" + e.stateMask + ":" + e.keyLocation);
976 } else if (logger.isLoggable(Level.FINE)) {
977 logger.fine(e.toString());
980 KeyEventData keyEventData = new KeyEventData(
981 KeyEventType.PRESSED.value(), keyCode, stateMask, e.keyLocation);
982 communicator.sendToQEMU(SendCommand.SEND_KEY_EVENT, keyEventData);
984 addPressedKey(keyEventData);
989 canvas.addKeyListener(canvasKeyListener);
992 private boolean isMetaKey(int keyCode) {
993 if (SWT.CTRL == keyCode ||
994 SWT.ALT == keyCode ||
995 SWT.SHIFT == keyCode ||
996 SWT.COMMAND == keyCode) {
1003 private synchronized boolean addPressedKey(KeyEventData pressData) {
1004 for (KeyEventData data : pressedKeyEventList) {
1005 if (data.keycode == pressData.keycode &&
1006 //data.stateMask == pressData.stateMask &&
1007 data.keyLocation == pressData.keyLocation) {
1012 pressedKeyEventList.add(pressData);
1016 private synchronized boolean removePressedKey(KeyEventData releaseData) {
1018 for (KeyEventData data : pressedKeyEventList) {
1019 if (data.keycode == releaseData.keycode &&
1020 //data.stateMask == releaseData.stateMask &&
1021 data.keyLocation == releaseData.keyLocation) {
1022 pressedKeyEventList.remove(data);
1031 private void removeCanvasListeners() {
1032 // if ( null != canvasDragDetectListener ) {
1033 // lcdCanvas.removeDragDetectListener( canvasDragDetectListener );
1035 if (null != canvasMouseMoveListener) {
1036 lcdCanvas.removeMouseMoveListener(canvasMouseMoveListener);
1039 if (null != canvasMouseListener) {
1040 lcdCanvas.removeMouseListener(canvasMouseListener);
1043 if (null != canvasKeyListener) {
1044 lcdCanvas.removeKeyListener(canvasKeyListener);
1047 if (null != canvasMenuDetectListener) {
1048 lcdCanvas.removeMenuDetectListener(canvasMenuDetectListener);
1051 if (null != canvasFocusListener) {
1052 lcdCanvas.removeFocusListener(canvasFocusListener);
1055 if (null != canvasMouseWheelListener) {
1056 lcdCanvas.removeMouseWheelListener(canvasMouseWheelListener);
1060 public void setFocus() {
1061 lcdCanvas.setFocus();
1064 protected void openScreenShotWindow() {
1068 public void dispalyBrightness(boolean on) {
1076 protected void displayOn() {
1080 protected void displayOff() {
1084 public boolean isSelectKeyWindow() {
1085 return keyWindowItem.getSelection();
1088 public void openKeyWindow(int dockValue, boolean recreate) {
1089 if (keyWindow != null) {
1090 if (recreate == false) {
1091 /* show the key window */
1092 keyWindowItem.setSelection(isKeyWindow = true);
1093 pairTag.setVisible(true);
1095 keyWindow.getShell().setVisible(true);
1096 SkinUtil.setTopMost(keyWindow.getShell(), isOnTop);
1100 logger.info("recreate a keywindow");
1105 /* create a key window */
1106 List<KeyMapType> keyMapList =
1107 SkinUtil.getHWKeyMapList(currentState.getCurrentRotationId());
1109 if (keyMapList == null) {
1110 keyWindowItem.setSelection(isKeyWindow = false);
1111 logger.info("keyMapList is null");
1113 } else if (keyMapList.isEmpty() == true) {
1114 keyWindowItem.setSelection(isKeyWindow = false);
1115 logger.info("keyMapList is empty");
1119 keyWindow = new KeyWindow(this, shell, communicator, keyMapList);
1121 keyWindowItem.setSelection(isKeyWindow = true);
1122 SkinUtil.setTopMost(keyWindow.getShell(), isOnTop);
1124 pairTag.setVisible(true);
1126 keyWindow.open(dockValue);
1129 public void hideKeyWindow() {
1130 keyWindowItem.setSelection(isKeyWindow = false);
1131 pairTag.setVisible(false);
1133 if (keyWindow != null) {
1134 keyWindow.getShell().setVisible(false);
1138 public void closeKeyWindow() {
1139 keyWindowItem.setSelection(isKeyWindow = false);
1140 pairTag.setVisible(false);
1142 if (keyWindow != null) {
1143 keyWindow.getShell().close();
1148 private void addMenuItems(final Shell shell, final Menu menu) {
1150 /* Emulator detail info menu */
1151 final MenuItem detailInfoItem = new MenuItem(menu, SWT.PUSH);
1153 String emulatorName = SkinUtil.makeEmulatorName(config);
1154 detailInfoItem.setText(emulatorName);
1155 detailInfoItem.setImage(imageRegistry.getIcon(IconName.DETAIL_INFO));
1156 detailInfoItem.addSelectionListener(new SelectionAdapter() {
1158 public void widgetSelected(SelectionEvent e) {
1159 if (logger.isLoggable(Level.FINE)) {
1160 logger.fine("Open detail info");
1163 String emulatorName = SkinUtil.makeEmulatorName(config);
1164 DetailInfoDialog detailInfoDialog = new DetailInfoDialog(
1165 shell, emulatorName, communicator, config);
1166 detailInfoDialog.open();
1170 new MenuItem(menu, SWT.SEPARATOR);
1172 /* Always on top menu */
1173 if (!SwtUtil.isMacPlatform()) { /* not supported on mac */
1174 final MenuItem onTopItem = new MenuItem(menu, SWT.CHECK);
1175 onTopItem.setText("&Always On Top");
1176 onTopItem.setSelection(isOnTop);
1178 onTopItem.addSelectionListener(new SelectionAdapter() {
1180 public void widgetSelected(SelectionEvent e) {
1181 isOnTop = onTopItem.getSelection();
1183 logger.info("Select Always On Top : " + isOnTop);
1184 // readyToReopen(EmulatorSkin.this, isOnTop);
1186 if (SkinUtil.setTopMost(shell, isOnTop) == false) {
1187 logger.info("failed to Always On Top");
1189 if (keyWindow != null) {
1190 SkinUtil.setTopMost(keyWindow.getShell(), isOnTop);
1198 final MenuItem rotateItem = new MenuItem(menu, SWT.CASCADE);
1199 rotateItem.setText("&Rotate");
1200 rotateItem.setImage(imageRegistry.getIcon(IconName.ROTATE));
1201 Menu rotateMenu = createRotateMenu(menu.getShell());
1202 rotateItem.setMenu(rotateMenu);
1205 final MenuItem scaleItem = new MenuItem(menu, SWT.CASCADE);
1206 scaleItem.setText("&Scale");
1207 scaleItem.setImage(imageRegistry.getIcon(IconName.SCALE));
1208 Menu scaleMenu = createScaleMenu(menu.getShell());
1209 scaleItem.setMenu(scaleMenu);
1211 new MenuItem(menu, SWT.SEPARATOR);
1213 /* Key Window menu */
1214 if (skinInfo.isPhoneShape() == false) { //TODO:
1215 keyWindowItem = new MenuItem(menu, SWT.CHECK);
1216 keyWindowItem.setText("&Key Window");
1217 keyWindowItem.setSelection(isKeyWindow);
1219 keyWindowItem.addSelectionListener(new SelectionAdapter() {
1221 public void widgetSelected(SelectionEvent e) {
1222 final boolean selectKeyWindow = keyWindowItem.getSelection();
1224 if (selectKeyWindow == true) {
1225 if (keyWindow == null) {
1226 openKeyWindow(recentlyDocked, false);
1227 recentlyDocked = SWT.NONE;
1229 openKeyWindow(keyWindow.getDockPosition(), false);
1231 } else { /* hide a key window */
1232 if (keyWindow != null &&
1233 keyWindow.getDockPosition() != SWT.NONE) {
1234 /* close the Key Window if it is docked to Main Window */
1235 recentlyDocked = keyWindow.getDockPosition();
1246 final MenuItem advancedItem = new MenuItem(menu, SWT.CASCADE);
1247 advancedItem.setText("Ad&vanced");
1248 advancedItem.setImage(imageRegistry.getIcon(IconName.ADVANCED));
1249 Menu advancedMenu = createAdvancedMenu(menu.getShell());
1250 advancedItem.setMenu(advancedMenu);
1253 final MenuItem shellItem = new MenuItem(menu, SWT.PUSH);
1254 shellItem.setText("S&hell");
1255 shellItem.setImage(imageRegistry.getIcon(IconName.SHELL));
1257 shellItem.addSelectionListener(new SelectionAdapter() {
1259 public void widgetSelected(SelectionEvent e) {
1260 if (!communicator.isSdbDaemonStarted()) {
1261 SkinUtil.openMessage(shell, null, "SDB is not ready.\n" +
1262 "Please wait until the emulator is completely boot up.",
1263 SWT.ICON_WARNING, config);
1267 String sdbPath = SkinUtil.getSdbPath();
1269 File sdbFile = new File(sdbPath);
1270 if (!sdbFile.exists()) {
1271 logger.log(Level.INFO, "SDB file is not exist : " + sdbFile.getAbsolutePath());
1273 SkinUtil.openMessage(shell, null,
1274 "SDB file is not exist in the following path.\n" + sdbFile.getCanonicalPath()
1275 , SWT.ICON_ERROR, config);
1276 } catch (IOException ee) {
1277 logger.log(Level.SEVERE, ee.getMessage(), ee);
1282 int portSdb = config.getArgInt(ArgsConstants.NET_BASE_PORT);
1284 ProcessBuilder procSdb = new ProcessBuilder();
1286 if (SwtUtil.isLinuxPlatform()) {
1287 procSdb.command("/usr/bin/gnome-terminal", "--disable-factory",
1288 "--title=" + SkinUtil.makeEmulatorName( config ), "-x", sdbPath,
1289 "-s", "emulator-" + portSdb, "shell");
1290 } else if (SwtUtil.isWindowsPlatform()) {
1291 procSdb.command("cmd.exe", "/c", "start", sdbPath, "sdb",
1292 "-s", "emulator-" + portSdb, "shell");
1293 } else if (SwtUtil.isMacPlatform()) {
1294 procSdb.command("./sdbscript", "emulator-" + portSdb);
1295 //procSdb.command("/usr/X11/bin/uxterm", "-T", "emulator-" + portSdb, "-e", sdbPath,"shell");
1298 logger.log(Level.INFO, procSdb.command().toString());
1301 procSdb.start(); /* open the sdb shell */
1302 } catch (Exception ee) {
1303 logger.log(Level.SEVERE, ee.getMessage(), ee);
1304 SkinUtil.openMessage(shell, null, "Fail to open Shell: \n" +
1305 ee.getMessage(), SWT.ICON_ERROR, config);
1308 communicator.sendToQEMU(SendCommand.OPEN_SHELL, null);
1312 new MenuItem(menu, SWT.SEPARATOR);
1315 MenuItem closeItem = new MenuItem(menu, SWT.PUSH);
1316 closeItem.setText("&Close");
1317 closeItem.setImage(imageRegistry.getIcon(IconName.CLOSE));
1319 closeItem.addSelectionListener(new SelectionAdapter() {
1321 public void widgetSelected(SelectionEvent e) {
1322 logger.info("Close Menu is selected");
1323 communicator.sendToQEMU(SendCommand.CLOSE, null);
1329 private Menu createRotateMenu(final Shell shell) {
1331 Menu menu = new Menu( shell, SWT.DROP_DOWN );
1333 final List<MenuItem> rotationList = new ArrayList<MenuItem>();
1335 Iterator<Entry<Short, RotationType>> iterator = SkinRotation.getRotationIterator();
1337 while ( iterator.hasNext() ) {
1339 Entry<Short, RotationType> entry = iterator.next();
1340 Short rotationId = entry.getKey();
1341 RotationType section = entry.getValue();
1343 final MenuItem menuItem = new MenuItem( menu, SWT.RADIO );
1344 menuItem.setText( section.getName().value() );
1345 menuItem.setData( rotationId );
1347 if (currentState.getCurrentRotationId() == rotationId) {
1348 menuItem.setSelection( true );
1351 rotationList.add( menuItem );
1355 /* temp : swap rotation menu names */
1356 if (currentState.getCurrentResolutionWidth() >
1357 currentState.getCurrentResolutionHeight())
1359 for (MenuItem m : rotationList) {
1360 short rotationId = (Short) m.getData();
1362 if (rotationId == RotationInfo.PORTRAIT.id()) {
1363 String landscape = SkinRotation.getRotation(
1364 RotationInfo.LANDSCAPE.id()).getName().value();
1365 m.setText(landscape);
1366 } else if (rotationId == RotationInfo.LANDSCAPE.id()) {
1367 String portrait = SkinRotation.getRotation(
1368 RotationInfo.PORTRAIT.id()).getName().value();
1369 m.setText(portrait);
1370 } else if (rotationId == RotationInfo.REVERSE_PORTRAIT.id()) {
1371 String landscapeReverse = SkinRotation.getRotation(
1372 RotationInfo.REVERSE_LANDSCAPE.id()).getName().value();
1373 m.setText(landscapeReverse);
1374 } else if (rotationId == RotationInfo.REVERSE_LANDSCAPE.id()) {
1375 String portraitReverse = SkinRotation.getRotation(
1376 RotationInfo.REVERSE_PORTRAIT.id()).getName().value();
1377 m.setText(portraitReverse);
1382 SelectionAdapter selectionAdapter = new SelectionAdapter() {
1384 public void widgetSelected(SelectionEvent e) {
1386 MenuItem item = (MenuItem) e.getSource();
1388 boolean selection = item.getSelection();
1394 if (!communicator.isSensorDaemonStarted()) {
1396 /* roll back a selection */
1397 item.setSelection(false);
1399 for (MenuItem m : rotationList) {
1400 short rotationId = (Short) m.getData();
1401 if (currentState.getCurrentRotationId() == rotationId) {
1402 m.setSelection(true);
1407 SkinUtil.openMessage(shell, null,
1408 "Rotation is not ready.\nPlease wait until the emulator is completely boot up.",
1409 SWT.ICON_WARNING, config);
1413 final short rotationId = ((Short) item.getData());
1415 shell.getDisplay().syncExec(new Runnable() {
1418 // Point location = new Point(100, 100);
1420 // if (skinInfo.isPhoneShape()) { /* TODO: */
1421 // location = shell.getLocation();
1422 // shell.setVisible(false);
1425 skinComposer.arrangeSkin(currentState.getCurrentScale(), rotationId);
1427 // if (skinInfo.isPhoneShape()) { /* TODO: */
1428 // shell.setVisible(true);
1429 // shell.setLocation(location);
1430 // SkinUtil.setTopMost(shell, isOnTop);
1433 /* location correction */
1434 Rectangle monitorBounds = Display.getDefault().getBounds();
1435 Rectangle emulatorBounds = shell.getBounds();
1437 Math.max(emulatorBounds.x, monitorBounds.x),
1438 Math.max(emulatorBounds.y, monitorBounds.y));
1442 DisplayStateData lcdStateData =
1443 new DisplayStateData(currentState.getCurrentScale(), rotationId);
1444 communicator.sendToQEMU(SendCommand.CHANGE_LCD_STATE, lcdStateData);
1448 for (MenuItem menuItem : rotationList) {
1449 menuItem.addSelectionListener(selectionAdapter);
1455 private Menu createScaleMenu(final Shell shell) {
1457 Menu menu = new Menu(shell, SWT.DROP_DOWN);
1459 final List<MenuItem> scaleList = new ArrayList<MenuItem>();
1461 final MenuItem scaleOneItem = new MenuItem(menu, SWT.RADIO);
1462 scaleOneItem.setText("1x");
1463 scaleOneItem.setData(Scale.SCALE_100);
1464 scaleList.add(scaleOneItem);
1466 final MenuItem scaleThreeQtrItem = new MenuItem(menu, SWT.RADIO);
1467 scaleThreeQtrItem.setText("3/4x");
1468 scaleThreeQtrItem.setData(Scale.SCALE_75);
1469 scaleList.add( scaleThreeQtrItem );
1471 final MenuItem scalehalfItem = new MenuItem(menu, SWT.RADIO);
1472 scalehalfItem.setText("1/2x");
1473 scalehalfItem.setData(Scale.SCALE_50);
1474 scaleList.add(scalehalfItem);
1476 final MenuItem scaleOneQtrItem = new MenuItem(menu, SWT.RADIO);
1477 scaleOneQtrItem.setText("1/4x");
1478 scaleOneQtrItem.setData(Scale.SCALE_25);
1479 scaleList.add(scaleOneQtrItem);
1481 SelectionAdapter selectionAdapter = new SelectionAdapter() {
1483 public void widgetSelected(SelectionEvent e) {
1485 MenuItem item = (MenuItem) e.getSource();
1487 boolean selection = item.getSelection();
1493 final int scale = ((Scale) item.getData()).value();
1495 shell.getDisplay().syncExec(new Runnable() {
1498 // Point location = new Point(100, 100);
1500 // if (skinInfo.isPhoneShape()) { /* TODO: */
1501 // location = shell.getLocation();
1502 // shell.setVisible(false);
1505 skinComposer.arrangeSkin(scale, currentState.getCurrentRotationId());
1507 // if (skinInfo.isPhoneShape()) { /* TODO: */
1508 // shell.setVisible(true);
1509 // shell.setLocation(location);
1510 // SkinUtil.setTopMost(shell, isOnTop);
1513 /* location correction */
1514 Rectangle monitorBounds = Display.getDefault().getBounds();
1515 Rectangle emulatorBounds = shell.getBounds();
1517 Math.max(emulatorBounds.x, monitorBounds.x),
1518 Math.max(emulatorBounds.y, monitorBounds.y));
1522 DisplayStateData lcdStateData =
1523 new DisplayStateData(scale, currentState.getCurrentRotationId());
1524 communicator.sendToQEMU(SendCommand.CHANGE_LCD_STATE, lcdStateData);
1529 for (MenuItem menuItem : scaleList) {
1531 int scale = ((Scale) menuItem.getData()).value();
1532 if (currentState.getCurrentScale() == scale) {
1533 menuItem.setSelection(true);
1536 menuItem.addSelectionListener(selectionAdapter);
1542 private Menu createDiagnosisMenu(Shell shell) {
1543 Menu menu = new Menu(shell, SWT.DROP_DOWN);
1545 final MenuItem ramdumpItem = new MenuItem(menu, SWT.PUSH);
1546 ramdumpItem.setText("&Ram Dump");
1548 ramdumpItem.addSelectionListener(new SelectionAdapter() {
1550 public void widgetSelected(SelectionEvent e) {
1551 logger.info("Ram dump menu is selected");
1553 communicator.setRamdumpFlag(true);
1554 communicator.sendToQEMU(SendCommand.RAM_DUMP, null);
1556 RamdumpDialog ramdumpDialog;
1558 ramdumpDialog = new RamdumpDialog(EmulatorSkin.this.shell, communicator, config);
1559 ramdumpDialog.open();
1560 } catch (IOException ee) {
1561 logger.log( Level.SEVERE, ee.getMessage(), ee);
1566 /* final MenuItem guestdumpItem = new MenuItem(menu, SWT.PUSH);
1567 guestdumpItem.setText("&Guest Memory Dump");
1569 guestdumpItem.addSelectionListener(new SelectionAdapter() {
1571 public void widgetSelected(SelectionEvent e) {
1572 logger.info("Guest memory dump menu is selected");
1574 communicator.setRamdumpFlag(true);
1575 communicator.sendToQEMU(SendCommand.GUEST_DUMP, null);
1582 private Menu createAdvancedMenu(final Shell shell) {
1584 final Menu menu = new Menu(shell, SWT.DROP_DOWN);
1586 /* Screen shot menu */
1587 final MenuItem screenshotItem = new MenuItem(menu, SWT.PUSH);
1588 screenshotItem.setText("&Screen Shot");
1589 screenshotItem.setImage(imageRegistry.getIcon(IconName.SCREENSHOT));
1590 screenshotItem.addSelectionListener(new SelectionAdapter() {
1592 public void widgetSelected(SelectionEvent e) {
1593 logger.info("ScreenShot Menu is selected");
1595 openScreenShotWindow();
1599 /* VirtIO Keyboard Menu */
1600 final MenuItem hostKeyboardItem = new MenuItem(menu, SWT.CASCADE);
1601 hostKeyboardItem.setText("&Host Keyboard");
1602 hostKeyboardItem.setImage(imageRegistry.getIcon(IconName.HOST_KEYBOARD));
1604 Menu hostKeyboardMenu = new Menu(shell, SWT.DROP_DOWN);
1606 final MenuItem kbdOnItem = new MenuItem(hostKeyboardMenu, SWT.RADIO);
1607 kbdOnItem.setText("On");
1608 kbdOnItem.setSelection( isOnKbd );
1610 final MenuItem kbdOffItem = new MenuItem(hostKeyboardMenu, SWT.RADIO);
1611 kbdOffItem.setText("Off");
1612 kbdOffItem.setSelection(!isOnKbd);
1614 SelectionAdapter kbdSelectionAdaptor = new SelectionAdapter() {
1616 public void widgetSelected(SelectionEvent e) {
1617 if (!communicator.isSensorDaemonStarted()) {
1618 SkinUtil.openMessage(shell, null,
1619 "Host Keyboard is not ready.\nPlease wait until the emulator is completely boot up.",
1620 SWT.ICON_WARNING, config);
1621 kbdOnItem.setSelection(isOnKbd);
1622 kbdOffItem.setSelection(!isOnKbd);
1627 MenuItem item = (MenuItem) e.getSource();
1628 if (item.getSelection()) {
1629 boolean on = item.equals(kbdOnItem);
1631 logger.info("Host Keyboard " + isOnKbd);
1633 communicator.sendToQEMU(
1634 SendCommand.HOST_KBD, new BooleanData(on, SendCommand.HOST_KBD.toString()));
1640 kbdOnItem.addSelectionListener(kbdSelectionAdaptor);
1641 kbdOffItem.addSelectionListener(kbdSelectionAdaptor);
1643 hostKeyboardItem.setMenu(hostKeyboardMenu);
1645 /* Diagnosis menu */
1646 if (SwtUtil.isLinuxPlatform()) { //TODO: windows
1647 final MenuItem diagnosisItem = new MenuItem(menu, SWT.CASCADE);
1648 diagnosisItem.setText("&Diagnosis");
1649 diagnosisItem.setImage(imageRegistry.getIcon(IconName.DIAGNOSIS));
1650 Menu diagnosisMenu = createDiagnosisMenu(menu.getShell());
1651 diagnosisItem.setMenu(diagnosisMenu);
1654 new MenuItem(menu, SWT.SEPARATOR);
1657 final MenuItem aboutItem = new MenuItem(menu, SWT.PUSH);
1658 aboutItem.setText("&About");
1659 aboutItem.setImage(imageRegistry.getIcon(IconName.ABOUT));
1661 aboutItem.addSelectionListener(new SelectionAdapter() {
1662 private boolean isOpen;
1665 public void widgetSelected(SelectionEvent e) {
1669 logger.info("Open the about dialog");
1670 AboutDialog dialog = new AboutDialog(shell, config);
1677 new MenuItem(menu, SWT.SEPARATOR);
1679 /* Force close menu */
1680 final MenuItem forceCloseItem = new MenuItem(menu, SWT.PUSH);
1681 forceCloseItem.setText("&Force Close");
1682 forceCloseItem.setImage(imageRegistry.getIcon(IconName.FORCE_CLOSE));
1684 forceCloseItem.addSelectionListener(new SelectionAdapter() {
1686 public void widgetSelected(SelectionEvent e) {
1687 logger.info("Force close is selected");
1689 int answer = SkinUtil.openMessage(shell, null,
1690 "If you force stop an emulator, it may cause some problems.\n" +
1691 "Are you sure you want to contiue?",
1692 SWT.ICON_QUESTION | SWT.OK | SWT.CANCEL, config);
1694 if (answer == SWT.OK) {
1695 logger.info("force close!!!");
1705 public void shutdown() {
1707 isShutdownRequested = true;
1709 if (!this.shell.isDisposed()) {
1710 this.shell.getDisplay().asyncExec(new Runnable() {
1713 if (!shell.isDisposed()) {
1714 EmulatorSkin.this.shell.close();
1722 public short getCurrentRotationId() {
1723 return currentState.getCurrentRotationId();
1726 public void keyForceRelease(boolean isMetaFilter) {
1727 /* key event compensation */
1728 if (pressedKeyEventList.isEmpty() == false) {
1729 for (KeyEventData data : pressedKeyEventList) {
1730 if (isMetaFilter == true) {
1731 if (isMetaKey(data.keycode) == true) {
1732 /* keep multi-touching */
1737 KeyEventData keyEventData = new KeyEventData(
1738 KeyEventType.RELEASED.value(), data.keycode,
1739 data.stateMask, data.keyLocation);
1740 communicator.sendToQEMU(
1741 SendCommand.SEND_KEY_EVENT, keyEventData, false);
1743 logger.info("auto release : keycode=" + keyEventData.keycode +
1744 ", stateMask=" + keyEventData.stateMask +
1745 ", keyLocation=" + keyEventData.keyLocation);
1749 pressedKeyEventList.clear();