📄 rdesktopcanvas.java
字号:
/* RdesktopCanvas.java
* Component: ProperJavaRDP
*
* Revision: $Revision: 1.8 $
* Author: $Author: telliott $
* Date: $Date: 2005/09/27 14:15:39 $
*
* Copyright (c) 2005 Propero Limited
*
* Purpose: Canvas component, handles drawing requests from server,
* and passes user input to Input class.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* (See gpl.txt for details of the GNU General Public License.)
*
*/
package net.propero.rdp;
import java.awt.*;
import java.awt.image.*;
import net.propero.rdp.keymapping.KeyCode;
import net.propero.rdp.keymapping.KeyCode_FileBased;
import net.propero.rdp.orders.*;
import org.apache.log4j.Logger;
// import org.apache.log4j.NDC;
public abstract class RdesktopCanvas extends Canvas {
static Logger logger = Logger.getLogger(RdesktopCanvas.class);
private RasterOp rop = null;
WrappedImage backstore;
// Graphics backstore_graphics;
private Cursor previous_cursor = null; // for setBusyCursor and
// unsetBusyCursor
private Input input = null;
public static final int ROP2_COPY = 0xc;
private static final int ROP2_XOR = 0x6;
private static final int ROP2_AND = 0x8;
private static final int ROP2_NXOR = 0x9;
private static final int ROP2_OR = 0xe;
private static final int MIX_TRANSPARENT = 0;
private static final int MIX_OPAQUE = 1;
private static final int TEXT2_VERTICAL = 0x04;
private static final int TEXT2_IMPLICIT_X = 0x20;
public KeyCode keys = null;
public KeyCode_FileBased fbKeys = null;
public String sKeys = null;
public int width = 0;
public int height = 0;
// private int[] colors = null; // needed for integer backstore
protected IndexColorModel colormap = null;
private Cache cache = null;
public Rdp rdp = null;
// protected int[] backstore_int = null;
// Clip region
private int top = 0;
private int left = 0;
private int right = 0;
private int bottom = 0;
/**
* Initialise this canvas to specified width and height, also initialise
* backstore
*
* @param width
* Desired width of canvas
* @param height
* Desired height of canvas
*/
public RdesktopCanvas(int width, int height) {
super();
rop = new RasterOp();
this.width = width;
this.height = height;
this.right = width - 1; // changed
this.bottom = height - 1; // changed
setSize(width, height);
backstore = new WrappedImage(width, height, BufferedImage.TYPE_INT_RGB);
// now do input listeners in registerCommLayer() / registerKeyboard()
}
public void paint(Graphics g) {
update(g);
}
public abstract void update(Graphics g);
/**
* Register a colour palette with this canvas
*
* @param cm
* Colour model to be used with this canvas
*/
public void registerPalette(IndexColorModel cm) {
this.colormap = cm;
backstore.setIndexColorModel(cm);
}
/**
* Register the Rdp layer to act as the communications interface to this
* canvas
* @param rdp Rdp object controlling Rdp layer communication
*/
public void registerCommLayer(Rdp rdp) {
this.rdp = rdp;
if (fbKeys != null)
input = new Input_Localised(this, rdp, fbKeys);
}
/**
* Register keymap
* @param keys Keymapping object for use in handling keyboard events
*/
public void registerKeyboard(KeyCode_FileBased keys) {
this.fbKeys = keys;
if (rdp != null) {
// rdp and keys have been registered...
input = new Input_Localised(this, rdp, keys);
}
}
/**
* Set cache for this session
*
* @param cache
* Cache to be used in this session
*/
public void registerCache(Cache cache) {
this.cache = cache;
}
/**
* Display a compressed bitmap direct to the backstore NOTE: Currently not
* functioning correctly, see Bitmap.decompressImgDirect Does not call
* repaint. Image is drawn to canvas on next update
*
* @param x
* x coordinate within backstore for drawing of bitmap
* @param y
* y coordinate within backstore for drawing of bitmap
* @param width
* Width of bitmap
* @param height
* Height of bitmap
* @param size
* Size (bytes) of compressed bitmap data
* @param data
* Packet containing compressed bitmap data at current read
* position
* @param Bpp
* Bytes-per-pixel for bitmap
* @param cm
* Colour model currently in use, if any
* @throws RdesktopException
*/
public void displayCompressed(int x, int y, int width, int height,
int size, RdpPacket_Localised data, int Bpp, IndexColorModel cm)
throws RdesktopException {
backstore = Bitmap.decompressImgDirect(width, height, size, data, Bpp,
cm, x, y, backstore);
}
/**
* Draw an image object to the backstore, does not call repaint. Image is
* drawn to canvas on next update.
*
* @param img
* Image to draw to backstore
* @param x
* x coordinate for drawing location
* @param y
* y coordinate for drawing location
* @throws RdesktopException
*/
public void displayImage(Image img, int x, int y) throws RdesktopException {
Graphics g = backstore.getGraphics();
g.drawImage(img, x, y, null);
/* ********* Useful test for identifying image boundaries ************ */
// g.setColor(Color.RED);
// g.drawRect(x,y,data.getWidth(null),data.getHeight(null));
g.dispose();
}
/**
* Draw an image (from an integer array of colour data) to the backstore,
* does not call repaint. Image is drawn to canvas on next update.
*
* @param data
* Integer array of pixel colour information
* @param w
* Width of image
* @param h
* Height of image
* @param x
* x coordinate for drawing location
* @param y
* y coordinate for drawing location
* @param cx
* Width of drawn image (clips, does not scale)
* @param cy
* Height of drawn image (clips, does not scale)
* @throws RdesktopException
*/
public void displayImage(int[] data, int w, int h, int x, int y, int cx,
int cy) throws RdesktopException {
backstore.setRGB(x, y, cx, cy, data, 0, w);
/* ********* Useful test for identifying image boundaries ************ */
// Graphics g = backstore.getGraphics();
// g.drawImage(data,x,y,null);
// g.setColor(Color.RED);
// g.drawRect(x,y,cx,cy);
// g.dispose();
}
/**
* Retrieve an image from the backstore, as integer pixel information
*
* @param x
* x coordinate of image to retrieve
* @param y
* y coordinage of image to retrieve
* @param cx
* width of image to retrieve
* @param cy
* height of image to retrieve
* @return Requested area of backstore, as an array of integer pixel colours
*/
public int[] getImage(int x, int y, int cx, int cy) {
int[] data = new int[cx * cy];
data = backstore.getRGB(x, y, cx, cy, null, // no existing image data to
// add to
0, // retrieving as complete image, no offset needed
cx);
return data;
}
/**
* Draw an image (from an integer array of colour data) to the backstore,
* also calls repaint to draw image to canvas
*
* @param x
* x coordinate at which to draw image
* @param y
* y coordinate at which to draw image
* @param cx
* Width of drawn image (clips, does not scale)
* @param cy
* Height of drawn image (clips, does not scale)
* @param data
* Image to draw, represented as an array of integer pixel
* colours
*/
public void putImage(int x, int y, int cx, int cy, int[] data) {
backstore.setRGBNoConversion(x, y, cx, cy, data, 0, // drawing entire image, no
// offset needed
cx);
this.repaint(x, y, cx, cy);
}
/**
* Reset clipping boundaries for canvas
*/
public void resetClip() {
Graphics g = this.getGraphics();
Rectangle bounds = this.getBounds();
g.setClip(bounds.x, bounds.y, bounds.width, bounds.height);
this.top = 0;
this.left = 0;
this.right = this.width - 1; // changed
this.bottom = this.height - 1; // changed
}
/**
* Set clipping boundaries for canvas, based on a bounds order
*
* @param bounds
* Order defining new boundaries
*/
public void setClip(BoundsOrder bounds) {
Graphics g = this.getGraphics();
g.setClip(bounds.getLeft(), bounds.getTop(), bounds.getRight()
- bounds.getLeft(), bounds.getBottom() - bounds.getTop());
this.top = bounds.getTop();
this.left = bounds.getLeft();
this.right = bounds.getRight();
this.bottom = bounds.getBottom();
}
/**
* Move the mouse pointer (only available in Java 1.3+)
*
* @param x
* x coordinate for mouse move
* @param y
* y coordinate for mouse move
*/
public void movePointer(int x, int y) {
// need Java 1.3+ to move mouse with Robot
}
/**
* Draw a filled rectangle to the screen
*
* @param x
* x coordinate (left) of rectangle
* @param y
* y coordinate (top) of rectangle
* @param cx
* Width of rectangle
* @param cy
* Height of rectangle
* @param color
* Colour of rectangle
*/
public void fillRectangle(int x, int y, int cx, int cy, int color) {
// clip here instead
if (x > this.right || y > this.bottom)
return; // off screen
int Bpp = Options.Bpp;
// convert to 24-bit colour
color = Bitmap.convertTo24(color);
// correction for 24-bit colour
if (Bpp == 3)
color = ((color & 0xFF) << 16) | (color & 0xFF00)
| ((color & 0xFF0000) >> 16);
// Perform standard clipping checks, x-axis
int clipright = x + cx - 1;
if (clipright > this.right)
clipright = this.right;
if (x < this.left)
x = this.left;
cx = clipright - x + 1;
// Perform standard clipping checks, y-axis
int clipbottom = y + cy - 1;
if (clipbottom > this.bottom)
clipbottom = this.bottom;
if (y < this.top)
y = this.top;
cy = clipbottom - y + 1;
// construct rectangle as integer array, filled with color
int[] rect = new int[cx * cy];
for (int i = 0; i < rect.length; i++)
rect[i] = color;
// draw rectangle to backstore
backstore.setRGB(x, y, cx, cy, rect, 0, cx);
// if(logger.isInfoEnabled()) logger.info("rect
// \t(\t"+x+",\t"+y+"),(\t"+(x+cx-1)+",\t"+(y+cy-1)+")");
this.repaint(x, y, cx, cy); // seems to be faster than Graphics.fillRect
// according to JProbe
}
/**
* Draw a line to the screen
*
* @param x1
* x coordinate of start point of line
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -