harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From telli...@apache.org
Subject svn commit: r660326 [2/17] - in /harmony/enhanced/microemulator: ./ microemu-android/ microemu-android/src/ microemu-android/src/org/ microemu-android/src/org/microemu/ microemu-android/src/org/microemu/android/ microemu-android/src/org/microemu/androi...
Date Mon, 26 May 2008 22:21:57 GMT
Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/asm/AndroidProducer.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/asm/AndroidProducer.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/asm/AndroidProducer.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/asm/AndroidProducer.java Mon May 26 15:20:19 2008
@@ -0,0 +1,116 @@
+/*
+ *  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 org.microemu.android.asm;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+
+public class AndroidProducer {
+
+	private static byte[] instrument(final InputStream classInputStream, boolean isMidlet) throws IOException {
+		ClassReader cr = new ClassReader(classInputStream);
+		ClassWriter cw = new ClassWriter(0);
+		ClassVisitor cv = new AndroidClassVisitor(cw, isMidlet);
+		cr.accept(cv, 0);
+
+		return cw.toByteArray();
+    }
+
+	public static void processJar(File jarInputFile, File jarOutputFile, boolean isMidlet) throws IOException {
+		JarInputStream jis = null;
+		JarOutputStream jos = null;
+		try {
+			jis = new JarInputStream(new FileInputStream(jarInputFile));
+			Manifest manifest = jis.getManifest();
+			if (manifest == null) {
+				jos = new JarOutputStream(new FileOutputStream(jarOutputFile));
+			} else {
+				jos = new JarOutputStream(new FileOutputStream(jarOutputFile), manifest);
+			}
+		
+			byte[] inputBuffer = new byte[1024];
+			JarEntry jarEntry;
+			while ((jarEntry = jis.getNextJarEntry()) != null) {
+				if (jarEntry.isDirectory() == false) {
+					String name = jarEntry.getName();
+					int size = 0;
+					int read;
+					int length = inputBuffer.length;
+					while ((read = jis.read(inputBuffer, size, length)) > 0) {
+						size += read;
+						
+						length = 1024;
+						if (size + length > inputBuffer.length) {
+							byte[] newInputBuffer = new byte[size + length];
+							System.arraycopy(inputBuffer, 0, newInputBuffer, 0, inputBuffer.length);
+							inputBuffer = newInputBuffer;
+						}
+					}
+					
+					byte[] outputBuffer = inputBuffer;
+					int outputSize = size;
+					if (name.endsWith(".class")) {					
+				        outputBuffer = instrument(new ByteArrayInputStream(inputBuffer, 0, size), isMidlet);
+				        outputSize = outputBuffer.length;
+				        name = AndroidClassVisitor.fixPackage(name);
+					}
+					jos.putNextEntry(new JarEntry(name));
+					jos.write(outputBuffer, 0, outputSize);
+				}
+			}			
+		} finally {
+			if (jis != null) {
+				jis.close();
+			}
+			if (jos != null) {
+				jos.close();
+			}
+		}
+	}
+	
+	public static void main(String args[]) {
+		if (args.length < 2 || args.length > 3) {
+			System.out.println("usage: AndroidProducer <infile> <outfile> [midlet]");
+		} else {
+			boolean isMidlet = false;
+			if (args.length == 3 && args[2].toLowerCase().equals("midlet")) {
+				isMidlet = true;
+			}
+			try {
+				processJar(new File(args[0]), new File(args[1]), isMidlet);
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+	}
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/asm/AndroidProducer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDevice.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDevice.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDevice.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDevice.java Mon May 26 15:20:19 2008
@@ -0,0 +1,165 @@
+/*
+ *  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 org.microemu.android.device;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.microedition.android.lcdui.Alert;
+import javax.microedition.android.lcdui.Canvas;
+import javax.microedition.android.lcdui.Form;
+import javax.microedition.android.lcdui.Image;
+import javax.microedition.android.lcdui.List;
+import javax.microedition.android.lcdui.TextBox;
+
+import org.microemu.EmulatorContext;
+import org.microemu.android.MicroEmulatorActivity;
+import org.microemu.android.device.ui.AndroidCanvasUI;
+import org.microemu.android.device.ui.AndroidListUI;
+import org.microemu.android.device.ui.AndroidTextBoxUI;
+import org.microemu.device.Device;
+import org.microemu.device.DeviceDisplay;
+import org.microemu.device.FontManager;
+import org.microemu.device.InputMethod;
+import org.microemu.device.ui.CanvasUI;
+import org.microemu.device.ui.DisplayableUI;
+import org.microemu.device.ui.ListUI;
+import org.microemu.device.ui.TextBoxUI;
+import org.microemu.device.ui.UIFactory;
+
+public class AndroidDevice implements Device {
+
+	private EmulatorContext emulatorContext;
+	
+	private MicroEmulatorActivity activity;
+	
+	private UIFactory ui = new UIFactory() {
+
+		public DisplayableUI createAlertUI(Alert alert) {
+			// TODO Not yet implemented
+			return new AndroidCanvasUI(activity, null);
+		}
+
+		public CanvasUI createCanvasUI(Canvas canvas) {
+			return new AndroidCanvasUI(activity, canvas);
+		}
+
+		public DisplayableUI createFormUI(Form form) {
+			// TODO Not yet implemented
+			return new AndroidCanvasUI(activity, null);
+		}
+
+		public ListUI createListUI(List list) {
+			return new AndroidListUI(activity, list);
+		}
+		
+		public TextBoxUI createTextBoxUI(TextBox textBox) {
+			return new AndroidTextBoxUI(activity, textBox);
+		}
+
+	};
+	
+	private Map systemProperties = new HashMap();
+	
+	private Vector softButtons = new Vector();
+	
+	public AndroidDevice(EmulatorContext emulatorContext, MicroEmulatorActivity activity) {
+		this.emulatorContext = emulatorContext;
+		this.activity = activity;
+	}
+
+	public void destroy() {
+		// TODO Auto-generated method stub
+		
+	}
+
+	public Vector getButtons() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public DeviceDisplay getDeviceDisplay() {
+		return emulatorContext.getDeviceDisplay();
+	}
+
+	public FontManager getFontManager() {
+		return emulatorContext.getDeviceFontManager();
+	}
+
+	public InputMethod getInputMethod() {
+		return emulatorContext.getDeviceInputMethod();
+	}
+	
+	public UIFactory getUIFactory() {
+		return ui;
+	}
+
+	public String getName() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Image getNormalImage() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Image getOverImage() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Image getPressedImage() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Vector getSoftButtons() {
+		return softButtons;
+	}
+
+	public Map getSystemProperties() {
+		return systemProperties;
+	}
+
+	public boolean hasPointerEvents() {
+		return true;
+	}
+
+	public boolean hasPointerMotionEvents() {
+		return true;
+	}
+
+	public boolean hasRepeatEvents() {
+		return true;
+	}
+
+	public void init() {
+		// TODO Auto-generated method stub
+		
+	}
+
+	public boolean vibrate(int arg0) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDevice.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDeviceDisplay.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDeviceDisplay.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDeviceDisplay.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDeviceDisplay.java Mon May 26 15:20:19 2008
@@ -0,0 +1,321 @@
+/*
+ *  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 org.microemu.android.device;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.microedition.android.lcdui.Graphics;
+import javax.microedition.android.lcdui.Image;
+import javax.microedition.android.lcdui.game.Sprite;
+
+import org.microemu.DisplayAccess;
+import org.microemu.EmulatorContext;
+import org.microemu.MIDletAccess;
+import org.microemu.MIDletBridge;
+import org.microemu.android.device.ui.AndroidCanvasUI;
+import org.microemu.device.Device;
+import org.microemu.device.DeviceDisplay;
+import org.microemu.device.DeviceFactory;
+import org.microemu.device.MutableImage;
+import org.microemu.device.ui.CanvasUI;
+import org.microemu.device.ui.DisplayableUI;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.view.View;
+
+public class AndroidDeviceDisplay implements DeviceDisplay {
+	
+	private EmulatorContext context;
+	
+	// TODO change this
+	public int displayRectangleWidth;
+	
+	// TODO change this
+	public int displayRectangleHeight;
+	
+	public AndroidDeviceDisplay(EmulatorContext context) {
+		this.context = context;
+	}
+
+	public Image createImage(String arg0) throws IOException {
+		System.out.println("createImage: " + arg0);
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Image createImage(Image arg0) {
+		System.out.println("createImage: " + arg0);
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Image createImage(InputStream arg0) throws IOException {
+		System.out.println("createImage: " + arg0);
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Image createImage(int width, int height) {
+		if (width <= 0 || height <= 0) {
+			throw new IllegalArgumentException();
+		}
+
+		return new AndroidMutableImage(width, height);
+	}
+
+	public Image createImage(byte[] imageData, int imageOffset, int imageLength) {
+		return new AndroidImmutableImage(BitmapFactory.decodeByteArray(imageData, imageOffset, imageLength));
+	}
+
+	public Image createImage(Image image, int x, int y, int width, int height, int transform) {
+		// TODO AndroidDisplayGraphics.drawRegion code is similar
+		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 AndroidImmutableImage) {
+			((AndroidImmutableImage) image).getRGB(rgbData, 0, width, x, y, width, height);
+		} else {
+			((AndroidMutableImage) 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++) {
+/*			    int a = (rgbData[offset] & 0xFF000000);
+			    int b = (rgbData[offset] & 0x00FF0000) >>> 16;
+			    int g = (rgbData[offset] & 0x0000FF00) >>> 8;
+			    int r = (rgbData[offset] & 0x000000FF);
+
+			    rgbTransformedData[i] = a | (r << 16) | (g << 8) | b;*/
+				rgbTransformedData[i] = rgbData[offset];
+			}
+		}
+		// to aid gc
+		rgbData = null;
+		image = null;
+
+		return createRGBImage(rgbTransformedData, width, height, true);
+	}
+
+	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();
+		
+		// TODO processAlpha is not handled natively, check whether we need to create copy of rgb
+		int[] newrgb = rgb;
+		if (!processAlpha) {
+			newrgb = new int[rgb.length];
+			for (int i = 0; i < rgb.length; i++) {
+				newrgb[i] = (0x00ffffff & rgb[i]) | 0xff000000;
+			}
+		}
+		return new AndroidImmutableImage(Bitmap.createBitmap(newrgb, width, height, Bitmap.Config.ARGB_8888));
+	}
+
+	public MutableImage getDisplayImage() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public int getFullHeight() {
+		return displayRectangleHeight;
+	}
+
+	public int getFullWidth() {
+		return displayRectangleWidth;
+	}
+
+	public int getHeight() {
+		// TODO Auto-generated method stub
+		return displayRectangleHeight;
+	}
+
+	public int getWidth() {
+		// TODO Auto-generated method stub
+		return displayRectangleWidth;
+	}
+
+	public boolean isColor() {
+		return true;
+	}
+
+	public boolean isFullScreenMode() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	public int numAlphaLevels() {
+		return 256;
+	}
+
+	public int numColors() {
+		return 65536;
+	}
+
+	public void repaint(int x, int y, int width, int height) {
+		paintDisplayable(x, y, width, height);
+	}
+
+	public void setScrollDown(boolean arg0) {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void setScrollUp(boolean arg0) {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void paintDisplayable(int x, int y, int width, int height) {
+		MIDletAccess ma = MIDletBridge.getMIDletAccess();
+		if (ma == null) {
+			return;
+		}
+		DisplayAccess da = ma.getDisplayAccess();
+		if (da == null) {
+			return;
+		}
+		DisplayableUI current = da.getCurrentUI();
+		if (current == null) {
+			return;
+		}
+
+		// TODO
+		// g.save(android.graphics.Canvas.CLIP_SAVE_FLAG);
+		// TODO
+		// if (!(current instanceof Canvas) || ((Canvas) current).getWidth() != displayRectangle.width
+		// 		|| ((Canvas) current).getHeight() != displayRectangle.height) {
+		// 	g.translate(displayPaintable.x, displayPaintable.y);
+		// }
+		// TODO
+		// Font oldf = g.getFont();
+		if (current instanceof CanvasUI) {
+			Device device = DeviceFactory.getDevice();
+			
+			// TODO take region size into account
+			if (device != null) {
+				synchronized (current) {
+					Image displayImage = ((AndroidCanvasUI) current).getImage();
+					synchronized (displayImage) {
+						Graphics canvas = displayImage.getGraphics();
+
+						canvas.clipRect(x, y, x + width, y + height);
+						ma.getDisplayAccess().paint(canvas);
+						// TODO
+						// if (!deviceDisplay.isFullScreenMode()) {
+						// 	deviceDisplay.paintControls(canvas);
+						// }
+					}
+				}
+			}
+			View view = ((AndroidCanvasUI) current).getView(); 
+			view.postInvalidate();
+		} else {
+			// TODO extend DisplayableUI interface
+			//current.paint();
+		}
+		// TODO
+		// g.setFont(oldf);
+		// TODO
+		// if (!(current instanceof Canvas) || ((Canvas) current).getWidth() != displayRectangle.width
+		//		|| ((Canvas) current).getHeight() != displayRectangle.height) {
+		// 	g.translate(-displayPaintable.x, -displayPaintable.y);
+		//}
+		// TODO
+		// g.restore();
+	}
+	
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDeviceDisplay.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDisplayGraphics.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDisplayGraphics.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDisplayGraphics.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDisplayGraphics.java Mon May 26 15:20:19 2008
@@ -0,0 +1,386 @@
+/*
+ *  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 org.microemu.android.device;
+
+import javax.microedition.android.lcdui.Font;
+import javax.microedition.android.lcdui.Image;
+
+import org.microemu.device.DeviceFactory;
+import org.microemu.device.MutableImage;
+import org.microemu.log.Logger;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+
+public class AndroidDisplayGraphics extends javax.microedition.android.lcdui.Graphics {
+	
+	private Canvas canvas;
+	
+	private Paint paint = new Paint();
+	
+	private Rect clip;
+	
+	public AndroidDisplayGraphics(Canvas canvas, MutableImage image) {
+		this.canvas = canvas;
+		this.canvas.save(Canvas.CLIP_SAVE_FLAG);
+		this.clip = canvas.getClipBounds();
+	}
+	
+	public void clipRect(int x, int y, int width, int height) {
+		canvas.clipRect(x, y, x + width, y + height);
+		clip = canvas.getClipBounds();
+	}
+
+	public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
+		Logger.debug("drawArc");
+    }
+
+	public void drawImage(Image img, int x, int y, int anchor) {
+        int newx = x;
+        int newy = y;
+
+        if (anchor == 0) {
+            anchor = javax.microedition.lcdui.Graphics.TOP | javax.microedition.lcdui.Graphics.LEFT;
+        }
+
+        if ((anchor & javax.microedition.lcdui.Graphics.RIGHT) != 0) {
+            newx -= img.getWidth();
+        } else if ((anchor & javax.microedition.lcdui.Graphics.HCENTER) != 0) {
+            newx -= img.getWidth() / 2;
+        }
+        if ((anchor & javax.microedition.lcdui.Graphics.BOTTOM) != 0) {
+            newy -= img.getHeight();
+        } else if ((anchor & javax.microedition.lcdui.Graphics.VCENTER) != 0) {
+            newy -= img.getHeight() / 2;
+        }
+
+        if (img.isMutable()) {
+            canvas.drawBitmap(((AndroidMutableImage) img).getBitmap(), newx, newy, paint);
+        } else {
+        	canvas.drawBitmap(((AndroidImmutableImage) img).getBitmap(), newx, newy, paint);
+        }
+	}
+
+	public void drawLine(int x1, int y1, int x2, int y2) {
+		canvas.drawLine(x1, y1, x2, y2, paint);
+	}
+
+	public void drawRect(int x, int y, int width, int height) {
+		paint.setStyle(Paint.Style.STROKE);
+		canvas.drawRect(x, y, x + width, y + height, paint);
+	}
+
+	public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
+		Logger.debug("drawRoundRect");
+    }
+
+	public void drawString(String str, int x, int y, int anchor) {
+        int newx = x;
+        int newy = y;
+
+        if (anchor == 0) {
+            anchor = javax.microedition.android.lcdui.Graphics.TOP | javax.microedition.android.lcdui.Graphics.LEFT;
+        }
+
+        if ((anchor & javax.microedition.android.lcdui.Graphics.TOP) != 0) {
+            newy -= paint.getFontMetricsInt().ascent;
+        } else if ((anchor & javax.microedition.android.lcdui.Graphics.BOTTOM) != 0) {
+            newy -= paint.getFontMetricsInt().descent;
+        }
+        if ((anchor & javax.microedition.android.lcdui.Graphics.HCENTER) != 0) {
+            newx -= paint.measureText(str) / 2;
+        } else if ((anchor & javax.microedition.android.lcdui.Graphics.RIGHT) != 0) {
+            newx -= paint.measureText(str);
+        }
+
+        canvas.drawText(str, newx, newy, AndroidFont.paint);
+
+        // TODO
+        // if ((currentFont.getStyle() & javax.microedition.android.lcdui.Font.STYLE_UNDERLINED) != 0) {
+        //     g.drawLine(newx, newy + 1, newx + g.getFontMetrics().stringWidth(str), newy + 1);
+        // }
+	}
+
+    public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
+		Logger.debug("fillArc");
+    }
+
+	public void fillRect(int x, int y, int width, int height) {
+		paint.setStyle(Paint.Style.FILL);
+		canvas.drawRect(x, y, x + width, y + height, paint);
+	}
+
+	public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
+		Logger.debug("fillRoundRect");
+    }
+
+	public int getClipHeight() {
+		return clip.bottom - clip.top;
+	}
+
+	public int getClipWidth() {
+		return clip.right - clip.left;
+	}
+
+	public int getClipX() {
+		return clip.left;
+	}
+
+	public int getClipY() {
+		return clip.top;
+	}
+
+	public int getColor() {
+		return paint.getColor();
+	}
+
+	public Font getFont() {
+		Logger.debug("getFont");
+
+		return null;
+	}
+
+	public void setClip(int x, int y, int width, int height) {
+		if (x == clip.left && x+ width == clip.right && y == clip.top && y + height == clip.bottom) {
+			return;
+		}
+		if (x < clip.left || x + width > clip.right || y < clip.top || y + height > clip.bottom) {
+			canvas.restore();
+			canvas.save(Canvas.CLIP_SAVE_FLAG);
+		}
+        clip.left = x;
+        clip.top = y;
+        clip.right = x + width;
+        clip.bottom = y + height;
+		canvas.clipRect(clip);
+	}
+
+	public void setColor(int RGB) {
+		paint.setColor(0xff000000 | RGB);
+		// TODO AndroidFont.paint cannot be static 
+		AndroidFont.paint.setColor(0xff000000 | RGB);
+	}
+
+	public void setFont(Font font) {
+		// TODO
+		// Logger.debug("(todo) setFont");
+	}
+
+    public void translate(int x, int y) {
+        super.translate(x, y);
+        canvas.translate(x, y);
+    }
+
+	public void drawRegion(Image src, int x_src, int y_src, int width,
+			int height, int transform, int x_dst, int y_dst, int anchor) {
+        // may throw NullPointerException, this is ok
+        if (x_src + width > src.getWidth() || y_src + height > src.getHeight() || width < 0 || height < 0 || x_src < 0
+                || y_src < 0)
+            throw new IllegalArgumentException("Area out of Image");
+
+        // this cannot be done on the same image we are drawing
+        // check this if the implementation of getGraphics change so
+        // as to return different Graphic Objects on each call to
+        // getGraphics
+        if (src.isMutable() && src.getGraphics() == this)
+            throw new IllegalArgumentException("Image is source and target");
+
+        Bitmap img;
+
+        if (src.isMutable()) {
+            img = ((AndroidMutableImage) src).getBitmap();
+        } else {
+            img = ((AndroidImmutableImage) src).getBitmap();
+        }            
+
+// TODO  
+        if (anchor != 0) {
+//        	Logger.debug("(todo) drawRegion: " + anchor);
+        }
+/*        java.awt.geom.AffineTransform t = new java.awt.geom.AffineTransform();
+
+        int dW = width, dH = height;
+        switch (transform) {
+        case Sprite.TRANS_NONE: {
+            break;
+        }
+        case Sprite.TRANS_ROT90: {
+            t.translate((double) height, 0);
+            t.rotate(Math.PI / 2);
+            dW = height;
+            dH = width;
+            break;
+        }
+        case Sprite.TRANS_ROT180: {
+            t.translate(width, height);
+            t.rotate(Math.PI);
+            break;
+        }
+        case Sprite.TRANS_ROT270: {
+            t.translate(0, width);
+            t.rotate(Math.PI * 3 / 2);
+            dW = height;
+            dH = width;
+            break;
+        }
+        case Sprite.TRANS_MIRROR: {
+            t.translate(width, 0);
+            t.scale(-1, 1);
+            break;
+        }
+        case Sprite.TRANS_MIRROR_ROT90: {
+            t.translate((double) height, 0);
+            t.rotate(Math.PI / 2);
+            t.translate((double) width, 0);
+            t.scale(-1, 1);
+            dW = height;
+            dH = width;
+            break;
+        }
+        case Sprite.TRANS_MIRROR_ROT180: {
+            t.translate(width, 0);
+            t.scale(-1, 1);
+            t.translate(width, height);
+            t.rotate(Math.PI);
+            break;
+        }
+        case Sprite.TRANS_MIRROR_ROT270: {
+            t.rotate(Math.PI * 3 / 2);
+            t.scale(-1, 1);
+            dW = height;
+            dH = width;
+            break;
+        }
+        default:
+            throw new IllegalArgumentException("Bad transform");
+        }
+
+        // process anchor and correct x and y _dest
+        // vertical
+        boolean badAnchor = false;
+
+        if (anchor == 0) {
+            anchor = TOP | LEFT;
+        }
+
+        if ((anchor & 0x7f) != anchor || (anchor & BASELINE) != 0)
+            badAnchor = true;
+
+        if ((anchor & TOP) != 0) {
+            if ((anchor & (VCENTER | BOTTOM)) != 0)
+                badAnchor = true;
+        } else if ((anchor & BOTTOM) != 0) {
+            if ((anchor & VCENTER) != 0)
+                badAnchor = true;
+            else {
+                y_dst -= dH - 1;
+            }
+        } else if ((anchor & VCENTER) != 0) {
+            y_dst -= (dH - 1) >>> 1;
+        } else {
+            // no vertical anchor
+            badAnchor = true;
+        }
+
+        // horizontal
+        if ((anchor & LEFT) != 0) {
+            if ((anchor & (HCENTER | RIGHT)) != 0)
+                badAnchor = true;
+        } else if ((anchor & RIGHT) != 0) {
+            if ((anchor & HCENTER) != 0)
+                badAnchor = true;
+            else {
+                x_dst -= dW - 1;
+            }
+        } else if ((anchor & HCENTER) != 0) {
+            x_dst -= (dW - 1) >>> 1;
+        } else {
+            // no horizontal anchor
+            badAnchor = true;
+        }
+
+        if (badAnchor)
+            throw new IllegalArgumentException("Bad Anchor");
+
+        java.awt.geom.AffineTransform savedT = g.getTransform();
+
+        g.translate(x_dst, y_dst);
+        g.transform(t);*/
+
+        Rect srcRect = new Rect(x_src, y_src, x_src + width, y_src + height);
+        Rect dstRect = new Rect(x_dst, y_dst, x_dst + width, y_dst + height);
+        canvas.drawBitmap(img, srcRect, dstRect, paint);
+
+        // return to saved
+// TODO        
+//        g.setTransform(savedT);
+	}
+
+	public void drawRGB(int[] rgbData, int offset, int scanlength, int x,
+			int y, int width, int height, boolean processAlpha) {
+        // this is less than ideal in terms of memory
+        // but it's the easiest way
+
+        if (rgbData == null)
+            throw new NullPointerException();
+
+        if (width == 0 || height == 0) {
+            return;
+        }
+
+        int l = rgbData.length;
+
+        if (width < 0 || height < 0 || offset < 0 || offset >= l || (scanlength < 0 && scanlength * (height - 1) < 0)
+                || (scanlength >= 0 && scanlength * (height - 1) + width - 1 >= l))
+            throw new ArrayIndexOutOfBoundsException();
+
+        int[] rgb = new int[width * height];
+        // this way we dont create yet another array in createImage
+        int transparencyMask = processAlpha ? 0 : 0xff000000;
+        for (int row = 0; row < height; row++) {
+            for (int px = 0; px < width; px++)
+                rgb[row * width + px] = rgbData[offset + px] | transparencyMask;
+            offset += scanlength;
+        }
+
+        // help gc
+        rgbData = null;
+        Image img = DeviceFactory.getDevice().getDeviceDisplay().createRGBImage(rgb, width, height, true);
+        drawImage(img, x, y, TOP | LEFT);
+	}
+
+	public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
+		Logger.debug("fillTriangle");
+	}
+
+	public void copyArea(int x_src, int y_src, int width, int height,
+			int x_dest, int y_dest, int anchor) {
+		Logger.debug("copyArea");
+	}
+
+	public int getDisplayColor(int color) {
+		Logger.debug("getDisplayColor");
+
+		return -1;
+	}
+	
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidDisplayGraphics.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidFont.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidFont.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidFont.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidFont.java Mon May 26 15:20:19 2008
@@ -0,0 +1,54 @@
+/*
+ *  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 org.microemu.android.device;
+
+import org.microemu.device.impl.Font;
+
+import android.graphics.Paint;
+
+public class AndroidFont implements Font {
+
+	static Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
+	
+	public AndroidFont(String name, String style, int size) {
+		// TODO Auto-generated constructor stub
+	}
+
+	public int charWidth(char ch) {
+		return (int) paint.measureText(new char[] { ch }, 0, 1);
+	}
+
+	public int charsWidth(char[] ch, int offset, int length) {
+		return (int) paint.measureText(ch, offset, length);
+	}
+
+	public int getBaselinePosition() {
+		return -paint.getFontMetricsInt().ascent;
+	}
+
+	public int getHeight() {
+		return paint.getFontMetricsInt(paint.getFontMetricsInt());
+	}
+
+	public int stringWidth(String str) {
+		return (int) paint.measureText(str);
+	}
+
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidFont.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidFontManager.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidFontManager.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidFontManager.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidFontManager.java Mon May 26 15:20:19 2008
@@ -0,0 +1,123 @@
+/*
+ *  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 org.microemu.android.device;
+
+import java.util.Hashtable;
+
+import javax.microedition.android.lcdui.Font;
+
+import org.microemu.device.FontManager;
+
+public class AndroidFontManager implements FontManager
+{
+	private static String FACE_SYSTEM_NAME = "SansSerif";
+	private static String FACE_MONOSPACE_NAME = "Monospaced";
+	private static String FACE_PROPORTIONAL_NAME = "SansSerif";
+
+	private static int SIZE_SMALL = 9;
+	private static int SIZE_MEDIUM = 11;
+	private static int SIZE_LARGE = 13;
+
+	private Hashtable fonts = new Hashtable();
+
+
+	org.microemu.device.impl.Font getFont(Font meFont)
+	{
+    	int key = 0;
+    	key |= meFont.getFace();
+    	key |= meFont.getStyle();
+    	key |= meFont.getSize();
+    	
+    	org.microemu.device.impl.Font result = (org.microemu.device.impl.Font) fonts.get(new Integer(key));
+	    
+	    if (result == null) {
+	    	String name = null;
+	    	if (meFont.getFace() == Font.FACE_SYSTEM) {
+	    		name = FACE_SYSTEM_NAME;
+	    	} else if (meFont.getFace() == Font.FACE_MONOSPACE) {
+	    		name = FACE_MONOSPACE_NAME;
+	    	} else if (meFont.getFace() == Font.FACE_PROPORTIONAL) {
+	    		name = FACE_PROPORTIONAL_NAME;
+	    	}
+	    	String style = ",";
+	    	if ((meFont.getStyle() & Font.STYLE_PLAIN) != 0) {
+	    		style += "plain,";
+	    	}
+	    	if ((meFont.getStyle() & Font.STYLE_BOLD) != 0) {
+	    		style += "bold,";
+	    	}
+	    	if ((meFont.getStyle() & Font.STYLE_ITALIC) != 0) {
+	    		style += "italic,";
+	    	}
+	    	if ((meFont.getStyle() & Font.STYLE_ITALIC) != 0) {
+	    		style += "underlined,";
+	    	}
+	    	style = style.substring(0, style.length() - 1);
+	    	int size = 0;
+	    	if (meFont.getSize() == Font.SIZE_SMALL) {
+	    		size = SIZE_SMALL;
+	    	} else if (meFont.getSize() == Font.SIZE_MEDIUM) {
+	    		size = SIZE_MEDIUM;
+	    	} else if (meFont.getSize() == Font.SIZE_LARGE) {
+	    		size = SIZE_LARGE;
+	    	}
+	    	result = new AndroidFont(name, style, size);
+	    	fonts.put(new Integer(key), result);
+	    }
+	    
+	    return result;
+	}
+	
+	
+	public void init()
+	{
+		fonts.clear();
+	}
+  
+
+	public int charWidth(Font f, char ch)
+	{
+		return getFont(f).charWidth(ch);
+	}
+
+
+	public int charsWidth(Font f, char[] ch, int offset, int length) 
+	{
+		return getFont(f).charsWidth(ch, offset, length);
+	}
+
+	public int getBaselinePosition(Font f) 
+	{
+		return getFont(f).getBaselinePosition();
+	}
+
+
+	public int getHeight(Font f)
+	{
+		return getFont(f).getHeight();
+	}
+
+
+	public int stringWidth(Font f, String str)
+	{
+		return getFont(f).stringWidth(str);
+	}
+	
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidFontManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidImmutableImage.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidImmutableImage.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidImmutableImage.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidImmutableImage.java Mon May 26 15:20:19 2008
@@ -0,0 +1,79 @@
+/*
+ *  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 org.microemu.android.device;
+
+import android.graphics.Bitmap;
+
+public class AndroidImmutableImage extends javax.microedition.android.lcdui.Image {
+
+	private Bitmap bitmap;
+	
+	public AndroidImmutableImage(Bitmap bitmap) {
+		this.bitmap = bitmap;
+	}
+
+	public Bitmap getBitmap() {
+		return bitmap;
+	}
+
+	@Override
+	public int getWidth() {
+		return bitmap.width();
+	}
+	
+	@Override
+	public int getHeight() {
+		return bitmap.height();
+	}
+
+	@Override
+    public void getRGB(int []argb, int offset, int scanlength,
+            int x, int y, int width, int height) {
+        if (width <= 0 || height <= 0)
+            return;
+        if (x < 0 || y < 0 || x + width > getWidth() || y + height > getHeight())
+            throw new IllegalArgumentException("Specified area exceeds bounds of image");
+        if ((scanlength < 0? -scanlength:scanlength) < width)
+            throw new IllegalArgumentException("abs value of scanlength is less than width");
+        if (argb == null)
+            throw new NullPointerException("null rgbData");
+        if (offset < 0 || offset + width > argb.length)
+            throw new ArrayIndexOutOfBoundsException();
+        if (scanlength < 0) {
+            if (offset + scanlength*(height-1) < 0)
+                throw new ArrayIndexOutOfBoundsException();
+        } else {
+            if (offset + scanlength*(height-1) + width > argb.length)
+                throw new ArrayIndexOutOfBoundsException();
+        }
+
+        bitmap.getPixels(argb, offset, scanlength, x, y, width, height);
+
+/*        for (int i = 0; i < argb.length; i++) {
+		    int a = (argb[i] & 0xFF000000);
+		    int b = (argb[i] & 0x00FF0000) >>> 16;
+		    int g = (argb[i] & 0x0000FF00) >>> 8;
+		    int r = (argb[i] & 0x000000FF);
+	
+		    argb[i] = a | (r << 16) | (g << 8) | b;
+        }*/
+	}
+	
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidImmutableImage.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidInputMethod.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidInputMethod.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidInputMethod.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidInputMethod.java Mon May 26 15:20:19 2008
@@ -0,0 +1,425 @@
+/*
+ *  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 org.microemu.android.device;
+
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.Vector;
+
+import javax.microedition.android.lcdui.Canvas;
+
+import org.microemu.DisplayAccess;
+import org.microemu.MIDletAccess;
+import org.microemu.MIDletBridge;
+import org.microemu.device.DeviceFactory;
+import org.microemu.device.InputMethod;
+import org.microemu.util.ThreadUtils;
+
+import android.view.KeyEvent;
+
+public class AndroidInputMethod extends InputMethod {
+
+	private boolean eventAlreadyConsumed;
+
+	private Timer keyReleasedDelayTimer;
+
+	private List repeatModeKeyCodes = new Vector();
+
+	private class KeyReleasedDelayTask extends TimerTask {
+
+		private int repeatModeKeyCode;
+
+		KeyReleasedDelayTask(int repeatModeKeyCode) {
+			this.repeatModeKeyCode = repeatModeKeyCode;
+
+		}
+
+		public void run() {
+			if (repeatModeKeyCode != Integer.MIN_VALUE) {
+				MIDletAccess ma = MIDletBridge.getMIDletAccess();
+				if (ma == null) {
+					return;
+				}
+
+				DisplayAccess da = ma.getDisplayAccess();
+				if (da == null) {
+					return;
+				}
+
+				da.keyReleased(repeatModeKeyCode);
+				eventAlreadyConsumed = false;
+				repeatModeKeyCode = Integer.MIN_VALUE;
+			}
+		}
+	};
+	
+	public AndroidInputMethod() {
+		keyReleasedDelayTimer = ThreadUtils.createTimer("InputKeyReleasedDelayTimer");
+	}
+
+	public void buttonPressed(KeyEvent keyEvent) {
+		eventAlreadyConsumed = false;
+		if (DeviceFactory.getDevice().hasRepeatEvents() && inputMethodListener == null) {
+			if (repeatModeKeyCodes.contains(new Integer(getKeyCode(keyEvent)))) {
+				MIDletAccess ma = MIDletBridge.getMIDletAccess();
+				if (ma == null) {
+					return;
+				}
+				DisplayAccess da = ma.getDisplayAccess();
+				if (da == null) {
+					return;
+				}
+				da.keyRepeated(getKeyCode(keyEvent));
+				eventAlreadyConsumed = true;
+				return;
+			} else {
+				repeatModeKeyCodes.add(new Integer(getKeyCode(keyEvent)));
+			}
+		}
+
+		// invoke any associated commands, but send the raw key codes instead
+// TODO
+//		boolean rawSoftKeys = DeviceFactory.getDevice().getDeviceDisplay().isFullScreenMode();
+//		if (button instanceof SoftButton && !rawSoftKeys) {
+//			Command cmd = ((SoftButton) button).getCommand();
+//			if (cmd != null) {
+//				CommandManager.getInstance().commandAction(cmd);
+//				eventAlreadyConsumed = true;
+//				return;
+//			}
+//		}
+
+		if (fireInputMethodListener(keyEvent)) {
+			eventAlreadyConsumed = true;
+			return;
+		}
+	}
+
+	public void buttonReleased(KeyEvent keyEvent) {
+		if (DeviceFactory.getDevice().hasRepeatEvents() && inputMethodListener == null) {
+			repeatModeKeyCodes.remove(new Integer(getKeyCode(keyEvent)));
+			keyReleasedDelayTimer.schedule(new KeyReleasedDelayTask(getKeyCode(keyEvent)), 50);
+		} else {
+			MIDletAccess ma = MIDletBridge.getMIDletAccess();
+			if (ma == null) {
+				return;
+			}
+
+			DisplayAccess da = ma.getDisplayAccess();
+			if (da == null) {
+				return;
+			}
+
+			da.keyReleased(getKeyCode(keyEvent));
+			eventAlreadyConsumed = false;
+		}
+	}
+	
+	public void pointerPressed(int x, int y) {		
+		if (DeviceFactory.getDevice().hasPointerEvents()) {
+			MIDletBridge.getMIDletAccess().getDisplayAccess().pointerPressed(x, y);
+		}
+	}
+
+	public void pointerReleased(int x, int y) {
+		if (DeviceFactory.getDevice().hasPointerEvents()) {
+			MIDletBridge.getMIDletAccess().getDisplayAccess().pointerReleased(x, y);
+		}
+	}
+
+	public void pointerDragged(int x, int y) {
+		if (DeviceFactory.getDevice().hasPointerMotionEvents()) {
+			MIDletBridge.getMIDletAccess().getDisplayAccess().pointerDragged(x, y);
+		}
+	}
+
+	protected boolean fireInputMethodListener(KeyEvent keyEvent) {
+		MIDletAccess ma = MIDletBridge.getMIDletAccess();
+		if (ma == null) {
+			return false;
+		}
+		DisplayAccess da = ma.getDisplayAccess();
+		if (da == null) {
+			return false;
+		}
+
+		if (inputMethodListener == null) {
+			da.keyPressed(getKeyCode(keyEvent));
+			return true;
+		}
+// TODO
+/*		
+		ButtonName functionalName = button.getFunctionalName();
+
+		if (functionalName == ButtonName.UP || functionalName == ButtonName.DOWN) {
+			da.keyPressed(getKeyCode(keyEvent));
+			return true;
+		}
+
+		int caret = inputMethodListener.getCaretPosition();
+
+		if (button.isModeChange()) {
+			switch (inputMethodListener.getConstraints() & TextField.CONSTRAINT_MASK) {
+			case TextField.ANY:
+			case TextField.EMAILADDR:
+			case TextField.URL:
+				if (getInputMode() == InputMethod.INPUT_123) {
+					setInputMode(InputMethod.INPUT_ABC_UPPER);
+				} else if (getInputMode() == InputMethod.INPUT_ABC_UPPER) {
+					setInputMode(InputMethod.INPUT_ABC_LOWER);
+				} else if (getInputMode() == InputMethod.INPUT_ABC_LOWER) {
+					setInputMode(InputMethod.INPUT_123);
+				}
+				synchronized (this) {
+					if (lastButton != null) {
+						caret++;
+						lastButton = null;
+						lastButtonCharIndex = -1;
+					}
+				}
+				InputMethodEvent event = new InputMethodEvent(InputMethodEvent.CARET_POSITION_CHANGED, caret,
+						inputMethodListener.getText());
+				inputMethodListener.caretPositionChanged(event);
+				break;
+			}
+			return true;
+		}
+
+		if (functionalName == ButtonName.LEFT || functionalName == ButtonName.RIGHT) {
+			synchronized (this) {
+				if ((functionalName == ButtonName.LEFT) && caret > 0) {
+					caret--;
+				} else if ((functionalName == ButtonName.RIGHT) && caret < inputMethodListener.getText().length()) {
+					caret++;
+				}
+				lastButton = null;
+				lastButtonCharIndex = -1;
+			}
+			InputMethodEvent event = new InputMethodEvent(InputMethodEvent.CARET_POSITION_CHANGED, caret,
+					inputMethodListener.getText());
+			inputMethodListener.caretPositionChanged(event);
+			return true;
+		}
+
+		if (functionalName == ButtonName.BACK_SPACE) {
+			String tmp = "";
+			synchronized (this) {
+				if (lastButton != null) {
+					caret++;
+					lastButton = null;
+					lastButtonCharIndex = -1;
+				}
+				if (caret > 0) {
+					caret--;
+					if (caret > 0) {
+						tmp += inputMethodListener.getText().substring(0, caret);
+					}
+					if (caret < inputMethodListener.getText().length() - 1) {
+						tmp += inputMethodListener.getText().substring(caret + 1);
+					}
+				}
+			}
+			if (!validate(tmp, inputMethodListener.getConstraints())) {
+				return true;
+			}
+			InputMethodEvent event = new InputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, caret, tmp);
+			inputMethodListener.inputMethodTextChanged(event);
+			event = new InputMethodEvent(InputMethodEvent.CARET_POSITION_CHANGED, caret, tmp);
+			inputMethodListener.caretPositionChanged(event);
+			return true;
+		}
+
+		if (functionalName == ButtonName.DELETE) {
+			String tmp = inputMethodListener.getText();
+			synchronized (this) {
+				if (lastButton != null) {
+					lastButton = null;
+					lastButtonCharIndex = -1;
+				}
+				if (caret != inputMethodListener.getText().length()) {
+					tmp = inputMethodListener.getText().substring(0, caret)
+							+ inputMethodListener.getText().substring(caret + 1);
+				}
+			}
+			if (!validate(tmp, inputMethodListener.getConstraints())) {
+				return true;
+			}
+			InputMethodEvent event = new InputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, caret, tmp);
+			inputMethodListener.inputMethodTextChanged(event);
+			event = new InputMethodEvent(InputMethodEvent.CARET_POSITION_CHANGED, caret, tmp);
+			inputMethodListener.caretPositionChanged(event);
+			return true;
+		}
+
+		if (inputMethodListener.getText().length() < maxSize) {
+			StringBuffer editText = new StringBuffer(inputMethodListener.getText());
+			synchronized (this) {
+				lastButtonCharIndex++;
+				char[] buttonChars = filterConstraints(filterInputMode(button.getChars(getInputMode())));
+				if (keyChar != '\0') {
+					// Pass through letters and characters typed on keyboard but
+					// not numbers that are buttons keys (presumably).
+					editText.append(keyChar);
+					caret++;
+					lastButton = null;
+					lastButtonCharIndex = -1;
+				} else if (buttonChars.length > 0) {
+					if (lastButtonCharIndex == buttonChars.length) {
+						if (buttonChars.length == 1) {
+							if (lastButton != null) {
+								caret++;
+							}
+							lastButton = null;
+						} else {
+							lastButtonCharIndex = 0;
+						}
+					}
+					if (lastButton != button) {
+						if (lastButton != null) {
+							caret++;
+						}
+						if (editText.length() < caret) {
+							editText.append(buttonChars[0]);
+						} else {
+							editText.insert(caret, buttonChars[0]);
+						}
+						lastButton = button;
+						lastButtonCharIndex = 0;
+					} else {
+						editText.setCharAt(caret, buttonChars[lastButtonCharIndex]);
+						lastButton = button;
+					}
+				} else {
+					lastButton = null;
+					lastButtonCharIndex = -1;
+				}
+				resetKey = false;
+				notify();
+			}
+			if (!validate(editText.toString(), inputMethodListener.getConstraints())) {
+				return false;
+			}
+			InputMethodEvent event = new InputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, caret, editText
+					.toString());
+			inputMethodListener.inputMethodTextChanged(event);
+		}*/
+		return false;
+	}
+
+	private int getKeyCode(KeyEvent keyEvent) {
+		// TODO implement as lookup table
+		int deviceKeyCode = keyEvent.getKeyCode();
+		
+		int resultKeyCode;
+		switch (deviceKeyCode) {
+		case KeyEvent.KEYCODE_DPAD_CENTER :
+			resultKeyCode = Canvas.FIRE;
+			break;
+		case KeyEvent.KEYCODE_DPAD_UP :
+			resultKeyCode = Canvas.UP;
+			break;
+		case KeyEvent.KEYCODE_DPAD_DOWN :
+			resultKeyCode = Canvas.DOWN;
+			break;
+		case KeyEvent.KEYCODE_DPAD_LEFT :
+			resultKeyCode = Canvas.LEFT;
+			break;
+		case KeyEvent.KEYCODE_DPAD_RIGHT :
+			resultKeyCode = Canvas.RIGHT;
+			break;
+		default: 
+			System.out.println("(todo) getKeyCode: " + keyEvent);
+			resultKeyCode = -1;
+		}
+
+		return resultKeyCode;
+	}
+
+	@Override
+	public void dispose() {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	public int getGameAction(int keyCode) {
+		// TODO implement as lookup table
+		int gameAction;
+		switch (keyCode) {
+		case Canvas.FIRE :
+			gameAction = Canvas.FIRE;
+			break;
+		case Canvas.UP :
+			gameAction = Canvas.UP;
+			break;
+		case Canvas.DOWN :
+			gameAction = Canvas.DOWN;
+			break;
+		case Canvas.LEFT :
+			gameAction = Canvas.LEFT;
+			break;
+		case Canvas.RIGHT :
+			gameAction = Canvas.RIGHT;
+			break;
+		default:
+			System.out.println("(todo) getGameAction: " + keyCode);
+			gameAction = -1; 
+		}
+
+		return gameAction;
+	}
+
+	@Override
+	public int getKeyCode(int gameAction) {
+		System.out.println("getKeyCode: " + gameAction);
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public String getKeyName(int keyCode) throws IllegalArgumentException {
+		// TODO implement as lookup table
+		String keyName;
+		switch (keyCode) {
+		case Canvas.FIRE :
+			keyName = "SEL";
+			break;
+		case Canvas.UP :
+			keyName = "U";
+			break;
+		case Canvas.DOWN :
+			keyName = "D";
+			break;
+		case Canvas.LEFT :
+			keyName = "L";
+			break;
+		case Canvas.RIGHT :
+			keyName = "R";
+			break;
+		default:
+			System.out.println("(todo) getKeyName: " + keyCode);
+			keyName = ""; 
+		}
+
+		return keyName;
+	}
+
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidInputMethod.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidMutableImage.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidMutableImage.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidMutableImage.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidMutableImage.java Mon May 26 15:20:19 2008
@@ -0,0 +1,107 @@
+/*
+ *  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 org.microemu.android.device;
+
+import javax.microedition.android.lcdui.Graphics;
+
+import org.microemu.device.MutableImage;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+
+public class AndroidMutableImage extends MutableImage {
+	
+	private Bitmap bitmap;
+	
+	public AndroidMutableImage(int width, int height) {
+		bitmap = Bitmap.createBitmap(width, height, false);
+	}
+
+	@Override
+	public int[] getData() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Graphics getGraphics() {
+        Canvas canvas = new Canvas(bitmap);
+        canvas.clipRect(0, 0, getWidth(), getHeight());
+        AndroidDisplayGraphics displayGraphics = new AndroidDisplayGraphics(canvas, this);
+		displayGraphics.setColor(0x00000000);
+		displayGraphics.translate(-displayGraphics.getTranslateX(), -displayGraphics.getTranslateY());
+		
+		return displayGraphics;
+	}
+
+	@Override
+	public boolean isMutable() {
+		return true;
+	}
+
+	public Bitmap getBitmap() {
+		return bitmap;
+	}
+
+	@Override
+	public int getWidth() {
+		return bitmap.width();
+	}
+	
+	@Override
+	public int getHeight() {
+		return bitmap.height();
+	}
+
+	@Override
+    public void getRGB(int []argb, int offset, int scanlength,
+            int x, int y, int width, int height) {
+
+        if (width <= 0 || height <= 0)
+            return;
+        if (x < 0 || y < 0 || x + width > getWidth() || y + height > getHeight())
+            throw new IllegalArgumentException("Specified area exceeds bounds of image");
+        if ((scanlength < 0? -scanlength:scanlength) < width)
+            throw new IllegalArgumentException("abs value of scanlength is less than width");
+        if (argb == null)
+            throw new NullPointerException("null rgbData");
+        if (offset < 0 || offset + width > argb.length)
+            throw new ArrayIndexOutOfBoundsException();
+        if (scanlength < 0) {
+            if (offset + scanlength*(height-1) < 0)
+                throw new ArrayIndexOutOfBoundsException();
+        } else {
+            if (offset + scanlength*(height-1) + width > argb.length)
+                throw new ArrayIndexOutOfBoundsException();
+        }
+
+        bitmap.getPixels(argb, offset, scanlength, x, y, width, height);
+
+/*        for (int i = 0; i < argb.length; i++) {
+		    int a = (argb[i] & 0xFF000000);
+		    int b = (argb[i] & 0x00FF0000) >>> 16;
+		    int g = (argb[i] & 0x0000FF00) >>> 8;
+		    int r = (argb[i] & 0x000000FF);
+	
+		    argb[i] = a | (r << 16) | (g << 8) | b;
+        }*/
+	}
+	
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/AndroidMutableImage.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidCanvasUI.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidCanvasUI.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidCanvasUI.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidCanvasUI.java Mon May 26 15:20:19 2008
@@ -0,0 +1,186 @@
+/*
+ *  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 org.microemu.android.device.ui;
+
+import javax.microedition.android.lcdui.Canvas;
+import javax.microedition.android.lcdui.Image;
+
+import org.microemu.MIDletBridge;
+import org.microemu.android.MicroEmulatorActivity;
+import org.microemu.android.device.AndroidDeviceDisplay;
+import org.microemu.android.device.AndroidInputMethod;
+import org.microemu.android.device.AndroidMutableImage;
+import org.microemu.device.Device;
+import org.microemu.device.DeviceDisplay;
+import org.microemu.device.DeviceFactory;
+import org.microemu.device.ui.CanvasUI;
+
+import android.content.Context;
+import android.graphics.Paint;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+
+public class AndroidCanvasUI extends AndroidDisplayableUI implements CanvasUI {
+
+	private MicroEmulatorActivity activity;
+	
+	private CanvasView view;
+	
+	public AndroidCanvasUI(final MicroEmulatorActivity activity, Canvas canvas) {
+		this.activity = activity;
+		
+		activity.post(new Runnable() {
+			public void run() {
+				AndroidCanvasUI.this.view = new CanvasView(activity);
+			}
+		});
+	}
+	
+	public View getView() {
+		return view;
+	}
+	
+	public Image getImage() {
+		// TODO improve method that waits for for view being initialized
+		while (view == null) {
+			try {
+				Thread.sleep(100);
+			} catch (InterruptedException ex) {
+				ex.printStackTrace();
+			}
+		}
+		return view.getImage();
+	}
+
+	//
+	// DisplayableUI
+	//
+
+	public void hideNotify() {
+	}
+
+	public void showNotify() {
+		activity.post(new Runnable() {
+			public void run() {
+				activity.setContentView(view);
+				view.requestFocus();
+			}
+		});
+	}
+	
+	public void invalidate() {
+		// TODO implement title painting		
+	}
+
+	private class CanvasView extends View {
+		
+		public CanvasView(Context context) {
+			super(context);
+			
+			setFocusable(true);
+		}
+
+		private AndroidMutableImage displayImage = null;
+		
+		private Paint paint = new Paint();
+		
+		public Image getImage() {
+			synchronized(this) {
+				if (displayImage == null) {
+					DeviceDisplay deviceDisplay = DeviceFactory.getDevice().getDeviceDisplay();
+					displayImage = new AndroidMutableImage(deviceDisplay.getFullWidth(), deviceDisplay.getFullHeight());
+				}
+			}
+
+			return displayImage;
+		}
+
+		//
+		// View
+		//
+		
+		@Override
+		protected void onDraw(android.graphics.Canvas canvas) {
+			if (displayImage != null) {
+				synchronized (displayImage) {
+					canvas.drawBitmap(displayImage.getBitmap(), 0, 0, paint);
+				}
+			}
+		}	
+		
+		@Override
+		public boolean onKeyDown(int keyCode, KeyEvent event) {
+			if (MIDletBridge.getCurrentMIDlet() == null) {
+				return false;
+			}
+			
+			// KEYCODE_SOFT_LEFT == menu key 
+			if (keyCode == KeyEvent.KEYCODE_SOFT_LEFT) {
+				return false;
+			}
+			
+			Device device = DeviceFactory.getDevice();
+			((AndroidInputMethod) device.getInputMethod()).buttonPressed(event);
+			
+			return true;
+		}
+
+		@Override
+		public boolean onKeyUp(int keyCode, KeyEvent event) {
+			if (MIDletBridge.getCurrentMIDlet() == null) {
+				return false;
+			}
+
+			// KEYCODE_SOFT_LEFT == menu key 
+			if (keyCode == KeyEvent.KEYCODE_SOFT_LEFT) {
+				return false;
+			}
+
+			Device device = DeviceFactory.getDevice();
+			((AndroidInputMethod) device.getInputMethod()).buttonReleased(event);
+
+			return true;
+		}
+
+		@Override
+		public boolean onTouchEvent(MotionEvent event) {
+			Device device = DeviceFactory.getDevice();
+			AndroidInputMethod inputMethod = (AndroidInputMethod) device.getInputMethod();
+			switch (event.getAction()) {
+			case MotionEvent.ACTION_DOWN :
+				inputMethod.pointerPressed((int) event.getX(), (int) event.getY());
+				break;
+			case MotionEvent.ACTION_UP :
+				inputMethod.pointerReleased((int) event.getX(), (int) event.getY());
+				break;
+			case MotionEvent.ACTION_MOVE :
+				inputMethod.pointerDragged((int) event.getX(), (int) event.getY());
+				break;
+			default:
+				return false;
+			}
+			
+			return true;
+		}
+
+	}
+
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidCanvasUI.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidDisplayableUI.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidDisplayableUI.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidDisplayableUI.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidDisplayableUI.java Mon May 26 15:20:19 2008
@@ -0,0 +1,78 @@
+/*
+ *  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 org.microemu.android.device.ui;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.microedition.android.lcdui.Command;
+import javax.microedition.android.lcdui.CommandListener;
+
+import org.microemu.device.ui.DisplayableUI;
+
+public abstract class AndroidDisplayableUI implements DisplayableUI {
+	
+	private static Comparator<Command> commandsPriorityComparator = new Comparator<Command>() {
+
+		public int compare(Command first, Command second) {
+			if (first.getPriority() == second.getPriority()) {
+				return 0;
+			} else if (first.getPriority() < second.getPriority()) {
+				return -1;
+			} else {
+				return 1;
+			}
+		}
+		
+	};
+	
+	private List<Command> commands = new ArrayList<Command>();
+	
+	private CommandListener commandListener = null;
+	
+	public List<Command> getCommands() {
+		return commands;
+	}
+	
+	public CommandListener getCommandListener() {
+		return commandListener;
+	}
+	
+	//
+	// DisplayableUI
+	//
+
+	public void addCommand(Command cmd) {
+		commands.add(cmd);
+		// TODO decide whether this is the best way for keeping sorted commands
+		Collections.sort(commands, commandsPriorityComparator);
+	}
+
+	public void removeCommand(Command cmd) {
+		commands.remove(cmd);
+	}
+
+	public void setCommandListener(CommandListener l) {
+		this.commandListener = l;
+	}
+
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidDisplayableUI.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidListUI.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidListUI.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidListUI.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidListUI.java Mon May 26 15:20:19 2008
@@ -0,0 +1,187 @@
+/*
+ *  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 org.microemu.android.device.ui;
+
+import java.util.ArrayList;
+
+import javax.microedition.android.lcdui.Image;
+import javax.microedition.android.lcdui.List;
+import javax.microedition.android.lcdui.Command;
+
+import org.microemu.android.MicroEmulatorActivity;
+import org.microemu.device.ui.ListUI;
+
+import android.content.Context;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+
+public class AndroidListUI extends AndroidDisplayableUI implements ListUI {
+
+	private MicroEmulatorActivity activity;
+	
+	private List list;
+	
+	private Command selectCommand;
+	
+	private LinearLayout view;
+	
+	private TextView titleView;
+	
+	private AndroidListAdapter listAdapter;
+	
+	private AndroidListView listView;
+	
+	public AndroidListUI(final MicroEmulatorActivity activity, List list) {
+		this.activity = activity;
+		this.list = list;
+		
+		this.selectCommand = List.SELECT_COMMAND;
+			
+		activity.post(new Runnable() {
+			public void run() {
+				AndroidListUI.this.view = new LinearLayout(activity);
+				AndroidListUI.this.view.setOrientation(LinearLayout.VERTICAL);
+				AndroidListUI.this.view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
+				
+				AndroidListUI.this.titleView = new TextView(activity);
+				AndroidListUI.this.titleView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+				AndroidListUI.this.view.addView(titleView);				
+		
+				AndroidListUI.this.listAdapter = new AndroidListAdapter();
+				AndroidListUI.this.listView = new AndroidListView(activity);
+				AndroidListUI.this.listView.setAdapter(AndroidListUI.this.listAdapter);
+				AndroidListUI.this.listView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));				
+				AndroidListUI.this.view.addView(AndroidListUI.this.listView);		
+
+				AndroidListUI.this.invalidate();
+			}
+		});		
+	}
+	
+	//
+	// DisplayableUI
+	//
+	
+	public void hideNotify() {
+	}
+
+	public void showNotify() {
+		activity.post(new Runnable() {
+			public void run() {
+				activity.setContentView(view);
+				listView.requestFocus();
+			}
+		});
+	}
+	
+	public void invalidate() {
+		titleView.setText(list.getTitle());		
+	}	
+
+	//
+	// ListUI
+	//
+	
+	public int append(String stringPart, Image imagePart) {
+		return listAdapter.append(stringPart);
+	}
+	
+	public int getSelectedIndex() {
+		return listView.getSelectedItemPosition();
+	}
+
+	public String getString(int elementNum) {
+		return (String) listAdapter.getItem(elementNum);
+	}
+
+	public void setSelectCommand(Command command) {
+		this.selectCommand = command;		
+	}
+
+	private class AndroidListAdapter extends BaseAdapter {
+		
+		ArrayList<String> objects = new ArrayList<String>();
+		
+		public int append(String stringPart) {
+			objects.add(stringPart);
+			notifyDataSetChanged();
+			
+			return objects.lastIndexOf(stringPart);
+		}
+
+		public int getCount() {
+			return objects.size();
+		}
+
+		public Object getItem(int position) {
+			return objects.get(position);
+		}
+
+		public long getItemId(int position) {
+			return position;
+		}
+
+		public View getView(int position, View convertView, ViewGroup parent) {
+			if (convertView == null) {
+				convertView = new TextView(activity);
+			}
+			
+			((TextView) convertView).setText((String) getItem(position));
+			
+			return convertView;
+		}
+		
+	}
+	
+	private class AndroidListView extends ListView {
+
+		public AndroidListView(Context context) {
+			super(context);
+		}
+
+		@Override
+		public boolean onKeyDown(int keyCode, KeyEvent event) {
+			if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
+				if (getCommandListener() != null) {
+					getCommandListener().commandAction(selectCommand, list);
+					return true;
+				} else {				
+					return false;
+				}
+			} else {
+				return super.onKeyDown(keyCode, event);
+			}
+		}
+	
+		@Override
+		public boolean onTouchEvent(MotionEvent ev) {
+			// TODO implement pointer events
+			return super.onTouchEvent(ev);
+		}
+		
+	}
+	
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidListUI.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidTextBoxUI.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidTextBoxUI.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidTextBoxUI.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidTextBoxUI.java Mon May 26 15:20:19 2008
@@ -0,0 +1,103 @@
+/*
+ *  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 org.microemu.android.device.ui;
+
+import javax.microedition.android.lcdui.TextBox;
+
+import org.microemu.android.MicroEmulatorActivity;
+import org.microemu.device.ui.TextBoxUI;
+
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class AndroidTextBoxUI extends AndroidDisplayableUI implements TextBoxUI {
+	
+	private MicroEmulatorActivity activity;
+	
+	private TextBox textBox;
+	
+	private LinearLayout view;
+	
+	private TextView titleView;
+	
+	private EditText editView;
+	
+	public AndroidTextBoxUI(final MicroEmulatorActivity activity, TextBox textBox) {
+		this.activity = activity;		
+		this.textBox = textBox;
+		
+		activity.post(new Runnable() {
+			public void run() {
+				AndroidTextBoxUI.this.view = new LinearLayout(activity);
+				AndroidTextBoxUI.this.view.setOrientation(LinearLayout.VERTICAL);
+				AndroidTextBoxUI.this.view.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
+				
+				titleView = new TextView(activity);
+				titleView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+				AndroidTextBoxUI.this.view.addView(titleView);
+				
+				editView = new EditText(activity);
+				editView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
+				AndroidTextBoxUI.this.view.addView(editView);
+				
+				AndroidTextBoxUI.this.invalidate();
+			}
+		});		
+	}
+
+	//
+	// DisplayableUI
+	//
+	
+	public void hideNotify() {
+	}
+
+	public void showNotify() {
+		activity.post(new Runnable() {
+			public void run() {
+				activity.setContentView(view);
+				editView.requestFocus();
+			}
+		});
+	}
+	
+	public void invalidate() {
+		titleView.setText(textBox.getTitle());		
+	}	
+
+	//
+	// TextBoxUI
+	//
+	
+	public int getCaretPosition() {
+		return editView.getSelectionStart();
+	}
+	
+	public String getString() {
+		return editView.getText().toString();
+	}
+
+	public void setString(String text) {
+		editView.setText(text);
+		editView.setSelection(text.length());
+	}
+
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/device/ui/AndroidTextBoxUI.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/util/AndroidLoggerAppender.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/util/AndroidLoggerAppender.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/util/AndroidLoggerAppender.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/util/AndroidLoggerAppender.java Mon May 26 15:20:19 2008
@@ -0,0 +1,56 @@
+/*
+ *  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 org.microemu.android.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import org.microemu.android.MicroEmulator;
+import org.microemu.log.LoggerAppender;
+import org.microemu.log.LoggingEvent;
+
+import android.util.Log;
+
+public class AndroidLoggerAppender implements LoggerAppender {
+
+	public static String formatLocation(StackTraceElement ste) {
+		if (ste == null) {
+			return "";
+		}
+		// Make Line# clickable in eclipse
+		return ste.getClassName() + "." + ste.getMethodName() + "(" + ste.getFileName() + ":" + ste.getLineNumber()
+				+ ")";
+	}
+
+	public void append(LoggingEvent event) {
+    	String data = "";
+    	if (event.hasData()) {
+    		data = " [" + event.getFormatedData() + "]";
+    	}
+		Log.v(MicroEmulator.LOG_TAG, event.getMessage() + data +  "\n\t  " + formatLocation(event.getLocation()));
+    	if (event.getThrowable() != null) {
+    		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    		event.getThrowable().printStackTrace(new PrintStream(baos));
+    		Log.v(MicroEmulator.LOG_TAG, baos.toString());
+    	}
+
+	}
+
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/util/AndroidLoggerAppender.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/util/AndroidRecordStoreManager.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/util/AndroidRecordStoreManager.java?rev=660326&view=auto
==============================================================================
--- harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/util/AndroidRecordStoreManager.java (added)
+++ harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/util/AndroidRecordStoreManager.java Mon May 26 15:20:19 2008
@@ -0,0 +1,199 @@
+/*
+ *  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 org.microemu.android.util;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Hashtable;
+
+import javax.microedition.rms.RecordListener;
+import javax.microedition.rms.RecordStore;
+import javax.microedition.rms.RecordStoreException;
+import javax.microedition.rms.RecordStoreNotFoundException;
+import javax.microedition.rms.RecordStoreNotOpenException;
+
+import org.microemu.MicroEmulator;
+import org.microemu.RecordStoreManager;
+import org.microemu.app.launcher.Launcher;
+import org.microemu.log.Logger;
+import org.microemu.util.RecordStoreImpl;
+
+import android.content.Context;
+
+public class AndroidRecordStoreManager implements RecordStoreManager {
+
+	private final static String RECORD_STORE_SUFFIX = ".rs";
+	
+	private Context context;
+
+	private Launcher launcher;
+
+	private Hashtable testOpenRecordStores = new Hashtable();
+
+	private RecordListener recordListener = null;
+
+// TODO move to listRecordStores
+/*	private FilenameFilter filter = new FilenameFilter() {
+		public boolean accept(File dir, String name) {
+			if (name.endsWith(RECORD_STORE_SUFFIX)) {
+				return true;
+			} else {
+				return false;
+			}
+		}
+	};*/
+	
+	public AndroidRecordStoreManager(Context context) {
+		this.context = context;
+	}
+
+	public void init(MicroEmulator emulator) {
+		this.launcher = emulator.getLauncher();
+	}
+
+	public String getName() {
+		return "Android record store";
+	}
+
+	private String getSuiteName() {
+		return launcher.getSuiteName();
+	}
+
+	public void deleteRecordStore(final String recordStoreName) throws RecordStoreNotFoundException,
+			RecordStoreException {
+		String storeFileName = getSuiteName() + "." + recordStoreName + RECORD_STORE_SUFFIX;
+
+		RecordStoreImpl recordStoreImpl = (RecordStoreImpl) testOpenRecordStores.get(storeFileName);
+		if (recordStoreImpl != null && recordStoreImpl.isOpen()) {
+			throw new RecordStoreException();
+		}
+
+		try {
+			recordStoreImpl = loadFromDisk(storeFileName);
+		} catch (FileNotFoundException ex) {
+			throw new RecordStoreNotFoundException(recordStoreName);
+		}
+
+		context.deleteFile(storeFileName);
+		fireRecordStoreListener(RecordListener.RECORDSTORE_DELETE, recordStoreName);
+	}
+
+	public RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary) throws RecordStoreException {
+		String storeFileName = getSuiteName() + "." + recordStoreName + RECORD_STORE_SUFFIX;
+
+		RecordStoreImpl recordStoreImpl;
+		try {
+			recordStoreImpl = loadFromDisk(storeFileName);
+		} catch (FileNotFoundException e) {
+			if (!createIfNecessary) {
+				throw new RecordStoreNotFoundException(recordStoreName);
+			}
+			recordStoreImpl = new RecordStoreImpl(this, recordStoreName);
+			saveToDisk(getSuiteName() + "." + recordStoreName + RECORD_STORE_SUFFIX, recordStoreImpl);
+		}
+		recordStoreImpl.setOpen(true);
+		if (recordListener != null) {
+			recordStoreImpl.addRecordListener(recordListener);
+		}
+
+		testOpenRecordStores.put(storeFileName, recordStoreImpl);
+
+		fireRecordStoreListener(RecordListener.RECORDSTORE_OPEN, recordStoreName);
+
+		return recordStoreImpl;
+	}
+
+	public String[] listRecordStores() {
+		String[] result= context.fileList();
+		if (result != null) {
+			if (result.length == 0) {
+				result = null;
+			} else {
+				for (int i = 0; i < result.length; i++) {
+					result[i] = result[i].substring(0, result[i].length() - RECORD_STORE_SUFFIX.length());
+				}
+			}
+		}
+		return result;
+	}
+
+	public void saveChanges(RecordStoreImpl recordStoreImpl) 
+			throws RecordStoreNotOpenException, RecordStoreException {
+		saveToDisk(getSuiteName() + "." + recordStoreImpl.getName() + RECORD_STORE_SUFFIX, recordStoreImpl);
+	}
+
+	public void init() {
+	}
+
+	public void deleteStores() {
+		String[] stores = listRecordStores();
+		for (int i = 0; i < stores.length; i++) {
+			String store = stores[i];
+			try {
+				deleteRecordStore(store);
+			} catch (RecordStoreException e) {
+				Logger.debug("deleteRecordStore", e);
+			}
+		}
+	}
+
+	private RecordStoreImpl loadFromDisk(String recordStoreFileName) throws FileNotFoundException {
+		RecordStoreImpl store = null;
+		try {
+			DataInputStream dis = new DataInputStream(context.openFileInput(recordStoreFileName));
+			store = new RecordStoreImpl(this, dis);
+			dis.close();
+		} catch (FileNotFoundException e) {
+			throw e;
+		} catch (IOException e) {
+			Logger.error("RecordStore.loadFromDisk: ERROR reading " + recordStoreFileName, e);
+		}
+		return store;
+	}
+
+	private void saveToDisk(String recordStoreFileName, final RecordStoreImpl recordStore)
+			throws RecordStoreException {
+		try {
+			DataOutputStream dos = new DataOutputStream(context.openFileOutput(recordStoreFileName, Context.MODE_PRIVATE));
+			recordStore.write(dos);
+			dos.close();
+		} catch (IOException e) {
+			Logger.error("RecordStore.saveToDisk: ERROR writting object to " + recordStoreFileName, e);
+			throw new RecordStoreException(e.getMessage());
+		}
+	}
+
+	public int getSizeAvailable(RecordStoreImpl recordStoreImpl) {
+		// FIXME should return free space on device
+		return 1024 * 1024;
+	}
+
+	public void setRecordListener(RecordListener recordListener) {
+		this.recordListener = recordListener;
+	}
+
+	public void fireRecordStoreListener(int type, String recordStoreName) {
+		if (recordListener != null) {
+			recordListener.recordStoreEvent(type, System.currentTimeMillis(), recordStoreName);
+		}
+	}
+}

Propchange: harmony/enhanced/microemulator/microemu-android/src/org/microemu/android/util/AndroidRecordStoreManager.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message