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>
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29 package org.tizen.emulator.skin;
31 import java.util.logging.Level;
32 import java.util.logging.Logger;
34 import org.eclipse.swt.SWT;
35 import org.eclipse.swt.events.PaintEvent;
36 import org.eclipse.swt.events.PaintListener;
37 import org.eclipse.swt.graphics.Image;
38 import org.eclipse.swt.graphics.ImageData;
39 import org.eclipse.swt.graphics.PaletteData;
40 import org.eclipse.swt.graphics.Transform;
41 import org.eclipse.swt.widgets.Display;
42 import org.tizen.emulator.skin.config.EmulatorConfig;
43 import org.tizen.emulator.skin.config.EmulatorConfig.ArgsConstants;
44 import org.tizen.emulator.skin.exception.ScreenShotException;
45 import org.tizen.emulator.skin.image.ImageRegistry.IconName;
46 import org.tizen.emulator.skin.info.SkinInformation;
47 import org.tizen.emulator.skin.log.SkinLogger;
48 import org.tizen.emulator.skin.screenshot.ShmScreenShotWindow;
49 import org.tizen.emulator.skin.util.SkinUtil;
51 public class EmulatorShmSkin extends EmulatorSkin {
52 private Logger logger = SkinLogger.getSkinLogger(
53 EmulatorShmSkin.class).getLogger();
55 public static final int RED_MASK = 0x00FF0000;
56 public static final int GREEN_MASK = 0x0000FF00;
57 public static final int BLUE_MASK = 0x000000FF;
58 public static final int COLOR_DEPTH = 24; /* no need to Alpha channel */
60 /* define JNI functions */
61 public native int shmget(int shmkey, int size);
62 public native int shmdt();
63 public native int getPixels(int[] array);
65 private PaletteData paletteData;
66 private PollFBThread pollThread;
68 class PollFBThread extends Thread {
69 private Display display;
72 private int[] arrayFramebuffer;
73 private ImageData imageData;
74 private Image framebuffer;
76 private volatile boolean stopRequest;
77 private Runnable runnable;
78 private int intervalWait;
80 public PollFBThread(int widthFB, int heightFB) {
81 this.display = Display.getDefault();
82 this.widthFB = widthFB;
83 this.heightFB = heightFB;
84 this.arrayFramebuffer = new int[widthFB * heightFB];
85 this.imageData = new ImageData(widthFB, heightFB, COLOR_DEPTH, paletteData);
86 this.framebuffer = new Image(Display.getDefault(), imageData);
89 setWaitIntervalTime(30);
91 this.runnable = new Runnable() {
94 // logger.info("update display framebuffer");
95 if (lcdCanvas.isDisposed() == false) {
102 public synchronized void setWaitIntervalTime(int ms) {
106 public synchronized int getWaitIntervalTime() {
115 int sizeFramebuffer = widthFB * heightFB;
117 while (!stopRequest) {
120 this.wait(intervalWait); /* ms */
121 } catch (InterruptedException e) {
127 int result = getPixels(arrayFramebuffer); /* from shared memory */
128 //logger.info("getPixels native function returned " + result);
130 imageData.setPixels(0, 0, sizeFramebuffer, arrayFramebuffer, 0);
132 display.syncExec(new Runnable() {
135 framebuffer.dispose();
136 framebuffer = new Image(display, imageData);
140 if (display.isDisposed() == false) {
142 display.asyncExec(runnable);
146 logger.info("PollFBThread is stopped");
148 int result = shmdt();
149 logger.info("shmdt native function returned " + result);
152 public void stopRequest() {
155 synchronized(pollThread) {
164 public EmulatorShmSkin(EmulatorSkinState state, EmulatorFingers finger,
165 EmulatorConfig config, SkinInformation skinInfo, boolean isOnTop) {
166 super(state, finger, config, skinInfo, SWT.NONE, isOnTop);
167 this.paletteData = new PaletteData(RED_MASK, GREEN_MASK, BLUE_MASK);
170 protected void skinFinalize() {
171 pollThread.stopRequest();
173 super.finger.setMultiTouchEnable(0);
174 super.finger.clearFingerSlot();
175 super.finger.cleanup_multiTouchState();
177 super.skinFinalize();
180 public long initLayout() {
183 /* base + 1 = sdb port */
184 /* base + 2 = shared memory key */
185 int shmkey = config.getArgInt(ArgsConstants.NET_BASE_PORT) + 2;
186 logger.info("shmkey = " + shmkey);
188 /* initialize shared memory */
189 int result = shmget(shmkey,
190 currentState.getCurrentResolutionWidth() *
191 currentState.getCurrentResolutionHeight() * 4);
192 logger.info("shmget native function returned " + result);
194 /* update lcd thread */
195 pollThread = new PollFBThread(
196 currentState.getCurrentResolutionWidth(),
197 currentState.getCurrentResolutionHeight());
199 lcdCanvas.addPaintListener(new PaintListener() {
200 public void paintControl(PaintEvent e) { //TODO: optimize
201 /* e.gc.setAdvanced(true);
202 if (!e.gc.getAdvanced()) {
203 logger.info("Advanced graphics not supported");
206 int x = lcdCanvas.getSize().x;
207 int y = lcdCanvas.getSize().y;
209 if (pollThread.getWaitIntervalTime() == 0) {
210 logger.info("draw black screen");
212 e.gc.drawRectangle(-1, -1, x + 1, y + 1);
216 if (currentState.getCurrentAngle() == 0) { /* portrait */
217 e.gc.drawImage(pollThread.framebuffer,
218 0, 0, pollThread.widthFB, pollThread.heightFB,
221 if (finger.getMultiTouchEnable() == 1) {
222 finger.rearrangeFingerPoints(currentState.getCurrentResolutionWidth(),
223 currentState.getCurrentResolutionHeight(),
224 currentState.getCurrentScale(),
225 currentState.getCurrentRotationId());
228 finger.drawImage(e, currentState.getCurrentAngle());
232 Transform transform = new Transform(lcdCanvas.getDisplay());
233 Transform oldtransform = new Transform(lcdCanvas.getDisplay());
234 transform.rotate(currentState.getCurrentAngle());
236 if (currentState.getCurrentAngle() == 90) { /* reverse landscape */
241 transform.translate(0, y * -1);
242 } else if (currentState.getCurrentAngle() == 180) { /* reverse portrait */
243 transform.translate(x * -1, y * -1);
244 } else if (currentState.getCurrentAngle() == -90) { /* landscape */
249 transform.translate(x * -1, 0);
252 /* draw finger image for when rotate while use multitouch */
253 if (finger.getMultiTouchEnable() == 1) {
254 finger.rearrangeFingerPoints(currentState.getCurrentResolutionWidth(),
255 currentState.getCurrentResolutionHeight(),
256 currentState.getCurrentScale(),
257 currentState.getCurrentRotationId());
259 /* save current transform as "oldtransform" */
260 e.gc.getTransform(oldtransform);
261 /* set to new transfrom */
262 e.gc.setTransform(transform);
263 e.gc.drawImage(pollThread.framebuffer,
264 0, 0, pollThread.widthFB, pollThread.heightFB,
266 /* back to old transform */
267 e.gc.setTransform(oldtransform);
270 finger.drawImage(e, currentState.getCurrentAngle());
280 public void displayOn() {
281 logger.info("display on");
283 if (pollThread.isAlive()) {
284 pollThread.setWaitIntervalTime(30);
286 synchronized(pollThread) {
293 public void displayOff() {
294 logger.info("display off");
296 if (pollThread.isAlive()) {
297 pollThread.setWaitIntervalTime(0);
299 shell.getDisplay().asyncExec(new Runnable() {
309 protected void openScreenShotWindow() {
310 if (screenShotDialog != null) {
311 logger.info("screenshot window was already opened");
316 screenShotDialog = new ShmScreenShotWindow(shell, communicator, this, config,
317 imageRegistry.getIcon(IconName.SCREENSHOT));
318 screenShotDialog.open();
320 } catch (ScreenShotException ex) {
321 screenShotDialog = null;
322 logger.log(Level.SEVERE, ex.getMessage(), ex);
324 SkinUtil.openMessage(shell, null,
325 "Fail to create a screen shot.", SWT.ICON_ERROR, config);
327 } catch (Exception ex) {
328 screenShotDialog = null;
329 logger.log(Level.SEVERE, ex.getMessage(), ex);
331 SkinUtil.openMessage(shell, null, "ScreenShot is not ready.\n" +
332 "Please wait until the emulator is completely boot up.",
333 SWT.ICON_WARNING, config);