vmwarecore.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 877 行 · 第 1/2 页
JAVA
877 行
/*
* $Id: VMWareCore.java,v 1.7 2004/01/04 15:40:01 epr Exp $
*/
package org.jnode.driver.video.vmware;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.Raster;
import javax.naming.NameNotFoundException;
import org.apache.log4j.Logger;
import org.jnode.awt.util.BitmapGraphics;
import org.jnode.driver.DriverException;
import org.jnode.driver.pci.PCIDevice;
import org.jnode.driver.pci.PCI_IDs;
import org.jnode.driver.video.FrameBufferConfiguration;
import org.jnode.driver.video.HardwareCursor;
import org.jnode.driver.video.HardwareCursorAPI;
import org.jnode.driver.video.HardwareCursorImage;
import org.jnode.driver.video.Surface;
import org.jnode.driver.video.util.AbstractSurface;
import org.jnode.naming.InitialNaming;
import org.jnode.system.IOResource;
import org.jnode.system.MemoryResource;
import org.jnode.system.ResourceManager;
import org.jnode.system.ResourceNotFreeException;
import org.jnode.system.ResourceOwner;
import org.jnode.util.NumberUtils;
import org.jnode.vm.Address;
/**
* @author epr
*/
public class VMWareCore extends AbstractSurface implements VMWareConstants, PCI_IDs, HardwareCursorAPI {
/** My logger */
private final Logger log = Logger.getLogger(getClass());
private final VMWareDriver driver;
private final int indexPort;
private final int valuePort;
private final IOResource ports;
private final MemoryResource fifo;
private final MemoryResource videoRam;
private final int videoRamSize;
private final int maxWidth;
private final int maxHeight;
private final int bitsPerPixel;
private final int redMask;
private final int greenMask;
private final int blueMask;
private final int redMaskShift;
private final int greenMaskShift;
private final int blueMaskShift;
private final int capabilities;
private int bytesPerLine;
private int offset;
private int displayWidth;
private boolean fifoDirty = false;
private BitmapGraphics bitmapGraphics;
private ColorModel model;
private static final int MOUSE_ID = 1;
private int curX;
private int curY;
private boolean curVisible;
/**
* Create a new instance
*
* @param driver
* @param device
*/
public VMWareCore(VMWareDriver driver, PCIDevice device) throws ResourceNotFreeException, DriverException {
super(640, 480);
this.driver = driver;
final int basePort;
if (device.getConfig().getDeviceID() == PCI_DEVICE_ID_VMWARE_SVGA) {
basePort = SVGA_LEGACY_BASE_PORT;
this.indexPort = SVGA_LEGACY_BASE_PORT + SVGA_INDEX_PORT * 4;
this.valuePort = SVGA_LEGACY_BASE_PORT + SVGA_VALUE_PORT * 4;
} else {
basePort = device.getConfig().getBaseAddresses()[0].getIOBase();
this.indexPort = basePort + SVGA_INDEX_PORT;
this.valuePort = basePort + SVGA_VALUE_PORT;
}
log.debug("Found VMWare SVGA device using ports 0x" + NumberUtils.hex(indexPort) + " and 0x" + NumberUtils.hex(valuePort));
try {
final ResourceManager rm = (ResourceManager) InitialNaming.lookup(ResourceManager.NAME);
ports = rm.claimIOResource(device, basePort, SVGA_NUM_PORTS * 4);
final int id = getVMWareID();
if (id == SVGA_ID_0 || id == SVGA_ID_INVALID) {
dumpState();
throw new DriverException("No supported VMWare SVGA found, found id 0x" + NumberUtils.hex(id));
} else {
log.debug("VMWare SVGA ID: 0x" + NumberUtils.hex(id));
}
fifo = initFifo(device, rm);
this.capabilities = getReg32(SVGA_REG_CAPABILITIES);
this.videoRamSize = getReg32(SVGA_REG_FB_MAX_SIZE);
final int videoRamBase = getReg32(SVGA_REG_FB_START);
this.maxWidth = getReg32(SVGA_REG_MAX_WIDTH);
this.maxHeight = getReg32(SVGA_REG_MAX_HEIGHT);
final int bitsPerPixel = getReg32(SVGA_REG_BITS_PER_PIXEL);
this.bytesPerLine = getReg32(SVGA_REG_BYTES_PER_LINE);
this.videoRam = rm.claimMemoryResource(device, Address.valueOf(videoRamBase), videoRamSize, ResourceManager.MEMMODE_NORMAL);
this.bitsPerPixel = bitsPerPixel;
switch (bitsPerPixel) {
case 8 :
{
bitmapGraphics = BitmapGraphics.create8bppInstance(videoRam, width, height, bytesPerLine, 0);
}
break;
case 16 :
{
bitmapGraphics = BitmapGraphics.create16bppInstance(videoRam, width, height, bytesPerLine, 0);
}
break;
case 24 :
{
bitmapGraphics = BitmapGraphics.create24bppInstance(videoRam, width, height, bytesPerLine, 0);
}
break;
case 32 :
{
bitmapGraphics = BitmapGraphics.create32bppInstance(videoRam, width, height, bytesPerLine, 0);
}
break;
default :
throw new DriverException("Unknown bits/pixel value " + bitsPerPixel);
}
this.redMask = getReg32(SVGA_REG_RED_MASK);
this.greenMask = getReg32(SVGA_REG_GREEN_MASK);
this.blueMask = getReg32(SVGA_REG_BLUE_MASK);
this.redMaskShift = getMaskShift(redMask);
this.greenMaskShift = getMaskShift(greenMask);
this.blueMaskShift = getMaskShift(blueMask);
} catch (NameNotFoundException ex) {
throw new ResourceNotFreeException(ex);
}
}
/**
* Release all resources
*/
public final void release() {
ports.release();
fifo.release();
videoRam.release();
}
/**
* Open a given configuration
*
* @param config
*/
public void open(FrameBufferConfiguration config) {
final int w = config.getScreenWidth();
final int h = config.getScreenHeight();
setMode(w, h, config.getColorModel());
fillRect(0, 0, w, h, 0, PAINT_MODE);
//dumpState(); // For debugging purposes
defineCursor();
}
/**
* Close the SVGA screen
*
* @see org.jnode.driver.video.Surface#close()
*/
public synchronized void close() {
disableSVGA();
driver.close(this);
super.close();
}
/**
* Initialize the grahpics mode
*
* @param width
* @param height
*/
public final void setMode(int width, int height, ColorModel model) {
setReg32(SVGA_REG_WIDTH, width);
setReg32(SVGA_REG_HEIGHT, height);
setReg32(SVGA_REG_ENABLE, 1);
this.model = model;
this.offset = getReg32(SVGA_REG_FB_OFFSET);
setReg32(SVGA_REG_GUEST_ID, GUEST_OS_OTHER);
this.displayWidth = (getReg32(SVGA_REG_BYTES_PER_LINE) * 8) / ((bitsPerPixel + 7) & ~7);
this.bytesPerLine = getReg32(SVGA_REG_BYTES_PER_LINE);
setSize(width, height);
this.width = width;
this.height = height;
switch (bitsPerPixel) {
case 8 :
{
bitmapGraphics = BitmapGraphics.create8bppInstance(videoRam, width, height, bytesPerLine, 0);
}
break;
case 16 :
{
bitmapGraphics = BitmapGraphics.create16bppInstance(videoRam, width, height, bytesPerLine, 0);
}
break;
case 24 :
{
bitmapGraphics = BitmapGraphics.create24bppInstance(videoRam, width, height, bytesPerLine, 0);
}
break;
case 32 :
{
bitmapGraphics = BitmapGraphics.create32bppInstance(videoRam, width, height, bytesPerLine, 0);
}
break;
}
}
public FrameBufferConfiguration[] getConfigs() {
final FrameBufferConfiguration[] r = new FrameBufferConfiguration[3];
final ColorModel cm = new DirectColorModel(bitsPerPixel, redMask, greenMask, blueMask);
r[0] = new VMWareConfiguration(640, 480, cm);
r[1] = new VMWareConfiguration(800, 600, cm);
r[2] = new VMWareConfiguration(1024, 768, cm);
return r;
}
/**
* Disable the SVGA mode.
*/
public final void disableSVGA() {
setReg32(SVGA_REG_ENABLE, 0);
}
/**
* Update the entire screen
*/
public final void updateScreen() {
updateScreen(0, 0, width, height);
}
/**
* Update the given region of the screen
*/
public final void updateScreen(int x, int y, int width, int height) {
writeWordToFIFO(SVGA_CMD_UPDATE);
writeWordToFIFO(x);
writeWordToFIFO(y);
writeWordToFIFO(width);
writeWordToFIFO(height);
}
/**
* Draw the given shape
*
* @param shape
* @param color
* @param mode
*/
public final synchronized void draw(Shape shape, Shape clip, AffineTransform tx, Color color, int mode) {
syncFIFO();
super.draw(shape, clip, tx, color, mode);
final Rectangle r = getBounds(shape, tx);
updateScreen(r.x - 1, r.y - 1, r.width + 2, r.height + 2);
}
/**
* Draw an image to this surface
*
* @param src
* @param srcX
* @param srcY
* @param x
* The upper left x coordinate
* @param y
* The upper left y coordinate
* @param w
* @param h
* @param bgColor
* The background color to use for transparent pixels. If null, no transparent
* pixels are unmodified on the destination
*/
public void drawCompatibleRaster(Raster src, int srcX, int srcY, int x, int y, int w, int h, Color bgColor) {
if (bgColor != null) {
bitmapGraphics.drawImage(src, srcX, srcY, x, y, w, h, convertColor(bgColor));
} else {
bitmapGraphics.drawImage(src, srcX, srcY, x, y, w, h);
}
updateScreen(x, y, w, h);
}
/**
* @see org.jnode.driver.video.Surface#fill(Shape, Shape, AffineTransform, Color, int)
*/
public final synchronized void fill(Shape shape, Shape clip, AffineTransform tx, Color color, int mode) {
syncFIFO();
super.fill(shape, clip, tx, color, mode);
final Rectangle b = getBounds(shape, tx);
updateScreen(b.x, b.y, b.width, b.height);
}
/**
* Fill a given rectangle with a given color
*/
public final synchronized void fillRectangle(int x1, int y1, int x2, int y2, Color color, int mode) {
fillRect(x1, y1, x2 - x1, y2 - y1, convertColor(color), mode);
}
/**
* Fill a given rectangle with a given color
*
* @param x
* @param y
* @param width
* @param height
* @param color
* @param mode
*/
protected final void fillRect(int x, int y, int width, int height, int color, int mode) {
if (x < 0) {
width = Math.max(0, x + width);
x = 0;
}
if (y < 0) {
height = Math.max(0, y + height);
y = 0;
}
if ((width > 0) && (height > 0)) {
if (mode == Surface.XOR_MODE) {
writeWordToFIFO(SVGA_CMD_RECT_ROP_FILL);
writeWordToFIFO(color);
writeWordToFIFO(x);
writeWordToFIFO(y);
writeWordToFIFO(width);
writeWordToFIFO(height);
writeWordToFIFO(SVGA_ROP_XOR);
} else {
writeWordToFIFO(SVGA_CMD_RECT_FILL);
writeWordToFIFO(color);
writeWordToFIFO(x);
writeWordToFIFO(y);
writeWordToFIFO(width);
writeWordToFIFO(height);
}
}
}
/**
* Dump the state of the SVGA to log.
*/
public final void dumpState() {
log.debug("Max. Resolution " + maxWidth + "*" + maxHeight);
log.debug("Cur. Resolution " + width + "*" + height);
log.debug("Bits/Pixel " + bitsPerPixel);
log.debug("Bytes/Line " + bytesPerLine);
log.debug("Offset " + offset);
log.debug("Display width " + displayWidth);
log.debug("Red mask 0x" + NumberUtils.hex(getReg32(SVGA_REG_RED_MASK)));
log.debug("Green mask 0x" + NumberUtils.hex(getReg32(SVGA_REG_GREEN_MASK)));
log.debug("Blue mask 0x" + NumberUtils.hex(getReg32(SVGA_REG_BLUE_MASK)));
log.debug("Capabilities 0x" + NumberUtils.hex(capabilities));
}
/**
* Set the pixel at the given location to the given color.
*
* @param x
* @param y
* @param color
*/
protected final void drawPixel(int x, int y, int color, int mode) {
bitmapGraphics.drawPixels(x, y, 1, color, mode);
/*
* if ((x >= 0) && (x < width) && (y > = 0) && (y
* < height)) { y; final int ofs; if (mode == Surface.XOR_MODE) { switch (bitsPerPixel) {
* case 8 : ofs = ofsY + x; videoRam.xorByte(ofs, (byte) color, 1); break; case 16 : ofs =
* ofsY + (x << 1); videoRam.xorShort(ofs, (short) color, 1); break; case 24 : 3);
* videoRam.xorShort(ofs, (short) (color & 0xFFFF), 1); videoRam.xorByte(ofs + 2, (byte)
* ((color >> 16) & 0xFF), 1); break; case 32 : ofs = ofsY + (x
* << 2); videoRam.xorInt(ofs, color, 1); break; default : throw new
* RuntimeException("Unknown bitsPerPixel"); } } else { switch (bitsPerPixel) { case 8 :
* ofs = ofsY + x; videoRam.setByte(ofs, (byte) color); break; case 16 : ofs = ofsY + (x
* << 1); videoRam.setShort(ofs, (short) color); break; case 24 : 3);
* videoRam.setShort(ofs, (short) (color & 0xFFFF)); videoRam.setByte(ofs + 2, (byte)
* ((color >> 16) & 0xFF)); break; case 32 : ofs = ofsY + (x << 2); videoRam.setInt(ofs,
* color); break; default : throw new RuntimeException("Unknown bitsPerPixel"); } }
*/
}
/**
* Low level draw line method. This method does not call updateScreen.
*
* @param x1
* @param y1
* @param x2
* @param y2
* @param c
* @param mode
*/
protected final void drawLine(int x1, int y1, int x2, int y2, int c, int mode) {
if (x1 == x2) {
// Vertical line
fillRect(x1, Math.min(y1, y2), 1, Math.abs(y2 - y1), c, mode);
} else if (y1 == y2) {
// Horizontal line
//drawHorizontalLine(Math.min(x1, x2), y1, Math.abs(x2 - x1)+1, c, mode);
fillRect(Math.min(x1, x2), y1, Math.abs(x2 - x1) + 1, 1, c, mode);
} else {
super.drawLine(x1, y1, x2, y2, c, mode);
}
}
protected final void drawHorizontalLine(int x, int y, int w, int color, int mode) {
if ((x >= 0) && (x < width) && (y >= 0) && (y < height)) {
w = Math.min(width - x, w);
final int ofsY = bytesPerLine * y;
int ofs;
if (mode == Surface.XOR_MODE) {
switch (bitsPerPixel) {
case 8 :
ofs = ofsY + x;
videoRam.xorByte(ofs, (byte) color, w);
break;
case 16 :
ofs = ofsY + (x << 1);
videoRam.xorShort(ofs, (short) color, w);
break;
case 24 :
ofs = ofsY + (x * 3);
while (w > 0) {
videoRam.xorShort(ofs, (short) (color & 0xFFFF), 1);
videoRam.xorByte(ofs + 2, (byte) ((color >> 16) & 0xFF), 1);
w--;
ofs += 3;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?