| /* |
| * Copyright (C) 2012 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.motorola.studio.android.emulator.ui.controls; |
| |
| import java.util.Timer; |
| import java.util.TimerTask; |
| |
| import org.eclipse.sequoyah.vnc.vncviewer.graphics.swt.ISWTPainter; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.GC; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.widgets.Canvas; |
| import org.eclipse.swt.widgets.Composite; |
| |
| import com.motorola.studio.android.emulator.core.model.IAndroidEmulatorInstance; |
| |
| /** |
| * DESCRIPTION: |
| * This class implements the composite that displays the contents of the |
| * CLI display, according to the provided painter object. |
| * |
| * RESPONSIBILITY: |
| * - Display the contents of the CLI display at screen |
| * |
| * COLABORATORS: |
| * None. |
| * |
| * USAGE: |
| * Add the composite to a view or other equivalent SWT object for it to |
| * display the result of the communication through VNC Protocol |
| * |
| */ |
| public class RemoteCLIDisplay extends Composite |
| { |
| private Canvas canvas; |
| |
| private Image screen = null; |
| |
| private ISWTPainter painter; |
| |
| private Timer refreshTimer; |
| |
| private static long FIRST_REFRESH_DELAY_MS = 500; /* Time in milliseconds for the first update */ |
| |
| private static long REFRESH_DELAY_PERIOD_MS = 300; /* Time in milliseconds between 2 updates */ |
| |
| private boolean active = false; |
| |
| private double zoomFactor = 1; |
| |
| /** |
| * Creates a new RemoteCLIDisplay object. |
| * |
| * @param parent The parent composite |
| * @param cliPainter The object where to retrieve pixels from |
| */ |
| public RemoteCLIDisplay(Composite parent, ISWTPainter cliPainter) |
| { |
| super(parent, SWT.BACKGROUND); |
| this.painter = cliPainter; |
| this.setLayout(parent.getLayout()); |
| canvas = new Canvas(this, SWT.BACKGROUND); |
| } |
| |
| /** |
| * Starts the display refresh |
| */ |
| synchronized public void start() |
| { |
| addRefreshTimer(); |
| setRunning(true); |
| } |
| |
| /** |
| * Stops the display refresh |
| */ |
| synchronized public void stop() |
| { |
| setRunning(false); |
| refreshTimer.cancel(); |
| |
| if (!canvas.isDisposed()) |
| { |
| GC gc = new GC(canvas); |
| canvas.drawBackground(gc, 0, 0, canvas.getSize().x, canvas.getSize().y); |
| gc.dispose(); |
| } |
| } |
| |
| /** |
| * Adds a timer that schedules the screen's update in a fixed period. |
| */ |
| private void addRefreshTimer() |
| { |
| refreshTimer = new Timer(); |
| |
| final IAndroidEmulatorInstance instance = UIHelper.getInstanceAssociatedToControl(this); |
| |
| refreshTimer.scheduleAtFixedRate(new TimerTask() |
| { |
| @Override |
| public void run() |
| { |
| if (instance.getHasCli()) |
| { |
| // Request CLI Update here (when applicable) |
| |
| getDisplay().syncExec(new Runnable() |
| { |
| public void run() |
| { |
| updateScreen(); |
| } |
| }); |
| } |
| } |
| }, FIRST_REFRESH_DELAY_MS, REFRESH_DELAY_PERIOD_MS); |
| } |
| |
| /** |
| * Performs the screen update itself |
| */ |
| private void updateScreen() |
| { |
| if (screen != null) |
| { |
| screen.dispose(); |
| } |
| |
| if ((!getDisplay().isDisposed()) && (isDisplayActive())) |
| { |
| if ((painter.getImageData() != null) && (!canvas.isDisposed())) |
| { |
| screen = |
| new Image(canvas.getDisplay(), painter.getImageData().scaledTo( |
| (int) (painter.getImageData().width * zoomFactor), |
| (int) (painter.getImageData().height * zoomFactor))); |
| |
| GC gc = new GC(canvas); |
| gc.drawImage(screen, 0, 0); |
| gc.dispose(); |
| } |
| } |
| else |
| { |
| stop(); |
| } |
| } |
| |
| /** |
| * Returns true if the component is running. |
| */ |
| synchronized public boolean isDisplayActive() |
| { |
| return active; |
| } |
| |
| /** |
| * Gets the Canvas used to show the screen. |
| * |
| * @return the Canvas object. |
| */ |
| public Canvas getCanvas() |
| { |
| return canvas; |
| } |
| |
| /** |
| * Retrieves the image being drawn at display |
| * |
| * @return The image being drawn at display |
| */ |
| public Image getScreen() |
| { |
| return screen; |
| } |
| |
| /** |
| * Retrieves the display width |
| * |
| * @return The display width |
| */ |
| public int getScreenWidth() |
| { |
| return painter.getWidth(); |
| } |
| |
| /** |
| * Retrieves the display height |
| * |
| * @return The display height |
| */ |
| public int getScreenHeight() |
| { |
| return painter.getHeight(); |
| } |
| |
| /** |
| * Sets the current state of the display |
| * |
| * @param running true if the display is refreshing; false otherwise |
| */ |
| synchronized private void setRunning(boolean running) |
| { |
| this.active = running; |
| } |
| |
| /** |
| * @see org.eclipse.swt.widgets.Widget#dispose() |
| */ |
| @Override |
| public void dispose() |
| { |
| if (isDisplayActive()) |
| { |
| stop(); |
| } |
| |
| if (screen != null) |
| { |
| screen.dispose(); |
| } |
| |
| canvas.dispose(); |
| super.dispose(); |
| } |
| |
| /** |
| * @see org.eclipse.swt.widgets.Control#setBackground(Color) |
| */ |
| @Override |
| public void setBackground(Color color) |
| { |
| super.setBackground(color); |
| canvas.setBackground(color); |
| } |
| |
| /** |
| * Retrieves the current zoom factor being applied to the screen |
| * |
| * @return The current zoom factor |
| */ |
| public double getZoomFactor() |
| { |
| return zoomFactor; |
| } |
| |
| /** |
| * Sets a new zoom factor to the screen |
| * |
| * @param zoomFactor The zoom factor to set to the screen |
| */ |
| public void setZoomFactor(double zoomFactor) |
| { |
| this.zoomFactor = zoomFactor; |
| |
| IAndroidEmulatorInstance instance = UIHelper.getInstanceAssociatedToControl(this); |
| if (instance.getHasCli()) |
| { |
| updateScreen(); |
| } |
| } |
| } |