using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestApp { public class CasioPrizmDevice : USBMassStorage.USBDevice { private System.Threading.Thread _screenReceiverThread; public enum ImageType { Unknown = 0, Nibble = 1, Word = 2 }; public EventHandler ScreenDataReceived; internal CasioPrizmDevice(LibUsbDotNet.Main.UsbRegistry registry, byte configurationId, byte interfaceId) : base(registry, configurationId, interfaceId) { } public static bool IsDetected { get { return (_GetDevice() != null); } } public static CasioPrizmDevice GetDevice() { var device = _GetDevice(); return new CasioPrizmDevice(device.Registry, device.ConfigurationId, device.InterfaceId); } public void StartScreenReceiverService() { if (_screenReceiverThread != null) { try { StopScreenReceiverService(); } catch { //Whatever... } } //I don't know, just go with it for now SendCommand(new byte[] { 0xC2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, new byte[] { 0x06, 0x30, 0x32, 0x30, 0x30, 0x31, 0x30, 0x44 }); //Start handling thread _screenReceiverThread = new System.Threading.Thread(new System.Threading.ThreadStart(_HandleScreenReceiverData)); _screenReceiverThread.IsBackground = true; _screenReceiverThread.Start(); } public void StopScreenReceiverService() { //TODO: Figure out what command to send to make it shut up //Stop handling thread if (_screenReceiverThread != null) { _screenReceiverThread.Abort(); _screenReceiverThread = null; } } private static USBMassStorage.USBDevice _GetDevice() { const int VENDOR_ID = 0x07CF; const int PRODUCT_ID = 0x6102; var list = USBMassStorage.USBDevice.GetAllCompatibleDevices(); USBMassStorage.USBDevice ret = null; foreach (var item in list) { if (item.VendorId == VENDOR_ID && item.ProductId == PRODUCT_ID) { ret = item; break; } } return ret; } private void _HandleScreenReceiverData() { ImageType type = ImageType.Unknown; byte[] screenData = null; long bytesRemaining = 0; int screenDataIndex = 0; while (true) { //Find out whether there's any screen data to retrieve var request = new byte[] { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; var ret = new byte[16]; SendCommand(request, ref ret); int count = ((ret[6] << 8) & 0xFF00) | ret[7]; if (count > 0) { //Yes, so request it request[0] = 0xC1; request[6] = ret[6]; request[7] = ret[7]; ret = new byte[count]; SendCommand(request, ref ret); if (ret[0] != 0x16) //not sure what this is { //Valid response, so let's grab that data! int startOffset = 0; //See if this is the start of data if (ret[1] == 0x54 && ret[2] == 0x59 && ret[3] == 0x50 && ret[4] == 0x5A) //dumb check on "TYPZ" header { //It is, parse out the bytes remaining string size = String.Empty; //this is dumb size += (char)ret[0x09]; size += (char)ret[0x0A]; size += (char)ret[0x0B]; size += (char)ret[0x0C]; size += (char)ret[0x0D]; long.TryParse(size, System.Globalization.NumberStyles.HexNumber, null, out bytesRemaining); screenDataIndex = 0; startOffset = 0x1A; //Prepare our buffer screenData = new byte[bytesRemaining]; switch (bytesRemaining) { case 0xA200: { type = ImageType.Nibble; break; } case 0x28800: { type = ImageType.Word; break; } default: { type = ImageType.Unknown; break; } } } //Copy the image data into our buffer int bytesToCopy = Math.Min(screenData.Length - screenDataIndex, ret.Length - startOffset); Array.Copy(ret, startOffset, screenData, screenDataIndex, bytesToCopy); screenDataIndex += bytesToCopy; bytesRemaining -= bytesToCopy; //Let somebody know if we have a whole image's worth of data if (bytesRemaining == 0) if (ScreenDataReceived != null) ScreenDataReceived(this, new ScreenDataReceivedEventArgs(type, screenData)); } } System.Threading.Thread.Sleep(0); } } } }