blob: f3a73d70dbdd30ca5b83c9727c33ebfc608e2689 [file] [log] [blame]
// 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 common.adapter;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import rdpclient.rdp.ServerBitmapUpdate;
import streamer.BaseElement;
import streamer.ByteBuffer;
import streamer.Element;
import streamer.Link;
import streamer.Order;
import streamer.Pipeline;
import streamer.PipelineImpl;
import common.BitmapOrder;
import common.BitmapRectangle;
import common.BufferedImageCanvas;
import common.CopyRectOrder;
import common.OrderType;
import common.ScreenDescription;
public class AwtCanvasAdapter extends BaseElement {
protected ScreenDescription screen;
public AwtCanvasAdapter(String id, BufferedImageCanvas canvas, ScreenDescription screen) {
super(id);
this.canvas = canvas;
this.screen = screen;
}
protected BufferedImageCanvas canvas;
@Override
public String toString() {
return "AwtRdpAdapter(" + id + ")";
}
@Override
public void handleData(ByteBuffer buf, Link link) {
if (verbose)
System.out.println("[" + this + "] INFO: Data received: " + buf + ".");
Order order = buf.getOrder();
switch ((OrderType)order.type) {
case BITMAP_UPDATE:
handleBitmap((BitmapOrder)order, buf);
break;
case COPY_RECT:
handleCopyRect((CopyRectOrder)order, buf);
break;
default:
throw new RuntimeException("Order is not implemented: " + buf + ".");
// break;
}
buf.unref();
}
private void handleCopyRect(CopyRectOrder order, ByteBuffer buf) {
// Copy image
canvas.getOfflineGraphics().copyArea(order.srcX, order.srcY, order.width, order.height, order.x - order.srcX, order.y - order.srcY);
// Request update of repainted area
canvas.updateFrameBuffer(order.x, order.y, order.width, order.height);
canvas.repaint(order.x, order.y, order.width, order.height);
}
private void handleBitmap(BitmapOrder order, ByteBuffer buf) {
// Draw rectangle on offline buffer
BufferedImage image = canvas.getOfflineImage();
Graphics2D g = (Graphics2D)image.getGraphics();
for (BitmapRectangle rectangle : order.rectangles) {
// *DEBUG*/System.out.println("["+this+"] DEBUG: Rectangle: " +
// rectangle.toString());
int x = rectangle.x;
int y = rectangle.y;
int width = rectangle.width;
int height = rectangle.height;
int bufferWidth = rectangle.bufferWidth;
int bufferHeight = rectangle.bufferHeight;
BufferedImage rectImage;
switch (rectangle.colorDepth) {
case 8: {
rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_BYTE_INDEXED, screen.colorMap);
WritableRaster raster = rectImage.getRaster();
raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toByteArray());
break;
}
case 15: {
rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_USHORT_555_RGB);
WritableRaster raster = rectImage.getRaster();
raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toShortArray());
break;
}
case 16: {
rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_USHORT_565_RGB);
WritableRaster raster = rectImage.getRaster();
raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toShortArray());
break;
}
case 24:
case 32: {
rectImage = new BufferedImage(bufferWidth, height, BufferedImage.TYPE_INT_RGB);
WritableRaster raster = rectImage.getRaster();
raster.setDataElements(0, 0, bufferWidth, bufferHeight, rectangle.bitmapDataStream.toIntLEArray());
break;
}
default:
throw new RuntimeException("Unsupported color depth: " + rectangle.colorDepth + ".");
}
g.setClip(x, y, width, height);
g.drawImage(rectImage, x, y, null);
// Request update of repainted area
canvas.updateFrameBuffer(x, y, width, height);
canvas.repaint(x, y, width, height);
}
}
/**
* Example.
*/
public static void main(String args[]) {
// System.setProperty("streamer.Link.debug", "true");
// System.setProperty("streamer.Element.debug", "true");
// System.setProperty("streamer.Pipeline.debug", "true");
ByteBuffer packet = new ByteBuffer(new byte[] {0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x00,
0x01, 0x04, 0x0a, 0x00, 0x0c, (byte)0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
Pipeline pipeline = new PipelineImpl("test");
Element bitmap = new ServerBitmapUpdate("bitmap");
BufferedImageCanvas canvas = new BufferedImageCanvas(1024, 768);
Element adapter = new AwtCanvasAdapter("test", canvas, null) {
{
verbose = true;
}
};
pipeline.addAndLink(bitmap, adapter);
bitmap.handleData(packet, null);
}
}