public void Init(Syscalls syscalls, Core core, Runtime runtime) { runtime.RegisterCleaner(delegate() { foreach(KeyValuePair<int, Connection> p in mConnections) { p.Value.close(); } mConnections.Clear(); }); mResultHandler = delegate(int handle, int connOp, int result) { Memory evt = new Memory(4 * 4); evt.WriteInt32(MAEvent_type, MoSync.Constants.EVENT_TYPE_CONN); evt.WriteInt32(MAConnEventData_handle, handle); evt.WriteInt32(MAConnEventData_opType, connOp); evt.WriteInt32(MAConnEventData_result, result); runtime.PostEvent(new Event(evt)); }; syscalls.maConnect = delegate(int _url) { String url = core.GetDataMemory().ReadStringAtAddress(_url); Uri uri = new Uri(url); Connection c; if (uri.Scheme.Equals("socket")) { c = new SocketConnection(uri, mNextConnHandle); } else if (uri.Scheme.Equals("http") || uri.Scheme.Equals("https")) { c = new WebRequestConnection(uri, mNextConnHandle, MoSync.Constants.HTTP_GET); } else { return MoSync.Constants.CONNERR_GENERIC; } c.connect(mResultHandler); mConnections.Add(mNextConnHandle, c); return mNextConnHandle++; }; syscalls.maConnClose = delegate(int _conn) { Connection c = mConnections[_conn]; c.close(); mConnections.Remove(_conn); }; syscalls.maConnGetAddr = delegate(int _conn, int _addr) { Connection c = mConnections[_conn]; return c.getAddr(_addr); }; syscalls.maConnRead = delegate(int _conn, int _dst, int _size) { Connection c = mConnections[_conn]; c.recv(core.GetDataMemory().GetData(), _dst, _size, mResultHandler); }; DataDelegate dataDelegate = delegate(int _conn, int _data, CommDelegate cd) { Connection c = mConnections[_conn]; Resource res = runtime.GetResource(MoSync.Constants.RT_BINARY, _data); Memory mem = (Memory)res.GetInternalObject(); runtime.SetResourceRaw(_data, Resource.Flux); cd(c, mem.GetData(), delegate(int handle, int connOp, int result) { runtime.SetResourceRaw(_data, res); mResultHandler(handle, connOp, result); }); }; syscalls.maConnReadToData = delegate(int _conn, int _data, int _offset, int _size) { dataDelegate(_conn, _data, delegate(Connection c, byte[] buf, ResultHandler rh) { c.recv(buf, _offset, _size, rh); }); }; syscalls.maConnWrite = delegate(int _conn, int _src, int _size) { Connection c = mConnections[_conn]; c.write(core.GetDataMemory().GetData(), _src, _size, mResultHandler); }; syscalls.maConnWriteFromData = delegate(int _conn, int _data, int _offset, int _size) { dataDelegate(_conn, _data, delegate(Connection c, byte[] buf, ResultHandler rh) { c.write(buf, _offset, _size, rh); }); }; syscalls.maHttpCreate = delegate(int _url, int _method) { String url = core.GetDataMemory().ReadStringAtAddress(_url); Uri uri = new Uri(url); WebRequestConnection c = new WebRequestConnection(uri, mNextConnHandle, _method); mConnections.Add(mNextConnHandle, c); return mNextConnHandle++; }; syscalls.maHttpFinish = delegate(int _conn) { WebRequestConnection c = (WebRequestConnection)mConnections[_conn]; c.connect(delegate(int handle, int connOp, int result) { mResultHandler(handle, MoSync.Constants.CONNOP_FINISH, result); }); }; syscalls.maHttpSetRequestHeader = delegate(int _conn, int _key, int _value) { WebRequestConnection c = (WebRequestConnection)mConnections[_conn]; String key = core.GetDataMemory().ReadStringAtAddress(_key); String value = core.GetDataMemory().ReadStringAtAddress(_value); c.setRequestHeader(key, value); }; syscalls.maHttpGetResponseHeader = delegate(int _conn, int _key, int _buffer, int _bufSize) { WebRequestConnection c = (WebRequestConnection)mConnections[_conn]; String key = core.GetDataMemory().ReadStringAtAddress(_key); String value = c.getResponseHeader(key); if (value == null) return MoSync.Constants.CONNERR_NOHEADER; if (value.Length + 1 <= _bufSize) core.GetDataMemory().WriteStringAtAddress(_buffer, value, _bufSize); return value.Length; }; }
public void Init(Syscalls syscalls, Core core, Runtime runtime) { runtime.RegisterCleaner(delegate() { CleanDictionary(mFileHandles); CleanDictionary(mStoreHandles); mFileListHandles.Clear(); }); // todo: store "stores" in a separate location from the filesystem, // to avoid clashes. syscalls.maOpenStore = delegate(int _name, int _flags) { String name = core.GetDataMemory().ReadStringAtAddress(_name); name = ConvertPath(name); File file = new File(name, FileAccess.ReadWrite); if (file.IsDirectory) { throw new Exception("Invalid store name"); } if (file.Exists) file.TryOpen(); else if ((_flags & MoSync.Constants.MAS_CREATE_IF_NECESSARY) != 0) { file.Create(); } else return MoSync.Constants.STERR_NONEXISTENT; if (file.FileStream == null) return MoSync.Constants.STERR_GENERIC; mStoreHandles.Add(mNextStoreHandle, file); return mNextStoreHandle++; }; syscalls.maWriteStore = delegate(int _store, int _data) { File file = mStoreHandles[_store]; IsolatedStorageFileStream fileStream = file.FileStream; fileStream.SetLength(0); Resource dataRes = runtime.GetResource(MoSync.Constants.RT_BINARY, _data); Stream data = (Stream)dataRes.GetInternalObject(); data.Seek(0, SeekOrigin.Begin); //fileStream.Write(data.GetData(), 0, data.GetData().Length); data.CopyTo(fileStream); return 1; }; syscalls.maReadStore = delegate(int _store, int _placeholder) { File file = mStoreHandles[_store]; IsolatedStorageFileStream fileStream = file.FileStream; //Memory mem = new Memory((int)fileStream.Length); MemoryStream mem = new MemoryStream((int)fileStream.Length); fileStream.Seek(0, SeekOrigin.Begin); fileStream.Read(mem.GetBuffer(), 0, (int)fileStream.Length); runtime.SetResource(_placeholder, new Resource(mem, MoSync.Constants.RT_BINARY)); return MoSync.Constants.RES_OK; }; syscalls.maCloseStore = delegate(int _store, int _delete) { File file = mStoreHandles[_store]; file.Close(); if (_delete != 0) file.Delete(); mStoreHandles.Remove(_store); }; }
public void Init(Syscalls syscalls, Core core, Runtime runtime) { PhoneApplicationFrame frame = (PhoneApplicationFrame)Application.Current.RootVisual; double screenWidth = System.Windows.Application.Current.Host.Content.ActualWidth; double screenHeight = System.Windows.Application.Current.Host.Content.ActualHeight; if ((int)screenHeight == 0) throw new Exception("screenHeight"); PhoneApplicationPage mainPage = (PhoneApplicationPage)frame.Content; Image mainImage = new Image(); mainPage.Width = screenWidth; mainPage.Height = screenHeight; mainImage.Width = screenWidth; mainImage.Height = screenHeight; mainPage.Content = mainImage; // no apparent effect on memory leaks. runtime.RegisterCleaner(delegate() { MoSync.Util.RunActionOnMainThreadSync(() => { mainPage.Content = null; }); }); mBackBuffer = new WriteableBitmap( (int)screenWidth, (int)screenHeight); mFrontBuffer = new WriteableBitmap( (int)screenWidth, (int)screenHeight); mainImage.Source = mFrontBuffer; mCurrentDrawTarget = mBackBuffer; mCurrentWindowsColor = System.Windows.Media.Color.FromArgb(0xff, (byte)(mCurrentColor >> 16), (byte)(mCurrentColor >> 8), (byte)(mCurrentColor)); syscalls.maSetColor = delegate(int rgb) { int oldColor = (int)mCurrentColor; mCurrentColor = 0xff000000 | (uint)(rgb & 0xffffff); mCurrentWindowsColor = System.Windows.Media.Color.FromArgb(0xff, (byte)(mCurrentColor >> 16), (byte)(mCurrentColor >> 8), (byte)(mCurrentColor)); return oldColor & 0xffffff; }; syscalls.maSetClipRect = delegate(int x, int y, int w, int h) { }; syscalls.maGetClipRect = delegate(int cliprect) { }; syscalls.maPlot = delegate(int x, int y) { mCurrentDrawTarget.SetPixel(x, y, (int)mCurrentColor); }; syscalls.maUpdateScreen = delegate() { System.Array.Copy(mBackBuffer.Pixels, mFrontBuffer.Pixels, mFrontBuffer.PixelWidth * mFrontBuffer.PixelHeight); InvalidateWriteableBitmapOnMainThread(mFrontBuffer); }; syscalls.maFillRect = delegate(int x, int y, int w, int h) { mCurrentDrawTarget.FillRectangle(x, y, x + w, y + h, (int)mCurrentColor); }; syscalls.maLine = delegate(int x1, int y1, int x2, int y2) { mCurrentDrawTarget.DrawLine(x1, y1, x2, y2, (int)mCurrentColor); }; TextBlock textBlock = new TextBlock(); textBlock.FontSize = mCurrentFontSize; syscalls.maDrawText = delegate(int left, int top, int str) { String text = core.GetDataMemory().ReadStringAtAddress(str); if (text.Length == 0) return; MoSync.Util.RunActionOnMainThreadSync(() => { textBlock.Text = text; textBlock.Foreground = new SolidColorBrush(mCurrentWindowsColor); WriteableBitmap b = new WriteableBitmap(textBlock, null); mCurrentDrawTarget.Blit(new Rect(left, top, b.PixelWidth, b.PixelHeight), b, new Rect(0, 0, b.PixelWidth, b.PixelHeight)); }); }; syscalls.maGetTextSize = delegate(int str) { String text = core.GetDataMemory().ReadStringAtAddress(str); int textWidth = 0; int textHeight = 0; MoSync.Util.RunActionOnMainThreadSync(() => { textBlock.Text = text; textWidth = (int)textBlock.ActualWidth; textHeight = (int)textBlock.ActualHeight; }); return MoSync.Util.CreateExtent(textWidth, textHeight); }; syscalls.maDrawTextW = delegate(int left, int top, int str) { String text = core.GetDataMemory().ReadWStringAtAddress(str); if (text.Length == 0) return; MoSync.Util.RunActionOnMainThreadSync(() => { textBlock.Text = text; textBlock.Foreground = new SolidColorBrush(mCurrentWindowsColor); WriteableBitmap b = new WriteableBitmap(textBlock, null); Rect dstRect = new Rect(left, top, b.PixelWidth, b.PixelHeight); Rect srcRect = new Rect(0, 0, b.PixelWidth, b.PixelHeight); // cliprect.. Rect clipRect = new Rect(0, 0, mBackBuffer.PixelWidth, mBackBuffer.PixelHeight); clipRect.Intersect(dstRect); if (clipRect.IsEmpty == true) { return; } mCurrentDrawTarget.Blit(dstRect, b, srcRect); }); }; syscalls.maGetTextSizeW = delegate(int str) { String text = core.GetDataMemory().ReadWStringAtAddress(str); int textWidth = 0; int textHeight = 0; MoSync.Util.RunActionOnMainThreadSync(() => { textBlock.Text = text; textWidth = (int)textBlock.ActualWidth; textHeight = (int)textBlock.ActualHeight; }); return MoSync.Util.CreateExtent(textWidth, textHeight); }; syscalls.maFillTriangleFan = delegate(int points, int count) { int[] newPoints = new int[count * 2 + 2]; for (int i = 0; i < count; i++) { newPoints[i * 2 + 0] = core.GetDataMemory().ReadInt32(points + i * 8); newPoints[i * 2 + 1] = core.GetDataMemory().ReadInt32(points + i * 8 + 4); } newPoints[count * 2 + 0] = core.GetDataMemory().ReadInt32(points + 0); newPoints[count * 2 + 1] = core.GetDataMemory().ReadInt32(points + 4); mCurrentDrawTarget.FillPolygon(newPoints, (int)mCurrentColor); }; syscalls.maFillTriangleStrip = delegate(int points, int count) { int[] xcoords = new int[count]; int[] ycoords = new int[count]; for (int i = 0; i < count; i++) { xcoords[i] = core.GetDataMemory().ReadInt32(points + i * 8); ycoords[i] = core.GetDataMemory().ReadInt32(points + i * 8 + 4); } for (int i = 2; i < count; i++) { mCurrentDrawTarget.FillTriangle( xcoords[i - 2], ycoords[i - 2], xcoords[i - 1], ycoords[i - 1], xcoords[i - 0], ycoords[i - 0], (int)mCurrentColor); } }; syscalls.maSetDrawTarget = delegate(int drawTarget) { int oldDrawTarget = mCurrentDrawTargetIndex; if (drawTarget == mCurrentDrawTargetIndex) return oldDrawTarget; if (drawTarget == MoSync.Constants.HANDLE_SCREEN) { mCurrentDrawTarget = mBackBuffer; mCurrentDrawTargetIndex = drawTarget; return oldDrawTarget; } Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, drawTarget); mCurrentDrawTarget = (WriteableBitmap)res.GetInternalObject(); mCurrentDrawTargetIndex = drawTarget; return oldDrawTarget; }; syscalls.maGetScrSize = delegate() { return MoSync.Util.CreateExtent(mBackBuffer.PixelWidth, mBackBuffer.PixelHeight); }; syscalls.maGetImageSize = delegate(int handle) { Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, handle); BitmapSource src = (BitmapSource)res.GetInternalObject(); int w = 0, h = 0; MoSync.Util.RunActionOnMainThreadSync(() => { w = src.PixelWidth; h = src.PixelHeight; }); return MoSync.Util.CreateExtent(w, h); }; syscalls.maDrawImage = delegate(int image, int left, int top) { Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, image); WriteableBitmap src = (WriteableBitmap)res.GetInternalObject(); Rect srcRect = new Rect(0, 0, src.PixelWidth, src.PixelHeight); Rect dstRect = new Rect(left, top, src.PixelWidth, src.PixelHeight); mCurrentDrawTarget.Blit(dstRect, src, srcRect, WriteableBitmapExtensions.BlendMode.Alpha); }; syscalls.maDrawImageRegion = delegate(int image, int srcRectPtr, int dstPointPtr, int transformMode) { Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, image); WriteableBitmap src = (WriteableBitmap)res.GetInternalObject(); Memory dataMemory = core.GetDataMemory(); int srcRectX = dataMemory.ReadInt32(srcRectPtr + 0); int srcRectY = dataMemory.ReadInt32(srcRectPtr + 4); int srcRectW = dataMemory.ReadInt32(srcRectPtr + 8); int srcRectH = dataMemory.ReadInt32(srcRectPtr + 12); int dstPointX = dataMemory.ReadInt32(dstPointPtr + 0); int dstPointY = dataMemory.ReadInt32(dstPointPtr + 4); Rect srcRect = new Rect(srcRectX, srcRectY, srcRectW, srcRectH); Rect dstRect = new Rect(dstPointX, dstPointY, srcRectW, srcRectH); // mCurrentDrawTarget.Blit(dstRect, src, srcRect, WriteableBitmapExtensions.BlendMode.Alpha); DrawImageRegion(mCurrentDrawTarget, dstPointX, dstPointY, srcRect, src, transformMode); }; syscalls.maCreateDrawableImage = delegate(int placeholder, int width, int height) { Resource res = runtime.GetResource(MoSync.Constants.RT_PLACEHOLDER, placeholder); res.SetResourceType(MoSync.Constants.RT_IMAGE); WriteableBitmap bitmap = null; MoSync.Util.RunActionOnMainThreadSync(() => { bitmap = new WriteableBitmap(width, height); }); if (bitmap == null) return MoSync.Constants.RES_OUT_OF_MEMORY; res.SetInternalObject(bitmap); return MoSync.Constants.RES_OK; }; syscalls.maCreateImageRaw = delegate(int _placeholder, int _src, int _size, int _alpha) { int width = MoSync.Util.ExtentX(_size); int height = MoSync.Util.ExtentY(_size); WriteableBitmap bitmap = null; MoSync.Util.RunActionOnMainThreadSync(() => { bitmap = new WriteableBitmap(width, height); }); //core.GetDataMemory().ReadIntegers(bitmap.Pixels, _src, width * height); bitmap.FromByteArray(core.GetDataMemory().GetData(), _src, width * height * 4); if (_alpha == 0) { int[] pixels = bitmap.Pixels; int numPixels = width * height; for (int i = 0; i < numPixels; i++) { pixels[i] = (int)((uint)pixels[i] | 0xff000000); } } runtime.SetResource(_placeholder, new Resource( bitmap, MoSync.Constants.RT_IMAGE ) ); return MoSync.Constants.RES_OK; }; syscalls.maDrawRGB = delegate(int _dstPoint, int _src, int _srcRect, int _scanlength) { Memory dataMemory = core.GetDataMemory(); int dstX = dataMemory.ReadInt32(_dstPoint + 0); int dstY = dataMemory.ReadInt32(_dstPoint + 4); int srcRectX = dataMemory.ReadInt32(_srcRect + 0); int srcRectY = dataMemory.ReadInt32(_srcRect + 4); int srcRectW = dataMemory.ReadInt32(_srcRect + 8); int srcRectH = dataMemory.ReadInt32(_srcRect + 12); int[] pixels = mCurrentDrawTarget.Pixels; // todo: clipRect _scanlength *= 4; // sizeof(int) for (int h = 0; h < srcRectH; h++) { int pixelIndex = dstY * mCurrentDrawTarget.PixelWidth + dstX; int address = _src + (srcRectY + h) * _scanlength; for (int w = 0; w < srcRectW; w++) { uint srcPixel = dataMemory.ReadUInt32(address); uint dstPixel = (uint)pixels[pixelIndex]; uint srcPixelR = (srcPixel & 0x00ff0000) >> 16; uint srcPixelG = (srcPixel & 0x0000ff00) >> 8; uint srcPixelB = (srcPixel & 0x000000ff) >> 0; uint srcPixelA = (srcPixel & 0xff000000) >> 24; uint dstPixelR = (dstPixel & 0x00ff0000) >> 16; uint dstPixelG = (dstPixel & 0x0000ff00) >> 8; uint dstPixelB = (dstPixel & 0x000000ff) >> 0; uint dstPixelA = (dstPixel & 0xff000000) >> 24; dstPixelR += ((srcPixelR - dstPixelR) * srcPixelA) / 255; dstPixelG += ((srcPixelG - dstPixelG) * srcPixelA) / 255; dstPixelB += ((srcPixelB - dstPixelB) * srcPixelA) / 255; dstPixel = (dstPixelA << 24) | (dstPixelR << 16) | (dstPixelG << 8) | (dstPixelB); pixels[pixelIndex] = (int)dstPixel; address += 4; pixelIndex++; } dstY++; } }; syscalls.maGetImageData = delegate(int _image, int _dst, int _srcRect, int _scanlength) { Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, _image); WriteableBitmap src = (WriteableBitmap)res.GetInternalObject(); Memory dataMemory = core.GetDataMemory(); int srcRectX = dataMemory.ReadInt32(_srcRect + 0); int srcRectY = dataMemory.ReadInt32(_srcRect + 4); int srcRectW = dataMemory.ReadInt32(_srcRect + 8); int srcRectH = dataMemory.ReadInt32(_srcRect + 12); int lineDst = _dst; byte[] data = src.ToByteArray(srcRectY * src.PixelWidth, srcRectH * src.PixelWidth); byte[] coreArray = dataMemory.GetData(); for (int y = 0; y < srcRectH; y++) { System.Array.Copy(data, y * src.PixelWidth * 4, coreArray, lineDst, src.PixelWidth * 4); lineDst += _scanlength * 4; } }; syscalls.maCreateImageFromData = delegate(int _placeholder, int _data, int _offset, int _size) { Resource res = runtime.GetResource(MoSync.Constants.RT_BINARY, _data); Memory mem = (Memory)res.GetInternalObject(); Stream s = mem.GetStream(_offset, _size); WriteableBitmap bitmap = MoSync.Util.CreateWriteableBitmapFromStream(s); s.Close(); runtime.SetResource( _placeholder, new Resource( bitmap, MoSync.Constants.RT_IMAGE ) ); return MoSync.Constants.RES_OK; }; }
public void Init(Syscalls syscalls, Core core, Runtime runtime) { runtime.RegisterCleaner(delegate() { foreach (KeyValuePair<int, Connection> p in mConnections) { p.Value.close(); } mConnections.Clear(); }); mResultHandler = delegate(int handle, int connOp, int result) { Memory evt = new Memory(4 * 4); evt.WriteInt32(MoSync.Struct.MAEvent.type, MoSync.Constants.EVENT_TYPE_CONN); evt.WriteInt32(MoSync.Struct.MAEvent.conn.handle, handle); evt.WriteInt32(MoSync.Struct.MAEvent.conn.opType, connOp); evt.WriteInt32(MoSync.Struct.MAEvent.conn.result, result); runtime.PostEvent(new Event(evt)); }; syscalls.maConnect = delegate(int _url) { String url = core.GetDataMemory().ReadStringAtAddress(_url); //Util.Log("maConnect(" + url + ")\n"); if (url.StartsWith("btspp")) return MoSync.Constants.CONNERR_UNAVAILABLE; Uri uri = new Uri(url); Connection c; if (uri.Scheme.Equals("socket")) { c = new SocketConnection(uri, mNextConnHandle); } else if (uri.Scheme.Equals("http") || uri.Scheme.Equals("https")) { c = new WebRequestConnection(uri, mNextConnHandle, MoSync.Constants.HTTP_GET); } else { return MoSync.Constants.CONNERR_GENERIC; } c.connect(mResultHandler); mConnections.Add(mNextConnHandle, c); return mNextConnHandle++; }; syscalls.maConnClose = delegate(int _conn) { Connection c = mConnections[_conn]; c.close(); mConnections.Remove(_conn); }; syscalls.maConnGetAddr = delegate(int _conn, int _addr) { if (_conn == MoSync.Constants.HANDLE_LOCAL) // unavailable return -1; Connection c = mConnections[_conn]; return c.getAddr(core.GetDataMemory(), _addr); }; syscalls.maConnRead = delegate(int _conn, int _dst, int _size) { Connection c = mConnections[_conn]; c.recv(core.GetDataMemory().GetData(), _dst, _size, mResultHandler); }; DataDelegate dataDelegate = delegate(int _conn, int _data, CommDelegate cd) { Connection c = mConnections[_conn]; Resource res = runtime.GetResource(MoSync.Constants.RT_BINARY, _data); Stream s = (Stream)res.GetInternalObject(); runtime.SetResourceRaw(_data, Resource.Flux); MemoryStream mem = null; if (s.GetType() == typeof(MemoryStream)) { mem = (MemoryStream)s; } else { MoSync.Util.CriticalError("Only binaries (non-ubins) are allowed for maConn(Read/Write)(To/From)Data"); } cd(c, mem.GetBuffer(), delegate(int handle, int connOp, int result) { runtime.SetResourceRaw(_data, res); mResultHandler(handle, connOp, result); }); }; syscalls.maConnReadToData = delegate(int _conn, int _data, int _offset, int _size) { dataDelegate(_conn, _data, delegate(Connection c, byte[] buf, ResultHandler rh) { c.recv(buf, _offset, _size, rh); }); }; syscalls.maConnWrite = delegate(int _conn, int _src, int _size) { Connection c = mConnections[_conn]; c.write(core.GetDataMemory().GetData(), _src, _size, mResultHandler); }; syscalls.maConnWriteFromData = delegate(int _conn, int _data, int _offset, int _size) { dataDelegate(_conn, _data, delegate(Connection c, byte[] buf, ResultHandler rh) { c.write(buf, _offset, _size, rh); }); }; syscalls.maHttpCreate = delegate(int _url, int _method) { String url = core.GetDataMemory().ReadStringAtAddress(_url); //Util.Log("maHttpCreate(" + url + ")\n"); Uri uri = new Uri(url); WebRequestConnection c = new WebRequestConnection(uri, mNextConnHandle, _method); mConnections.Add(mNextConnHandle, c); return mNextConnHandle++; }; syscalls.maHttpFinish = delegate(int _conn) { WebRequestConnection c = (WebRequestConnection)mConnections[_conn]; c.connect(delegate(int handle, int connOp, int result) { mResultHandler(handle, MoSync.Constants.CONNOP_FINISH, result); }); }; syscalls.maHttpSetRequestHeader = delegate(int _conn, int _key, int _value) { WebRequestConnection c = (WebRequestConnection)mConnections[_conn]; String key = core.GetDataMemory().ReadStringAtAddress(_key); String value = core.GetDataMemory().ReadStringAtAddress(_value); if (value.Length > 0) c.setRequestHeader(key, value); }; syscalls.maHttpGetResponseHeader = delegate(int _conn, int _key, int _buffer, int _bufSize) { WebRequestConnection c = (WebRequestConnection)mConnections[_conn]; String key = core.GetDataMemory().ReadStringAtAddress(_key); String value = c.getResponseHeader(key); if (value == null) return MoSync.Constants.CONNERR_NOHEADER; if (value.Length + 1 <= _bufSize) core.GetDataMemory().WriteStringAtAddress(_buffer, value, _bufSize); return value.Length; }; }
public void Init(Ioctls ioctls, Core core, Runtime runtime) { mCamera = new PhotoCamera(CameraType.Primary); mVideoBrush = new VideoBrush(); mVideoBrush.SetSource(mCamera); mVideoBrush.Stretch = Stretch.Uniform; runtime.RegisterCleaner(delegate() { mCamera.Dispose(); mCamera = null; }); // this should be set according to the orientation of // the device I guess. mVideoBrush.RelativeTransform = new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 90 }; ioctls.maCameraFormat = delegate(int _index, int _fmt) { System.Windows.Size dim; if (GetCameraFormat(_index, out dim) == false) return MoSync.Constants.MA_CAMERA_RES_FAILED; core.GetDataMemory().WriteInt32(_fmt + MoSync.Struct.MA_CAMERA_FORMAT.width, (int)dim.Width); core.GetDataMemory().WriteInt32(_fmt + MoSync.Struct.MA_CAMERA_FORMAT.height, (int)dim.Height); return MoSync.Constants.MA_CAMERA_RES_OK; }; ioctls.maCameraFormatNumber = delegate() { IEnumerable<System.Windows.Size> res = mCamera.AvailableResolutions; if (res == null) return 0; IEnumerator<System.Windows.Size> resolutions = res.GetEnumerator(); resolutions.MoveNext(); int number = 0; while (resolutions.Current != null) { number++; } return number; }; ioctls.maCameraStart = delegate() { return 0; }; ioctls.maCameraStop = delegate() { return 0; }; ioctls.maCameraSetPreview = delegate(int _widgetHandle) { // something like // videoBrush = ((CameraViewFinder)runtime.GetModule<MoSyncNativeUIModule>.GetWidget(_widgetHandle)).GetBrush(); // videoBrush.SetSource(mCamera) IWidget w = runtime.GetModule<NativeUIModule>().GetWidget(_widgetHandle); if (w.GetType() != typeof(MoSync.NativeUI.CameraPreview)) { return MoSync.Constants.MA_CAMERA_RES_FAILED; } NativeUI.CameraPreview prev = (NativeUI.CameraPreview)w; System.Windows.Controls.Canvas canvas = prev.GetViewFinderCanvas(); MoSync.Util.RunActionOnMainThreadSync(() => { canvas.Background = mVideoBrush; }); return 0; }; ioctls.maCameraSelect = delegate(int _cameraNumber) { CameraType cameraType = CameraType.Primary; if(_cameraNumber == MoSync.Constants.MA_CAMERA_CONST_BACK_CAMERA) { cameraType = CameraType.Primary; } else if(_cameraNumber == MoSync.Constants.MA_CAMERA_CONST_FRONT_CAMERA) { cameraType = CameraType.FrontFacing; } if(mCamera==null || mCamera.CameraType != cameraType) { mCamera = new PhotoCamera(cameraType); if(mVideoBrush == null) mVideoBrush = new VideoBrush(); mVideoBrush.SetSource(mCamera); } return 0; }; ioctls.maCameraNumber = delegate() { // front facing and back facing is the standard I believe. return 2; }; ioctls.maCameraSnapshot = delegate(int _formatIndex, int _placeHolder) { AutoResetEvent are = new AutoResetEvent(false); System.Windows.Size dim; if (GetCameraFormat(_formatIndex, out dim) == false) return MoSync.Constants.MA_CAMERA_RES_FAILED; mCamera.Resolution = dim; if (mCameraSnapshotDelegate != null) mCamera.CaptureImageAvailable -= mCameraSnapshotDelegate; mCameraSnapshotDelegate = delegate(object o, ContentReadyEventArgs args) { MoSync.Util.RunActionOnMainThreadSync(() => { Resource res = runtime.GetResource(MoSync.Constants.RT_PLACEHOLDER, _placeHolder); Stream data = args.ImageStream; Memory dataMem = new Memory((int)data.Length); dataMem.WriteFromStream(0, data, (int)data.Length); res.SetInternalObject(dataMem); }); are.Set(); }; mCamera.CaptureImageAvailable += mCameraSnapshotDelegate; mCamera.CaptureImage(); are.WaitOne(); return 0; }; ioctls.maCameraSetProperty = delegate(int _property, int _value) { return 0; }; ioctls.maCameraSelect = delegate(int _camera) { return 0; }; ioctls.maCameraGetProperty = delegate(int _property, int _value, int _bufSize) { String property = core.GetDataMemory().ReadStringAtAddress(_property); if (property.Equals(MoSync.Constants.MA_CAMERA_MAX_ZOOM)) { core.GetDataMemory().WriteStringAtAddress( _value, "0", _bufSize); } return 0; }; ioctls.maCameraRecord = delegate(int _stopStartFlag) { return 0; }; }
/** * Initializing the ioctls. */ public void Init(Ioctls ioctls, Core core, Runtime runtime) { mCamera = new PhotoCamera(mCameraType); mVideoBrush = new VideoBrush(); runtime.RegisterCleaner(delegate() { if (null != mCamera) { mCamera.Dispose(); mCamera = null; } }); // this should be set according to the orientation of // the device I guess. // we need to handle the camera orientation by hand PhoneApplicationPage currentPage = (((PhoneApplicationFrame)Application.Current.RootVisual).Content as PhoneApplicationPage); // we need to handle the initial page orientation double rotation = mCamera.Orientation; if (currentPage.Orientation == PageOrientation.LandscapeLeft) { rotation -= 90; } else if (currentPage.Orientation == PageOrientation.LandscapeRight) { rotation += 90; } mVideoBrush.RelativeTransform = new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = rotation }; // on orientation changed, we need to rotate the video brush currentPage.OrientationChanged += new System.EventHandler<OrientationChangedEventArgs>( delegate(object o, OrientationChangedEventArgs args) { rotation = mCamera.Orientation; if (args.Orientation == PageOrientation.LandscapeLeft) { rotation -= 90; } else if (args.Orientation == PageOrientation.LandscapeRight) { rotation += 90; } mVideoBrush.RelativeTransform = new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = rotation }; }); /** * Stores an output format in fmm parameter. * @param _index int the index of the required format. * @param _fmt int the momory address at which to write the output format dimensions. * * Note: the _index should be greater than 0 and smaller than the number of camera formats. */ ioctls.maCameraFormat = delegate(int _index, int _fmt) { System.Windows.Size dim; if (GetCameraFormat(_index, out dim) == false) return MoSync.Constants.MA_CAMERA_RES_FAILED; core.GetDataMemory().WriteInt32(_fmt + MoSync.Struct.MA_CAMERA_FORMAT.width, (int)dim.Width); core.GetDataMemory().WriteInt32(_fmt + MoSync.Struct.MA_CAMERA_FORMAT.height, (int)dim.Height); return MoSync.Constants.MA_CAMERA_RES_OK; }; /** * Returns the number of different output formats supported by the current device's camera. * \< 0 if there is no camera support. * 0 if there is camera support, but the format is unknown. */ ioctls.maCameraFormatNumber = delegate() { // if the camera is not initialized, we cannot access any of its properties if (!isCameraInitialized) { // because the cammera is supported but not initialized, we return 0 return 0; } IEnumerable<System.Windows.Size> res = mCamera.AvailableResolutions; if (res == null) return 0; IEnumerator<System.Windows.Size> resolutions = res.GetEnumerator(); resolutions.MoveNext(); int number = 0; while (resolutions.Current != null) { number++; resolutions.MoveNext(); if (resolutions.Current == new System.Windows.Size(0, 0)) break; } return number; }; /** * Starts the viewfinder and the camera */ ioctls.maCameraStart = delegate() { initCamera(); MoSync.Util.RunActionOnMainThreadSync(() => { mCameraPrev.StartViewFinder(); }); return 0; }; /** * stops the view finder and the camera. */ ioctls.maCameraStop = delegate() { MoSync.Util.RunActionOnMainThreadSync(() => { mCameraPrev.StopViewFinder(); }); return 0; }; /** * Adds a previewWidget to the camera controller in devices that support native UI. */ ioctls.maCameraSetPreview = delegate(int _widgetHandle) { // if the camera is not initialized, we need to initialize it before // setting the preview if (!isCameraInitialized) { initCamera(); } IWidget w = runtime.GetModule<NativeUIModule>().GetWidget(_widgetHandle); if (w.GetType() != typeof(MoSync.NativeUI.CameraPreview)) { return MoSync.Constants.MA_CAMERA_RES_FAILED; } mCameraPrev = (NativeUI.CameraPreview)w; mCameraPrev.SetViewFinderContent(mVideoBrush); return MoSync.Constants.MA_CAMERA_RES_OK; }; /** * Returns the number of available Camera on the device. */ ioctls.maCameraNumber = delegate() { if (PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing) && PhotoCamera.IsCameraTypeSupported(CameraType.Primary)) return 2; else if (PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing) || PhotoCamera.IsCameraTypeSupported(CameraType.Primary)) return 1; return 0; }; /** * Captures an image and stores it as a new data object in the * supplied placeholder. * @param _formatIndex int the required format. * @param _placeHolder int the placeholder used for storing the image. */ ioctls.maCameraSnapshot = delegate(int _formatIndex, int _placeHolder) { AutoResetEvent are = new AutoResetEvent(false); System.Windows.Size dim; if (GetCameraFormat(_formatIndex, out dim) == false) return MoSync.Constants.MA_CAMERA_RES_FAILED; mCamera.Resolution = dim; if (mCameraSnapshotDelegate != null) mCamera.CaptureImageAvailable -= mCameraSnapshotDelegate; mCameraSnapshotDelegate = delegate(object o, ContentReadyEventArgs args) { MoSync.Util.RunActionOnMainThreadSync(() => { Resource res = runtime.GetResource(MoSync.Constants.RT_PLACEHOLDER, _placeHolder); Stream data = args.ImageStream; MemoryStream dataMem = new MemoryStream((int)data.Length); MoSync.Util.CopySeekableStreams(data, 0, dataMem, 0, (int)data.Length); res.SetInternalObject(dataMem); }); are.Set(); }; mCamera.CaptureImageAvailable += mCameraSnapshotDelegate; mCamera.CaptureImage(); are.WaitOne(); return 0; }; /** * Sets the property represented by the string situated at the * _property address with the value situated at the _value address. * @param _property int the property name address * @param _value int the value address * * Note: the fallowing properties are not available on windows phone * MA_CAMERA_FOCUS_MODE, MA_CAMERA_IMAGE_FORMAT, MA_CAMERA_ZOOM, * MA_CAMERA_MAX_ZOOM. */ ioctls.maCameraSetProperty = delegate(int _property, int _value) { // if the camera is not initialized, we cannot access any of its properties if (!isCameraInitialized) { return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; } String property = core.GetDataMemory().ReadStringAtAddress(_property); String value = core.GetDataMemory().ReadStringAtAddress(_value); if (property.Equals(MoSync.Constants.MA_CAMERA_FLASH_MODE)) { if (value.Equals(MoSync.Constants.MA_CAMERA_FLASH_ON)) { mCamera.FlashMode = FlashMode.On; mFlashMode = FlashMode.On; } else if (value.Equals(MoSync.Constants.MA_CAMERA_FLASH_OFF)) { mCamera.FlashMode = FlashMode.Off; mFlashMode = FlashMode.Off; } else if (value.Equals(MoSync.Constants.MA_CAMERA_FLASH_AUTO)) { mCamera.FlashMode = FlashMode.Auto; mFlashMode = FlashMode.Auto; } else return MoSync.Constants.MA_CAMERA_RES_INVALID_PROPERTY_VALUE; return MoSync.Constants.MA_CAMERA_RES_OK; } else if (property.Equals(MoSync.Constants.MA_CAMERA_FOCUS_MODE)) { return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; } else if (property.Equals(MoSync.Constants.MA_CAMERA_IMAGE_FORMAT)) { return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; } else if (property.Equals(MoSync.Constants.MA_CAMERA_ZOOM)) { return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; } else if (property.Equals(MoSync.Constants.MA_CAMERA_MAX_ZOOM)) { return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; } else return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; }; /** * Selects a camera from the avalable ones; * in this eigther the back or the front camera is * chosen */ ioctls.maCameraSelect = delegate(int _camera) { // if the camera is not initialized, we cannot access any of its properties if (!isCameraInitialized) { return MoSync.Constants.MA_CAMERA_RES_FAILED; } if ( MoSync.Constants.MA_CAMERA_CONST_BACK_CAMERA == _camera) { if (mCamera.CameraType != CameraType.Primary) { mCameraType = CameraType.Primary; initCamera(); } } else if (MoSync.Constants.MA_CAMERA_CONST_FRONT_CAMERA == _camera) { if (mCamera.CameraType != CameraType.FrontFacing) { mCameraType = CameraType.FrontFacing; initCamera(); } } else return MoSync.Constants.MA_CAMERA_RES_FAILED; return MoSync.Constants.MA_CAMERA_RES_OK; }; /** * Retrieves the specified property value in the given buffer. * @param _property int the address for the property string * @param _value int the address for the property value string (the buffer) * @param _bufSize int the buffer size */ ioctls.maCameraGetProperty = delegate(int _property, int _value, int _bufSize) { String property = core.GetDataMemory().ReadStringAtAddress(_property); if (property.Equals(MoSync.Constants.MA_CAMERA_MAX_ZOOM)) { core.GetDataMemory().WriteStringAtAddress( _value, "0", _bufSize); } else if (property.Equals(MoSync.Constants.MA_CAMERA_ZOOM_SUPPORTED)) { core.GetDataMemory().WriteStringAtAddress( _value, "false", _bufSize); } else if (property.Equals(MoSync.Constants.MA_CAMERA_FLASH_SUPPORTED)) { core.GetDataMemory().WriteStringAtAddress( _value, "true", _bufSize); } else return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; return 0; }; ioctls.maCameraRecord = delegate(int _stopStartFlag) { return MoSync.Constants.MA_CAMERA_RES_FAILED; }; }
public void Init(Syscalls syscalls, Core core, Runtime runtime) { PhoneApplicationFrame frame = (PhoneApplicationFrame)Application.Current.RootVisual; double screenWidth = System.Windows.Application.Current.Host.Content.ActualWidth; double screenHeight = System.Windows.Application.Current.Host.Content.ActualHeight; if ((int)screenHeight == 0) throw new Exception("screenHeight"); PhoneApplicationPage mainPage = (PhoneApplicationPage)frame.Content; mMainImage = new Image(); mainPage.Width = screenWidth; mainPage.Height = screenHeight; mMainImage.Width = screenWidth; mMainImage.Height = screenHeight; mainPage.Content = mMainImage; mClipRect.X = 0.0; mClipRect.Y = 0.0; mClipRect.Width = screenWidth; mClipRect.Height = screenHeight; // no apparent effect on memory leaks. runtime.RegisterCleaner(delegate() { MoSync.Util.RunActionOnMainThreadSync(() => { mainPage.Content = null; }); }); mBackBuffer = new WriteableBitmap( (int)screenWidth, (int)screenHeight); mFrontBuffer = new WriteableBitmap( (int)screenWidth, (int)screenHeight); mMainImage.Source = mFrontBuffer; // clear front and backbuffer. for (int i = 0; i < mFrontBuffer.PixelWidth * mFrontBuffer.PixelHeight; i++) { mBackBuffer.Pixels[i] = mBackBuffer.Pixels[i] = (int)(0xff<<24); } mCurrentDrawTarget = mBackBuffer; mCurrentWindowsColor = System.Windows.Media.Color.FromArgb(0xff, (byte)(mCurrentColor >> 16), (byte)(mCurrentColor >> 8), (byte)(mCurrentColor)); syscalls.maSetColor = delegate(int rgb) { int oldColor = (int)mCurrentColor; mCurrentColor = 0xff000000 | (uint)(rgb & 0xffffff); mCurrentWindowsColor = System.Windows.Media.Color.FromArgb(0xff, (byte)(mCurrentColor >> 16), (byte)(mCurrentColor >> 8), (byte)(mCurrentColor)); return oldColor & 0xffffff; }; syscalls.maSetClipRect = delegate(int x, int y, int w, int h) { MoSync.GraphicsUtil.ClipRectangle( x, y, w, h, 0, 0, mCurrentDrawTarget.PixelWidth, mCurrentDrawTarget.PixelHeight, out x, out y, out w, out h); mClipRect.X = x; mClipRect.Y = y; mClipRect.Width = w; mClipRect.Height = h; }; syscalls.maGetClipRect = delegate(int cliprect) { Memory mem = core.GetDataMemory(); mem.WriteInt32(cliprect + MoSync.Struct.MARect.left, (int)mClipRect.X); mem.WriteInt32(cliprect + MoSync.Struct.MARect.top, (int)mClipRect.Y); mem.WriteInt32(cliprect + MoSync.Struct.MARect.width, (int)mClipRect.Width); mem.WriteInt32(cliprect + MoSync.Struct.MARect.height, (int)mClipRect.Height); }; syscalls.maPlot = delegate(int x, int y) { mCurrentDrawTarget.SetPixel(x, y, (int)mCurrentColor); }; syscalls.maUpdateScreen = delegate() { //System.Array.Copy(mBackBuffer.Pixels, mFrontBuffer.Pixels, mFrontBuffer.PixelWidth * mFrontBuffer.PixelHeight); System.Buffer.BlockCopy(mBackBuffer.Pixels, 0, mFrontBuffer.Pixels, 0, mFrontBuffer.PixelWidth * mFrontBuffer.PixelHeight * 4); InvalidateWriteableBitmapOnMainThread(mFrontBuffer); }; syscalls.maFillRect = delegate(int x, int y, int w, int h) { // this function has a bug (it only fills one pixel less than the image.) //mCurrentDrawTarget.FillRectangle(x, y, x + w, y + h, (int)mCurrentColor); MoSync.GraphicsUtil.ClipRectangle( x, y, w, h, 0, 0, mCurrentDrawTarget.PixelWidth, mCurrentDrawTarget.PixelHeight, out x, out y, out w, out h); MoSync.GraphicsUtil.ClipRectangle( x, y, w, h, (int)mClipRect.X, (int)mClipRect.Y, (int)mClipRect.Width, (int)mClipRect.Height, out x, out y, out w, out h); if (w <= 0 || h <= 0) return; int index = x + y * mCurrentDrawTarget.PixelWidth; while(h-- != 0) { int width = w; while(width-- != 0) { mCurrentDrawTarget.Pixels[index] = (int)mCurrentColor; index++; } index += -w + mCurrentDrawTarget.PixelWidth; } }; syscalls.maLine = delegate(int x1, int y1, int x2, int y2) { GraphicsUtil.Point p1 = new GraphicsUtil.Point(x1, y1); GraphicsUtil.Point p2 = new GraphicsUtil.Point(x2, y2); if(!GraphicsUtil.ClipLine(p1, p2, (int)mClipRect.X, (int)(mClipRect.X+mClipRect.Width), (int)mClipRect.Y, (int)(mClipRect.Y+mClipRect.Height))) return; mCurrentDrawTarget.DrawLine((int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, (int)mCurrentColor); }; textBlock.FontSize = mCurrentFontSize; syscalls.maDrawText = delegate(int left, int top, int str) { String text = core.GetDataMemory().ReadStringAtAddress(str); if (text.Length == 0) return; DrawText(text, left, top); }; syscalls.maGetTextSize = delegate(int str) { String text = core.GetDataMemory().ReadStringAtAddress(str); int textWidth = 0; int textHeight = 0; GetTextSize(text, out textWidth, out textHeight); return MoSync.Util.CreateExtent(textWidth, textHeight); }; syscalls.maDrawTextW = delegate(int left, int top, int str) { String text = core.GetDataMemory().ReadWStringAtAddress(str); if (text.Length == 0) return; DrawText(text, left, top); }; syscalls.maGetTextSizeW = delegate(int str) { String text = core.GetDataMemory().ReadWStringAtAddress(str); int textWidth = 0; int textHeight = 0; GetTextSize(text, out textWidth, out textHeight); return MoSync.Util.CreateExtent(textWidth, textHeight); }; syscalls.maFillTriangleFan = delegate(int points, int count) { int[] newPoints = new int[count * 2 + 2]; for (int i = 0; i < count; i++) { newPoints[i * 2 + 0] = core.GetDataMemory().ReadInt32(points + i * 8 + MoSync.Struct.MAPoint2d.x); newPoints[i * 2 + 1] = core.GetDataMemory().ReadInt32(points + i * 8 + MoSync.Struct.MAPoint2d.y); } newPoints[count * 2 + 0] = core.GetDataMemory().ReadInt32(points + MoSync.Struct.MAPoint2d.x); newPoints[count * 2 + 1] = core.GetDataMemory().ReadInt32(points + MoSync.Struct.MAPoint2d.y); mCurrentDrawTarget.FillPolygon(newPoints, (int)mCurrentColor); }; syscalls.maFillTriangleStrip = delegate(int points, int count) { int[] xcoords = new int[count]; int[] ycoords = new int[count]; for (int i = 0; i < count; i++) { xcoords[i] = core.GetDataMemory().ReadInt32(points + i * 8 + MoSync.Struct.MAPoint2d.x); ycoords[i] = core.GetDataMemory().ReadInt32(points + i * 8 + MoSync.Struct.MAPoint2d.y); } for (int i = 2; i < count; i++) { mCurrentDrawTarget.FillTriangle( xcoords[i - 2], ycoords[i - 2], xcoords[i - 1], ycoords[i - 1], xcoords[i - 0], ycoords[i - 0], (int)mCurrentColor); } }; syscalls.maSetDrawTarget = delegate(int drawTarget) { int oldDrawTarget = mCurrentDrawTargetIndex; if (drawTarget == mCurrentDrawTargetIndex) return oldDrawTarget; if (drawTarget == MoSync.Constants.HANDLE_SCREEN) { mCurrentDrawTarget = mBackBuffer; mCurrentDrawTargetIndex = drawTarget; return oldDrawTarget; } Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, drawTarget); mCurrentDrawTarget = (WriteableBitmap)res.GetInternalObject(); mCurrentDrawTargetIndex = drawTarget; return oldDrawTarget; }; syscalls.maGetScrSize = delegate() { return MoSync.Util.CreateExtent(mBackBuffer.PixelWidth, mBackBuffer.PixelHeight); }; syscalls.maGetImageSize = delegate(int handle) { Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, handle); BitmapSource src = (BitmapSource)res.GetInternalObject(); if (src == null) MoSync.Util.CriticalError("maGetImageSize used with an invalid image resource."); int w = 0, h = 0; MoSync.Util.RunActionOnMainThreadSync(() => { w = src.PixelWidth; h = src.PixelHeight; }); return MoSync.Util.CreateExtent(w, h); }; syscalls.maDrawImage = delegate(int image, int left, int top) { Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, image); WriteableBitmap src = (WriteableBitmap)res.GetInternalObject(); Rect srcRect = new Rect(0, 0, src.PixelWidth, src.PixelHeight); Rect dstRect = new Rect(left, top, src.PixelWidth, src.PixelHeight); mCurrentDrawTarget.Blit(dstRect, src, srcRect, WriteableBitmapExtensions.BlendMode.Alpha); }; syscalls.maDrawImageRegion = delegate(int image, int srcRectPtr, int dstPointPtr, int transformMode) { Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, image); WriteableBitmap src = (WriteableBitmap)res.GetInternalObject(); Memory dataMemory = core.GetDataMemory(); int srcRectX = dataMemory.ReadInt32(srcRectPtr + MoSync.Struct.MARect.left); int srcRectY = dataMemory.ReadInt32(srcRectPtr + MoSync.Struct.MARect.top); int srcRectW = dataMemory.ReadInt32(srcRectPtr + MoSync.Struct.MARect.width); int srcRectH = dataMemory.ReadInt32(srcRectPtr + MoSync.Struct.MARect.height); int dstPointX = dataMemory.ReadInt32(dstPointPtr + MoSync.Struct.MAPoint2d.x); int dstPointY = dataMemory.ReadInt32(dstPointPtr + MoSync.Struct.MAPoint2d.y); Rect srcRect = new Rect(srcRectX, srcRectY, srcRectW, srcRectH); Rect dstRect = new Rect(dstPointX, dstPointY, srcRectW, srcRectH); GraphicsUtil.DrawImageRegion(mCurrentDrawTarget, dstPointX, dstPointY, srcRect, src, transformMode, mClipRect); }; syscalls.maCreateDrawableImage = delegate(int placeholder, int width, int height) { Resource res = runtime.GetResource(MoSync.Constants.RT_PLACEHOLDER, placeholder); res.SetResourceType(MoSync.Constants.RT_IMAGE); WriteableBitmap bitmap = null; MoSync.Util.RunActionOnMainThreadSync(() => { bitmap = new WriteableBitmap(width, height); for (int i = 0; i < bitmap.PixelWidth * bitmap.PixelHeight; i++) { bitmap.Pixels[i] = (int)(0xff << 24); } }); if (bitmap == null) return MoSync.Constants.RES_OUT_OF_MEMORY; res.SetInternalObject(bitmap); return MoSync.Constants.RES_OK; }; syscalls.maCreateImageRaw = delegate(int _placeholder, int _src, int _size, int _alpha) { int width = MoSync.Util.ExtentX(_size); int height = MoSync.Util.ExtentY(_size); WriteableBitmap bitmap = null; MoSync.Util.RunActionOnMainThreadSync(() => { bitmap = new WriteableBitmap(width, height); }); //core.GetDataMemory().ReadIntegers(bitmap.Pixels, _src, width * height); bitmap.FromByteArray(core.GetDataMemory().GetData(), _src, width * height * 4); if (_alpha == 0) { int[] pixels = bitmap.Pixels; int numPixels = width * height; for (int i = 0; i < numPixels; i++) { pixels[i] = (int)((uint)pixels[i] | 0xff000000); } } Resource res = runtime.GetResource(MoSync.Constants.RT_PLACEHOLDER, _placeholder); res.SetInternalObject(bitmap); res.SetResourceType(MoSync.Constants.RT_IMAGE); return MoSync.Constants.RES_OK; }; syscalls.maDrawRGB = delegate(int _dstPoint, int _src, int _srcRect, int _scanlength) { Memory dataMemory = core.GetDataMemory(); int dstX = dataMemory.ReadInt32(_dstPoint + MoSync.Struct.MAPoint2d.x); int dstY = dataMemory.ReadInt32(_dstPoint + MoSync.Struct.MAPoint2d.y); int srcRectX = dataMemory.ReadInt32(_srcRect + MoSync.Struct.MARect.left); int srcRectY = dataMemory.ReadInt32(_srcRect + MoSync.Struct.MARect.top); int srcRectW = dataMemory.ReadInt32(_srcRect + MoSync.Struct.MARect.width); int srcRectH = dataMemory.ReadInt32(_srcRect + MoSync.Struct.MARect.height); int[] pixels = mCurrentDrawTarget.Pixels; // todo: clipRect _scanlength *= 4; // sizeof(int) for (int h = 0; h < srcRectH; h++) { int pixelIndex = dstY * mCurrentDrawTarget.PixelWidth + dstX; int address = _src + (srcRectY + h) * _scanlength; for (int w = 0; w < srcRectW; w++) { uint srcPixel = dataMemory.ReadUInt32(address); uint dstPixel = (uint)pixels[pixelIndex]; uint srcPixelR = (srcPixel & 0x00ff0000) >> 16; uint srcPixelG = (srcPixel & 0x0000ff00) >> 8; uint srcPixelB = (srcPixel & 0x000000ff) >> 0; uint srcPixelA = (srcPixel & 0xff000000) >> 24; uint dstPixelR = (dstPixel & 0x00ff0000) >> 16; uint dstPixelG = (dstPixel & 0x0000ff00) >> 8; uint dstPixelB = (dstPixel & 0x000000ff) >> 0; uint dstPixelA = (dstPixel & 0xff000000) >> 24; dstPixelR += ((srcPixelR - dstPixelR) * srcPixelA) / 255; dstPixelG += ((srcPixelG - dstPixelG) * srcPixelA) / 255; dstPixelB += ((srcPixelB - dstPixelB) * srcPixelA) / 255; dstPixel = (dstPixelA << 24) | (dstPixelR << 16) | (dstPixelG << 8) | (dstPixelB); pixels[pixelIndex] = (int)dstPixel; address += 4; pixelIndex++; } dstY++; } }; syscalls.maGetImageData = delegate(int _image, int _dst, int _srcRect, int _scanlength) { Resource res = runtime.GetResource(MoSync.Constants.RT_IMAGE, _image); WriteableBitmap src = (WriteableBitmap)res.GetInternalObject(); Memory dataMemory = core.GetDataMemory(); int srcRectX = dataMemory.ReadInt32(_srcRect + MoSync.Struct.MARect.left); int srcRectY = dataMemory.ReadInt32(_srcRect + MoSync.Struct.MARect.top); int srcRectW = dataMemory.ReadInt32(_srcRect + MoSync.Struct.MARect.width); int srcRectH = dataMemory.ReadInt32(_srcRect + MoSync.Struct.MARect.height); int lineDst = _dst; byte[] data = src.ToByteArray(srcRectY * src.PixelWidth, srcRectH * src.PixelWidth); // BlockCopy? byte[] coreArray = dataMemory.GetData(); for (int y = 0; y < srcRectH; y++) { System.Array.Copy(data, y * src.PixelWidth * 4, coreArray, lineDst, src.PixelWidth * 4); lineDst += _scanlength * 4; } }; syscalls.maCreateImageFromData = delegate(int _placeholder, int _data, int _offset, int _size) { Resource res = runtime.GetResource(MoSync.Constants.RT_BINARY, _data); if (res == null) return MoSync.Constants.RES_BAD_INPUT; Stream bin = (Stream)res.GetInternalObject(); if (bin == null) return MoSync.Constants.RES_BAD_INPUT; BoundedStream s = new BoundedStream(bin, _offset, _size); WriteableBitmap bitmap = MoSync.Util.CreateWriteableBitmapFromStream(s); s.Close(); if (bitmap == null) return MoSync.Constants.RES_BAD_INPUT; Resource imageRes = runtime.GetResource(MoSync.Constants.RT_PLACEHOLDER, _placeholder); imageRes.SetInternalObject(bitmap); imageRes.SetResourceType(MoSync.Constants.RT_IMAGE); return MoSync.Constants.RES_OK; }; }
/** * Initializing the ioctls. */ public void Init(Ioctls ioctls, Core core, Runtime runtime) { mCamera = new PhotoCamera(mCameraType); mVideoBrush = new VideoBrush(); runtime.RegisterCleaner(delegate() { if (null != mCamera) { mCamera.Dispose(); mCamera = null; } }); PhoneApplicationPage currentPage = (((PhoneApplicationFrame)Application.Current.RootVisual).Content as PhoneApplicationPage); // set the initial camera orientation in respect to the current page orientation SetInitialCameraOrientation(currentPage); // handle current page orientation and adjust the camera orientation accordingly HandleDeviceOrientation(currentPage); /** * Stores an output format in fmm parameter. * @param _index int the index of the required format. * @param _fmt int the momory address at which to write the output format dimensions. * * Note: the _index should be greater than 0 and smaller than the number of camera formats. */ ioctls.maCameraFormat = delegate(int _index, int _fmt) { System.Windows.Size dim; if (GetCameraFormat(_index, out dim) == false) return MoSync.Constants.MA_CAMERA_RES_FAILED; core.GetDataMemory().WriteInt32(_fmt + MoSync.Struct.MA_CAMERA_FORMAT.width, (int)dim.Width); core.GetDataMemory().WriteInt32(_fmt + MoSync.Struct.MA_CAMERA_FORMAT.height, (int)dim.Height); return MoSync.Constants.MA_CAMERA_RES_OK; }; /** * Returns the number of different output formats supported by the current device's camera. * \< 0 if there is no camera support. * 0 if there is camera support, but the format is unknown. */ ioctls.maCameraFormatNumber = delegate() { // if the camera is not initialized, we cannot access any of its properties if (!isCameraInitialized) { // because the cammera is supported but not initialized, we return 0 return 0; } IEnumerable<System.Windows.Size> res = mCamera.AvailableResolutions; if (res == null) return 0; IEnumerator<System.Windows.Size> resolutions = res.GetEnumerator(); resolutions.MoveNext(); int number = 0; while (resolutions.Current != null) { number++; resolutions.MoveNext(); if (resolutions.Current == new System.Windows.Size(0, 0)) break; } return number; }; /** * Starts the viewfinder and the camera */ ioctls.maCameraStart = delegate() { InitCamera(); MoSync.Util.RunActionOnMainThreadSync(() => { mCameraPrev.StartViewFinder(); }); return 0; }; /** * stops the view finder and the camera. */ ioctls.maCameraStop = delegate() { MoSync.Util.RunActionOnMainThreadSync(() => { mCameraPrev.StopViewFinder(); }); return 0; }; /** * Adds a previewWidget to the camera controller in devices that support native UI. */ ioctls.maCameraSetPreview = delegate(int _widgetHandle) { // if the camera is not initialized, we need to initialize it before // setting the preview if (!isCameraInitialized) { InitCamera(); } IWidget w = runtime.GetModule<NativeUIModule>().GetWidget(_widgetHandle); if (w.GetType() != typeof(MoSync.NativeUI.CameraPreview)) { return MoSync.Constants.MA_CAMERA_RES_FAILED; } mCameraPrev = (NativeUI.CameraPreview)w; mCameraPrev.SetViewFinderContent(mVideoBrush); return MoSync.Constants.MA_CAMERA_RES_OK; }; /** * Returns the number of available Camera on the device. */ ioctls.maCameraNumber = delegate() { if (PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing) && PhotoCamera.IsCameraTypeSupported(CameraType.Primary)) return 2; else if (PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing) || PhotoCamera.IsCameraTypeSupported(CameraType.Primary)) return 1; return 0; }; /** * Captures an image and stores it as a new data object in the * supplied placeholder. * @param _formatIndex int the required format. * @param _placeHolder int the placeholder used for storing the image. */ ioctls.maCameraSnapshot = delegate(int _formatIndex, int _placeHolder) { AutoResetEvent are = new AutoResetEvent(false); System.Windows.Size dim; if (GetCameraFormat(_formatIndex, out dim) == false) return MoSync.Constants.MA_CAMERA_RES_FAILED; mCamera.Resolution = dim; if (mCameraSnapshotDelegate != null) mCamera.CaptureImageAvailable -= mCameraSnapshotDelegate; mCameraSnapshotDelegate = delegate(object o, ContentReadyEventArgs args) { MoSync.Util.RunActionOnMainThreadSync(() => { Resource res = runtime.GetResource(MoSync.Constants.RT_PLACEHOLDER, _placeHolder); Stream data = null; try { // as the camera always takes a snapshot in landscape left orientation, // we need to rotate the resulting image 90 degrees for a current PortraitUp orientation // and 180 degrees for a current LandscapeRight orientation int rotateAngle = 0; if (currentPage.Orientation == PageOrientation.PortraitUp) { rotateAngle = 90; } else if (currentPage.Orientation == PageOrientation.LandscapeRight) { rotateAngle = 180; } // if the current page is in a LandscapeLeft orientation, the orientation angle will be 0 data = RotateImage(args.ImageStream, rotateAngle); } catch { // the orientation angle was not a multiple of 90 - we keep the original image data = args.ImageStream; } MemoryStream dataMem = new MemoryStream((int)data.Length); MoSync.Util.CopySeekableStreams(data, 0, dataMem, 0, (int)data.Length); res.SetInternalObject(dataMem); }); are.Set(); }; mCamera.CaptureImageAvailable += mCameraSnapshotDelegate; mCamera.CaptureImage(); are.WaitOne(); return MoSync.Constants.MA_CAMERA_RES_OK; }; /** * Captures an image and stores it as a new data object in new * placeholder that is sent via #EVENT_TYPE_CAMERA_SNAPSHOT event. * @param _formatIndex int the required format index (size index). */ ioctls.maCameraSnapshotAsync = delegate(int _formatIndex) { System.Windows.Size dim; if (GetCameraFormat(_formatIndex, out dim) == false) { return MoSync.Constants.MA_CAMERA_RES_FAILED; } mCamera.Resolution = dim; if (mCameraSnapshotDelegate != null) { mCamera.CaptureImageAvailable -= mCameraSnapshotDelegate; } mCameraSnapshotDelegate = delegate(object o, ContentReadyEventArgs args) { MoSync.Util.RunActionOnMainThreadSync(() => { Stream data = null; try { // as the camera always takes a snapshot in landscape left orientation, // we need to rotate the resulting image 90 degrees for a current PortraitUp orientation // and 180 degrees for a current LandscapeRight orientation int rotateAngle = 0; if (currentPage.Orientation == PageOrientation.PortraitUp) { rotateAngle = 90; } else if (currentPage.Orientation == PageOrientation.LandscapeRight) { rotateAngle = 180; } // if the current page is in a LandscapeLeft orientation, the orientation angle will be 0 data = RotateImage(args.ImageStream, rotateAngle); } catch { // the orientation angle was not a multiple of 90 - we keep the original image data = args.ImageStream; } MemoryStream dataMem = new MemoryStream((int)data.Length); MoSync.Util.CopySeekableStreams(data, 0, dataMem, 0, (int)data.Length); Memory eventData = new Memory(20); const int MAEventData_eventType = 0; const int MAEventData_snapshotImageDataHandle = 4; const int MAEventData_snapshotFormatIndex = 8; const int MAEventData_snapshotImageDataRepresentation = 12; const int MAEventData_snapshotReturnCode = 16; eventData.WriteInt32(MAEventData_eventType, MoSync.Constants.EVENT_TYPE_CAMERA_SNAPSHOT); // Create new place holder. eventData.WriteInt32(MAEventData_snapshotImageDataHandle, runtime.AddResource( new Resource(dataMem, MoSync.Constants.RT_BINARY, true))); eventData.WriteInt32(MAEventData_snapshotFormatIndex, _formatIndex); eventData.WriteInt32(MAEventData_snapshotImageDataRepresentation, MoSync.Constants.MA_IMAGE_REPRESENTATION_RAW); eventData.WriteInt32(MAEventData_snapshotReturnCode, MoSync.Constants.MA_CAMERA_RES_OK); runtime.PostEvent(new Event(eventData)); }); }; mCamera.CaptureImageAvailable += mCameraSnapshotDelegate; mCamera.CaptureImage(); return MoSync.Constants.MA_CAMERA_RES_OK; }; /** * Sets the property represented by the string situated at the * _property address with the value situated at the _value address. * @param _property int the property name address * @param _value int the value address * * Note: the fallowing properties are not available on windows phone * MA_CAMERA_FOCUS_MODE, MA_CAMERA_IMAGE_FORMAT, MA_CAMERA_ZOOM, * MA_CAMERA_MAX_ZOOM. */ ioctls.maCameraSetProperty = delegate(int _property, int _value) { // if the camera is not initialized, we cannot access any of its properties if (!isCameraInitialized) { return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; } String property = core.GetDataMemory().ReadStringAtAddress(_property); String value = core.GetDataMemory().ReadStringAtAddress(_value); if (property.Equals(MoSync.Constants.MA_CAMERA_FLASH_MODE)) { if (value.Equals(MoSync.Constants.MA_CAMERA_FLASH_ON)) { mCamera.FlashMode = FlashMode.On; mFlashMode = FlashMode.On; } else if (value.Equals(MoSync.Constants.MA_CAMERA_FLASH_OFF)) { mCamera.FlashMode = FlashMode.Off; mFlashMode = FlashMode.Off; } else if (value.Equals(MoSync.Constants.MA_CAMERA_FLASH_AUTO)) { mCamera.FlashMode = FlashMode.Auto; mFlashMode = FlashMode.Auto; } else return MoSync.Constants.MA_CAMERA_RES_INVALID_PROPERTY_VALUE; return MoSync.Constants.MA_CAMERA_RES_OK; } else if (property.Equals(MoSync.Constants.MA_CAMERA_FOCUS_MODE)) { return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; } else if (property.Equals(MoSync.Constants.MA_CAMERA_IMAGE_FORMAT)) { return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; } else if (property.Equals(MoSync.Constants.MA_CAMERA_ZOOM)) { return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; } else if (property.Equals(MoSync.Constants.MA_CAMERA_MAX_ZOOM)) { return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; } else return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; }; /** * Selects a camera from the avalable ones; * in this eigther the back or the front camera is * chosen */ ioctls.maCameraSelect = delegate(int _camera) { // if the camera is not initialized, we cannot access any of its properties if (!isCameraInitialized) { return MoSync.Constants.MA_CAMERA_RES_FAILED; } if ( MoSync.Constants.MA_CAMERA_CONST_BACK_CAMERA == _camera) { if (mCamera.CameraType != CameraType.Primary) { mCameraType = CameraType.Primary; InitCamera(); } } else if (MoSync.Constants.MA_CAMERA_CONST_FRONT_CAMERA == _camera) { if (mCamera.CameraType != CameraType.FrontFacing) { mCameraType = CameraType.FrontFacing; InitCamera(); MoSync.Util.RunActionOnMainThreadSync(() => { SetInitialCameraOrientation(currentPage); } ); } } else return MoSync.Constants.MA_CAMERA_RES_FAILED; return MoSync.Constants.MA_CAMERA_RES_OK; }; /** * Retrieves the specified property value in the given buffer. * @param _property int the address for the property string * @param _value int the address for the property value string (the buffer) * @param _bufSize int the buffer size */ ioctls.maCameraGetProperty = delegate(int _property, int _value, int _bufSize) { String property = core.GetDataMemory().ReadStringAtAddress(_property); if (property.Equals(MoSync.Constants.MA_CAMERA_MAX_ZOOM)) { core.GetDataMemory().WriteStringAtAddress( _value, "0", _bufSize); } else if (property.Equals(MoSync.Constants.MA_CAMERA_ZOOM_SUPPORTED)) { core.GetDataMemory().WriteStringAtAddress( _value, "false", _bufSize); } else if (property.Equals(MoSync.Constants.MA_CAMERA_FLASH_SUPPORTED)) { core.GetDataMemory().WriteStringAtAddress( _value, "true", _bufSize); } else return MoSync.Constants.MA_CAMERA_RES_PROPERTY_NOTSUPPORTED; return 0; }; ioctls.maCameraRecord = delegate(int _stopStartFlag) { return MoSync.Constants.MA_CAMERA_RES_FAILED; }; }