All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.microemu.device.swt.SwtDeviceDisplay Maven / Gradle / Ivy

The newest version!
/*
 *  MicroEmulator
 *  Copyright (C) 2002 Bartek Teodorczyk 
 *
 *  It is licensed under the following two licenses as alternatives:
 *    1. GNU Lesser General Public License (the "LGPL") version 2.1 or any newer version
 *    2. Apache License (the "AL") Version 2.0
 *
 *  You may not use this file except in compliance with at least one of
 *  the above two licenses.
 *
 *  You may obtain a copy of the LGPL at
 *      http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
 *
 *  You may obtain a copy of the AL 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 LGPL or the AL for the specific language governing permissions and
 *  limitations.
 */

package org.microemu.device.swt;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;

import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.RGB;
import org.microemu.DisplayAccess;
import org.microemu.EmulatorContext;
import org.microemu.MIDletAccess;
import org.microemu.MIDletBridge;
import org.microemu.app.ui.swt.ImageFilter;
import org.microemu.app.ui.swt.SwtDeviceComponent;
import org.microemu.app.ui.swt.SwtGraphics;
import org.microemu.app.util.IOUtils;
import org.microemu.device.Device;
import org.microemu.device.DeviceFactory;
import org.microemu.device.InputMethod;
import org.microemu.device.MutableImage;
import org.microemu.device.impl.Button;
import org.microemu.device.impl.Color;
import org.microemu.device.impl.DeviceDisplayImpl;
import org.microemu.device.impl.PositionedImage;
import org.microemu.device.impl.Rectangle;
import org.microemu.device.impl.Shape;
import org.microemu.device.impl.SoftButton;

public class SwtDeviceDisplay implements DeviceDisplayImpl {
	EmulatorContext context;

	Rectangle displayRectangle;

	Rectangle displayPaintable;

	boolean isColor;

	int numColors;

	int numAlphaLevels;

	Color backgroundColor;

	Color foregroundColor;

	PositionedImage mode123Image;

	PositionedImage modeAbcUpperImage;

	PositionedImage modeAbcLowerImage;

	public SwtDeviceDisplay(EmulatorContext context) {
		this.context = context;
	}

	public MutableImage getDisplayImage() {
		return context.getDisplayComponent().getDisplayImage();
	}

	public int getHeight() {
		return displayPaintable.height;
	}

	public int getWidth() {
		return displayPaintable.width;
	}

	public int getFullHeight() {
		return displayRectangle.height;
	}

	public int getFullWidth() {
		return displayRectangle.width;
	}

	public boolean isColor() {
		return isColor;
	}

	public boolean isFullScreenMode() {
		MIDletAccess ma = MIDletBridge.getMIDletAccess();
		if (ma == null) {
			return false;
		} else {
			DisplayAccess da = ma.getDisplayAccess();
			if (da == null) {
				return false;
			} else {
				return da.isFullScreenMode();
			}
		}
	}

	public int numAlphaLevels() {
		return numAlphaLevels;
	}

	public int numColors() {
		return numColors;
	}

	public void paintControls(SwtGraphics g) {
		Device device = DeviceFactory.getDevice();

		g.setBackground(g.getColor(new RGB(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor
				.getBlue())));
		g.fillRectangle(0, 0, displayRectangle.width, displayPaintable.y);
		g.fillRectangle(0, displayPaintable.y, displayPaintable.x, displayPaintable.height);
		g.fillRectangle(displayPaintable.x + displayPaintable.width, displayPaintable.y, displayRectangle.width
				- displayPaintable.x - displayPaintable.width, displayPaintable.height);
		g.fillRectangle(0, displayPaintable.y + displayPaintable.height, displayRectangle.width,
				displayRectangle.height - displayPaintable.y - displayPaintable.height);

		g.setForeground(g.getColor(new RGB(foregroundColor.getRed(), foregroundColor.getGreen(), foregroundColor
				.getBlue())));
		for (Enumeration s = device.getSoftButtons().elements(); s.hasMoreElements();) {
			((SwtSoftButton) s.nextElement()).paint(g);
		}

		int inputMode = device.getInputMethod().getInputMode();
		if (inputMode == InputMethod.INPUT_123) {
			g.drawImage(((SwtImmutableImage) mode123Image.getImage()).getImage(), mode123Image.getRectangle().x,
					mode123Image.getRectangle().y);
		} else if (inputMode == InputMethod.INPUT_ABC_UPPER) {
			g.drawImage(((SwtImmutableImage) modeAbcUpperImage.getImage()).getImage(),
					modeAbcUpperImage.getRectangle().x, modeAbcUpperImage.getRectangle().y);
		} else if (inputMode == InputMethod.INPUT_ABC_LOWER) {
			g.drawImage(((SwtImmutableImage) modeAbcLowerImage.getImage()).getImage(),
					modeAbcLowerImage.getRectangle().x, modeAbcLowerImage.getRectangle().y);
		}
	}

	public void paintDisplayable(SwtGraphics g, int x, int y, int width, int height) {
		MIDletAccess ma = MIDletBridge.getMIDletAccess();
		if (ma == null) {
			return;
		}
		DisplayAccess da = ma.getDisplayAccess();
		if (da == null) {
			return;
		}
		Displayable current = da.getCurrent();
		if (current == null) {
			return;
		}

		g.setForeground(g.getColor(new RGB(foregroundColor.getRed(), foregroundColor.getGreen(), foregroundColor
				.getBlue())));

		org.eclipse.swt.graphics.Rectangle oldclip = g.getClipping();
		if (!(current instanceof Canvas) || ((Canvas) current).getWidth() != displayRectangle.width
				|| ((Canvas) current).getHeight() != displayRectangle.height) {
			g.translate(displayPaintable.x, displayPaintable.y);
		}
		g.setClipping(new org.eclipse.swt.graphics.Rectangle(x, y, width, height));
		Font oldf = g.getFont();
		ma.getDisplayAccess().paint(new SwtDisplayGraphics(g, getDisplayImage()));
		g.setFont(oldf);
		if (!(current instanceof Canvas) || ((Canvas) current).getWidth() != displayRectangle.width
				|| ((Canvas) current).getHeight() != displayRectangle.height) {
			g.translate(-displayPaintable.x, -displayPaintable.y);
		}
		g.setClipping(oldclip);
	}

	public void repaint(int x, int y, int width, int height) {
		context.getDisplayComponent().repaintRequest(x, y, width, height);
	}

	public void setScrollDown(boolean state) {
		Enumeration en = DeviceFactory.getDevice().getSoftButtons().elements();
		while (en.hasMoreElements()) {
			SoftButton button = (SoftButton) en.nextElement();
			if (button.getType() == SoftButton.TYPE_ICON && button.getName().equals("down")) {
				button.setVisible(state);
			}
		}
	}

	public void setScrollUp(boolean state) {
		Enumeration en = DeviceFactory.getDevice().getSoftButtons().elements();
		while (en.hasMoreElements()) {
			SoftButton button = (SoftButton) en.nextElement();
			if (button.getType() == SoftButton.TYPE_ICON && button.getName().equals("up")) {
				button.setVisible(state);
			}
		}
	}

	public Rectangle getDisplayRectangle() {
		return displayRectangle;
	}

	public Rectangle getDisplayPaintable() {
		return displayPaintable;
	}

	public Color getBackgroundColor() {
		return backgroundColor;
	}

	public Color getForegroundColor() {
		return foregroundColor;
	}

	public Image createImage(int width, int height) {
		if (width <= 0 || height <= 0) {
			throw new IllegalArgumentException();
		}

		return new SwtMutableImage(width, height);
	}

	public Image createImage(String name) throws IOException {
		return getImage(name);
	}

	public Image createImage(javax.microedition.lcdui.Image source) {
		if (source.isMutable()) {
			return new SwtImmutableImage((SwtMutableImage) source);
		} else {
			return source;
		}
	}

	public Image createImage(byte[] imageData, int imageOffset, int imageLength) {
		ByteArrayInputStream is = new ByteArrayInputStream(imageData, imageOffset, imageLength);
		try {
			return getImage(is);
		} catch (IOException ex) {
			throw new IllegalArgumentException(ex.toString());
		}
	}

	public Image createImage(InputStream is) throws IOException {
		if (is == null) {
			throw new IOException();
		}

		return getImage(is);
	}

	public void setNumAlphaLevels(int i) {
		numAlphaLevels = i;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.barteo.emulator.device.impl.DeviceDisplayImpl#setNumColors(int)
	 */
	public void setNumColors(int i) {
		numColors = i;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.barteo.emulator.device.impl.DeviceDisplayImpl#setIsColor(boolean)
	 */
	public void setIsColor(boolean b) {
		isColor = b;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.barteo.emulator.device.impl.DeviceDisplayImpl#setBackgroundColor(java.awt.Color)
	 */
	public void setBackgroundColor(Color color) {
		backgroundColor = color;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.barteo.emulator.device.impl.DeviceDisplayImpl#setForegroundColor(java.awt.Color)
	 */
	public void setForegroundColor(Color color) {
		foregroundColor = color;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.barteo.emulator.device.impl.DeviceDisplayImpl#setDisplayRectangle(java.awt.Rectangle)
	 */
	public void setDisplayRectangle(Rectangle rectangle) {
		displayRectangle = rectangle;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.barteo.emulator.device.impl.DeviceDisplayImpl#setDisplayPaintable(java.awt.Rectangle)
	 */
	public void setDisplayPaintable(Rectangle rectangle) {
		displayPaintable = rectangle;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.barteo.emulator.device.impl.DeviceDisplayImpl#setMode123Image(com.barteo.emulator.device.impl.PositionedImage)
	 */
	public void setMode123Image(PositionedImage object) {
		mode123Image = object;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.barteo.emulator.device.impl.DeviceDisplayImpl#setModeAbcLowerImage(com.barteo.emulator.device.impl.PositionedImage)
	 */
	public void setModeAbcLowerImage(PositionedImage object) {
		modeAbcLowerImage = object;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.barteo.emulator.device.impl.DeviceDisplayImpl#setModeAbcUpperImage(com.barteo.emulator.device.impl.PositionedImage)
	 */
	public void setModeAbcUpperImage(PositionedImage object) {
		modeAbcUpperImage = object;
	}

	public Image createSystemImage(URL url) throws IOException {
		return new SwtImmutableImage(SwtDeviceComponent.createImage(url.openStream()));
	}

	private Image getImage(String str) throws IOException {
		// TODO not always true, there could be some loading images before
		// invoke startApp, right now getCurrentMIDlet returns prevoius MIDlet
		Object midlet = MIDletBridge.getCurrentMIDlet();
		if (midlet == null) {
			midlet = getClass();
		}
		InputStream is = midlet.getClass().getResourceAsStream(str);

		if (is == null) {
			throw new IOException(str + " could not be found.");
		}
		try {
			return getImage(is);
		} finally {
			IOUtils.closeQuietly(is);
		}
	}

	private Image getImage(InputStream is) throws IOException {
		ImageFilter filter = null;
		if (isColor()) {
			filter = new RGBImageFilter();
		} else {
			if (numColors() == 2) {
				filter = new BWImageFilter();
			} else {
				filter = new GrayImageFilter();
			}
		}

		return new SwtImmutableImage(SwtDeviceComponent.createImage(is, filter));
	}

	public Button createButton(int skinVersion, String name, Shape shape, int keyCode, String keyboardKeys,
			String keyboardChars, Hashtable inputToChars, boolean modeChange) {
		return new SwtButton(name, shape, keyCode, keyboardKeys, inputToChars);
	}

	public SoftButton createSoftButton(int skinVersion, String name, Shape shape, int keyCode, String keyName,
			Rectangle paintable, String alignmentName, Vector commands, javax.microedition.lcdui.Font font) {
		return new SwtSoftButton(name, shape, keyCode, keyName, paintable, alignmentName, commands, font);
	}

	public SoftButton createSoftButton(int skinVersion, String name, Rectangle paintable, Image normalImage,
			Image pressedImage) {
		return new SwtSoftButton(name, paintable, normalImage, pressedImage);
	}

	public Image createRGBImage(int[] rgb, int width, int height, boolean processAlpha) {
		if (rgb == null)
			throw new NullPointerException();
		if (width <= 0 || height <= 0)
			throw new IllegalArgumentException();

		org.eclipse.swt.graphics.Image img = SwtDeviceComponent.createImage(width, height);
		ImageData imageData = img.getImageData();

		if (!processAlpha) {
			// we should eliminate the transparency info
			// but can't touch the original array
			// so we just create another
			int l = rgb.length;

			int[] rgbAux = new int[l];
			for (int i = 0; i < l; i++)
				rgbAux[i] = rgb[i] | 0xff000000;
			rgb = rgbAux;
		}

		for (int y = 0; y < height; y++) {
			imageData.setPixels(0, y, width, rgb, y * width);
		}

		// TODO now apply the corresponding filter
		ImageFilter filter = null;
		if (isColor()) {
			filter = new RGBImageFilter();
		} else {
			if (numColors() == 2) {
				filter = new BWImageFilter();
			} else {
				filter = new GrayImageFilter();
			}
		}

		return new SwtImmutableImage(SwtDeviceComponent.createImage(imageData));
	}

	public Image createImage(Image image, int x, int y, int width, int height, int transform) {
		if (image == null) {
			throw new NullPointerException();
		}
		if (x + width > image.getWidth() || y + height > image.getHeight() || width <= 0 || height <= 0 || x < 0
				|| y < 0) {
			throw new IllegalArgumentException("Area out of Image");
		}

		int[] rgbData = new int[height * width];
		int[] rgbTransformedData = new int[height * width];
		if (image instanceof SwtImmutableImage) {
			((SwtImmutableImage) image).getRGB(rgbData, 0, width, x, y, width, height);
		} else {
			((SwtMutableImage) image).getRGB(rgbData, 0, width, x, y, width, height);
		}

		int colIncr, rowIncr, offset;

		switch (transform) {
		case Sprite.TRANS_NONE: {
			offset = 0;
			colIncr = 1;
			rowIncr = 0;
			break;
		}
		case Sprite.TRANS_ROT90: {
			offset = (height - 1) * width;
			colIncr = -width;
			rowIncr = (height * width) + 1;
			int temp = width;
			width = height;
			height = temp;
			break;
		}
		case Sprite.TRANS_ROT180: {
			offset = (height * width) - 1;
			colIncr = -1;
			rowIncr = 0;
			break;
		}
		case Sprite.TRANS_ROT270: {
			offset = width - 1;
			colIncr = width;
			rowIncr = -(height * width) - 1;
			int temp = width;
			width = height;
			height = temp;
			break;
		}
		case Sprite.TRANS_MIRROR: {
			offset = width - 1;
			colIncr = -1;
			rowIncr = width << 1;
			break;
		}
		case Sprite.TRANS_MIRROR_ROT90: {
			offset = (height * width) - 1;
			colIncr = -width;
			rowIncr = (height * width) - 1;
			int temp = width;
			width = height;
			height = temp;
			break;
		}
		case Sprite.TRANS_MIRROR_ROT180: {
			offset = (height - 1) * width;
			colIncr = 1;
			rowIncr = -(width << 1);
			break;
		}
		case Sprite.TRANS_MIRROR_ROT270: {
			offset = 0;
			colIncr = width;
			rowIncr = -(height * width) + 1;
			int temp = width;
			width = height;
			height = temp;
			break;
		}
		default:
			throw new IllegalArgumentException("Bad transform");
		}

		// now the loops!
		for (int row = 0, i = 0; row < height; row++, offset += rowIncr) {
			for (int col = 0; col < width; col++, offset += colIncr, i++) {
				rgbTransformedData[i] = rgbData[offset];
			}
		}
		// to aid gc
		rgbData = null;
		image = null;

		return createRGBImage(rgbTransformedData, width, height, true);
	}

	public boolean isResizable() {
		// TODO Auto-generated method stub
		return false;
	}

	public void setResizable(boolean state) {
		// TODO Auto-generated method stub

	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy