--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?>
+
+<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+ <storageModule moduleId="org.eclipse.cdt.core.settings">
+ <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.599200627">
+ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.599200627" moduleId="org.eclipse.cdt.core.settings" name="Default">
+ <externalSettings/>
+ <extensions>
+ <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+ <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ </extensions>
+ </storageModule>
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+ <configuration artifactName="${ProjName}" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.599200627" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
+ <folderInfo id="cdt.managedbuild.toolchain.gnu.base.599200627.810909853" name="/" resourcePath="">
+ <toolChain id="cdt.managedbuild.toolchain.gnu.base.191848946" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base">
+ <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.1222568721" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
+ <builder command="" id="cdt.managedbuild.target.gnu.builder.base.628599481" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
+ <tool id="cdt.managedbuild.tool.gnu.archiver.base.574770557" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+ <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.2079317122" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"/>
+ <tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1922596436" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
+ <option id="gnu.c.compiler.option.include.paths.507417315" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+ <listOptionValue builtIn="false" value=""${workspace_loc:/qemu-develop/i386-softmmu}""/>
+ <listOptionValue builtIn="false" value="/usr/include/SDL"/>
+ </option>
+ <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.676204606" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+ </tool>
+ <tool id="cdt.managedbuild.tool.gnu.c.linker.base.2026169100" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base">
+ <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1055445101" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+ <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+ <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+ </inputType>
+ </tool>
+ <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1635507651" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"/>
+ <tool id="cdt.managedbuild.tool.gnu.assembler.base.903060300" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
+ <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1155102024" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+ </tool>
+ </toolChain>
+ </folderInfo>
+ </configuration>
+ </storageModule>
+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+ </cconfiguration>
+ </storageModule>
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+ <project id="qemu-develop.null.125981814" name="qemu-develop"/>
+ </storageModule>
+ <storageModule moduleId="refreshScope" versionNumber="1">
+ <resource resourceType="PROJECT" workspacePath="/qemu-develop"/>
+ </storageModule>
+ <storageModule moduleId="scannerConfiguration">
+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+ <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.599200627;cdt.managedbuild.toolchain.gnu.base.599200627.810909853;cdt.managedbuild.tool.gnu.c.compiler.base.1922596436;cdt.managedbuild.tool.gnu.c.compiler.input.676204606">
+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+ </scannerConfigBuildInfo>
+ </storageModule>
+</cproject>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>qemu-develop</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+ <triggers>clean,full,incremental,</triggers>
+ <arguments>
+ <dictionary>
+ <key>?name?</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.append_environment</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.autoBuildTarget</key>
+ <value>all</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildArguments</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildCommand</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+ <value>clean</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.contents</key>
+ <value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+ <value>false</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableFullBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.fullBuildTarget</key>
+ <value>all</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.stopOnError</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+ <value>false</value>
+ </dictionary>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+ <triggers>full,incremental,</triggers>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.cdt.core.cnature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+ </natures>
+ <filteredResources>
+ <filter>
+ <id>1332425928400</id>
+ <name></name>
+ <type>22</type>
+ <matcher>
+ <id>org.eclipse.ui.ide.multiFilter</id>
+ <arguments>1.0-name-matches-false-false-*.o</arguments>
+ </matcher>
+ </filter>
+ <filter>
+ <id>1332425928407</id>
+ <name></name>
+ <type>22</type>
+ <matcher>
+ <id>org.eclipse.ui.ide.multiFilter</id>
+ <arguments>1.0-name-matches-false-false-*.d</arguments>
+ </matcher>
+ </filter>
+ </filteredResources>
+</projectDescription>
#define SDL_FLAGS (SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL | SDL_NOFRAME)
#define SDL_BPP 32
+DisplaySurface* qemu_display_surface = NULL;
static void qemu_update(void)
{
vga_hw_update();
+ // surface may be NULL in init func.
+ qemu_display_surface = ds->surface;
+
while (maru_sdl_poll_event(ev)) {
switch (ev->type) {
case SDL_VIDEORESIZE:
//This function is thread safe, and can be called from other threads safely.
SDL_PushEvent(&ev);
}
+
+DisplaySurface* get_qemu_display_surface( void ) {
+ return qemu_display_surface;
+}
#include <SDL.h>
#include <SDL_syswm.h>
+#include "qemu-common.h"
#define SDL_USER_EVENT_CODE_HARDKEY 1
void maruskin_sdl_init(int swt_handle, int lcd_size_width, int lcd_size_height);
void maruskin_sdl_resize(void);
+DisplaySurface* get_qemu_display_surface( void );
+
#endif /* MARU_SDL_H_ */
--- /dev/null
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
-import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.tizen.emulator.skin.comm.ICommunicator.KeyEventType;
import org.tizen.emulator.skin.comm.ICommunicator.MouseEventType;
+import org.tizen.emulator.skin.comm.ICommunicator.RotationInfo;
import org.tizen.emulator.skin.comm.ICommunicator.SendCommand;
import org.tizen.emulator.skin.comm.sock.SocketCommunicator;
import org.tizen.emulator.skin.comm.sock.data.BooleanData;
import org.tizen.emulator.skin.screenshot.ScreenShotDialog;
import org.tizen.emulator.skin.util.SkinRegion;
import org.tizen.emulator.skin.util.SkinRotation;
-import org.tizen.emulator.skin.util.SkinRotation.RotationInfo;
import org.tizen.emulator.skin.util.SkinUtil;
import org.tizen.emulator.skin.util.StringUtil;
int scale = SkinUtil.getValidScale( config );
-// short rotationId = config.getPropertyShort( PropertiesConstants.WINDOW_DIRECTION, (short) 0 );
+// short rotationId = config.getPropertyShort( PropertiesConstants.WINDOW_ROTATION, RotationInfo.PORTRAIT.id() );
// has to be portrait mode at first booting time
arrangeSkin( lcdWidth, lcdHeight, scale, RotationInfo.PORTRAIT.id() );
addMenuItems( menu );
shell.setMenu( menu );
- // sdl uses this handle id.
- windowHandleId = getWindowHandleId( lcdCanvas );
-
addLCDListener( lcdCanvas );
addShellListener( shell );
+ // sdl uses this handle id.
+ windowHandleId = getWindowHandleId( lcdCanvas );
+
return windowHandleId;
}
config.setProperty( PropertiesConstants.WINDOW_X, shell.getLocation().x );
config.setProperty( PropertiesConstants.WINDOW_Y, shell.getLocation().y );
config.setProperty( PropertiesConstants.WINDOW_SCALE, currentScale );
- config.setProperty( PropertiesConstants.WINDOW_DIRECTION, currentRotationId );
+ config.setProperty( PropertiesConstants.WINDOW_ROTATION, currentRotationId );
config.saveProperties();
deviceInfoItem.setText( emulatorName );
deviceInfoItem.setImage( imageRegistry.getIcon( IconName.DEVICE_INFO ) );
//FIXME
-// deviceInfoItem.setEnabled( false );
+ deviceInfoItem.setEnabled( false );
deviceInfoItem.addSelectionListener( new SelectionAdapter() {
@Override
public void widgetSelected( SelectionEvent e ) {
procSdb.start(); //open sdb shell
} catch (Exception ee) {
logger.log(Level.SEVERE, ee.getMessage(), ee);
-
- MessageBox messageBox = new MessageBox(shell, SWT.ICON_ERROR);
- messageBox.setText(SkinUtil.makeEmulatorName(config));
- messageBox.setMessage(ee.getMessage());
- messageBox.open();
+ SkinUtil.openMessage( shell, null, "Fail to open Shell.", SWT.ICON_ERROR, config );
}
}
final List<MenuItem> rotationList = new ArrayList<MenuItem>();
- final short storedDirectionId = config.getPropertyShort( PropertiesConstants.WINDOW_DIRECTION,
- (short) RotationInfo.PORTRAIT.id() );
-
+// final short storedDirectionId = config.getPropertyShort( PropertiesConstants.WINDOW_ROTATION,
+// (short) RotationInfo.PORTRAIT.id() );
+ final short storedDirectionId = RotationInfo.PORTRAIT.id();
+
Iterator<Entry<Short, RotationType>> iterator = SkinRotation.getRotationIterator();
while ( iterator.hasNext() ) {
menuItem.setSelection( true );
}
+ if ( RotationInfo.PORTRAIT.id() == rotationId ) {
+ menuItem.setSelection( true );
+ }
+
rotationList.add( menuItem );
}
}
}
///////////
-
- MessageBox messageBox = new MessageBox( shell );
- messageBox.setMessage( "Rotation is not ready." );
- messageBox.open();
+
+ SkinUtil.openMessage( shell, null, "Rotation is not ready.", SWT.ICON_WARNING, config );
return;
screenshotItem.setText( "Screen Shot" );
screenshotItem.setImage( imageRegistry.getIcon( IconName.SCREENSHOT ) );
screenshotItem.addSelectionListener( new SelectionAdapter() {
+
private boolean isOpen;
+
@Override
public void widgetSelected( SelectionEvent e ) {
- if( !isOpen ) {
- isOpen = true;
- ScreenShotDialog dialog = new ScreenShotDialog( shell, lcdCanvas, config );
- dialog.open();
+
+ try {
+
+ if( !isOpen ) {
+ isOpen = true;
+ ScreenShotDialog dialog = new ScreenShotDialog( shell, communicator, EmulatorSkin.this, config );
+ dialog.open();
+ }
+
+ } catch ( Exception ex ) {
+ logger.log( Level.SEVERE, "Fail to create a screen shot.", ex );
+ SkinUtil.openMessage( shell, null, "Fail to create a screen shot.", SWT.ERROR, config );
+ } finally {
isOpen = false;
}
}
}
+ public short getCurrentRotationId() {
+ return currentRotationId;
+ }
+
}
package org.tizen.emulator.skin.comm;
import org.tizen.emulator.skin.comm.sock.data.ISendData;
+import org.tizen.emulator.skin.dbi.RotationNameType;
/**
*
}
+ public enum RotationInfo {
+
+ PORTRAIT( RotationNameType.PORTRAIT.value(), (short)0, 0 ),
+ LANDSCAPE( RotationNameType.LANDSCAPE.value(), (short)1, -90 ),
+ REVERSE_PORTRAIT( RotationNameType.REVERSE_PORTRAIT.value(), (short)2, 180 ),
+ REVERSE_LANDSCAPE( RotationNameType.REVERSE_LANDSCAPE.value(), (short)3, 90 );
+
+ private String value;
+ private short id;
+ private int angle;
+
+ RotationInfo( String value, short id, int ratio ) {
+ this.value = value;
+ this.id = id;
+ this.angle = ratio;
+ }
+ public String value() {
+ return this.value;
+ }
+ public int angle() {
+ return this.angle;
+ }
+ public short id() {
+ return this.id;
+ }
+
+ public static RotationInfo getValue( short id ) {
+ RotationInfo[] values = RotationInfo.values();
+ for (int i = 0; i < values.length; i++) {
+ if( values[i].id == id ) {
+ return values[i];
+ }
+ }
+ throw new IllegalArgumentException( Integer.toString(id) );
+ }
+
+ }
+
public enum SendCommand {
SEND_START( (short)1 ),
CHANGE_LCD_STATE( (short)13 ),
OPEN_SHELL( (short)14 ),
USB_KBD( (short)15 ),
+ SCREEN_SHOT( (short)16 ),
RESPONSE_HEART_BEAT( (short)900 ),
CLOSE( (short)998 ),
public enum ReceiveCommand {
HEART_BEAT( (short)1 ),
+ SCREEN_SHOT_DATA( (short)2 ),
SENSOR_DAEMON_START( (short)800 ),
SHUTDOWN( (short)999 );
package org.tizen.emulator.skin.comm.sock;
+import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
*/
public class SocketCommunicator implements ICommunicator {
+ public class DataTranfer {
+
+ private boolean isTransferState;
+ private byte[] receivedData;
+
+ private DataTranfer() {
+ }
+
+ private void reset() {
+ receivedData = null;
+ isTransferState = true;
+ }
+
+ private void setData( byte[] data ) {
+ this.receivedData = data;
+ isTransferState = false;
+ }
+
+ public synchronized boolean isTransferState() {
+ return isTransferState;
+ }
+
+ public synchronized byte[] getReceivedData() {
+ return receivedData;
+ }
+
+ }
+
private Logger logger = SkinLogger.getSkinLogger( SocketCommunicator.class ).getLogger();
-
+
private EmulatorConfig config;
private int uId;
private int windowHandleId;
private DataInputStream dis;
private DataOutputStream dos;
+ private DataTranfer dataTransfer;
+
private AtomicInteger heartbeatCount;
private boolean isTerminated;
private ScheduledExecutorService heartbeatExecutor;
-
+
private boolean isSensorDaemonStarted;
- public SocketCommunicator(EmulatorConfig config, int uId, int windowHandleId, EmulatorSkin skin) {
+ public SocketCommunicator( EmulatorConfig config, int uId, int windowHandleId, EmulatorSkin skin ) {
this.config = config;
this.uId = uId;
this.windowHandleId = windowHandleId;
this.skin = skin;
- this.heartbeatCount = new AtomicInteger(0);
+ this.dataTransfer = new DataTranfer();
+
+ this.heartbeatCount = new AtomicInteger( 0 );
this.heartbeatExecutor = Executors.newSingleThreadScheduledExecutor();
try {
- String portString = config.getArg(ArgsConstants.SERVER_PORT);
- int port = Integer.parseInt(portString);
- socket = new Socket("127.0.0.1", port);
- logger.info("socket.isConnected():" + socket.isConnected());
+ String portString = config.getArg( ArgsConstants.SERVER_PORT );
+ int port = Integer.parseInt( portString );
+ socket = new Socket( "127.0.0.1", port );
+ logger.info( "socket.isConnected():" + socket.isConnected() );
- } catch (UnknownHostException e) {
+ } catch ( UnknownHostException e ) {
logger.log( Level.SEVERE, e.getMessage(), e );
- } catch (IOException e) {
+ } catch ( IOException e ) {
logger.log( Level.SEVERE, e.getMessage(), e );
}
try {
- dis = new DataInputStream(socket.getInputStream());
- dos = new DataOutputStream(socket.getOutputStream());
-
+ dis = new DataInputStream( socket.getInputStream() );
+ dos = new DataOutputStream( socket.getOutputStream() );
+
+ int width = Integer.parseInt( config.getArg( ArgsConstants.RESOLUTION_WIDTH ) );
+ int height = Integer.parseInt( config.getArg( ArgsConstants.RESOLUTION_HEIGHT ) );
int scale = SkinUtil.getValidScale( config );
-
- short rotation = config.getPropertyShort( PropertiesConstants.WINDOW_DIRECTION, (short) 0 );
-
- sendToQEMU(SendCommand.SEND_START,
- new StartData(windowHandleId,
- Integer.parseInt( config.getArg(ArgsConstants.RESOLUTION_WIDTH) ),
- Integer.parseInt( config.getArg(ArgsConstants.RESOLUTION_HEIGHT) ),
- scale, rotation));
-
- } catch (IOException e) {
+ short rotation = config.getPropertyShort( PropertiesConstants.WINDOW_ROTATION, RotationInfo.PORTRAIT.id() );
+
+ StartData startData = new StartData( windowHandleId, width, height, scale, rotation );
+
+ sendToQEMU( SendCommand.SEND_START, startData );
+
+ } catch ( IOException e ) {
logger.log( Level.SEVERE, e.getMessage(), e );
terminate();
return;
}
-
+
String ignoreHeartbeatString = config.getArg( ArgsConstants.TEST_HEART_BEAT_IGNORE, Boolean.FALSE.toString() );
Boolean ignoreHeartbeat = Boolean.parseBoolean( ignoreHeartbeatString );
-
- if( ignoreHeartbeat ) {
+
+ if ( ignoreHeartbeat ) {
logger.info( "Ignore Skin heartbeat." );
- }else {
-
- heartbeatExecutor.scheduleAtFixedRate(new Runnable() {
-
+ } else {
+
+ heartbeatExecutor.scheduleAtFixedRate( new Runnable() {
+
@Override
public void run() {
-
+
increaseHeartbeatCount();
-
- if (isHeartbeatExpired()) {
+
+ if ( isHeartbeatExpired() ) {
terminate();
}
-
+
}
-
- }, 0, EmulatorConstants.HEART_BEAT_INTERVAL, TimeUnit.SECONDS);
-
+
+ }, 0, EmulatorConstants.HEART_BEAT_INTERVAL, TimeUnit.SECONDS );
+
}
while ( true ) {
int reqId = dis.readInt();
short cmd = dis.readShort();
+ int length = dis.readInt();
- if( logger.isLoggable( Level.FINE ) ) {
- logger.fine( "[Socket] read - reqId:" + reqId + ", command:" + cmd + ", " );
+ if ( logger.isLoggable( Level.FINE ) ) {
+ logger.fine( "[Socket] read - reqId:" + reqId + ", command:" + cmd + ", dataLength:" + length );
}
ReceiveCommand command = null;
-
+
try {
command = ReceiveCommand.getValue( cmd );
} catch ( IllegalArgumentException e ) {
switch ( command ) {
case HEART_BEAT: {
resetHeartbeatCount();
- if( logger.isLoggable( Level.FINE ) ) {
+ if ( logger.isLoggable( Level.FINE ) ) {
logger.fine( "received HEAR_BEAT from QEMU." );
}
sendToQEMU( SendCommand.RESPONSE_HEART_BEAT, null );
break;
}
+ case SCREEN_SHOT_DATA: {
+ logger.info( "received SCREEN_SHOT_DATA from QEMU." );
+
+ synchronized ( dataTransfer ) {
+ byte[] imageData = readData( dis, length );
+ dataTransfer.setData( imageData );
+ dataTransfer.notifyAll();
+ }
+
+ logger.info( "finish receiving data from QEMU." );
+
+ break;
+ }
case SENSOR_DAEMON_START: {
logger.info( "received SENSOR_DAEMON_START from QEMU." );
synchronized ( this ) {
}
}
-
+
+ }
+
+ private byte[] readData( DataInputStream is, int length ) throws IOException {
+
+ if ( 0 >= length ) {
+ return null;
+ }
+
+ BufferedInputStream bfis = new BufferedInputStream( is, length );
+ byte[] data = new byte[length];
+
+ int read = 0;
+ int total = 0;
+
+ while ( true ) {
+
+ if ( total == length ) {
+ break;
+ }
+
+ read = bfis.read( data, total, length - total );
+
+ if ( 0 > read ) {
+ if ( total < length ) {
+ continue;
+ }
+ } else {
+ total += read;
+ }
+
+ }
+
+ logger.info( "finished reading stream. read:" + total );
+
+ return data;
+
+ }
+
+ public void sendToQEMU( SendCommand command, ISendData data, boolean useDataTransfer ) {
+ if ( useDataTransfer ) {
+ this.dataTransfer.reset();
+ }
+ sendToQEMU( command, data );
}
@Override
- public void sendToQEMU(SendCommand command, ISendData data) {
+ public void sendToQEMU( SendCommand command, ISendData data ) {
try {
- //anyway down casting
- int reqId = (int) UUID.randomUUID().getMostSignificantBits();
-
+ // anyway down casting
+ long longReqId = UUID.randomUUID().getMostSignificantBits();
+ int reqId = (int) ( longReqId >> 32 );
+
ByteArrayOutputStream bao = new ByteArrayOutputStream();
- DataOutputStream dataOutputStream = new DataOutputStream(bao);
-
- dataOutputStream.writeInt(uId);
- dataOutputStream.writeInt(reqId);
- dataOutputStream.writeShort(command.value());
-
+ DataOutputStream dataOutputStream = new DataOutputStream( bao );
+
+ dataOutputStream.writeInt( uId );
+ dataOutputStream.writeInt( reqId );
+ dataOutputStream.writeShort( command.value() );
+
short length = 0;
- if( null == data ) {
+ if ( null == data ) {
length = 0;
- dataOutputStream.writeShort(length);
- }else {
+ dataOutputStream.writeShort( length );
+ } else {
byte[] byteData = data.serialize();
length = (short) byteData.length;
- dataOutputStream.writeShort(length);
- dataOutputStream.write(byteData);
+ dataOutputStream.writeShort( length );
+ dataOutputStream.write( byteData );
}
dataOutputStream.flush();
-
- dos.write(bao.toByteArray());
+
+ dos.write( bao.toByteArray() );
dos.flush();
- if( logger.isLoggable( Level.FINE ) ) {
- logger.fine( "[Socket] write - uid:" + uId + ", reqId:" + reqId + ", command:" + command.value() + " - "
- + command.toString() + ", length:" + length );
+ if ( logger.isLoggable( Level.FINE ) ) {
+ logger.fine( "[Socket] write - uid:" + uId + ", reqId:" + reqId + ", command:" + command.value()
+ + " - " + command.toString() + ", length:" + length );
}
if ( 0 < length ) {
- if( logger.isLoggable( Level.FINE ) ) {
+ if ( logger.isLoggable( Level.FINE ) ) {
logger.fine( "== data ==" );
logger.fine( data.toString() );
}
private void increaseHeartbeatCount() {
int count = heartbeatCount.incrementAndGet();
- if( logger.isLoggable( Level.FINE ) ) {
- logger.fine("HB count : " + count);
+ if ( logger.isLoggable( Level.FINE ) ) {
+ logger.fine( "HB count : " + count );
}
}
}
private void resetHeartbeatCount() {
- heartbeatCount.set(0);
+ heartbeatCount.set( 0 );
+ }
+
+ public DataTranfer getDataTranfer() {
+ return dataTransfer;
}
@Override
public void terminate() {
- if (null != heartbeatExecutor) {
+ if ( null != heartbeatExecutor ) {
heartbeatExecutor.shutdownNow();
}
- IOUtil.closeSocket(socket);
+ IOUtil.closeSocket( socket );
skin.shutdown();
}
public interface PropertiesConstants {
public static final String WINDOW_X = "window.x";
public static final String WINDOW_Y = "window.y";
- public static final String WINDOW_DIRECTION = "window.rotate";
+ public static final String WINDOW_ROTATION = "window.rotate";
public static final String WINDOW_SCALE = "window.scale";
}
--- /dev/null
+/**
+ *
+ *
+ * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Hyunjun Son <hj79.son@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+package org.tizen.emulator.skin.exception;
+
+/**
+ *
+ *
+ */
+public class ScreenShotException extends EmulatorException {
+
+ private static final long serialVersionUID = 7527776121326217994L;
+
+ public ScreenShotException() {
+ super();
+ }
+
+ public ScreenShotException( Throwable cause ) {
+ super( cause );
+ }
+
+ public ScreenShotException( String message ) {
+ super( message );
+ }
+
+ public ScreenShotException( String message, Throwable cause ) {
+ super( message, cause );
+ }
+
+}
package org.tizen.emulator.skin.screenshot;
+import java.io.File;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
-import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.MenuItem;
-import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+import org.tizen.emulator.skin.EmulatorSkin;
+import org.tizen.emulator.skin.comm.ICommunicator.SendCommand;
+import org.tizen.emulator.skin.comm.sock.SocketCommunicator;
+import org.tizen.emulator.skin.comm.sock.SocketCommunicator.DataTranfer;
import org.tizen.emulator.skin.config.EmulatorConfig;
+import org.tizen.emulator.skin.config.EmulatorConfig.ArgsConstants;
+import org.tizen.emulator.skin.exception.ScreenShotException;
import org.tizen.emulator.skin.log.SkinLogger;
import org.tizen.emulator.skin.util.IOUtil;
import org.tizen.emulator.skin.util.SkinUtil;
+import org.tizen.emulator.skin.util.StringUtil;
public class ScreenShotDialog extends Dialog {
+ public final static String DEFAULT_FILE_EXTENSION = "png";
+
+ public final static int SCREENSHOT_WAIT_INTERVAL = 3; // milli-seconds
+ public final static int SCREENSHOT_WAIT_LIMIT = 3000; // milli-seconds
+
+ public final static int RED_MASK = 0x0000FF00;
+ public final static int GREEN_MASK = 0x00FF0000;
+ public final static int BLUE_MASK = 0xFF000000;
+ public final static int COLOR_DEPTH = 32;
+
+ public final static int LEFT_MARGIN = 30;
+ public final static int TOP_MARGIN = 30;
+
private Logger logger = SkinLogger.getSkinLogger( ScreenShotDialog.class ).getLogger();
+ private PaletteData paletteData;
private Image image;
+ private Canvas imageCanvas;
private Shell shell;
private Shell parent;
- private EmulatorConfig config;
- private Canvas canvas;
+ private SocketCommunicator communicator;
+ private EmulatorSkin emulatorSkin;
+ private EmulatorConfig config;
- public ScreenShotDialog( Shell parent, Canvas lcdCanvas, EmulatorConfig config ) {
- super( parent );
+ public ScreenShotDialog( Shell parent, SocketCommunicator commuicator, EmulatorSkin emulatorSkin, EmulatorConfig config )
+ throws ScreenShotException {
+
+ super( parent, SWT.DIALOG_TRIM | SWT.RESIZE );
this.parent = parent;
+ this.communicator = commuicator;
+ this.emulatorSkin = emulatorSkin;
this.config = config;
-
- // image copy
- capture( lcdCanvas );
- shell = new Shell( parent, SWT.DIALOG_TRIM );
- shell.setLayout( new FormLayout() );
- shell.setText( "Screen Shot" );
- shell.setLocation( parent.getLocation().x + parent.getSize().x + 50, parent.getLocation().y );
+ shell = new Shell( parent, SWT.DIALOG_TRIM | SWT.RESIZE );
+ shell.setText( "Screen Shot - " + SkinUtil.getVmName( config ) );
+ shell.setLocation( parent.getLocation().x + parent.getSize().x + 30, parent.getLocation().y );
shell.addListener( SWT.Close, new Listener() {
@Override
public void handleEvent( Event event ) {
- image.dispose();
+ if( null != image ) {
+ image.dispose();
+ }
}
} );
- Menu menu = new Menu( shell, SWT.BAR );
- makeToolBarMenu( menu );
- shell.setMenuBar( menu );
-
- // canvas
- ScrolledComposite composite = new ScrolledComposite( shell, SWT.V_SCROLL | SWT.H_SCROLL );
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.marginWidth = 0;
+ gridLayout.marginHeight = 0;
+ gridLayout.horizontalSpacing = 0;
+ gridLayout.verticalSpacing = 0;
+ shell.setLayout( gridLayout );
- canvas = new Canvas( composite, SWT.NONE );
- composite.setContent( canvas );
+ makeMenuBar( shell );
- ImageData imageData = image.getImageData();
- Rectangle rect = new Rectangle( 0, 0, imageData.width, imageData.height );
- canvas.setBounds( rect );
+ final ScrolledComposite scrollComposite = new ScrolledComposite( shell, SWT.V_SCROLL | SWT.H_SCROLL );
+ GridData gridData = new GridData( SWT.FILL, SWT.FILL, true, true );
+ scrollComposite.setLayoutData( gridData );
+
+ scrollComposite.setExpandHorizontal( true );
+ scrollComposite.setExpandVertical( true );
- canvas.addPaintListener( new PaintListener() {
+ final int width = Integer.parseInt( config.getArg( ArgsConstants.RESOLUTION_WIDTH ) );
+ final int height = Integer.parseInt( config.getArg( ArgsConstants.RESOLUTION_HEIGHT ) );
+
+ imageCanvas = new Canvas( scrollComposite, SWT.NONE );
+ imageCanvas.setBackground( shell.getDisplay().getSystemColor( SWT.COLOR_DARK_GRAY ) );
+ imageCanvas.addPaintListener( new PaintListener() {
@Override
public void paintControl( PaintEvent e ) {
- e.gc.drawImage( image, 0, 0 );
+
+ logger.info( "capture screen." );
+
+ //TODO rotation
+// if( null != image && !image.isDisposed() ) {
+//
+// short currentRotationId = ScreenShotDialog.this.emulatorSkin.getCurrentRotationId();
+// RotationInfo rotationInfo = RotationInfo.getValue( currentRotationId );
+// float angle = (float) rotationInfo.angle();
+//
+// if( 0 != angle ) {
+//
+// Transform transform = new Transform( shell.getDisplay() );
+// transform.rotate( angle );
+// transform.translate( -width, 0 );
+//
+// e.gc.setTransform( transform );
+// e.gc.drawImage( image, LEFT_MARGIN, TOP_MARGIN );
+// transform.dispose();
+//
+// }else {
+// e.gc.drawImage( image, LEFT_MARGIN, TOP_MARGIN );
+// }
+//
+// }
+
+ e.gc.drawImage( image, LEFT_MARGIN, TOP_MARGIN );
+
}
} );
- int width = 0;
- int height = 0;
-
- Point shellLocation = shell.getLocation();
- Rectangle monitorSize = shell.getDisplay().getClientArea();
+ paletteData = new PaletteData( RED_MASK, GREEN_MASK, BLUE_MASK );
- if( shellLocation.y + imageData.height > monitorSize.height ) {
- shell.setSize( imageData.width, imageData.height );
- }else {
- shell.pack();
+ try {
+ capture();
+ } catch ( ScreenShotException e ) {
+ if( !shell.isDisposed() ) {
+ shell.close();
+ }
+ throw e;
}
+ scrollComposite.setContent( imageCanvas );
+ ImageData imageData = image.getImageData();
+ scrollComposite.setMinSize( imageData.width + ( 2 * LEFT_MARGIN ), imageData.height + ( 2 * TOP_MARGIN ) );
+
+ shell.pack();
+
}
- private void capture( Canvas canvas ) {
+ private void capture() throws ScreenShotException {
+
+ communicator.sendToQEMU( SendCommand.SCREEN_SHOT, null, true );
+ DataTranfer dataTranfer = communicator.getDataTranfer();
+
+ int count = 0;
+ boolean isFail = false;
+ byte[] receivedData = null;
+ int limitCount = SCREENSHOT_WAIT_LIMIT / SCREENSHOT_WAIT_INTERVAL;
- if( null != this.image ) {
- this.image.dispose();
+ synchronized ( dataTranfer ) {
+
+ while( dataTranfer.isTransferState() ) {
+
+ if( limitCount < count ) {
+ isFail = true;
+ break;
+ }
+
+ try {
+ dataTranfer.wait( SCREENSHOT_WAIT_INTERVAL );
+ } catch ( InterruptedException e ) {
+ logger.log( Level.SEVERE, e.getMessage(), e );
+ }
+
+ count++;
+ logger.info( "wait image data... count:" + count );
+
+ }
+
+ receivedData = dataTranfer.getReceivedData();
+
}
- this.image = new Image( parent.getDisplay(), canvas.getBounds() );
-
- GC gc = null;
- try {
- gc = new GC( canvas );
- gc.copyArea( image, 0, 0 );
- } finally {
- if ( null != gc ) {
- gc.dispose();
+ if( !isFail ) {
+
+ if( null != receivedData ) {
+
+ if( null != this.image ) {
+ this.image.dispose();
+ }
+
+ int width = Integer.parseInt( config.getArg( ArgsConstants.RESOLUTION_WIDTH ) );
+ int height = Integer.parseInt( config.getArg( ArgsConstants.RESOLUTION_HEIGHT ) );
+ ImageData imageData = new ImageData(width, height, COLOR_DEPTH, paletteData, 1, receivedData );
+
+ this.image = new Image( parent.getDisplay(), imageData );
+
+ imageCanvas.redraw();
+
+ }else {
+ throw new ScreenShotException( "Received image data is null." );
}
+
+ }else {
+ throw new ScreenShotException( "Fail to received image data." );
}
- canvas.update();
-
}
- private void makeToolBarMenu( Menu menu ) {
+ private void makeMenuBar( final Shell shell ) {
- MenuItem saveItem = new MenuItem( menu, SWT.FLAT );
+ ToolBar toolBar = new ToolBar( shell, SWT.HORIZONTAL );
+ GridData gridData = new GridData( GridData.FILL_HORIZONTAL );
+ toolBar.setLayoutData( gridData );
+
+ ToolItem saveItem = new ToolItem( toolBar, SWT.PUSH );
+ //FIXME icon
+// saveItem.setImage( shell.getDisplay().getSystemImage( SWT.ICON_QUESTION ) );
saveItem.setText( "Save" );
+ saveItem.setToolTipText( "Save" );
+ saveItem.setSelection( false );
saveItem.addSelectionListener( new SelectionAdapter() {
-
@Override
public void widgetSelected( SelectionEvent e ) {
- FileDialog fd = new FileDialog( shell, SWT.SAVE );
- fd.setText( "Save Image... " );
+ FileDialog fileDialog = new FileDialog( shell, SWT.SAVE );
+ fileDialog.setText( "Save Image" );
+
String[] filter = { "*.png;*.PNG;*.jpg;*.JPG;*.jpeg;*.JPEG;*.bmp;*.BMP" };
- String[] filterName = { "Image Files" };
- fd.setFilterExtensions( filter );
- fd.setFilterNames( filterName );
+ fileDialog.setFilterExtensions( filter );
+
+ String[] filterName = { "Image files (*.png *.jpg *.jpeg *.bmp)" };
+ fileDialog.setFilterNames( filterName );
- SimpleDateFormat formatter = new SimpleDateFormat( "yyyy-mm-dd-hhmmss" );
-
String vmName = SkinUtil.getVmName( config );
+ SimpleDateFormat formatter = new SimpleDateFormat( "yyyy-MM-dd-hhmmss" );
+ String dateString = formatter.format( new Date( System.currentTimeMillis() ) );
- fd.setFileName( vmName + "-" + formatter.format( new Date( System.currentTimeMillis() ) ) + ".png" );
+ fileDialog.setFileName( vmName + "-" + dateString + "." + DEFAULT_FILE_EXTENSION );
- String path = fd.open();
- if ( null == path ) {
- return;
+ String userHome = System.getProperty( "user.home" );
+ if( !StringUtil.isEmpty( userHome ) ) {
+ fileDialog.setFilterPath( userHome );
+ }else {
+ logger.warning( "Cannot find user home path int java System properties." );
}
-
- int i = path.lastIndexOf( '.' );
- String filePath = path;
- String format = "";
- if ( -1 != i ) {
- filePath = path.substring( 0, i - 1 );
- format = path.substring( i + 1, path.length() );
- format = format.toLowerCase();
- }
-
- FileOutputStream fos = null;
+ String filePath = fileDialog.open();
+ saveFile( filePath, fileDialog );
- try {
-
- fos = new FileOutputStream( filePath + "." + format, true );
-
- ImageLoader loader = new ImageLoader();
- loader.data = new ImageData[] { image.getImageData() };
-
- if ( null == format || format.equals( "png" ) ) {
- loader.save( fos, SWT.IMAGE_PNG );
- } else if ( format.equals( "jpg" ) || format.equals( "jpeg" ) ) {
- loader.save( fos, SWT.IMAGE_JPEG );
- } else if ( format.equals( "bmp" ) ) {
- loader.save( fos, SWT.IMAGE_BMP );
- } else {
-
- MessageBox msg = new MessageBox( shell, SWT.ICON_WARNING );
- msg.setText( "Warning" );
- msg.setMessage( "You have to use specific image formats. (PNG/JPG/BMP)" );
- msg.open();
-
- }
-
- } catch ( IOException ex ) {
- logger.log( Level.SEVERE, ex.getMessage(), ex );
- } finally {
- IOUtil.close( fos );
- }
}
} );
-
- MenuItem refreshItem = new MenuItem( menu, SWT.FLAT );
+ ToolItem refreshItem = new ToolItem( toolBar, SWT.PUSH );
+ //FIXME icon
+// refreshItem.setImage( shell.getDisplay().getSystemImage( SWT.ICON_INFORMATION ) );
refreshItem.setText( "Refresh" );
+ refreshItem.setToolTipText( "Refresh" );
+ refreshItem.setSelection( false );
- saveItem.addSelectionListener( new SelectionAdapter() {
-
+ refreshItem.addSelectionListener( new SelectionAdapter() {
@Override
public void widgetSelected( SelectionEvent e ) {
- capture( canvas );
+ try {
+ capture();
+ } catch ( ScreenShotException ex ) {
+ logger.log( Level.SEVERE, "Fail to create a screen shot.", ex );
+ SkinUtil.openMessage( shell, null, "Fail to create a screen shot.", SWT.ERROR, config );
+ }
}
} );
}
+ private void saveFile( String fileFullPath, FileDialog fileDialog ) {
+
+ if ( null == fileFullPath ) {
+ return;
+ }
+
+ String format = "";
+ String[] split = fileFullPath.split( "\\." );
+
+ if( 1 < split.length ) {
+
+ format = split[split.length - 1];
+
+ if ( new File( split[split.length - 2] ).isDirectory() ) {
+ // There is no file name.
+ SkinUtil.openMessage( shell, null, "Use correct file name.", SWT.ICON_WARNING, config );
+ String path = fileDialog.open();
+ saveFile( path, fileDialog );
+
+ }
+
+ }
+
+ FileOutputStream fos = null;
+
+ try {
+
+ if( StringUtil.isEmpty( format ) ) {
+ if( fileFullPath.endsWith( "." ) ) {
+ fileFullPath += DEFAULT_FILE_EXTENSION;
+ }else {
+ fileFullPath += "." + DEFAULT_FILE_EXTENSION;
+ }
+ }
+
+ fos = new FileOutputStream( fileFullPath, false );
+
+ ImageLoader loader = new ImageLoader();
+ loader.data = new ImageData[] { image.getImageData() };
+
+ if ( StringUtil.isEmpty( format ) || format.equalsIgnoreCase( "png" ) ) {
+ loader.save( fos, SWT.IMAGE_PNG );
+ } else if ( format.equalsIgnoreCase( "jpg" ) || format.equalsIgnoreCase( "jpeg" ) ) {
+ loader.save( fos, SWT.IMAGE_JPEG );
+ } else if ( format.equalsIgnoreCase( "bmp" ) ) {
+ loader.save( fos, SWT.IMAGE_BMP );
+ } else {
+
+ SkinUtil.openMessage( shell, null, "Use the specified image formats. ( PNG / JPG / JPEG / BMP )",
+ SWT.ICON_WARNING, config );
+ String path = fileDialog.open();
+ saveFile( path, fileDialog );
+
+ }
+
+ } catch ( FileNotFoundException ex ) {
+
+ logger.log( Level.WARNING, "Use correct file name.", ex );
+ SkinUtil.openMessage( shell, null, "Use correct file name.", SWT.ICON_WARNING, config );
+ String path = fileDialog.open();
+ saveFile( path, fileDialog );
+
+ } catch ( Exception ex ) {
+
+ logger.log( Level.SEVERE, "Fail to save this image file.", ex );
+ SkinUtil.openMessage( shell, null, "Fail to save this image file.", SWT.ERROR, config );
+ String path = fileDialog.open();
+ saveFile( path, fileDialog );
+
+ } finally {
+ IOUtil.close( fos );
+ }
+
+ }
+
public void open() {
+ if( shell.isDisposed() ) {
+ return;
+ }
+
shell.open();
while ( !shell.isDisposed() ) {
}
}
+
}
\ No newline at end of file
import java.util.Map;
import java.util.Map.Entry;
-import org.tizen.emulator.skin.dbi.RotationNameType;
+import org.tizen.emulator.skin.comm.ICommunicator.RotationInfo;
import org.tizen.emulator.skin.dbi.RotationType;
*
*/
public class SkinRotation {
-
- public enum RotationInfo {
-
- PORTRAIT( RotationNameType.PORTRAIT.value(), (short)0, 0 ),
- LANDSCAPE( RotationNameType.LANDSCAPE.value(), (short)1, -90 ),
- REVERSE_PORTRAIT( RotationNameType.REVERSE_PORTRAIT.value(), (short)2, 180 ),
- REVERSE_LANDSCAPE( RotationNameType.REVERSE_LANDSCAPE.value(), (short)3, 90 );
-
- private String value;
- private short id;
- private int angle;
-
- RotationInfo( String value, short id, int ratio ) {
- this.value = value;
- this.id = id;
- this.angle = ratio;
- }
- public String value() {
- return this.value;
- }
- public int angle() {
- return this.angle;
- }
- public short id() {
- return this.id;
- }
- }
private static Map<Short, RotationType> rotationMap;
private static Map<Short, RotationInfo> angleMap;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.tizen.emulator.skin.EmulatorConstants;
+import org.tizen.emulator.skin.comm.ICommunicator.RotationInfo;
import org.tizen.emulator.skin.config.EmulatorConfig;
import org.tizen.emulator.skin.config.EmulatorConfig.ArgsConstants;
import org.tizen.emulator.skin.config.EmulatorConfig.PropertiesConstants;
import org.tizen.emulator.skin.dbi.RotationType;
import org.tizen.emulator.skin.image.ImageRegistry;
import org.tizen.emulator.skin.image.ImageRegistry.ImageType;
-import org.tizen.emulator.skin.util.SkinRotation.RotationInfo;
/**
return false;
}
}
+
+ public static <T> void openMessage( Shell shell, String title, String message, int style, EmulatorConfig config ) {
+
+ MessageBox messageBox = new MessageBox( shell, style );
+
+ if( !StringUtil.isEmpty( title ) ) {
+ messageBox.setText( title );
+ }else {
+ messageBox.setText( makeEmulatorName( config ) );
+ }
+
+ messageBox.setMessage( StringUtil.nvl( message ) );
+ messageBox.open();
+
+ }
}
#include "maruskin_operation.h"
#include "maru_sdl.h"
#include "debug_ch.h"
-
#include "sdb.h"
#include "nbd.h"
-#include "../mloop_event.h"
+#include "mloop_event.h"
#include "emul_state.h"
#include "maruskin_keymap.h"
#include "emul_state.h"
+#include "hw/maru_pm.h"
+#include "qemu-common.h"
MULTI_DEBUG_CHANNEL(qemu, skin_operation);
{
TRACE( "do_hardkey_event event_type:%d, keycode:%d\n", event_type, keycode );
- if ( KEY_PRESSED == event_type ) {
- if ( kbd_mouse_is_absolute() ) {
- // home key or power key is used for resume.
- if ( ( HARD_KEY_HOME == keycode ) || ( HARD_KEY_POWER == keycode ) ) {
- if ( is_suspended_state() ) {
+ if ( is_suspended_state() ) {
+ if ( KEY_PRESSED == event_type ) {
+ if ( kbd_mouse_is_absolute() ) {
+ // home key or power key is used for resume.
+ if ( ( HARD_KEY_HOME == keycode ) || ( HARD_KEY_POWER == keycode ) ) {
INFO( "user requests system resume.\n" );
resume();
#ifdef _WIN32
socket_send( s, &buf_size, 4 );
socket_send( s, send_buf, buf_size );
- INFO( "send to sendord(size: %d) 127.0.0.1:%d/tcp \n", buf_size, tizen_base_port + SDB_TCP_EMULD_INDEX);
+ INFO( "send to sensord(size: %d) 127.0.0.1:%d/tcp \n", buf_size, tizen_base_port + SDB_TCP_EMULD_INDEX);
set_emul_rotation(rotation_type);
}
+QemuSurfaceInfo* get_screenshot_info( void ) {
+
+ DisplaySurface* qemu_display_surface = get_qemu_display_surface();
+
+ if ( !qemu_display_surface ) {
+ ERR( "qemu surface is NULL.\n" );
+ return NULL;
+ }
+
+ QemuSurfaceInfo* info = (QemuSurfaceInfo*) g_malloc0( sizeof(QemuSurfaceInfo) );
+ if ( !info ) {
+ ERR( "Fail to malloc for QemuSurfaceInfo.\n");
+ return NULL;
+ }
+
+ int length = qemu_display_surface->linesize * qemu_display_surface->height;
+ INFO( "screenshot data length:%d\n", length );
+
+ if ( 0 >= length ) {
+ g_free( info );
+ ERR( "screenshot data ( 0 >=length ). length:%d\n", length );
+ return NULL;
+ }
+
+ info->pixel_data = (unsigned char*) g_malloc0( length );
+ if ( !info->pixel_data ) {
+ g_free( info );
+ ERR( "Fail to malloc for pixel data.\n");
+ return NULL;
+ }
+
+ memcpy( info->pixel_data, qemu_display_surface->data, length );
+ info->pixel_data_length = length;
+
+ return info;
+
+}
+
+void free_screenshot_info( QemuSurfaceInfo* info ) {
+ if( info ) {
+ if( info->pixel_data ) {
+ g_free( info->pixel_data );
+ }
+ g_free( info );
+ }
+}
+
void open_shell(void)
{
//TODO
#ifndef MARUSKIN_OPERATION_H_
#define MARUSKIN_OPERATION_H_
+struct QemuSurfaceInfo {
+ unsigned char* pixel_data;
+ int pixel_data_length;
+};
+typedef struct QemuSurfaceInfo QemuSurfaceInfo;
+
void start_display( int handle_id, int lcd_size_width, int lcd_size_height, double scale_factor, short rotation_type );
void do_mouse_event( int event_type, int x, int y, int z );
void do_rotation_event( int rotation_type );
+QemuSurfaceInfo* get_screenshot_info( void );
+
+void free_screenshot_info( QemuSurfaceInfo* );
+
void open_shell(void);
void onoff_usb_kbd( int on );
#define RECV_BUF_SIZE 32
#define RECV_HEADER_SIZE 12
-#define SEND_HEADER_SIZE 6
+
+#define SEND_HEADER_SIZE 10
+#define SEND_BIG_BUF_SIZE 1024 * 1024 * 2
+#define SEND_BUF_SIZE 512
#define HEART_BEAT_INTERVAL 1
#define HEART_BEAT_FAIL_COUNT 5
RECV_CHANGE_LCD_STATE = 13,
RECV_OPEN_SHELL = 14,
RECV_USB_KBD = 15,
+ RECV_SCREEN_SHOT = 16,
RECV_RESPONSE_HEART_BEAT = 900,
RECV_CLOSE = 998,
RECV_RESPONSE_SHUTDOWN = 999,
enum {
SEND_HEART_BEAT = 1,
- SEND_HEART_BEAT_RESPONSE = 2,
+ SEND_SCREEN_SHOT = 2,
SEND_SENSOR_DAEMON_START = 800,
SEND_SHUTDOWN = 999,
};
static void* run_skin_server( void* args );
static int recv_n( int client_sock, char* read_buf, int recv_len );
-static int send_skin( int client_sock, short send_cmd );
+static int send_skin_header_only( int client_sock, short send_cmd );
+static int send_skin_data( int client_sock, short send_cmd, unsigned char* data, int length, int big_data );
+static int send_n( int client_sock, unsigned char* data, int length, int big_data );
+
static void* do_heart_beat( void* args );
static int start_heart_beat( int client_sock );
static void stop_heart_beat( void );
void shutdown_skin_server( void ) {
if ( client_sock ) {
INFO( "send shutdown to skin.\n" );
- if ( 0 > send_skin( client_sock, SEND_SHUTDOWN ) ) {
+ if ( 0 > send_skin_header_only( client_sock, SEND_SHUTDOWN ) ) {
ERR( "fail to send SEND_SHUTDOWN to skin.\n" );
stop_server = 1;
// force close
INFO( "notify_sensor_daemon_start\n" );
is_sensord_initialized = 1;
if ( client_sock ) {
- if ( 0 > send_skin( client_sock, SEND_SENSOR_DAEMON_START ) ) {
+ if ( 0 > send_skin_header_only( client_sock, SEND_SENSOR_DAEMON_START ) ) {
ERR( "fail to send SEND_SENSOR_DAEMON_START to skin.\n" );
}
}
maruskin_sdl_resize(); //send sdl event
break;
}
+ case RECV_SCREEN_SHOT: {
+ log_cnt += sprintf( log_buf + log_cnt, "RECV_SCREEN_SHOT ==\n" );
+ TRACE( log_buf );
+
+ QemuSurfaceInfo* info = get_screenshot_info();
+
+ if ( info ) {
+ send_skin_data( client_sock, SEND_SCREEN_SHOT, info->pixel_data, info->pixel_data_length, 1 );
+ free_screenshot_info( info );
+ } else {
+ ERR( "Fail to get screenshot data.\n" );
+ }
+
+ break;
+ }
case RECV_RESPONSE_HEART_BEAT: {
log_cnt += sprintf( log_buf + log_cnt, "RECV_RESPONSE_HEART_BEAT ==\n" );
TRACE( log_buf );
while ( 1 ) {
- recv_cnt = recv( client_sock, (void*) read_buf, ( recv_len - recv_cnt ), 0 );
+ recv_cnt = recv( client_sock, (void*) ( read_buf + recv_cnt ), ( recv_len - recv_cnt ), 0 );
if ( 0 > recv_cnt ) {
}
-static int send_skin( int client_sock, short send_cmd ) {
+static void make_header( int client_sock, short send_cmd, int data_length, char* sendbuf ) {
- char sendbuf[SEND_HEADER_SIZE];
- memset( &sendbuf, 0, SEND_HEADER_SIZE );
+ memset( sendbuf, 0, SEND_HEADER_SIZE );
int request_id = rand();
TRACE( "== SEND skin request_id:%d, send_cmd:%d ==\n", request_id, send_cmd );
request_id = htonl( request_id );
- short data = send_cmd;
- data = htons( data );
+ short cmd = send_cmd;
+ cmd = htons( cmd );
+
+ int length = data_length;
+ length = htonl( length );
char* p = sendbuf;
memcpy( p, &request_id, sizeof( request_id ) );
p += sizeof( request_id );
- memcpy( p, &data, sizeof( data ) );
+ memcpy( p, &cmd, sizeof( cmd ) );
+ p += sizeof( cmd );
+ memcpy( p, &length, sizeof( length ) );
+
+}
- ssize_t send_count = send( client_sock, sendbuf, SEND_HEADER_SIZE, 0 );
+static int send_n( int client_sock, unsigned char* data, int length, int big_data ) {
+
+ int send_cnt = 0;
+ int total_cnt = 0;
+
+ int buf_size = big_data ? SEND_BIG_BUF_SIZE : SEND_BUF_SIZE;
+ char databuf[buf_size];
+
+ INFO( "send_n start. length:%d\n", length );
+
+ while ( 1 ) {
+
+ if ( total_cnt == length ) {
+ break;
+ }
+
+ if ( buf_size < ( length - total_cnt ) ) {
+ send_cnt = buf_size;
+ } else {
+ send_cnt = ( length - total_cnt );
+ }
+ memset( &databuf, 0, send_cnt );
+ memcpy( &databuf, (char*) ( data + total_cnt ), send_cnt );
+
+ send_cnt = send( client_sock, databuf, send_cnt, 0 );
+
+ if ( 0 > send_cnt ) {
+ ERR( "send_n error. error code:%d\n", send_cnt );
+ return send_cnt;
+ } else {
+ total_cnt += send_cnt;
+ }
+
+ }
+
+ INFO( "send_n finished.\n" );
+
+ return total_cnt;
+
+}
+
+static int send_skin_header_only( int client_sock, short send_cmd ) {
+
+ char headerbuf[SEND_HEADER_SIZE];
+ make_header( client_sock, send_cmd, 0, headerbuf );
+
+ int send_count = send( client_sock, headerbuf, SEND_HEADER_SIZE, 0 );
return send_count;
}
+static int send_skin_data( int client_sock, short send_cmd, unsigned char* data, int length, int big_data ) {
+
+ char headerbuf[SEND_HEADER_SIZE];
+ make_header( client_sock, send_cmd, length, headerbuf );
+
+ int header_cnt = send( client_sock, headerbuf, SEND_HEADER_SIZE, 0 );
+
+ if ( 0 > header_cnt ) {
+ ERR( "send header for data is NULL.\n" );
+ return header_cnt;
+ }
+
+ if ( !data ) {
+ ERR( "send data is NULL.\n" );
+ return -1;
+ }
+
+ int send_cnt = send_n( client_sock, data, length, big_data );
+ INFO( "send_n result:%d\n", send_cnt );
+
+ return send_cnt;
+
+}
+
static void* do_heart_beat( void* args ) {
int client_sock = *(int*) args;
}
TRACE( "[HB] send heartbeat to skin.\n" );
- if ( 0 > send_skin( client_sock, SEND_HEART_BEAT ) ) {
+ if ( 0 > send_skin_header_only( client_sock, SEND_HEART_BEAT ) ) {
fail_count++;
} else {
fail_count = 0;