mirror of https://github.com/apache/cloudstack.git
154 lines
4.4 KiB
Java
154 lines
4.4 KiB
Java
// Licensed to the Apache Software Foundation (ASF) under one
|
|
// or more contributor license agreements. See the NOTICE file
|
|
// distributed with this work for additional information
|
|
// regarding copyright ownership. The ASF licenses this file
|
|
// to you 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.cloud.consoleproxy.vnc;
|
|
|
|
import java.awt.Canvas;
|
|
import java.awt.Color;
|
|
import java.awt.Graphics;
|
|
import java.awt.Graphics2D;
|
|
import java.awt.Image;
|
|
import java.awt.Rectangle;
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.IOException;
|
|
import java.util.List;
|
|
|
|
import com.cloud.consoleproxy.util.ImageHelper;
|
|
import com.cloud.consoleproxy.util.TileInfo;
|
|
|
|
/**
|
|
* A <code>BuffereImageCanvas</code> component represents frame buffer image on the
|
|
* screen. It also notifies its subscribers when screen is repainted.
|
|
*/
|
|
public class BufferedImageCanvas extends Canvas implements FrameBufferCanvas {
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
// Offline screen buffer
|
|
private BufferedImage offlineImage;
|
|
|
|
// Cached Graphics2D object for offline screen buffer
|
|
private Graphics2D graphics;
|
|
|
|
private PaintNotificationListener listener;
|
|
|
|
public BufferedImageCanvas(PaintNotificationListener listener, int width, int height) {
|
|
super();
|
|
this.listener = listener;
|
|
|
|
setBackground(Color.black);
|
|
|
|
setFocusable(true);
|
|
|
|
// Don't intercept TAB key
|
|
setFocusTraversalKeysEnabled(false);
|
|
|
|
setCanvasSize(width, height);
|
|
}
|
|
|
|
public void setCanvasSize(int width, int height) {
|
|
this.offlineImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
|
graphics = offlineImage.createGraphics();
|
|
|
|
setSize(offlineImage.getWidth(), offlineImage.getHeight());
|
|
}
|
|
|
|
@Override
|
|
public void update(Graphics g) {
|
|
// Call paint() directly, without clearing screen first
|
|
paint(g);
|
|
}
|
|
|
|
@Override
|
|
public void paint(Graphics g) {
|
|
// Only part of image, requested with repaint(Rectangle), will be
|
|
// painted on screen.
|
|
synchronized(offlineImage) {
|
|
g.drawImage(offlineImage, 0, 0, this);
|
|
}
|
|
// Notify server that update is painted on screen
|
|
listener.imagePaintedOnScreen();
|
|
}
|
|
|
|
public BufferedImage getOfflineImage() {
|
|
return offlineImage;
|
|
}
|
|
|
|
public Graphics2D getOfflineGraphics() {
|
|
return graphics;
|
|
}
|
|
|
|
public void copyTile(Graphics2D g, int x, int y, Rectangle rc) {
|
|
synchronized(offlineImage) {
|
|
g.drawImage(offlineImage, x, y, x + rc.width, y + rc.height,
|
|
rc.x, rc.y, rc.x + rc.width, rc.y + rc.height, null);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Image getFrameBufferScaledImage(int width, int height) {
|
|
if(offlineImage != null)
|
|
return offlineImage.getScaledInstance(width, height, Image.SCALE_DEFAULT);
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public byte[] getFrameBufferJpeg() {
|
|
int width = 800;
|
|
int height = 600;
|
|
|
|
width = offlineImage.getWidth();
|
|
height = offlineImage.getHeight();
|
|
|
|
BufferedImage bufferedImage = new BufferedImage(width, height,
|
|
BufferedImage.TYPE_3BYTE_BGR);
|
|
Graphics2D g = bufferedImage.createGraphics();
|
|
synchronized(offlineImage) {
|
|
g.drawImage(offlineImage, 0, 0, width, height, 0, 0, width, height, null);
|
|
}
|
|
|
|
byte[] imgBits = null;
|
|
try {
|
|
imgBits = ImageHelper.jpegFromImage(bufferedImage);
|
|
} catch (IOException e) {
|
|
}
|
|
return imgBits;
|
|
}
|
|
|
|
@Override
|
|
public byte[] getTilesMergedJpeg(List<TileInfo> tileList, int tileWidth, int tileHeight) {
|
|
int width = Math.max(tileWidth, tileWidth*tileList.size());
|
|
BufferedImage bufferedImage = new BufferedImage(width, tileHeight,
|
|
BufferedImage.TYPE_3BYTE_BGR);
|
|
Graphics2D g = bufferedImage.createGraphics();
|
|
|
|
synchronized(offlineImage) {
|
|
int i = 0;
|
|
for(TileInfo tile : tileList) {
|
|
Rectangle rc = tile.getTileRect();
|
|
g.drawImage(offlineImage, i*tileWidth, 0, i*tileWidth + rc.width, rc.height,
|
|
rc.x, rc.y, rc.x + rc.width, rc.y + rc.height, null);
|
|
i++;
|
|
}
|
|
}
|
|
|
|
byte[] imgBits = null;
|
|
try {
|
|
imgBits = ImageHelper.jpegFromImage(bufferedImage);
|
|
} catch (IOException e) {
|
|
}
|
|
return imgBits;
|
|
}
|
|
} |