Files reorganisation.
authorsl
Thu, 22 May 2014 07:16:55 +0200
changeset 127268128148b8
parent 11 11a0e8a2346e
child 13 69f1fcfdf6a5
Files reorganisation.
FutabaVfd.cpp
FutabaVfd.h
FutabaVfd.vcxproj
Main.cpp
MainWindow.h
inc/FutabaVfd.h
inc/MainWindow.h
inc/mac_support.h
mac_support.cpp
mac_support.h
src/FutabaVfd.cpp
src/Main.cpp
src/mac_support.cpp
src/test.cpp
test.cpp
     1.1 --- a/FutabaVfd.cpp	Wed May 21 22:55:14 2014 +0200
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,227 +0,0 @@
     1.4 -
     1.5 -#include "FutabaVfd.h"
     1.6 -//#include <stdlib.h>
     1.7 -#include <string.h>
     1.8 -
     1.9 -
    1.10 -//
    1.11 -//
    1.12 -//
    1.13 -
    1.14 -
    1.15 -
    1.16 -
    1.17 -
    1.18 -//
    1.19 -//
    1.20 -//
    1.21 -
    1.22 -FutabaVfdCommand::FutabaVfdCommand():/*iBuffer(NULL),*/iSize(0),iMaxSize(0)
    1.23 -    {
    1.24 -    }
    1.25 -
    1.26 -FutabaVfdCommand::~FutabaVfdCommand()
    1.27 -    {
    1.28 -    //Delete();
    1.29 -    }
    1.30 -
    1.31 -
    1.32 -/**
    1.33 -
    1.34 -*/
    1.35 -void FutabaVfdCommand::Reset()
    1.36 -    {
    1.37 -    memset(iReports,0,sizeof(iReports));
    1.38 -    }
    1.39 -
    1.40 -
    1.41 -
    1.42 -/**
    1.43 -
    1.44 -*/
    1.45 -/*
    1.46 -void FutabaVfdCommand::Create(int aMaxSize)
    1.47 -    {
    1.48 -    iBuffer=new unsigned char[aMaxSize];
    1.49 -    if (iBuffer)
    1.50 -        {
    1.51 -        iMaxSize = aMaxSize;
    1.52 -        iSize = 0;
    1.53 -        }
    1.54 -    }
    1.55 -*/
    1.56 -
    1.57 -/**
    1.58 -
    1.59 -*/
    1.60 -/*
    1.61 -void FutabaVfdCommand::Delete()
    1.62 -{
    1.63 -    delete[] iBuffer;
    1.64 -    iBuffer = NULL;
    1.65 -    iMaxSize = 0;
    1.66 -    iSize = 0;
    1.67 -}
    1.68 -*/
    1.69 -
    1.70 -
    1.71 -//
    1.72 -// class HidDevice
    1.73 -//
    1.74 -
    1.75 -/**
    1.76 -*/
    1.77 -int HidDevice::Open(const char* aPath)
    1.78 -	{
    1.79 -	Close();
    1.80 -
    1.81 -	iHidDevice =  hid_open_path(aPath);
    1.82 -
    1.83 -	if (!iHidDevice)
    1.84 -		{
    1.85 -		//Fail to connect our device
    1.86 -		return 0;
    1.87 -		}
    1.88 -
    1.89 -	return 1;
    1.90 -	}
    1.91 -
    1.92 -/**
    1.93 -See hidapi documentation.
    1.94 -*/
    1.95 -int HidDevice::Open(unsigned short aVendorId, unsigned short aProductId, const wchar_t* aSerialNumber)
    1.96 -	{
    1.97 -	iHidDevice = hid_open(aVendorId, aProductId, aSerialNumber);
    1.98 -
    1.99 -	if (!iHidDevice)
   1.100 -		{
   1.101 -		//Fail to connect our device
   1.102 -		return 0;
   1.103 -		}
   1.104 -
   1.105 -	return 1;
   1.106 -	}
   1.107 -
   1.108 -/**
   1.109 -*/
   1.110 -void HidDevice::Close()
   1.111 -	{
   1.112 -	hid_close(iHidDevice);
   1.113 -	iHidDevice=NULL;
   1.114 -	}
   1.115 -
   1.116 -
   1.117 -/**
   1.118 -*/
   1.119 -const wchar_t* HidDevice::Error()
   1.120 -	{
   1.121 -	return hid_error(iHidDevice);
   1.122 -	}
   1.123 -
   1.124 -/**
   1.125 -*/
   1.126 -int HidDevice::SetNonBlocking(int aNonBlocking)
   1.127 -	{
   1.128 -	//Success we are now connected to our HID device 
   1.129 -	//Set read operation as non blocking
   1.130 -	return hid_set_nonblocking(iHidDevice, aNonBlocking);
   1.131 -	}
   1.132 -
   1.133 -
   1.134 -//
   1.135 -// class GP1212A01A
   1.136 -//
   1.137 -
   1.138 -int GP1212A01A::Open()
   1.139 -	{
   1.140 -	int success = HidDevice::Open(KFutabaVendorId,KFutabaProductIdGP1212A01A,NULL);
   1.141 -	if (success)
   1.142 -		{
   1.143 -		SetNonBlocking(1);
   1.144 -		}
   1.145 -	return success;
   1.146 -	}
   1.147 -
   1.148 -/**
   1.149 -*/
   1.150 -void GP1212A01A::SetPixel(int aX, int aY, bool aOn)
   1.151 -	{
   1.152 -	//Just specify a one pixel block
   1.153 -	SetPixelBlock(aX,aY,0x00,0x01,aOn);
   1.154 -	}
   1.155 -
   1.156 -/**
   1.157 -*/
   1.158 -void GP1212A01A::SetAllPixels(bool aOn)
   1.159 -	{
   1.160 -	//One pixel at a time
   1.161 -	/*
   1.162 -	for (int i=0;i<256;i++)
   1.163 -		{
   1.164 -		for (int j=0;j<64;j++)
   1.165 -			{
   1.166 -			SetPixel(i,j,0x01);
   1.167 -			}
   1.168 -		}
   1.169 -	*/
   1.170 -
   1.171 -	//16x16=256 pixels at a time goes much faster
   1.172 -	//TODO: use even larger blocks
   1.173 -	for (int i=0;i<256;i+=16)
   1.174 -		{
   1.175 -		for (int j=0;j<64;j+=16)
   1.176 -			{
   1.177 -			SetPixelBlock(i,j,15,32,(aOn?0xFF:0x00));
   1.178 -			//FXThread::sleep(1000000000);
   1.179 -			}
   1.180 -		}
   1.181 -
   1.182 -	}
   1.183 -
   1.184 -/**
   1.185 -*/
   1.186 -void GP1212A01A::SetBrightness(int aBrightness)
   1.187 -	{
   1.188 -	}
   1.189 -
   1.190 -/**
   1.191 -Set the defined pixel block to the given value.
   1.192 -@param X coordinate of our pixel block starting point.
   1.193 -@param Y coordinate of our pixel block starting point.
   1.194 -@param The height of our pixel block.
   1.195 -@param The size of our pixel data. Number of pixels divided by 8.
   1.196 -@param The value set to 8 pixels.
   1.197 -*/
   1.198 -void GP1212A01A::SetPixelBlock(int aX, int aY, int aHeight, int aSize, unsigned char aValue)
   1.199 -	{
   1.200 -	//Size must be 63 or below
   1.201 -	FutabaVfdReport report;
   1.202 -	report[0]=0x00; //Report ID
   1.203 -	report[1]=0x08+aSize; //Report length
   1.204 -	report[2]=0x1B; //
   1.205 -	report[3]=0x5B; //
   1.206 -	report[4]=0xF0; //
   1.207 -	report[5]=aX; //X
   1.208 -	report[6]=aY; //Y
   1.209 -	report[7]=aHeight; //Y length before return. Though outside the specs, setting this to zero apparently allows us to modify a single pixel without touching any other.
   1.210 -	report[8]=0x00; //Size of pixel data in bytes (MSB)
   1.211 -	report[9]=aSize; //Size of pixel data in bytes (LSB)
   1.212 -	memset(report.Buffer()+10, aValue, aSize);
   1.213 -	//iOutputReportBuffer[10]=aValue; //Pixel data
   1.214 -	Write(report);
   1.215 -	}
   1.216 -
   1.217 -
   1.218 -/**
   1.219 -*/
   1.220 -void GP1212A01A::Clear()
   1.221 -	{
   1.222 -	FutabaVfdReport report;
   1.223 -	report[0]=0x00; //Report ID
   1.224 -	report[1]=0x04; //Report length
   1.225 -	report[2]=0x1B; //
   1.226 -	report[3]=0x5B; //
   1.227 -	report[4]=0x32; //
   1.228 -	report[5]=0x4A; //
   1.229 -	Write(report);
   1.230 -	}
   1.231 \ No newline at end of file
     2.1 --- a/FutabaVfd.h	Wed May 21 22:55:14 2014 +0200
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,177 +0,0 @@
     2.4 -
     2.5 -
     2.6 -#ifndef FUTABA_VFD_H
     2.7 -#define FUTABA_VFD_H
     2.8 -
     2.9 -#include "hidapi.h"
    2.10 -
    2.11 -//This was computed from our number of pixels as follow 256x64/8/64 = 32 + 1 = 33
    2.12 -//+1 was added for our header
    2.13 -const int KFutabaMaxCommandOutputReport = 33;
    2.14 -//TODO: Get ride of that constant once we figure out a way to get it from hidapi
    2.15 -const int KFutabaMaxHidReportSize = 65;
    2.16 -
    2.17 -const int KHidReportIdIndex=0;
    2.18 -const int KFutabaHidReportSizeIndex=1;
    2.19 -//Define Futaba vendor ID to filter our list of device
    2.20 -const unsigned short KFutabaVendorId = 0x1008;
    2.21 -const unsigned short KFutabaProductIdGP1212A01A = 0x100C;
    2.22 -const unsigned short KFutabaProductIdGP1212A02A = 0x1013; //Or is it 0x1015
    2.23 -
    2.24 -
    2.25 -//typedef struct hid_device_info HidDeviceInfo;
    2.26 -
    2.27 -/**
    2.28 -TODO: move to another header
    2.29 -*/
    2.30 -template <int S>
    2.31 -class HidReport
    2.32 -	{
    2.33 -public:
    2.34 -	HidReport(){Reset();};
    2.35 -	void Reset();
    2.36 -	inline unsigned char& operator[](int aIndex){return iBuffer[aIndex];}
    2.37 -	const unsigned char* Buffer() const {return iBuffer;};
    2.38 -	unsigned char* Buffer() {return iBuffer;};
    2.39 -protected:
    2.40 -	unsigned char iBuffer[S];
    2.41 -	};
    2.42 -
    2.43 -template <int S>
    2.44 -void HidReport<S>::Reset()
    2.45 -    {
    2.46 -    memset(iBuffer,0,sizeof(iBuffer));
    2.47 -    }
    2.48 -
    2.49 -/**
    2.50 -TODO: move to another header
    2.51 -*/
    2.52 -class HidDevice
    2.53 -	{
    2.54 -public:
    2.55 -	int Open(const char* aPath);
    2.56 -	int Open(unsigned short aVendorId, unsigned short aProductId, const wchar_t* aSerialNumber);
    2.57 -	void Close();
    2.58 -	//
    2.59 -	int SetNonBlocking(int aNonBlocking);
    2.60 -	//
    2.61 -	template<int S>
    2.62 -	int Write(const HidReport<S>& aOutputReport);
    2.63 -	//
    2.64 -	const wchar_t* Error();
    2.65 -
    2.66 -	
    2.67 -
    2.68 -private:
    2.69 -	///Our USB HID device
    2.70 -	hid_device* iHidDevice;
    2.71 -	};
    2.72 -
    2.73 -
    2.74 -/**
    2.75 -*/
    2.76 -template<int S>
    2.77 -int HidDevice::Write(const HidReport<S>& aOutputReport)
    2.78 -	{
    2.79 -	return hid_write(iHidDevice,aOutputReport.Buffer(),S);
    2.80 -	}
    2.81 -
    2.82 -
    2.83 -/**
    2.84 -*/
    2.85 -class FutabaVfdReport: public HidReport<KFutabaMaxHidReportSize>
    2.86 -	{
    2.87 -	
    2.88 -private:
    2.89 -	
    2.90 -	};
    2.91 -
    2.92 -
    2.93 -
    2.94 -/**
    2.95 -Define a generic Futaba VFD command.
    2.96 -*/
    2.97 -class FutabaVfdCommand
    2.98 -    {
    2.99 -public:
   2.100 -    FutabaVfdCommand();
   2.101 -    ~FutabaVfdCommand();
   2.102 -    //
   2.103 -    //void Create(int aMaxSize);
   2.104 -    //void Delete();
   2.105 -
   2.106 -    //inline unsigned char& operator[](int aIndex){return iBuffer[aIndex];}
   2.107 -
   2.108 -    void Reset();
   2.109 -
   2.110 -private:
   2.111 -    //unsigned char* iBuffer;
   2.112 -    FutabaVfdReport iReports[KFutabaMaxCommandOutputReport];
   2.113 -    int iSize;
   2.114 -    int iMaxSize;
   2.115 -    };
   2.116 -
   2.117 -/**
   2.118 -*/
   2.119 -class FutabaVfd : public HidDevice
   2.120 -	{
   2.121 -public:
   2.122 -	virtual int MinBrightness()=0;
   2.123 -	virtual int MaxBrightness()=0;
   2.124 -	virtual void SetBrightness(int aBrightness)=0;
   2.125 -	virtual void Clear()=0;
   2.126 -	};
   2.127 -
   2.128 -
   2.129 -/**
   2.130 -*/
   2.131 -class FutabaGraphicVfd : public FutabaVfd
   2.132 -	{
   2.133 -public:
   2.134 -	virtual int WidthInPixels()=0;
   2.135 -	virtual int HeightInPixels()=0;
   2.136 -	virtual void SetPixel(int aX, int aY, bool aOn)=0;
   2.137 -	virtual void SetAllPixels(bool aOn)=0;
   2.138 -
   2.139 -	};
   2.140 -
   2.141 -/**
   2.142 -Common functionality between GP1212A01A and GP1212A02A
   2.143 -*/
   2.144 -class GP1212XXXX : public FutabaGraphicVfd
   2.145 -	{
   2.146 -public:
   2.147 -	//From FutabaVfd
   2.148 -	virtual int MinBrightness(){return 0;};
   2.149 -	virtual int MaxBrightness(){return 5;};
   2.150 -	};
   2.151 -
   2.152 -/**
   2.153 -GP1212A01A is a graphic display module using a FUTABA 256x64dots VFD.
   2.154 -The module do not include character ROM, the customer will compile the character
   2.155 -by themselves (from main system).
   2.156 -*/
   2.157 -class GP1212A01A : public GP1212XXXX
   2.158 -	{
   2.159 -public:
   2.160 -	int Open();
   2.161 -	//From FutabaGraphicVfd
   2.162 -	virtual int WidthInPixels(){return 256;};
   2.163 -	virtual int HeightInPixels(){return 64;};
   2.164 -	virtual void SetPixel(int aX, int aY, bool aOn);
   2.165 -	virtual void SetAllPixels(bool aOn);
   2.166 -	//From FutabaVfd
   2.167 -	virtual void SetBrightness(int aBrightness);
   2.168 -	virtual void Clear();
   2.169 -	//
   2.170 -	void SetPixelBlock(int aX, int aY, int aHeight, int aSize, unsigned char aValue);
   2.171 -
   2.172 -private:
   2.173 -	///
   2.174 -	//FutabaVfdReport iReport;
   2.175 -	///
   2.176 -	unsigned char iPixelBuffer[256][128];
   2.177 -	};
   2.178 -
   2.179 -
   2.180 -#endif
   2.181 \ No newline at end of file
     3.1 --- a/FutabaVfd.vcxproj	Wed May 21 22:55:14 2014 +0200
     3.2 +++ b/FutabaVfd.vcxproj	Thu May 22 07:16:55 2014 +0200
     3.3 @@ -53,7 +53,7 @@
     3.4    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     3.5      <ClCompile>
     3.6        <Optimization>Disabled</Optimization>
     3.7 -      <AdditionalIncludeDirectories>..\hidapi-externals\fox\include;..\hidapi\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     3.8 +      <AdditionalIncludeDirectories>.\inc;..\hidapi-externals\fox\include;..\hidapi\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     3.9        <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    3.10        <MinimalRebuild>true</MinimalRebuild>
    3.11        <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
    3.12 @@ -104,16 +104,14 @@
    3.13    </ItemDefinitionGroup>
    3.14    <ItemGroup>
    3.15      <ClCompile Include="..\hidapi\windows\hid.c" />
    3.16 -    <ClCompile Include="FutabaVfd.cpp" />
    3.17 -    <ClCompile Include="Main.cpp" />
    3.18 -    <ClCompile Include="test.cpp" />
    3.19 +    <ClCompile Include="src\FutabaVfd.cpp" />
    3.20 +    <ClCompile Include="src\Main.cpp" />
    3.21 +    <ClCompile Include="src\test.cpp" />
    3.22    </ItemGroup>
    3.23    <ItemGroup>
    3.24 -    <ClInclude Include="FutabaVfd.h" />
    3.25 -    <ClInclude Include="MainWindow.h" />
    3.26 -  </ItemGroup>
    3.27 -  <ItemGroup>
    3.28 -    <Text Include="ReadMe.txt" />
    3.29 +    <ClInclude Include="..\hidapi\hidapi\hidapi.h" />
    3.30 +    <ClInclude Include="inc\FutabaVfd.h" />
    3.31 +    <ClInclude Include="inc\MainWindow.h" />
    3.32    </ItemGroup>
    3.33    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
    3.34    <ImportGroup Label="ExtensionTargets">
     4.1 --- a/Main.cpp	Wed May 21 22:55:14 2014 +0200
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,15 +0,0 @@
     4.4 -
     4.5 -
     4.6 -#include "MainWindow.h"
     4.7 -
     4.8 -FXMainWindow *g_main_window;
     4.9 -
    4.10 -int main(int argc, char **argv)
    4.11 -{
    4.12 -    FXApp app("Futaba VFD", "Slions Software");
    4.13 -    app.init(argc, argv);
    4.14 -    g_main_window = new MainWindow(&app);
    4.15 -    app.create();
    4.16 -    app.run();
    4.17 -    return 0;
    4.18 -}
    4.19 \ No newline at end of file
     5.1 --- a/MainWindow.h	Wed May 21 22:55:14 2014 +0200
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,128 +0,0 @@
     5.4 -
     5.5 -
     5.6 -#ifndef MAIN_WINDOW_H
     5.7 -#define MAIN_WINDOW_H
     5.8 -
     5.9 -#include <fx.h>
    5.10 -#include "hidapi.h"
    5.11 -#include "mac_support.h"
    5.12 -#include <string.h>
    5.13 -#include <stdlib.h>
    5.14 -#include <limits.h>
    5.15 -#include "FutabaVfd.h"
    5.16 -
    5.17 -#ifdef _WIN32
    5.18 -// Thanks Microsoft, but I know how to use strncpy().
    5.19 -#pragma warning(disable:4996)
    5.20 -#endif
    5.21 -
    5.22 -class MainWindow : public FXMainWindow {
    5.23 -    FXDECLARE(MainWindow)
    5.24 -
    5.25 -public:
    5.26 -    enum {
    5.27 -        ID_FIRST = FXMainWindow::ID_LAST,
    5.28 -        ID_CONNECT,
    5.29 -        ID_DISCONNECT,
    5.30 -        ID_RESCAN,
    5.31 -        ID_SEND_OUTPUT_REPORT,
    5.32 -        ID_SEND_FEATURE_REPORT,
    5.33 -        ID_GET_FEATURE_REPORT,
    5.34 -        ID_CLEAR,
    5.35 -        ID_TIMER,
    5.36 -        ID_MAC_TIMER,
    5.37 -        ID_FUTABA_CLEAR_DISPLAY,
    5.38 -        ID_FUTABA_DIMMING,
    5.39 -        ID_FUTABA_DISPLAY_DATA_INPUT,
    5.40 -        ID_FUTABA_READ_ID,
    5.41 -        ID_FUTABA_READ_FIRMWARE_REVISION,
    5.42 -        ID_FUTABA_POWER_SUPPLY_MONITOR,
    5.43 -        ID_FUTABA_SET_PIXEL,
    5.44 -        ID_FUTABA_RESET_PIXEL,
    5.45 -        ID_FUTABA_SET_ALL_PIXELS,
    5.46 -        ID_SELECT_FONT,
    5.47 -        ID_LAST
    5.48 -    };
    5.49 -
    5.50 -    size_t getDataFromTextField(FXTextField *tf, char *buf, size_t len);
    5.51 -    int getLengthFromTextField(FXTextField *tf);
    5.52 -
    5.53 -protected:
    5.54 -    MainWindow() {};
    5.55 -public:
    5.56 -    MainWindow(FXApp *a);
    5.57 -    ~MainWindow();
    5.58 -    virtual void create();
    5.59 -
    5.60 -    long onConnect(FXObject *sender, FXSelector sel, void *ptr);
    5.61 -    long onDisconnect(FXObject *sender, FXSelector sel, void *ptr);
    5.62 -    long onRescan(FXObject *sender, FXSelector sel, void *ptr);
    5.63 -    long onSendOutputReport(FXObject *sender, FXSelector sel, void *ptr);
    5.64 -    long onSendFeatureReport(FXObject *sender, FXSelector sel, void *ptr);
    5.65 -    long onGetFeatureReport(FXObject *sender, FXSelector sel, void *ptr);
    5.66 -    long onClear(FXObject *sender, FXSelector sel, void *ptr);
    5.67 -    //
    5.68 -    long onFutabaClearDisplay(FXObject *sender, FXSelector sel, void *ptr);
    5.69 -    long onFutabaDimming(FXObject *sender, FXSelector sel, void *ptr);
    5.70 -    long onFutabaDisplayDataInput(FXObject *sender, FXSelector sel, void *ptr);
    5.71 -    long onFutabaReadId(FXObject *sender, FXSelector sel, void *ptr);
    5.72 -    long onFutabaReadFirmwareRevision(FXObject *sender, FXSelector sel, void *ptr);
    5.73 -    long onFutabaPowerSupplyMonitor(FXObject *sender, FXSelector sel, void *ptr);
    5.74 -    long onFutabaSetAllPixels(FXObject *sender, FXSelector sel, void *ptr);
    5.75 -    long onFutabaSetPixel(FXObject *sender, FXSelector sel, void *ptr);
    5.76 -    long onFutabaResetPixel(FXObject *sender, FXSelector sel, void *ptr);
    5.77 -    //
    5.78 -    long onSelectFont(FXObject *sender, FXSelector sel, void *ptr);
    5.79 -    //
    5.80 -    long onTimeout(FXObject *sender, FXSelector sel, void *ptr);
    5.81 -    long onMacTimeout(FXObject *sender, FXSelector sel, void *ptr);
    5.82 -    //
    5.83 -    void SetPixel(int aX, int aY, unsigned char aValue);
    5.84 -    void SetPixelBlock(int aX, int aY, int aHeight, int aSize, unsigned char aValue);
    5.85 -
    5.86 -private:
    5.87 -    FXList *device_list;
    5.88 -    FXButton *connect_button;
    5.89 -    FXButton *disconnect_button;
    5.90 -    FXButton *rescan_button;
    5.91 -    FXButton *output_button;
    5.92 -    FXLabel *connected_label;
    5.93 -    FXTextField *output_text;
    5.94 -    FXTextField *output_len;
    5.95 -    FXButton *feature_button;
    5.96 -    FXButton *get_feature_button;
    5.97 -    FXTextField *feature_text;
    5.98 -    FXTextField *feature_len;
    5.99 -    FXTextField *get_feature_text;
   5.100 -    FXText *input_text;
   5.101 -    FXFont *title_font;
   5.102 -    //Futaba VFD control
   5.103 -    FXButton *iButtonClearDisplay;
   5.104 -    FXButton *iButtonDimming;
   5.105 -    FXButton *iButtonDisplayDataInput;
   5.106 -    FXButton *iButtonReadId;
   5.107 -    FXButton *iButtonReadFirmwareRevision;
   5.108 -    FXButton *iButtonPowerSupplyMonitor;
   5.109 -    FXTextField *iTextFieldX;
   5.110 -    FXTextField *iTextFieldY;
   5.111 -    FXButton *iButtonSetPixel;
   5.112 -    FXButton *iButtonResetPixel;
   5.113 -    FXButton *iButtonSetAllPixels;
   5.114 -    //Font
   5.115 -    FXButton *iButtonSelectFont;
   5.116 -
   5.117 -    unsigned char* iOutputReportBuffer;
   5.118 -    unsigned char iDimming; //Current VFD dimming
   5.119 -    FXFontDesc iCurrentFontDesc;
   5.120 -    FXFont* iCurrentFont;
   5.121 -    FXTGAImage* iFontImage;
   5.122 -
   5.123 -    struct hid_device_info *devices;
   5.124 -    hid_device *connected_device;
   5.125 -
   5.126 -	//Futaba
   5.127 -	GP1212A01A iVfd01;
   5.128 -
   5.129 -};
   5.130 -
   5.131 -#endif //
   5.132 \ No newline at end of file
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/inc/FutabaVfd.h	Thu May 22 07:16:55 2014 +0200
     6.3 @@ -0,0 +1,177 @@
     6.4 +
     6.5 +
     6.6 +#ifndef FUTABA_VFD_H
     6.7 +#define FUTABA_VFD_H
     6.8 +
     6.9 +#include "hidapi.h"
    6.10 +
    6.11 +//This was computed from our number of pixels as follow 256x64/8/64 = 32 + 1 = 33
    6.12 +//+1 was added for our header
    6.13 +const int KFutabaMaxCommandOutputReport = 33;
    6.14 +//TODO: Get ride of that constant once we figure out a way to get it from hidapi
    6.15 +const int KFutabaMaxHidReportSize = 65;
    6.16 +
    6.17 +const int KHidReportIdIndex=0;
    6.18 +const int KFutabaHidReportSizeIndex=1;
    6.19 +//Define Futaba vendor ID to filter our list of device
    6.20 +const unsigned short KFutabaVendorId = 0x1008;
    6.21 +const unsigned short KFutabaProductIdGP1212A01A = 0x100C;
    6.22 +const unsigned short KFutabaProductIdGP1212A02A = 0x1013; //Or is it 0x1015
    6.23 +
    6.24 +
    6.25 +//typedef struct hid_device_info HidDeviceInfo;
    6.26 +
    6.27 +/**
    6.28 +TODO: move to another header
    6.29 +*/
    6.30 +template <int S>
    6.31 +class HidReport
    6.32 +	{
    6.33 +public:
    6.34 +	HidReport(){Reset();};
    6.35 +	void Reset();
    6.36 +	inline unsigned char& operator[](int aIndex){return iBuffer[aIndex];}
    6.37 +	const unsigned char* Buffer() const {return iBuffer;};
    6.38 +	unsigned char* Buffer() {return iBuffer;};
    6.39 +protected:
    6.40 +	unsigned char iBuffer[S];
    6.41 +	};
    6.42 +
    6.43 +template <int S>
    6.44 +void HidReport<S>::Reset()
    6.45 +    {
    6.46 +    memset(iBuffer,0,sizeof(iBuffer));
    6.47 +    }
    6.48 +
    6.49 +/**
    6.50 +TODO: move to another header
    6.51 +*/
    6.52 +class HidDevice
    6.53 +	{
    6.54 +public:
    6.55 +	int Open(const char* aPath);
    6.56 +	int Open(unsigned short aVendorId, unsigned short aProductId, const wchar_t* aSerialNumber);
    6.57 +	void Close();
    6.58 +	//
    6.59 +	int SetNonBlocking(int aNonBlocking);
    6.60 +	//
    6.61 +	template<int S>
    6.62 +	int Write(const HidReport<S>& aOutputReport);
    6.63 +	//
    6.64 +	const wchar_t* Error();
    6.65 +
    6.66 +	
    6.67 +
    6.68 +private:
    6.69 +	///Our USB HID device
    6.70 +	hid_device* iHidDevice;
    6.71 +	};
    6.72 +
    6.73 +
    6.74 +/**
    6.75 +*/
    6.76 +template<int S>
    6.77 +int HidDevice::Write(const HidReport<S>& aOutputReport)
    6.78 +	{
    6.79 +	return hid_write(iHidDevice,aOutputReport.Buffer(),S);
    6.80 +	}
    6.81 +
    6.82 +
    6.83 +/**
    6.84 +*/
    6.85 +class FutabaVfdReport: public HidReport<KFutabaMaxHidReportSize>
    6.86 +	{
    6.87 +	
    6.88 +private:
    6.89 +	
    6.90 +	};
    6.91 +
    6.92 +
    6.93 +
    6.94 +/**
    6.95 +Define a generic Futaba VFD command.
    6.96 +*/
    6.97 +class FutabaVfdCommand
    6.98 +    {
    6.99 +public:
   6.100 +    FutabaVfdCommand();
   6.101 +    ~FutabaVfdCommand();
   6.102 +    //
   6.103 +    //void Create(int aMaxSize);
   6.104 +    //void Delete();
   6.105 +
   6.106 +    //inline unsigned char& operator[](int aIndex){return iBuffer[aIndex];}
   6.107 +
   6.108 +    void Reset();
   6.109 +
   6.110 +private:
   6.111 +    //unsigned char* iBuffer;
   6.112 +    FutabaVfdReport iReports[KFutabaMaxCommandOutputReport];
   6.113 +    int iSize;
   6.114 +    int iMaxSize;
   6.115 +    };
   6.116 +
   6.117 +/**
   6.118 +*/
   6.119 +class FutabaVfd : public HidDevice
   6.120 +	{
   6.121 +public:
   6.122 +	virtual int MinBrightness()=0;
   6.123 +	virtual int MaxBrightness()=0;
   6.124 +	virtual void SetBrightness(int aBrightness)=0;
   6.125 +	virtual void Clear()=0;
   6.126 +	};
   6.127 +
   6.128 +
   6.129 +/**
   6.130 +*/
   6.131 +class FutabaGraphicVfd : public FutabaVfd
   6.132 +	{
   6.133 +public:
   6.134 +	virtual int WidthInPixels()=0;
   6.135 +	virtual int HeightInPixels()=0;
   6.136 +	virtual void SetPixel(int aX, int aY, bool aOn)=0;
   6.137 +	virtual void SetAllPixels(bool aOn)=0;
   6.138 +
   6.139 +	};
   6.140 +
   6.141 +/**
   6.142 +Common functionality between GP1212A01A and GP1212A02A
   6.143 +*/
   6.144 +class GP1212XXXX : public FutabaGraphicVfd
   6.145 +	{
   6.146 +public:
   6.147 +	//From FutabaVfd
   6.148 +	virtual int MinBrightness(){return 0;};
   6.149 +	virtual int MaxBrightness(){return 5;};
   6.150 +	};
   6.151 +
   6.152 +/**
   6.153 +GP1212A01A is a graphic display module using a FUTABA 256x64dots VFD.
   6.154 +The module do not include character ROM, the customer will compile the character
   6.155 +by themselves (from main system).
   6.156 +*/
   6.157 +class GP1212A01A : public GP1212XXXX
   6.158 +	{
   6.159 +public:
   6.160 +	int Open();
   6.161 +	//From FutabaGraphicVfd
   6.162 +	virtual int WidthInPixels(){return 256;};
   6.163 +	virtual int HeightInPixels(){return 64;};
   6.164 +	virtual void SetPixel(int aX, int aY, bool aOn);
   6.165 +	virtual void SetAllPixels(bool aOn);
   6.166 +	//From FutabaVfd
   6.167 +	virtual void SetBrightness(int aBrightness);
   6.168 +	virtual void Clear();
   6.169 +	//
   6.170 +	void SetPixelBlock(int aX, int aY, int aHeight, int aSize, unsigned char aValue);
   6.171 +
   6.172 +private:
   6.173 +	///
   6.174 +	//FutabaVfdReport iReport;
   6.175 +	///
   6.176 +	unsigned char iPixelBuffer[256][128];
   6.177 +	};
   6.178 +
   6.179 +
   6.180 +#endif
   6.181 \ No newline at end of file
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/inc/MainWindow.h	Thu May 22 07:16:55 2014 +0200
     7.3 @@ -0,0 +1,128 @@
     7.4 +
     7.5 +
     7.6 +#ifndef MAIN_WINDOW_H
     7.7 +#define MAIN_WINDOW_H
     7.8 +
     7.9 +#include <fx.h>
    7.10 +#include "hidapi.h"
    7.11 +#include "mac_support.h"
    7.12 +#include <string.h>
    7.13 +#include <stdlib.h>
    7.14 +#include <limits.h>
    7.15 +#include "FutabaVfd.h"
    7.16 +
    7.17 +#ifdef _WIN32
    7.18 +// Thanks Microsoft, but I know how to use strncpy().
    7.19 +#pragma warning(disable:4996)
    7.20 +#endif
    7.21 +
    7.22 +class MainWindow : public FXMainWindow {
    7.23 +    FXDECLARE(MainWindow)
    7.24 +
    7.25 +public:
    7.26 +    enum {
    7.27 +        ID_FIRST = FXMainWindow::ID_LAST,
    7.28 +        ID_CONNECT,
    7.29 +        ID_DISCONNECT,
    7.30 +        ID_RESCAN,
    7.31 +        ID_SEND_OUTPUT_REPORT,
    7.32 +        ID_SEND_FEATURE_REPORT,
    7.33 +        ID_GET_FEATURE_REPORT,
    7.34 +        ID_CLEAR,
    7.35 +        ID_TIMER,
    7.36 +        ID_MAC_TIMER,
    7.37 +        ID_FUTABA_CLEAR_DISPLAY,
    7.38 +        ID_FUTABA_DIMMING,
    7.39 +        ID_FUTABA_DISPLAY_DATA_INPUT,
    7.40 +        ID_FUTABA_READ_ID,
    7.41 +        ID_FUTABA_READ_FIRMWARE_REVISION,
    7.42 +        ID_FUTABA_POWER_SUPPLY_MONITOR,
    7.43 +        ID_FUTABA_SET_PIXEL,
    7.44 +        ID_FUTABA_RESET_PIXEL,
    7.45 +        ID_FUTABA_SET_ALL_PIXELS,
    7.46 +        ID_SELECT_FONT,
    7.47 +        ID_LAST
    7.48 +    };
    7.49 +
    7.50 +    size_t getDataFromTextField(FXTextField *tf, char *buf, size_t len);
    7.51 +    int getLengthFromTextField(FXTextField *tf);
    7.52 +
    7.53 +protected:
    7.54 +    MainWindow() {};
    7.55 +public:
    7.56 +    MainWindow(FXApp *a);
    7.57 +    ~MainWindow();
    7.58 +    virtual void create();
    7.59 +
    7.60 +    long onConnect(FXObject *sender, FXSelector sel, void *ptr);
    7.61 +    long onDisconnect(FXObject *sender, FXSelector sel, void *ptr);
    7.62 +    long onRescan(FXObject *sender, FXSelector sel, void *ptr);
    7.63 +    long onSendOutputReport(FXObject *sender, FXSelector sel, void *ptr);
    7.64 +    long onSendFeatureReport(FXObject *sender, FXSelector sel, void *ptr);
    7.65 +    long onGetFeatureReport(FXObject *sender, FXSelector sel, void *ptr);
    7.66 +    long onClear(FXObject *sender, FXSelector sel, void *ptr);
    7.67 +    //
    7.68 +    long onFutabaClearDisplay(FXObject *sender, FXSelector sel, void *ptr);
    7.69 +    long onFutabaDimming(FXObject *sender, FXSelector sel, void *ptr);
    7.70 +    long onFutabaDisplayDataInput(FXObject *sender, FXSelector sel, void *ptr);
    7.71 +    long onFutabaReadId(FXObject *sender, FXSelector sel, void *ptr);
    7.72 +    long onFutabaReadFirmwareRevision(FXObject *sender, FXSelector sel, void *ptr);
    7.73 +    long onFutabaPowerSupplyMonitor(FXObject *sender, FXSelector sel, void *ptr);
    7.74 +    long onFutabaSetAllPixels(FXObject *sender, FXSelector sel, void *ptr);
    7.75 +    long onFutabaSetPixel(FXObject *sender, FXSelector sel, void *ptr);
    7.76 +    long onFutabaResetPixel(FXObject *sender, FXSelector sel, void *ptr);
    7.77 +    //
    7.78 +    long onSelectFont(FXObject *sender, FXSelector sel, void *ptr);
    7.79 +    //
    7.80 +    long onTimeout(FXObject *sender, FXSelector sel, void *ptr);
    7.81 +    long onMacTimeout(FXObject *sender, FXSelector sel, void *ptr);
    7.82 +    //
    7.83 +    void SetPixel(int aX, int aY, unsigned char aValue);
    7.84 +    void SetPixelBlock(int aX, int aY, int aHeight, int aSize, unsigned char aValue);
    7.85 +
    7.86 +private:
    7.87 +    FXList *device_list;
    7.88 +    FXButton *connect_button;
    7.89 +    FXButton *disconnect_button;
    7.90 +    FXButton *rescan_button;
    7.91 +    FXButton *output_button;
    7.92 +    FXLabel *connected_label;
    7.93 +    FXTextField *output_text;
    7.94 +    FXTextField *output_len;
    7.95 +    FXButton *feature_button;
    7.96 +    FXButton *get_feature_button;
    7.97 +    FXTextField *feature_text;
    7.98 +    FXTextField *feature_len;
    7.99 +    FXTextField *get_feature_text;
   7.100 +    FXText *input_text;
   7.101 +    FXFont *title_font;
   7.102 +    //Futaba VFD control
   7.103 +    FXButton *iButtonClearDisplay;
   7.104 +    FXButton *iButtonDimming;
   7.105 +    FXButton *iButtonDisplayDataInput;
   7.106 +    FXButton *iButtonReadId;
   7.107 +    FXButton *iButtonReadFirmwareRevision;
   7.108 +    FXButton *iButtonPowerSupplyMonitor;
   7.109 +    FXTextField *iTextFieldX;
   7.110 +    FXTextField *iTextFieldY;
   7.111 +    FXButton *iButtonSetPixel;
   7.112 +    FXButton *iButtonResetPixel;
   7.113 +    FXButton *iButtonSetAllPixels;
   7.114 +    //Font
   7.115 +    FXButton *iButtonSelectFont;
   7.116 +
   7.117 +    unsigned char* iOutputReportBuffer;
   7.118 +    unsigned char iDimming; //Current VFD dimming
   7.119 +    FXFontDesc iCurrentFontDesc;
   7.120 +    FXFont* iCurrentFont;
   7.121 +    FXTGAImage* iFontImage;
   7.122 +
   7.123 +    struct hid_device_info *devices;
   7.124 +    hid_device *connected_device;
   7.125 +
   7.126 +	//Futaba
   7.127 +	GP1212A01A iVfd01;
   7.128 +
   7.129 +};
   7.130 +
   7.131 +#endif //
   7.132 \ No newline at end of file
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/inc/mac_support.h	Thu May 22 07:16:55 2014 +0200
     8.3 @@ -0,0 +1,17 @@
     8.4 +/*******************************
     8.5 + Mac support for HID Test GUI
     8.6 + 
     8.7 + Alan Ott
     8.8 + Signal 11 Software
     8.9 + 
    8.10 +*******************************/
    8.11 +
    8.12 +#ifndef MAC_SUPPORT_H__
    8.13 +#define MAC_SUPPORT_H__
    8.14 +
    8.15 +extern "C" {
    8.16 +	void init_apple_message_system();
    8.17 +	void check_apple_events();
    8.18 +}
    8.19 +
    8.20 +#endif
     9.1 --- a/mac_support.cpp	Wed May 21 22:55:14 2014 +0200
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,134 +0,0 @@
     9.4 -/*******************************
     9.5 - Mac support for HID Test GUI
     9.6 - 
     9.7 - Alan Ott
     9.8 - Signal 11 Software
     9.9 -
    9.10 - Some of this code is from Apple Documentation, most notably
    9.11 - http://developer.apple.com/legacy/mac/library/documentation/AppleScript/Conceptual/AppleEvents/AppleEvents.pdf 
    9.12 -*******************************/
    9.13 -
    9.14 -#include <Carbon/Carbon.h>
    9.15 -#include <fx.h>
    9.16 -
    9.17 -
    9.18 -extern FXMainWindow *g_main_window;
    9.19 -
    9.20 -static pascal OSErr HandleQuitMessage(const AppleEvent *theAppleEvent, AppleEvent 
    9.21 -									  *reply, long handlerRefcon) 
    9.22 -{
    9.23 -	puts("Quitting\n");
    9.24 -	FXApp::instance()->exit();
    9.25 -	return 0;
    9.26 -}
    9.27 -
    9.28 -static pascal OSErr HandleReopenMessage(const AppleEvent *theAppleEvent, AppleEvent 
    9.29 -									  *reply, long handlerRefcon) 
    9.30 -{
    9.31 -	puts("Showing");
    9.32 -	g_main_window->show();
    9.33 -	return 0;
    9.34 -}
    9.35 -
    9.36 -static pascal OSErr HandleWildCardMessage(const AppleEvent *theAppleEvent, AppleEvent 
    9.37 -									  *reply, long handlerRefcon) 
    9.38 -{
    9.39 -	puts("WildCard\n");
    9.40 -	return 0;
    9.41 -}
    9.42 -
    9.43 -OSStatus AEHandler(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon) 
    9.44 -{ 
    9.45 -    Boolean     release = false; 
    9.46 -    EventRecord eventRecord; 
    9.47 -    OSErr       ignoreErrForThisSample; 
    9.48 -	
    9.49 -    // Events of type kEventAppleEvent must be removed from the queue 
    9.50 -    //  before being passed to AEProcessAppleEvent. 
    9.51 -    if (IsEventInQueue(GetMainEventQueue(), inEvent)) 
    9.52 -    { 
    9.53 -        // RemoveEventFromQueue will release the event, which will 
    9.54 -        //  destroy it if we don't retain it first. 
    9.55 -        RetainEvent(inEvent); 
    9.56 -        release = true; 
    9.57 -        RemoveEventFromQueue(GetMainEventQueue(), inEvent); 
    9.58 -    } 
    9.59 -    // Convert the event ref to the type AEProcessAppleEvent expects. 
    9.60 -    ConvertEventRefToEventRecord(inEvent, &eventRecord); 
    9.61 -    ignoreErrForThisSample = AEProcessAppleEvent(&eventRecord); 
    9.62 -    if (release) 
    9.63 -        ReleaseEvent(inEvent); 
    9.64 -    // This Carbon event has been handled, even if no AppleEvent handlers 
    9.65 -    //  were installed for the Apple event. 
    9.66 -    return noErr; 
    9.67 -}
    9.68 -
    9.69 -static void HandleEvent(EventRecord *event) 
    9.70 -{ 
    9.71 -	//printf("What: %d message %x\n", event->what, event->message);
    9.72 -	if (event->what == osEvt) {
    9.73 -		if (((event->message >> 24) & 0xff) == suspendResumeMessage) {
    9.74 -			if (event->message & resumeFlag) {
    9.75 -				g_main_window->show();				
    9.76 -			}
    9.77 -		}
    9.78 -	}
    9.79 -
    9.80 -#if 0
    9.81 -    switch (event->what) 
    9.82 -    { 
    9.83 -        case mouseDown: 
    9.84 -            //HandleMouseDown(event); 
    9.85 -            break; 
    9.86 -        case keyDown: 
    9.87 -        case autoKey: 
    9.88 -            //HandleKeyPress(event); 
    9.89 -            break; 
    9.90 -        case kHighLevelEvent: 
    9.91 -			puts("Calling ProcessAppleEvent\n");
    9.92 -            AEProcessAppleEvent(event); 
    9.93 -            break; 
    9.94 -    } 
    9.95 -#endif
    9.96 -} 
    9.97 -
    9.98 -void
    9.99 -init_apple_message_system()
   9.100 -{
   9.101 -	OSErr err;
   9.102 -	static const EventTypeSpec appleEvents[] = 
   9.103 -	{
   9.104 -		{ kEventClassAppleEvent, kEventAppleEvent }
   9.105 -	};
   9.106 -	
   9.107 -	/* Install the handler for Apple Events */
   9.108 -	InstallApplicationEventHandler(NewEventHandlerUPP(AEHandler), 
   9.109 -	              GetEventTypeCount(appleEvents), appleEvents, 0, NULL); 
   9.110 -
   9.111 -	/* Install handlers for the individual Apple Events that come
   9.112 -	   from the Dock icon: the Reopen (click), and the Quit messages. */
   9.113 -	err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, 
   9.114 -	              NewAEEventHandlerUPP(HandleQuitMessage), 0, false);
   9.115 -	err = AEInstallEventHandler(kCoreEventClass, kAEReopenApplication, 
   9.116 -	              NewAEEventHandlerUPP(HandleReopenMessage), 0, false);
   9.117 -#if 0
   9.118 -	// Left as an example of a wild card match.
   9.119 -	err = AEInstallEventHandler(kCoreEventClass, typeWildCard, 
   9.120 -	              NewAEEventHandlerUPP(HandleWildMessage), 0, false);
   9.121 -#endif
   9.122 -}
   9.123 -
   9.124 -void
   9.125 -check_apple_events()
   9.126 -{
   9.127 -	RgnHandle       cursorRgn = NULL; 
   9.128 -	Boolean         gotEvent=TRUE; 
   9.129 -	EventRecord     event; 
   9.130 -
   9.131 -	while (gotEvent) { 
   9.132 -		gotEvent = WaitNextEvent(everyEvent, &event, 0L/*timeout*/, cursorRgn); 
   9.133 -		if (gotEvent) { 
   9.134 -			HandleEvent(&event); 
   9.135 -		} 
   9.136 -	}
   9.137 -}
    10.1 --- a/mac_support.h	Wed May 21 22:55:14 2014 +0200
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,17 +0,0 @@
    10.4 -/*******************************
    10.5 - Mac support for HID Test GUI
    10.6 - 
    10.7 - Alan Ott
    10.8 - Signal 11 Software
    10.9 - 
   10.10 -*******************************/
   10.11 -
   10.12 -#ifndef MAC_SUPPORT_H__
   10.13 -#define MAC_SUPPORT_H__
   10.14 -
   10.15 -extern "C" {
   10.16 -	void init_apple_message_system();
   10.17 -	void check_apple_events();
   10.18 -}
   10.19 -
   10.20 -#endif
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/FutabaVfd.cpp	Thu May 22 07:16:55 2014 +0200
    11.3 @@ -0,0 +1,227 @@
    11.4 +
    11.5 +#include "FutabaVfd.h"
    11.6 +//#include <stdlib.h>
    11.7 +#include <string.h>
    11.8 +
    11.9 +
   11.10 +//
   11.11 +//
   11.12 +//
   11.13 +
   11.14 +
   11.15 +
   11.16 +
   11.17 +
   11.18 +//
   11.19 +//
   11.20 +//
   11.21 +
   11.22 +FutabaVfdCommand::FutabaVfdCommand():/*iBuffer(NULL),*/iSize(0),iMaxSize(0)
   11.23 +    {
   11.24 +    }
   11.25 +
   11.26 +FutabaVfdCommand::~FutabaVfdCommand()
   11.27 +    {
   11.28 +    //Delete();
   11.29 +    }
   11.30 +
   11.31 +
   11.32 +/**
   11.33 +
   11.34 +*/
   11.35 +void FutabaVfdCommand::Reset()
   11.36 +    {
   11.37 +    memset(iReports,0,sizeof(iReports));
   11.38 +    }
   11.39 +
   11.40 +
   11.41 +
   11.42 +/**
   11.43 +
   11.44 +*/
   11.45 +/*
   11.46 +void FutabaVfdCommand::Create(int aMaxSize)
   11.47 +    {
   11.48 +    iBuffer=new unsigned char[aMaxSize];
   11.49 +    if (iBuffer)
   11.50 +        {
   11.51 +        iMaxSize = aMaxSize;
   11.52 +        iSize = 0;
   11.53 +        }
   11.54 +    }
   11.55 +*/
   11.56 +
   11.57 +/**
   11.58 +
   11.59 +*/
   11.60 +/*
   11.61 +void FutabaVfdCommand::Delete()
   11.62 +{
   11.63 +    delete[] iBuffer;
   11.64 +    iBuffer = NULL;
   11.65 +    iMaxSize = 0;
   11.66 +    iSize = 0;
   11.67 +}
   11.68 +*/
   11.69 +
   11.70 +
   11.71 +//
   11.72 +// class HidDevice
   11.73 +//
   11.74 +
   11.75 +/**
   11.76 +*/
   11.77 +int HidDevice::Open(const char* aPath)
   11.78 +	{
   11.79 +	Close();
   11.80 +
   11.81 +	iHidDevice =  hid_open_path(aPath);
   11.82 +
   11.83 +	if (!iHidDevice)
   11.84 +		{
   11.85 +		//Fail to connect our device
   11.86 +		return 0;
   11.87 +		}
   11.88 +
   11.89 +	return 1;
   11.90 +	}
   11.91 +
   11.92 +/**
   11.93 +See hidapi documentation.
   11.94 +*/
   11.95 +int HidDevice::Open(unsigned short aVendorId, unsigned short aProductId, const wchar_t* aSerialNumber)
   11.96 +	{
   11.97 +	iHidDevice = hid_open(aVendorId, aProductId, aSerialNumber);
   11.98 +
   11.99 +	if (!iHidDevice)
  11.100 +		{
  11.101 +		//Fail to connect our device
  11.102 +		return 0;
  11.103 +		}
  11.104 +
  11.105 +	return 1;
  11.106 +	}
  11.107 +
  11.108 +/**
  11.109 +*/
  11.110 +void HidDevice::Close()
  11.111 +	{
  11.112 +	hid_close(iHidDevice);
  11.113 +	iHidDevice=NULL;
  11.114 +	}
  11.115 +
  11.116 +
  11.117 +/**
  11.118 +*/
  11.119 +const wchar_t* HidDevice::Error()
  11.120 +	{
  11.121 +	return hid_error(iHidDevice);
  11.122 +	}
  11.123 +
  11.124 +/**
  11.125 +*/
  11.126 +int HidDevice::SetNonBlocking(int aNonBlocking)
  11.127 +	{
  11.128 +	//Success we are now connected to our HID device 
  11.129 +	//Set read operation as non blocking
  11.130 +	return hid_set_nonblocking(iHidDevice, aNonBlocking);
  11.131 +	}
  11.132 +
  11.133 +
  11.134 +//
  11.135 +// class GP1212A01A
  11.136 +//
  11.137 +
  11.138 +int GP1212A01A::Open()
  11.139 +	{
  11.140 +	int success = HidDevice::Open(KFutabaVendorId,KFutabaProductIdGP1212A01A,NULL);
  11.141 +	if (success)
  11.142 +		{
  11.143 +		SetNonBlocking(1);
  11.144 +		}
  11.145 +	return success;
  11.146 +	}
  11.147 +
  11.148 +/**
  11.149 +*/
  11.150 +void GP1212A01A::SetPixel(int aX, int aY, bool aOn)
  11.151 +	{
  11.152 +	//Just specify a one pixel block
  11.153 +	SetPixelBlock(aX,aY,0x00,0x01,aOn);
  11.154 +	}
  11.155 +
  11.156 +/**
  11.157 +*/
  11.158 +void GP1212A01A::SetAllPixels(bool aOn)
  11.159 +	{
  11.160 +	//One pixel at a time
  11.161 +	/*
  11.162 +	for (int i=0;i<256;i++)
  11.163 +		{
  11.164 +		for (int j=0;j<64;j++)
  11.165 +			{
  11.166 +			SetPixel(i,j,0x01);
  11.167 +			}
  11.168 +		}
  11.169 +	*/
  11.170 +
  11.171 +	//16x16=256 pixels at a time goes much faster
  11.172 +	//TODO: use even larger blocks
  11.173 +	for (int i=0;i<256;i+=16)
  11.174 +		{
  11.175 +		for (int j=0;j<64;j+=16)
  11.176 +			{
  11.177 +			SetPixelBlock(i,j,15,32,(aOn?0xFF:0x00));
  11.178 +			//FXThread::sleep(1000000000);
  11.179 +			}
  11.180 +		}
  11.181 +
  11.182 +	}
  11.183 +
  11.184 +/**
  11.185 +*/
  11.186 +void GP1212A01A::SetBrightness(int aBrightness)
  11.187 +	{
  11.188 +	}
  11.189 +
  11.190 +/**
  11.191 +Set the defined pixel block to the given value.
  11.192 +@param X coordinate of our pixel block starting point.
  11.193 +@param Y coordinate of our pixel block starting point.
  11.194 +@param The height of our pixel block.
  11.195 +@param The size of our pixel data. Number of pixels divided by 8.
  11.196 +@param The value set to 8 pixels.
  11.197 +*/
  11.198 +void GP1212A01A::SetPixelBlock(int aX, int aY, int aHeight, int aSize, unsigned char aValue)
  11.199 +	{
  11.200 +	//Size must be 63 or below
  11.201 +	FutabaVfdReport report;
  11.202 +	report[0]=0x00; //Report ID
  11.203 +	report[1]=0x08+aSize; //Report length
  11.204 +	report[2]=0x1B; //
  11.205 +	report[3]=0x5B; //
  11.206 +	report[4]=0xF0; //
  11.207 +	report[5]=aX; //X
  11.208 +	report[6]=aY; //Y
  11.209 +	report[7]=aHeight; //Y length before return. Though outside the specs, setting this to zero apparently allows us to modify a single pixel without touching any other.
  11.210 +	report[8]=0x00; //Size of pixel data in bytes (MSB)
  11.211 +	report[9]=aSize; //Size of pixel data in bytes (LSB)
  11.212 +	memset(report.Buffer()+10, aValue, aSize);
  11.213 +	//iOutputReportBuffer[10]=aValue; //Pixel data
  11.214 +	Write(report);
  11.215 +	}
  11.216 +
  11.217 +
  11.218 +/**
  11.219 +*/
  11.220 +void GP1212A01A::Clear()
  11.221 +	{
  11.222 +	FutabaVfdReport report;
  11.223 +	report[0]=0x00; //Report ID
  11.224 +	report[1]=0x04; //Report length
  11.225 +	report[2]=0x1B; //
  11.226 +	report[3]=0x5B; //
  11.227 +	report[4]=0x32; //
  11.228 +	report[5]=0x4A; //
  11.229 +	Write(report);
  11.230 +	}
  11.231 \ No newline at end of file
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/Main.cpp	Thu May 22 07:16:55 2014 +0200
    12.3 @@ -0,0 +1,15 @@
    12.4 +
    12.5 +
    12.6 +#include "MainWindow.h"
    12.7 +
    12.8 +FXMainWindow *g_main_window;
    12.9 +
   12.10 +int main(int argc, char **argv)
   12.11 +{
   12.12 +    FXApp app("Futaba VFD", "Slions Software");
   12.13 +    app.init(argc, argv);
   12.14 +    g_main_window = new MainWindow(&app);
   12.15 +    app.create();
   12.16 +    app.run();
   12.17 +    return 0;
   12.18 +}
   12.19 \ No newline at end of file
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/mac_support.cpp	Thu May 22 07:16:55 2014 +0200
    13.3 @@ -0,0 +1,134 @@
    13.4 +/*******************************
    13.5 + Mac support for HID Test GUI
    13.6 + 
    13.7 + Alan Ott
    13.8 + Signal 11 Software
    13.9 +
   13.10 + Some of this code is from Apple Documentation, most notably
   13.11 + http://developer.apple.com/legacy/mac/library/documentation/AppleScript/Conceptual/AppleEvents/AppleEvents.pdf 
   13.12 +*******************************/
   13.13 +
   13.14 +#include <Carbon/Carbon.h>
   13.15 +#include <fx.h>
   13.16 +
   13.17 +
   13.18 +extern FXMainWindow *g_main_window;
   13.19 +
   13.20 +static pascal OSErr HandleQuitMessage(const AppleEvent *theAppleEvent, AppleEvent 
   13.21 +									  *reply, long handlerRefcon) 
   13.22 +{
   13.23 +	puts("Quitting\n");
   13.24 +	FXApp::instance()->exit();
   13.25 +	return 0;
   13.26 +}
   13.27 +
   13.28 +static pascal OSErr HandleReopenMessage(const AppleEvent *theAppleEvent, AppleEvent 
   13.29 +									  *reply, long handlerRefcon) 
   13.30 +{
   13.31 +	puts("Showing");
   13.32 +	g_main_window->show();
   13.33 +	return 0;
   13.34 +}
   13.35 +
   13.36 +static pascal OSErr HandleWildCardMessage(const AppleEvent *theAppleEvent, AppleEvent 
   13.37 +									  *reply, long handlerRefcon) 
   13.38 +{
   13.39 +	puts("WildCard\n");
   13.40 +	return 0;
   13.41 +}
   13.42 +
   13.43 +OSStatus AEHandler(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon) 
   13.44 +{ 
   13.45 +    Boolean     release = false; 
   13.46 +    EventRecord eventRecord; 
   13.47 +    OSErr       ignoreErrForThisSample; 
   13.48 +	
   13.49 +    // Events of type kEventAppleEvent must be removed from the queue 
   13.50 +    //  before being passed to AEProcessAppleEvent. 
   13.51 +    if (IsEventInQueue(GetMainEventQueue(), inEvent)) 
   13.52 +    { 
   13.53 +        // RemoveEventFromQueue will release the event, which will 
   13.54 +        //  destroy it if we don't retain it first. 
   13.55 +        RetainEvent(inEvent); 
   13.56 +        release = true; 
   13.57 +        RemoveEventFromQueue(GetMainEventQueue(), inEvent); 
   13.58 +    } 
   13.59 +    // Convert the event ref to the type AEProcessAppleEvent expects. 
   13.60 +    ConvertEventRefToEventRecord(inEvent, &eventRecord); 
   13.61 +    ignoreErrForThisSample = AEProcessAppleEvent(&eventRecord); 
   13.62 +    if (release) 
   13.63 +        ReleaseEvent(inEvent); 
   13.64 +    // This Carbon event has been handled, even if no AppleEvent handlers 
   13.65 +    //  were installed for the Apple event. 
   13.66 +    return noErr; 
   13.67 +}
   13.68 +
   13.69 +static void HandleEvent(EventRecord *event) 
   13.70 +{ 
   13.71 +	//printf("What: %d message %x\n", event->what, event->message);
   13.72 +	if (event->what == osEvt) {
   13.73 +		if (((event->message >> 24) & 0xff) == suspendResumeMessage) {
   13.74 +			if (event->message & resumeFlag) {
   13.75 +				g_main_window->show();				
   13.76 +			}
   13.77 +		}
   13.78 +	}
   13.79 +
   13.80 +#if 0
   13.81 +    switch (event->what) 
   13.82 +    { 
   13.83 +        case mouseDown: 
   13.84 +            //HandleMouseDown(event); 
   13.85 +            break; 
   13.86 +        case keyDown: 
   13.87 +        case autoKey: 
   13.88 +            //HandleKeyPress(event); 
   13.89 +            break; 
   13.90 +        case kHighLevelEvent: 
   13.91 +			puts("Calling ProcessAppleEvent\n");
   13.92 +            AEProcessAppleEvent(event); 
   13.93 +            break; 
   13.94 +    } 
   13.95 +#endif
   13.96 +} 
   13.97 +
   13.98 +void
   13.99 +init_apple_message_system()
  13.100 +{
  13.101 +	OSErr err;
  13.102 +	static const EventTypeSpec appleEvents[] = 
  13.103 +	{
  13.104 +		{ kEventClassAppleEvent, kEventAppleEvent }
  13.105 +	};
  13.106 +	
  13.107 +	/* Install the handler for Apple Events */
  13.108 +	InstallApplicationEventHandler(NewEventHandlerUPP(AEHandler), 
  13.109 +	              GetEventTypeCount(appleEvents), appleEvents, 0, NULL); 
  13.110 +
  13.111 +	/* Install handlers for the individual Apple Events that come
  13.112 +	   from the Dock icon: the Reopen (click), and the Quit messages. */
  13.113 +	err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, 
  13.114 +	              NewAEEventHandlerUPP(HandleQuitMessage), 0, false);
  13.115 +	err = AEInstallEventHandler(kCoreEventClass, kAEReopenApplication, 
  13.116 +	              NewAEEventHandlerUPP(HandleReopenMessage), 0, false);
  13.117 +#if 0
  13.118 +	// Left as an example of a wild card match.
  13.119 +	err = AEInstallEventHandler(kCoreEventClass, typeWildCard, 
  13.120 +	              NewAEEventHandlerUPP(HandleWildMessage), 0, false);
  13.121 +#endif
  13.122 +}
  13.123 +
  13.124 +void
  13.125 +check_apple_events()
  13.126 +{
  13.127 +	RgnHandle       cursorRgn = NULL; 
  13.128 +	Boolean         gotEvent=TRUE; 
  13.129 +	EventRecord     event; 
  13.130 +
  13.131 +	while (gotEvent) { 
  13.132 +		gotEvent = WaitNextEvent(everyEvent, &event, 0L/*timeout*/, cursorRgn); 
  13.133 +		if (gotEvent) { 
  13.134 +			HandleEvent(&event); 
  13.135 +		} 
  13.136 +	}
  13.137 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/src/test.cpp	Thu May 22 07:16:55 2014 +0200
    14.3 @@ -0,0 +1,826 @@
    14.4 +/*******************************************************
    14.5 + Demo Program for HIDAPI
    14.6 +
    14.7 + Alan Ott
    14.8 + Signal 11 Software
    14.9 +
   14.10 + 2010-07-20
   14.11 +
   14.12 + Copyright 2010, All Rights Reserved
   14.13 +
   14.14 + This contents of this file may be used by anyone
   14.15 + for any reason without any conditions and may be
   14.16 + used as a starting point for your own applications
   14.17 + which use HIDAPI.
   14.18 +********************************************************/
   14.19 +
   14.20 +#include "MainWindow.h"
   14.21 +
   14.22 +
   14.23 +// FOX 1.7 changes the timeouts to all be nanoseconds.
   14.24 +// Fox 1.6 had all timeouts as milliseconds.
   14.25 +#if (FOX_MINOR >= 7)
   14.26 +	const int timeout_scalar = 1000*1000;
   14.27 +#else
   14.28 +	const int timeout_scalar = 1;
   14.29 +#endif
   14.30 +
   14.31 +
   14.32 +FXDEFMAP(MainWindow) MainWindowMap [] = {
   14.33 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_CONNECT, MainWindow::onConnect ),
   14.34 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_DISCONNECT, MainWindow::onDisconnect ),
   14.35 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_RESCAN, MainWindow::onRescan ),
   14.36 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_SEND_OUTPUT_REPORT, MainWindow::onSendOutputReport ),
   14.37 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_SEND_FEATURE_REPORT, MainWindow::onSendFeatureReport ),
   14.38 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_GET_FEATURE_REPORT, MainWindow::onGetFeatureReport ),
   14.39 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_CLEAR, MainWindow::onClear ),
   14.40 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_CLEAR_DISPLAY, MainWindow::onFutabaClearDisplay ),
   14.41 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_DIMMING, MainWindow::onFutabaDimming ),
   14.42 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_DISPLAY_DATA_INPUT, MainWindow::onFutabaDisplayDataInput ),
   14.43 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_READ_ID, MainWindow::onFutabaReadId ),
   14.44 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_READ_FIRMWARE_REVISION, MainWindow::onFutabaReadFirmwareRevision ),
   14.45 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_POWER_SUPPLY_MONITOR, MainWindow::onFutabaPowerSupplyMonitor ),
   14.46 +    FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_SET_PIXEL, MainWindow::onFutabaSetPixel ),
   14.47 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_RESET_PIXEL, MainWindow::onFutabaResetPixel ),
   14.48 +    FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_SET_ALL_PIXELS, MainWindow::onFutabaSetAllPixels ),
   14.49 +    FXMAPFUNC(SEL_COMMAND, MainWindow::ID_SELECT_FONT, MainWindow::onSelectFont ),
   14.50 +	FXMAPFUNC(SEL_TIMEOUT, MainWindow::ID_TIMER, MainWindow::onTimeout ),
   14.51 +	FXMAPFUNC(SEL_TIMEOUT, MainWindow::ID_MAC_TIMER, MainWindow::onMacTimeout ),
   14.52 +};
   14.53 +
   14.54 +FXIMPLEMENT(MainWindow, FXMainWindow, MainWindowMap, ARRAYNUMBER(MainWindowMap));
   14.55 +
   14.56 +MainWindow::MainWindow(FXApp *app)
   14.57 +	: FXMainWindow(app, "HIDAPI Test Application", NULL, NULL, DECOR_ALL, 200,100, 600,900),
   14.58 +    iCurrentFont(NULL),
   14.59 +    iFontImage(NULL)
   14.60 +{
   14.61 +	iDimming=0x35;
   14.62 +	devices = NULL;
   14.63 +	connected_device = NULL;
   14.64 +
   14.65 +	FXVerticalFrame *vf = new FXVerticalFrame(this, LAYOUT_FILL_Y|LAYOUT_FILL_X);
   14.66 +
   14.67 +	FXLabel *label = new FXLabel(vf, "HIDAPI Test Tool");
   14.68 +	title_font = new FXFont(getApp(), "Arial", 14, FXFont::Bold);
   14.69 +	label->setFont(title_font);
   14.70 +
   14.71 +	new FXLabel(vf,
   14.72 +		"Select a device and press Connect.", NULL, JUSTIFY_LEFT);
   14.73 +	new FXLabel(vf,
   14.74 +		"Output data bytes can be entered in the Output section, \n"
   14.75 +		"separated by space, comma or brackets. Data starting with 0x\n"
   14.76 +		"is treated as hex. Data beginning with a 0 is treated as \n"
   14.77 +		"octal. All other data is treated as decimal.", NULL, JUSTIFY_LEFT);
   14.78 +	new FXLabel(vf,
   14.79 +		"Data received from the device appears in the Input section.",
   14.80 +		NULL, JUSTIFY_LEFT);
   14.81 +	new FXLabel(vf,
   14.82 +		"Optionally, a report length may be specified. Extra bytes are\n"
   14.83 +		"padded with zeros. If no length is specified, the length is \n"
   14.84 +		"inferred from the data.",
   14.85 +		NULL, JUSTIFY_LEFT);
   14.86 +	new FXLabel(vf, "");
   14.87 +
   14.88 +	// Device List and Connect/Disconnect buttons
   14.89 +	FXHorizontalFrame *hf = new FXHorizontalFrame(vf, LAYOUT_FILL_X);
   14.90 +	//device_list = new FXList(new FXHorizontalFrame(hf,FRAME_SUNKEN|FRAME_THICK, 0,0,0,0, 0,0,0,0), NULL, 0, LISTBOX_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 0,0,300,200);
   14.91 +	device_list = new FXList(new FXHorizontalFrame(hf,FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0), NULL, 0, LISTBOX_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,300,200);
   14.92 +	FXVerticalFrame *buttonVF = new FXVerticalFrame(hf);
   14.93 +	connect_button = new FXButton(buttonVF, "Connect", NULL, this, ID_CONNECT, BUTTON_NORMAL|LAYOUT_FILL_X);
   14.94 +	disconnect_button = new FXButton(buttonVF, "Disconnect", NULL, this, ID_DISCONNECT, BUTTON_NORMAL|LAYOUT_FILL_X);
   14.95 +	disconnect_button->disable();
   14.96 +	rescan_button = new FXButton(buttonVF, "Re-Scan devices", NULL, this, ID_RESCAN, BUTTON_NORMAL|LAYOUT_FILL_X);
   14.97 +	new FXHorizontalFrame(buttonVF, 0, 0,0,0,0, 0,0,50,0);
   14.98 +
   14.99 +	connected_label = new FXLabel(vf, "Disconnected");
  14.100 +
  14.101 +    //Font group
  14.102 +    new FXHorizontalFrame(vf);
  14.103 +    FXGroupBox *gb = new FXGroupBox(vf, "Fonts", FRAME_GROOVE|LAYOUT_FILL_X);
  14.104 +    FXMatrix *matrix = new FXMatrix(gb, 3, MATRIX_BY_COLUMNS|LAYOUT_FILL_X);
  14.105 +    iButtonSelectFont = new FXButton(matrix, "Select Font", NULL, this, ID_SELECT_FONT, BUTTON_NORMAL|LAYOUT_FILL_X);
  14.106 +
  14.107 +	//Futaba VFD commands
  14.108 +	new FXHorizontalFrame(vf);
  14.109 +	gb = new FXGroupBox(vf, "Futaba GP1212A01A", FRAME_GROOVE|LAYOUT_FILL_X);
  14.110 +	matrix = new FXMatrix(gb, 3, MATRIX_BY_COLUMNS|LAYOUT_FILL_X);
  14.111 +	iButtonClearDisplay = new FXButton(matrix, "Clear Display", NULL, this, ID_FUTABA_CLEAR_DISPLAY, BUTTON_NORMAL|LAYOUT_FILL_X);
  14.112 +	iButtonDimming = new FXButton(matrix, "Dimming", NULL, this, ID_FUTABA_DIMMING, BUTTON_NORMAL|LAYOUT_FILL_X);
  14.113 +	iButtonDisplayDataInput = new FXButton(matrix, "Display Data Input", NULL, this, ID_FUTABA_DISPLAY_DATA_INPUT, BUTTON_NORMAL|LAYOUT_FILL_X);
  14.114 +	iButtonReadId = new FXButton(matrix, "Read Id", NULL, this, ID_FUTABA_READ_ID, BUTTON_NORMAL|LAYOUT_FILL_X);
  14.115 +	iButtonReadFirmwareRevision =  new FXButton(matrix, "Read Firmware Revision", NULL, this, ID_FUTABA_READ_FIRMWARE_REVISION, BUTTON_NORMAL|LAYOUT_FILL_X);
  14.116 +	iButtonPowerSupplyMonitor = new FXButton(matrix, "Power Supply Monitor", NULL, this, ID_FUTABA_POWER_SUPPLY_MONITOR, BUTTON_NORMAL|LAYOUT_FILL_X);
  14.117 +    new FXLabel(matrix, "X",NULL,LABEL_NORMAL|LAYOUT_FILL_X);
  14.118 +    new FXLabel(matrix, "Y",NULL,LABEL_NORMAL|LAYOUT_FILL_X);
  14.119 +    new FXLabel(matrix, "",NULL,LABEL_NORMAL|LAYOUT_FILL_X);
  14.120 +    iTextFieldX = new FXTextField(matrix, 3, NULL, 0, TEXTFIELD_NORMAL|TEXTFIELD_INTEGER|LAYOUT_FILL_X);
  14.121 +    iTextFieldY = new FXTextField(matrix, 3, NULL, 0, TEXTFIELD_NORMAL|TEXTFIELD_INTEGER|LAYOUT_FILL_X);
  14.122 +    iButtonSetPixel = new FXButton(matrix, "Set Pixel", NULL, this, ID_FUTABA_SET_PIXEL, BUTTON_NORMAL|LAYOUT_FILL_X);
  14.123 +	iButtonResetPixel = new FXButton(matrix, "Reset Pixel", NULL, this, ID_FUTABA_RESET_PIXEL, BUTTON_NORMAL|LAYOUT_FILL_X);
  14.124 +    //
  14.125 +    iButtonSetAllPixels = new FXButton(matrix, "Set All Pixels", NULL, this, ID_FUTABA_SET_ALL_PIXELS, BUTTON_NORMAL|LAYOUT_FILL_X);
  14.126 +    //
  14.127 +
  14.128 +	//
  14.129 +	iButtonClearDisplay->disable();
  14.130 +	iButtonDimming->disable();
  14.131 +	iButtonDisplayDataInput->disable();
  14.132 +	iButtonReadId->disable();
  14.133 +	iButtonReadFirmwareRevision->disable();
  14.134 +	iButtonPowerSupplyMonitor->disable();
  14.135 +    iTextFieldX->disable();
  14.136 +    iTextFieldY->disable();
  14.137 +    iButtonSetPixel->disable();
  14.138 +	iButtonResetPixel->disable();
  14.139 +    iButtonSetAllPixels->disable();
  14.140 +	//
  14.141 +
  14.142 +	// Output Group Box
  14.143 +	new FXHorizontalFrame(vf);
  14.144 +	gb = new FXGroupBox(vf, "Output", FRAME_GROOVE|LAYOUT_FILL_X);
  14.145 +	matrix = new FXMatrix(gb, 3, MATRIX_BY_COLUMNS|LAYOUT_FILL_X);
  14.146 +	new FXLabel(matrix, "Data");
  14.147 +	new FXLabel(matrix, "Length");
  14.148 +	new FXLabel(matrix, "");
  14.149 +
  14.150 +	//hf = new FXHorizontalFrame(gb, LAYOUT_FILL_X);
  14.151 +	output_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  14.152 +	output_text->setText("1 0x81 0");
  14.153 +	output_len = new FXTextField(matrix, 5, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  14.154 +	output_button = new FXButton(matrix, "Send Output Report", NULL, this, ID_SEND_OUTPUT_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
  14.155 +	output_button->disable();
  14.156 +	//new FXHorizontalFrame(matrix, LAYOUT_FILL_X);
  14.157 +
  14.158 +	//hf = new FXHorizontalFrame(gb, LAYOUT_FILL_X);
  14.159 +	feature_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  14.160 +	feature_len = new FXTextField(matrix, 5, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  14.161 +	feature_button = new FXButton(matrix, "Send Feature Report", NULL, this, ID_SEND_FEATURE_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
  14.162 +	feature_button->disable();
  14.163 +
  14.164 +	get_feature_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  14.165 +	new FXWindow(matrix);
  14.166 +	get_feature_button = new FXButton(matrix, "Get Feature Report", NULL, this, ID_GET_FEATURE_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
  14.167 +	get_feature_button->disable();
  14.168 +
  14.169 +
  14.170 +	// Input Group Box
  14.171 +	gb = new FXGroupBox(vf, "Input", FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y);
  14.172 +	FXVerticalFrame *innerVF = new FXVerticalFrame(gb, LAYOUT_FILL_X|LAYOUT_FILL_Y);
  14.173 +	input_text = new FXText(new FXHorizontalFrame(innerVF,LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, 0,0,0,0, 0,0,0,0), NULL, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y);
  14.174 +	input_text->setEditable(false);
  14.175 +	new FXButton(innerVF, "Clear", NULL, this, ID_CLEAR, BUTTON_NORMAL|LAYOUT_RIGHT);
  14.176 +
  14.177 +
  14.178 +}
  14.179 +
  14.180 +MainWindow::~MainWindow()
  14.181 +{
  14.182 +    delete iCurrentFont;
  14.183 +    iCurrentFont = NULL;
  14.184 +
  14.185 +    delete iFontImage;
  14.186 +    iFontImage = NULL;
  14.187 +
  14.188 +	if (connected_device)
  14.189 +		hid_close(connected_device);
  14.190 +	hid_exit();
  14.191 +	delete title_font;
  14.192 +}
  14.193 +
  14.194 +void
  14.195 +MainWindow::create()
  14.196 +{
  14.197 +	FXMainWindow::create();
  14.198 +	show();
  14.199 +
  14.200 +	onRescan(NULL, 0, NULL);
  14.201 +
  14.202 +	//Just testing our new VFD class
  14.203 +	iVfd01.Open();
  14.204 +	iVfd01.SetAllPixels(true);
  14.205 +	iVfd01.Close();
  14.206 +
  14.207 +
  14.208 +#ifdef __APPLE__
  14.209 +	init_apple_message_system();
  14.210 +#endif
  14.211 +
  14.212 +	getApp()->addTimeout(this, ID_MAC_TIMER,
  14.213 +		50 * timeout_scalar /*50ms*/);
  14.214 +}
  14.215 +
  14.216 +long
  14.217 +MainWindow::onConnect(FXObject *sender, FXSelector sel, void *ptr)
  14.218 +{
  14.219 +	if (connected_device != NULL)
  14.220 +		return 1;
  14.221 +
  14.222 +	FXint cur_item = device_list->getCurrentItem();
  14.223 +	if (cur_item < 0)
  14.224 +		return -1;
  14.225 +	FXListItem *item = device_list->getItem(cur_item);
  14.226 +	if (!item)
  14.227 +		return -1;
  14.228 +	struct hid_device_info *device_info = (struct hid_device_info*) item->getData();
  14.229 +	if (!device_info)
  14.230 +		return -1;
  14.231 +
  14.232 +	connected_device =  hid_open_path(device_info->path);
  14.233 +
  14.234 +	if (!connected_device) {
  14.235 +		FXMessageBox::error(this, MBOX_OK, "Device Error", "Unable To Connect to Device");
  14.236 +		return -1;
  14.237 +	}
  14.238 +
  14.239 +	hid_set_nonblocking(connected_device, 1);
  14.240 +
  14.241 +	getApp()->addTimeout(this, ID_TIMER,
  14.242 +		5 * timeout_scalar /*5ms*/);
  14.243 +
  14.244 +	FXString s;
  14.245 +	s.format("Connected to: %04hx:%04hx -", device_info->vendor_id, device_info->product_id);
  14.246 +	s += FXString(" ") + device_info->manufacturer_string;
  14.247 +	s += FXString(" ") + device_info->product_string;
  14.248 +	connected_label->setText(s);
  14.249 +	output_button->enable();
  14.250 +	feature_button->enable();
  14.251 +	get_feature_button->enable();
  14.252 +	connect_button->disable();
  14.253 +	disconnect_button->enable();
  14.254 +	input_text->setText("");
  14.255 +	//
  14.256 +	iButtonClearDisplay->enable();
  14.257 +	iButtonDimming->enable();
  14.258 +	iButtonDisplayDataInput->enable();
  14.259 +	iButtonReadId->enable();
  14.260 +	iButtonReadFirmwareRevision->enable();
  14.261 +	iButtonPowerSupplyMonitor->enable();
  14.262 +    iTextFieldX->enable();
  14.263 +    iTextFieldY->enable();
  14.264 +    iButtonSetPixel->enable();
  14.265 +	iButtonResetPixel->enable();
  14.266 +    iButtonSetAllPixels->enable();
  14.267 +
  14.268 +	//
  14.269 +	iOutputReportBuffer=new unsigned char[KFutabaMaxHidReportSize]; //TODO: use connected_device->output_report_length
  14.270 +
  14.271 +	return 1;
  14.272 +}
  14.273 +
  14.274 +long
  14.275 +MainWindow::onDisconnect(FXObject *sender, FXSelector sel, void *ptr)
  14.276 +{
  14.277 +	hid_close(connected_device);
  14.278 +	connected_device = NULL;
  14.279 +	connected_label->setText("Disconnected");
  14.280 +	output_button->disable();
  14.281 +	feature_button->disable();
  14.282 +	get_feature_button->disable();
  14.283 +	connect_button->enable();
  14.284 +	disconnect_button->disable();
  14.285 +
  14.286 +	getApp()->removeTimeout(this, ID_TIMER);
  14.287 +
  14.288 +	//
  14.289 +	iButtonClearDisplay->disable();
  14.290 +	iButtonDimming->disable();
  14.291 +	iButtonDisplayDataInput->disable();
  14.292 +	iButtonReadId->disable();
  14.293 +	iButtonReadFirmwareRevision->disable();
  14.294 +	iButtonPowerSupplyMonitor->disable();
  14.295 +    iTextFieldX->disable();
  14.296 +    iTextFieldY->disable();
  14.297 +    iButtonSetPixel->disable();
  14.298 +	iButtonResetPixel->disable();
  14.299 +    iButtonSetAllPixels->disable();
  14.300 +	//
  14.301 +
  14.302 +
  14.303 +	delete iOutputReportBuffer;
  14.304 +	iOutputReportBuffer=NULL;
  14.305 +
  14.306 +	return 1;
  14.307 +}
  14.308 +
  14.309 +long
  14.310 +MainWindow::onRescan(FXObject *sender, FXSelector sel, void *ptr)
  14.311 +{
  14.312 +	struct hid_device_info *cur_dev;
  14.313 +
  14.314 +	device_list->clearItems();
  14.315 +
  14.316 +	// List the Devices
  14.317 +	hid_free_enumeration(devices);
  14.318 +	devices = hid_enumerate(0x0, 0x0);
  14.319 +	cur_dev = devices;
  14.320 +	while (cur_dev) {
  14.321 +		// Add it to the List Box only if it is a Futaba device
  14.322 +		if (cur_dev->vendor_id == KFutabaVendorId)
  14.323 +			{
  14.324 +			FXString s;
  14.325 +			FXString usage_str;
  14.326 +			s.format("%04hx:%04hx -", cur_dev->vendor_id, cur_dev->product_id);
  14.327 +			s += FXString(" ") + cur_dev->manufacturer_string;
  14.328 +			s += FXString(" ") + cur_dev->product_string;
  14.329 +			usage_str.format(" (usage: %04hx:%04hx) ", cur_dev->usage_page, cur_dev->usage);
  14.330 +			s += usage_str;
  14.331 +			FXListItem *li = new FXListItem(s, NULL, cur_dev);
  14.332 +			device_list->appendItem(li);
  14.333 +			}
  14.334 +
  14.335 +		cur_dev = cur_dev->next;
  14.336 +	}
  14.337 +
  14.338 +	if (device_list->getNumItems() == 0)
  14.339 +		device_list->appendItem("*** No Devices Connected ***");
  14.340 +	else {
  14.341 +		device_list->selectItem(0);
  14.342 +	}
  14.343 +
  14.344 +	return 1;
  14.345 +}
  14.346 +
  14.347 +size_t
  14.348 +MainWindow::getDataFromTextField(FXTextField *tf, char *buf, size_t len)
  14.349 +{
  14.350 +	const char *delim = " ,{}\t\r\n";
  14.351 +	FXString data = tf->getText();
  14.352 +	const FXchar *d = data.text();
  14.353 +	size_t i = 0;
  14.354 +
  14.355 +	// Copy the string from the GUI.
  14.356 +	size_t sz = strlen(d);
  14.357 +	char *str = (char*) malloc(sz+1);
  14.358 +	strcpy(str, d);
  14.359 +
  14.360 +	// For each token in the string, parse and store in buf[].
  14.361 +	char *token = strtok(str, delim);
  14.362 +	while (token) {
  14.363 +		char *endptr;
  14.364 +		long int val = strtol(token, &endptr, 0);
  14.365 +		buf[i++] = val;
  14.366 +		token = strtok(NULL, delim);
  14.367 +	}
  14.368 +
  14.369 +	free(str);
  14.370 +	return i;
  14.371 +}
  14.372 +
  14.373 +/* getLengthFromTextField()
  14.374 +   Returns length:
  14.375 +	 0: empty text field
  14.376 +	>0: valid length
  14.377 +	-1: invalid length */
  14.378 +int
  14.379 +MainWindow::getLengthFromTextField(FXTextField *tf)
  14.380 +{
  14.381 +	long int len;
  14.382 +	FXString str = tf->getText();
  14.383 +	size_t sz = str.length();
  14.384 +
  14.385 +	if (sz > 0) {
  14.386 +		char *endptr;
  14.387 +		len = strtol(str.text(), &endptr, 0);
  14.388 +		if (endptr != str.text() && *endptr == '\0') {
  14.389 +			if (len <= 0) {
  14.390 +				FXMessageBox::error(this, MBOX_OK, "Invalid length", "Enter a length greater than zero.");
  14.391 +				return -1;
  14.392 +			}
  14.393 +			return len;
  14.394 +		}
  14.395 +		else
  14.396 +			return -1;
  14.397 +	}
  14.398 +
  14.399 +	return 0;
  14.400 +}
  14.401 +
  14.402 +long
  14.403 +MainWindow::onSendOutputReport(FXObject *sender, FXSelector sel, void *ptr)
  14.404 +{
  14.405 +	char buf[256];
  14.406 +	size_t data_len, len;
  14.407 +	int textfield_len;
  14.408 +
  14.409 +	memset(buf, 0x0, sizeof(buf));
  14.410 +	textfield_len = getLengthFromTextField(output_len);
  14.411 +	data_len = getDataFromTextField(output_text, buf, sizeof(buf));
  14.412 +
  14.413 +	if (textfield_len < 0) {
  14.414 +		FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is invalid. Please enter a number in hex, octal, or decimal.");
  14.415 +		return 1;
  14.416 +	}
  14.417 +
  14.418 +	if (textfield_len > sizeof(buf)) {
  14.419 +		FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is too long.");
  14.420 +		return 1;
  14.421 +	}
  14.422 +
  14.423 +	len = (textfield_len)? textfield_len: data_len;
  14.424 +
  14.425 +	int res = hid_write(connected_device, (const unsigned char*)buf, len);
  14.426 +	if (res < 0) {
  14.427 +		FXMessageBox::error(this, MBOX_OK, "Error Writing", "Could not write to device. Error reported was: %ls", hid_error(connected_device));
  14.428 +	}
  14.429 +
  14.430 +	return 1;
  14.431 +}
  14.432 +
  14.433 +long
  14.434 +MainWindow::onSendFeatureReport(FXObject *sender, FXSelector sel, void *ptr)
  14.435 +{
  14.436 +	char buf[256];
  14.437 +	size_t data_len, len;
  14.438 +	int textfield_len;
  14.439 +
  14.440 +	memset(buf, 0x0, sizeof(buf));
  14.441 +	textfield_len = getLengthFromTextField(feature_len);
  14.442 +	data_len = getDataFromTextField(feature_text, buf, sizeof(buf));
  14.443 +
  14.444 +	if (textfield_len < 0) {
  14.445 +		FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is invalid. Please enter a number in hex, octal, or decimal.");
  14.446 +		return 1;
  14.447 +	}
  14.448 +
  14.449 +	if (textfield_len > sizeof(buf)) {
  14.450 +		FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is too long.");
  14.451 +		return 1;
  14.452 +	}
  14.453 +
  14.454 +	len = (textfield_len)? textfield_len: data_len;
  14.455 +
  14.456 +	int res = hid_send_feature_report(connected_device, (const unsigned char*)buf, len);
  14.457 +	if (res < 0) {
  14.458 +		FXMessageBox::error(this, MBOX_OK, "Error Writing", "Could not send feature report to device. Error reported was: %ls", hid_error(connected_device));
  14.459 +	}
  14.460 +
  14.461 +	return 1;
  14.462 +}
  14.463 +
  14.464 +long
  14.465 +MainWindow::onGetFeatureReport(FXObject *sender, FXSelector sel, void *ptr)
  14.466 +{
  14.467 +	char buf[256];
  14.468 +	size_t len;
  14.469 +
  14.470 +	memset(buf, 0x0, sizeof(buf));
  14.471 +	len = getDataFromTextField(get_feature_text, buf, sizeof(buf));
  14.472 +
  14.473 +	if (len != 1) {
  14.474 +		FXMessageBox::error(this, MBOX_OK, "Too many numbers", "Enter only a single report number in the text field");
  14.475 +	}
  14.476 +
  14.477 +	int res = hid_get_feature_report(connected_device, (unsigned char*)buf, sizeof(buf));
  14.478 +	if (res < 0) {
  14.479 +		FXMessageBox::error(this, MBOX_OK, "Error Getting Report", "Could not get feature report from device. Error reported was: %ls", hid_error(connected_device));
  14.480 +	}
  14.481 +
  14.482 +	if (res > 0) {
  14.483 +		FXString s;
  14.484 +		s.format("Returned Feature Report. %d bytes:\n", res);
  14.485 +		for (int i = 0; i < res; i++) {
  14.486 +			FXString t;
  14.487 +			t.format("%02hhx ", buf[i]);
  14.488 +			s += t;
  14.489 +			if ((i+1) % 4 == 0)
  14.490 +				s += " ";
  14.491 +			if ((i+1) % 16 == 0)
  14.492 +				s += "\n";
  14.493 +		}
  14.494 +		s += "\n";
  14.495 +		input_text->appendText(s);
  14.496 +		input_text->setBottomLine(INT_MAX);
  14.497 +	}
  14.498 +
  14.499 +	return 1;
  14.500 +}
  14.501 +
  14.502 +long
  14.503 +MainWindow::onClear(FXObject *sender, FXSelector sel, void *ptr)
  14.504 +{
  14.505 +	input_text->setText("");
  14.506 +	return 1;
  14.507 +}
  14.508 +
  14.509 +
  14.510 +long
  14.511 +MainWindow::onFutabaClearDisplay(FXObject *sender, FXSelector sel, void *ptr)
  14.512 +{
  14.513 +	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  14.514 +	iOutputReportBuffer[0]=0x00; //Report ID
  14.515 +	iOutputReportBuffer[1]=0x04; //Report length
  14.516 +	iOutputReportBuffer[2]=0x1B; //
  14.517 +	iOutputReportBuffer[3]=0x5B; //
  14.518 +	iOutputReportBuffer[4]=0x32; //
  14.519 +	iOutputReportBuffer[5]=0x4A; //
  14.520 +	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  14.521 +
  14.522 +	return 1;
  14.523 +}
  14.524 +
  14.525 +long
  14.526 +MainWindow::onFutabaDimming(FXObject *sender, FXSelector sel, void *ptr)
  14.527 +{
  14.528 +	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  14.529 +	iOutputReportBuffer[0]=0x00; //Report ID
  14.530 +	iOutputReportBuffer[1]=0x06; //Report length
  14.531 +	iOutputReportBuffer[2]=0x1B; //
  14.532 +	iOutputReportBuffer[3]=0x5C; //
  14.533 +	iOutputReportBuffer[4]=0x3F; //
  14.534 +	iOutputReportBuffer[5]=0x4C; //
  14.535 +	iOutputReportBuffer[6]=0x44; //
  14.536 +	iDimming = (iDimming==0x35?0x30:++iDimming);
  14.537 +	iOutputReportBuffer[7]=iDimming;
  14.538 +	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  14.539 +
  14.540 +	return 1;
  14.541 +}
  14.542 +
  14.543 +long
  14.544 +MainWindow::onFutabaDisplayDataInput(FXObject *sender, FXSelector sel, void *ptr)
  14.545 +{
  14.546 +	//@1B 5B F0 00 00 07 00 01 FF
  14.547 +
  14.548 +	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  14.549 +	iOutputReportBuffer[0]=0x00; //Report ID
  14.550 +	iOutputReportBuffer[1]=0x09; //Report length
  14.551 +	iOutputReportBuffer[2]=0x1B; //
  14.552 +	iOutputReportBuffer[3]=0x5B; //
  14.553 +	iOutputReportBuffer[4]=0xF0; //
  14.554 +	iOutputReportBuffer[5]=0x00; //X
  14.555 +	iOutputReportBuffer[6]=0x00; //Y
  14.556 +	iOutputReportBuffer[7]=0x07; //
  14.557 +	iOutputReportBuffer[8]=0x00; //
  14.558 +	iOutputReportBuffer[9]=0x01; //
  14.559 +	iOutputReportBuffer[10]=0xFF; //
  14.560 +	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  14.561 +
  14.562 +
  14.563 +	return 1;
  14.564 +}
  14.565 +
  14.566 +
  14.567 +
  14.568 +
  14.569 +/**
  14.570 +Set a single pixel to the specified value.
  14.571 +@param X coordinate of our pixel.
  14.572 +@param Y coordinate of our pixel.
  14.573 +@param The LSB defines our pixel value.
  14.574 +*/
  14.575 +void MainWindow::SetPixel(int aX, int aY, unsigned char aValue)
  14.576 +	{
  14.577 +	//Just specify a one pixel block
  14.578 +	SetPixelBlock(aX,aY,0x00,0x01,aValue);
  14.579 +	}
  14.580 +
  14.581 +/**
  14.582 +Set the defined pixel block to the given value.
  14.583 +@param X coordinate of our pixel block starting point.
  14.584 +@param Y coordinate of our pixel block starting point.
  14.585 +@param The height of our pixel block.
  14.586 +@param The size of our pixel data. Number of pixels divided by 8.
  14.587 +@param The value set to 8 pixels.
  14.588 +*/
  14.589 +void MainWindow::SetPixelBlock(int aX, int aY, int aHeight, int aSize, unsigned char aValue)
  14.590 +	{
  14.591 +	//Size must be 63 or below
  14.592 +	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  14.593 +	iOutputReportBuffer[0]=0x00; //Report ID
  14.594 +	iOutputReportBuffer[1]=0x08+aSize; //Report length
  14.595 +	iOutputReportBuffer[2]=0x1B; //
  14.596 +	iOutputReportBuffer[3]=0x5B; //
  14.597 +	iOutputReportBuffer[4]=0xF0; //
  14.598 +	iOutputReportBuffer[5]=aX; //X
  14.599 +	iOutputReportBuffer[6]=aY; //Y
  14.600 +	iOutputReportBuffer[7]=aHeight; //Y length before return. Though outside the specs, setting this to zero apparently allows us to modify a single pixel without touching any other.
  14.601 +	iOutputReportBuffer[8]=0x00; //Size of pixel data in bytes (MSB)
  14.602 +	iOutputReportBuffer[9]=aSize; //Size of pixel data in bytes (LSB)
  14.603 +	memset(iOutputReportBuffer+10, aValue, KFutabaMaxHidReportSize);
  14.604 +	//iOutputReportBuffer[10]=aValue; //Pixel data
  14.605 +	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  14.606 +	}
  14.607 +
  14.608 +/**
  14.609 +Send an output report to a Futaba VFD device.
  14.610 +*/
  14.611 +/*
  14.612 +void MainWindow::SendFutabaOutputReport(unsigned char* aReportData, unsigned char aSize)
  14.613 +    {
  14.614 +    //
  14.615 +    memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  14.616 +    iOutputReportBuffer[0]=0x00; //Report ID is always null
  14.617 +    iOutputReportBuffer[1]=0x08+aSize; //Report length
  14.618 +    iOutputReportBuffer[2]=0x1B; //
  14.619 +    iOutputReportBuffer[3]=0x5B; //
  14.620 +    iOutputReportBuffer[4]=0xF0; //
  14.621 +    iOutputReportBuffer[5]=aX; //X
  14.622 +    iOutputReportBuffer[6]=aY; //Y
  14.623 +    iOutputReportBuffer[7]=aHeight; //Y length before return. Though outside the specs, setting this to zero apparently allows us to modify a single pixel without touching any other.
  14.624 +    iOutputReportBuffer[8]=0x00; //Size of pixel data in bytes (MSB)
  14.625 +    iOutputReportBuffer[9]=aSize; //Size of pixel data in bytes (LSB)
  14.626 +    memset(iOutputReportBuffer+10, aValue, KFutabaMaxHidReportSize);
  14.627 +    //iOutputReportBuffer[10]=aValue; //Pixel data
  14.628 +    int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  14.629 +    }
  14.630 +*/
  14.631 +
  14.632 +
  14.633 +/**
  14.634 +*/
  14.635 +long MainWindow::onFutabaSetPixel(FXObject *sender, FXSelector sel, void *ptr)
  14.636 +{
  14.637 +	int x=0;
  14.638 +	int y=0;
  14.639 +	iTextFieldX->getText().scan("%d",&x);
  14.640 +	iTextFieldY->getText().scan("%d",&y);
  14.641 +    SetPixel(x,y,0x01);
  14.642 +	return 1;
  14.643 +}
  14.644 +
  14.645 +/**
  14.646 +*/
  14.647 +long MainWindow::onFutabaResetPixel(FXObject *sender, FXSelector sel, void *ptr)
  14.648 +{
  14.649 +	int x=0;
  14.650 +	int y=0;
  14.651 +	iTextFieldX->getText().scan("%d",&x);
  14.652 +	iTextFieldY->getText().scan("%d",&y);
  14.653 +    SetPixel(x,y,0x00);
  14.654 +    return 1;
  14.655 +}
  14.656 +
  14.657 +long MainWindow::onFutabaSetAllPixels(FXObject *sender, FXSelector sel, void *ptr)
  14.658 +	{
  14.659 +	//One pixel at a time
  14.660 +	/*
  14.661 +	for (int i=0;i<256;i++)
  14.662 +		{
  14.663 +		for (int j=0;j<64;j++)
  14.664 +			{
  14.665 +			SetPixel(i,j,0x01);
  14.666 +			}
  14.667 +		}
  14.668 +	*/
  14.669 +	//16x16=256 pixels at a time goes much faster
  14.670 +	for (int i=0;i<256;i+=16)
  14.671 +		{
  14.672 +		for (int j=0;j<64;j+=16)
  14.673 +			{
  14.674 +			SetPixelBlock(i,j,15,32,0xFF);
  14.675 +			//FXThread::sleep(1000000000);
  14.676 +			}
  14.677 +		}
  14.678 +
  14.679 +    return 1;
  14.680 +	}
  14.681 +
  14.682 +long
  14.683 +MainWindow::onFutabaReadId(FXObject *sender, FXSelector sel, void *ptr)
  14.684 +{
  14.685 +	//1BH,5BH,63H,49H,44H
  14.686 +	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  14.687 +	iOutputReportBuffer[0]=0x00; //Report ID
  14.688 +	iOutputReportBuffer[1]=0x05; //Report length
  14.689 +	iOutputReportBuffer[2]=0x1B; //
  14.690 +	iOutputReportBuffer[3]=0x5B; //
  14.691 +	iOutputReportBuffer[4]=0x63; //
  14.692 +	iOutputReportBuffer[5]=0x49; //
  14.693 +	iOutputReportBuffer[6]=0x44; //
  14.694 +	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  14.695 +
  14.696 +	return 1;
  14.697 +}
  14.698 +
  14.699 +long
  14.700 +MainWindow::onFutabaReadFirmwareRevision(FXObject *sender, FXSelector sel, void *ptr)
  14.701 +{
  14.702 +	//1BH,5BH,63H,46H,52H
  14.703 +	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  14.704 +	iOutputReportBuffer[0]=0x00; //Report ID
  14.705 +	iOutputReportBuffer[1]=0x05; //Report length
  14.706 +	iOutputReportBuffer[2]=0x1B; //
  14.707 +	iOutputReportBuffer[3]=0x5B; //
  14.708 +	iOutputReportBuffer[4]=0x63; //
  14.709 +	iOutputReportBuffer[5]=0x46; //
  14.710 +	iOutputReportBuffer[6]=0x52; //
  14.711 +	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  14.712 +
  14.713 +	return 1;
  14.714 +}
  14.715 +
  14.716 +long
  14.717 +MainWindow::onFutabaPowerSupplyMonitor(FXObject *sender, FXSelector sel, void *ptr)
  14.718 +{
  14.719 +	//1BH,5BH,63H,50H,4DH
  14.720 +	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  14.721 +	iOutputReportBuffer[0]=0x00; //Report ID
  14.722 +	iOutputReportBuffer[1]=0x05; //Report length
  14.723 +	iOutputReportBuffer[2]=0x1B; //
  14.724 +	iOutputReportBuffer[3]=0x5B; //
  14.725 +	iOutputReportBuffer[4]=0x63; //
  14.726 +	iOutputReportBuffer[5]=0x50; //
  14.727 +	iOutputReportBuffer[6]=0x4D; //
  14.728 +	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  14.729 +
  14.730 +	return 1;
  14.731 +}
  14.732 +
  14.733 +
  14.734 +
  14.735 +long
  14.736 +MainWindow::onTimeout(FXObject *sender, FXSelector sel, void *ptr)
  14.737 +{
  14.738 +	unsigned char buf[256];
  14.739 +	int res = hid_read(connected_device, buf, sizeof(buf));
  14.740 +
  14.741 +	if (res > 0) {
  14.742 +		FXString s;
  14.743 +		s.format("Received %d bytes:\n", res);
  14.744 +		for (int i = 0; i < res; i++) {
  14.745 +			FXString t;
  14.746 +			t.format("%02hhx ", buf[i]);
  14.747 +			s += t;
  14.748 +			if ((i+1) % 4 == 0)
  14.749 +				s += " ";
  14.750 +			if ((i+1) % 16 == 0)
  14.751 +				s += "\n";
  14.752 +		}
  14.753 +		s += "\n";
  14.754 +		input_text->appendText(s);
  14.755 +		input_text->setBottomLine(INT_MAX);
  14.756 +	}
  14.757 +	if (res < 0) {
  14.758 +		input_text->appendText("hid_read() returned error\n");
  14.759 +		input_text->setBottomLine(INT_MAX);
  14.760 +	}
  14.761 +
  14.762 +	getApp()->addTimeout(this, ID_TIMER,
  14.763 +		5 * timeout_scalar /*5ms*/);
  14.764 +	return 1;
  14.765 +}
  14.766 +
  14.767 +long
  14.768 +MainWindow::onMacTimeout(FXObject *sender, FXSelector sel, void *ptr)
  14.769 +{
  14.770 +#ifdef __APPLE__
  14.771 +	check_apple_events();
  14.772 +
  14.773 +	getApp()->addTimeout(this, ID_MAC_TIMER,
  14.774 +		50 * timeout_scalar /*50ms*/);
  14.775 +#endif
  14.776 +
  14.777 +	return 1;
  14.778 +}
  14.779 +
  14.780 +/**
  14.781 +
  14.782 +*/
  14.783 +long MainWindow::onSelectFont(FXObject *sender, FXSelector sel, void *ptr)
  14.784 +    {
  14.785 +    FXFontDialog* dlg=new FXFontDialog(this,"Pick a font");
  14.786 +    if (dlg->execute())
  14.787 +        {
  14.788 +        dlg->getFontSelection(iCurrentFontDesc);
  14.789 +        delete iCurrentFont;
  14.790 +        iCurrentFont = NULL;
  14.791 +        iCurrentFont = new FXFont(getApp(),iCurrentFontDesc);
  14.792 +        iCurrentFont->create();
  14.793 +        //
  14.794 +        delete iFontImage;
  14.795 +        iFontImage = NULL;
  14.796 +        //
  14.797 +        FXString text="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-[]{}();%$£&~#|_";
  14.798 +        //Create an image the proper size for our text
  14.799 +        iFontImage = new FXTGAImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,iCurrentFont->getTextWidth(text),iCurrentFont->getFontHeight());
  14.800 +        iFontImage->create();
  14.801 +        //Perform our drawing
  14.802 +            {
  14.803 +            FXDCWindow dc(iFontImage);
  14.804 +            //dc.begin(iFontImage);
  14.805 +            dc.setFont(iCurrentFont);
  14.806 +            dc.setForeground(0xFFFFFFFF);
  14.807 +            //dc.setBackground(0xFF000000);
  14.808 +            //dc.setFillStyle(FILL_SOLID);
  14.809 +            dc.fillRectangle(0,0,iFontImage->getWidth(),iFontImage->getHeight());
  14.810 +            dc.setForeground(0xFF000000);
  14.811 +            dc.drawText(0,iCurrentFont->getFontAscent(),text);
  14.812 +            //dc.end();
  14.813 +            }
  14.814 +        FXFileStream file;
  14.815 +        file.open("fonttest.tga",FXStreamSave);
  14.816 +        iFontImage->restore();
  14.817 +        iFontImage->savePixels(file);
  14.818 +        file.close();
  14.819 +
  14.820 +        //
  14.821 +
  14.822 +        }
  14.823 +
  14.824 +    delete dlg;
  14.825 +    return 1;
  14.826 +    }
  14.827 +
  14.828 +
  14.829 +
    15.1 --- a/test.cpp	Wed May 21 22:55:14 2014 +0200
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,826 +0,0 @@
    15.4 -/*******************************************************
    15.5 - Demo Program for HIDAPI
    15.6 -
    15.7 - Alan Ott
    15.8 - Signal 11 Software
    15.9 -
   15.10 - 2010-07-20
   15.11 -
   15.12 - Copyright 2010, All Rights Reserved
   15.13 -
   15.14 - This contents of this file may be used by anyone
   15.15 - for any reason without any conditions and may be
   15.16 - used as a starting point for your own applications
   15.17 - which use HIDAPI.
   15.18 -********************************************************/
   15.19 -
   15.20 -#include "MainWindow.h"
   15.21 -
   15.22 -
   15.23 -// FOX 1.7 changes the timeouts to all be nanoseconds.
   15.24 -// Fox 1.6 had all timeouts as milliseconds.
   15.25 -#if (FOX_MINOR >= 7)
   15.26 -	const int timeout_scalar = 1000*1000;
   15.27 -#else
   15.28 -	const int timeout_scalar = 1;
   15.29 -#endif
   15.30 -
   15.31 -
   15.32 -FXDEFMAP(MainWindow) MainWindowMap [] = {
   15.33 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_CONNECT, MainWindow::onConnect ),
   15.34 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_DISCONNECT, MainWindow::onDisconnect ),
   15.35 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_RESCAN, MainWindow::onRescan ),
   15.36 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_SEND_OUTPUT_REPORT, MainWindow::onSendOutputReport ),
   15.37 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_SEND_FEATURE_REPORT, MainWindow::onSendFeatureReport ),
   15.38 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_GET_FEATURE_REPORT, MainWindow::onGetFeatureReport ),
   15.39 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_CLEAR, MainWindow::onClear ),
   15.40 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_CLEAR_DISPLAY, MainWindow::onFutabaClearDisplay ),
   15.41 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_DIMMING, MainWindow::onFutabaDimming ),
   15.42 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_DISPLAY_DATA_INPUT, MainWindow::onFutabaDisplayDataInput ),
   15.43 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_READ_ID, MainWindow::onFutabaReadId ),
   15.44 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_READ_FIRMWARE_REVISION, MainWindow::onFutabaReadFirmwareRevision ),
   15.45 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_POWER_SUPPLY_MONITOR, MainWindow::onFutabaPowerSupplyMonitor ),
   15.46 -    FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_SET_PIXEL, MainWindow::onFutabaSetPixel ),
   15.47 -	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_RESET_PIXEL, MainWindow::onFutabaResetPixel ),
   15.48 -    FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_SET_ALL_PIXELS, MainWindow::onFutabaSetAllPixels ),
   15.49 -    FXMAPFUNC(SEL_COMMAND, MainWindow::ID_SELECT_FONT, MainWindow::onSelectFont ),
   15.50 -	FXMAPFUNC(SEL_TIMEOUT, MainWindow::ID_TIMER, MainWindow::onTimeout ),
   15.51 -	FXMAPFUNC(SEL_TIMEOUT, MainWindow::ID_MAC_TIMER, MainWindow::onMacTimeout ),
   15.52 -};
   15.53 -
   15.54 -FXIMPLEMENT(MainWindow, FXMainWindow, MainWindowMap, ARRAYNUMBER(MainWindowMap));
   15.55 -
   15.56 -MainWindow::MainWindow(FXApp *app)
   15.57 -	: FXMainWindow(app, "HIDAPI Test Application", NULL, NULL, DECOR_ALL, 200,100, 600,900),
   15.58 -    iCurrentFont(NULL),
   15.59 -    iFontImage(NULL)
   15.60 -{
   15.61 -	iDimming=0x35;
   15.62 -	devices = NULL;
   15.63 -	connected_device = NULL;
   15.64 -
   15.65 -	FXVerticalFrame *vf = new FXVerticalFrame(this, LAYOUT_FILL_Y|LAYOUT_FILL_X);
   15.66 -
   15.67 -	FXLabel *label = new FXLabel(vf, "HIDAPI Test Tool");
   15.68 -	title_font = new FXFont(getApp(), "Arial", 14, FXFont::Bold);
   15.69 -	label->setFont(title_font);
   15.70 -
   15.71 -	new FXLabel(vf,
   15.72 -		"Select a device and press Connect.", NULL, JUSTIFY_LEFT);
   15.73 -	new FXLabel(vf,
   15.74 -		"Output data bytes can be entered in the Output section, \n"
   15.75 -		"separated by space, comma or brackets. Data starting with 0x\n"
   15.76 -		"is treated as hex. Data beginning with a 0 is treated as \n"
   15.77 -		"octal. All other data is treated as decimal.", NULL, JUSTIFY_LEFT);
   15.78 -	new FXLabel(vf,
   15.79 -		"Data received from the device appears in the Input section.",
   15.80 -		NULL, JUSTIFY_LEFT);
   15.81 -	new FXLabel(vf,
   15.82 -		"Optionally, a report length may be specified. Extra bytes are\n"
   15.83 -		"padded with zeros. If no length is specified, the length is \n"
   15.84 -		"inferred from the data.",
   15.85 -		NULL, JUSTIFY_LEFT);
   15.86 -	new FXLabel(vf, "");
   15.87 -
   15.88 -	// Device List and Connect/Disconnect buttons
   15.89 -	FXHorizontalFrame *hf = new FXHorizontalFrame(vf, LAYOUT_FILL_X);
   15.90 -	//device_list = new FXList(new FXHorizontalFrame(hf,FRAME_SUNKEN|FRAME_THICK, 0,0,0,0, 0,0,0,0), NULL, 0, LISTBOX_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT, 0,0,300,200);
   15.91 -	device_list = new FXList(new FXHorizontalFrame(hf,FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0), NULL, 0, LISTBOX_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,300,200);
   15.92 -	FXVerticalFrame *buttonVF = new FXVerticalFrame(hf);
   15.93 -	connect_button = new FXButton(buttonVF, "Connect", NULL, this, ID_CONNECT, BUTTON_NORMAL|LAYOUT_FILL_X);
   15.94 -	disconnect_button = new FXButton(buttonVF, "Disconnect", NULL, this, ID_DISCONNECT, BUTTON_NORMAL|LAYOUT_FILL_X);
   15.95 -	disconnect_button->disable();
   15.96 -	rescan_button = new FXButton(buttonVF, "Re-Scan devices", NULL, this, ID_RESCAN, BUTTON_NORMAL|LAYOUT_FILL_X);
   15.97 -	new FXHorizontalFrame(buttonVF, 0, 0,0,0,0, 0,0,50,0);
   15.98 -
   15.99 -	connected_label = new FXLabel(vf, "Disconnected");
  15.100 -
  15.101 -    //Font group
  15.102 -    new FXHorizontalFrame(vf);
  15.103 -    FXGroupBox *gb = new FXGroupBox(vf, "Fonts", FRAME_GROOVE|LAYOUT_FILL_X);
  15.104 -    FXMatrix *matrix = new FXMatrix(gb, 3, MATRIX_BY_COLUMNS|LAYOUT_FILL_X);
  15.105 -    iButtonSelectFont = new FXButton(matrix, "Select Font", NULL, this, ID_SELECT_FONT, BUTTON_NORMAL|LAYOUT_FILL_X);
  15.106 -
  15.107 -	//Futaba VFD commands
  15.108 -	new FXHorizontalFrame(vf);
  15.109 -	gb = new FXGroupBox(vf, "Futaba GP1212A01A", FRAME_GROOVE|LAYOUT_FILL_X);
  15.110 -	matrix = new FXMatrix(gb, 3, MATRIX_BY_COLUMNS|LAYOUT_FILL_X);
  15.111 -	iButtonClearDisplay = new FXButton(matrix, "Clear Display", NULL, this, ID_FUTABA_CLEAR_DISPLAY, BUTTON_NORMAL|LAYOUT_FILL_X);
  15.112 -	iButtonDimming = new FXButton(matrix, "Dimming", NULL, this, ID_FUTABA_DIMMING, BUTTON_NORMAL|LAYOUT_FILL_X);
  15.113 -	iButtonDisplayDataInput = new FXButton(matrix, "Display Data Input", NULL, this, ID_FUTABA_DISPLAY_DATA_INPUT, BUTTON_NORMAL|LAYOUT_FILL_X);
  15.114 -	iButtonReadId = new FXButton(matrix, "Read Id", NULL, this, ID_FUTABA_READ_ID, BUTTON_NORMAL|LAYOUT_FILL_X);
  15.115 -	iButtonReadFirmwareRevision =  new FXButton(matrix, "Read Firmware Revision", NULL, this, ID_FUTABA_READ_FIRMWARE_REVISION, BUTTON_NORMAL|LAYOUT_FILL_X);
  15.116 -	iButtonPowerSupplyMonitor = new FXButton(matrix, "Power Supply Monitor", NULL, this, ID_FUTABA_POWER_SUPPLY_MONITOR, BUTTON_NORMAL|LAYOUT_FILL_X);
  15.117 -    new FXLabel(matrix, "X",NULL,LABEL_NORMAL|LAYOUT_FILL_X);
  15.118 -    new FXLabel(matrix, "Y",NULL,LABEL_NORMAL|LAYOUT_FILL_X);
  15.119 -    new FXLabel(matrix, "",NULL,LABEL_NORMAL|LAYOUT_FILL_X);
  15.120 -    iTextFieldX = new FXTextField(matrix, 3, NULL, 0, TEXTFIELD_NORMAL|TEXTFIELD_INTEGER|LAYOUT_FILL_X);
  15.121 -    iTextFieldY = new FXTextField(matrix, 3, NULL, 0, TEXTFIELD_NORMAL|TEXTFIELD_INTEGER|LAYOUT_FILL_X);
  15.122 -    iButtonSetPixel = new FXButton(matrix, "Set Pixel", NULL, this, ID_FUTABA_SET_PIXEL, BUTTON_NORMAL|LAYOUT_FILL_X);
  15.123 -	iButtonResetPixel = new FXButton(matrix, "Reset Pixel", NULL, this, ID_FUTABA_RESET_PIXEL, BUTTON_NORMAL|LAYOUT_FILL_X);
  15.124 -    //
  15.125 -    iButtonSetAllPixels = new FXButton(matrix, "Set All Pixels", NULL, this, ID_FUTABA_SET_ALL_PIXELS, BUTTON_NORMAL|LAYOUT_FILL_X);
  15.126 -    //
  15.127 -
  15.128 -	//
  15.129 -	iButtonClearDisplay->disable();
  15.130 -	iButtonDimming->disable();
  15.131 -	iButtonDisplayDataInput->disable();
  15.132 -	iButtonReadId->disable();
  15.133 -	iButtonReadFirmwareRevision->disable();
  15.134 -	iButtonPowerSupplyMonitor->disable();
  15.135 -    iTextFieldX->disable();
  15.136 -    iTextFieldY->disable();
  15.137 -    iButtonSetPixel->disable();
  15.138 -	iButtonResetPixel->disable();
  15.139 -    iButtonSetAllPixels->disable();
  15.140 -	//
  15.141 -
  15.142 -	// Output Group Box
  15.143 -	new FXHorizontalFrame(vf);
  15.144 -	gb = new FXGroupBox(vf, "Output", FRAME_GROOVE|LAYOUT_FILL_X);
  15.145 -	matrix = new FXMatrix(gb, 3, MATRIX_BY_COLUMNS|LAYOUT_FILL_X);
  15.146 -	new FXLabel(matrix, "Data");
  15.147 -	new FXLabel(matrix, "Length");
  15.148 -	new FXLabel(matrix, "");
  15.149 -
  15.150 -	//hf = new FXHorizontalFrame(gb, LAYOUT_FILL_X);
  15.151 -	output_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  15.152 -	output_text->setText("1 0x81 0");
  15.153 -	output_len = new FXTextField(matrix, 5, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  15.154 -	output_button = new FXButton(matrix, "Send Output Report", NULL, this, ID_SEND_OUTPUT_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
  15.155 -	output_button->disable();
  15.156 -	//new FXHorizontalFrame(matrix, LAYOUT_FILL_X);
  15.157 -
  15.158 -	//hf = new FXHorizontalFrame(gb, LAYOUT_FILL_X);
  15.159 -	feature_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  15.160 -	feature_len = new FXTextField(matrix, 5, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  15.161 -	feature_button = new FXButton(matrix, "Send Feature Report", NULL, this, ID_SEND_FEATURE_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
  15.162 -	feature_button->disable();
  15.163 -
  15.164 -	get_feature_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  15.165 -	new FXWindow(matrix);
  15.166 -	get_feature_button = new FXButton(matrix, "Get Feature Report", NULL, this, ID_GET_FEATURE_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
  15.167 -	get_feature_button->disable();
  15.168 -
  15.169 -
  15.170 -	// Input Group Box
  15.171 -	gb = new FXGroupBox(vf, "Input", FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y);
  15.172 -	FXVerticalFrame *innerVF = new FXVerticalFrame(gb, LAYOUT_FILL_X|LAYOUT_FILL_Y);
  15.173 -	input_text = new FXText(new FXHorizontalFrame(innerVF,LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, 0,0,0,0, 0,0,0,0), NULL, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y);
  15.174 -	input_text->setEditable(false);
  15.175 -	new FXButton(innerVF, "Clear", NULL, this, ID_CLEAR, BUTTON_NORMAL|LAYOUT_RIGHT);
  15.176 -
  15.177 -
  15.178 -}
  15.179 -
  15.180 -MainWindow::~MainWindow()
  15.181 -{
  15.182 -    delete iCurrentFont;
  15.183 -    iCurrentFont = NULL;
  15.184 -
  15.185 -    delete iFontImage;
  15.186 -    iFontImage = NULL;
  15.187 -
  15.188 -	if (connected_device)
  15.189 -		hid_close(connected_device);
  15.190 -	hid_exit();
  15.191 -	delete title_font;
  15.192 -}
  15.193 -
  15.194 -void
  15.195 -MainWindow::create()
  15.196 -{
  15.197 -	FXMainWindow::create();
  15.198 -	show();
  15.199 -
  15.200 -	onRescan(NULL, 0, NULL);
  15.201 -
  15.202 -	//Just testing our new VFD class
  15.203 -	iVfd01.Open();
  15.204 -	iVfd01.SetAllPixels(true);
  15.205 -	iVfd01.Close();
  15.206 -
  15.207 -
  15.208 -#ifdef __APPLE__
  15.209 -	init_apple_message_system();
  15.210 -#endif
  15.211 -
  15.212 -	getApp()->addTimeout(this, ID_MAC_TIMER,
  15.213 -		50 * timeout_scalar /*50ms*/);
  15.214 -}
  15.215 -
  15.216 -long
  15.217 -MainWindow::onConnect(FXObject *sender, FXSelector sel, void *ptr)
  15.218 -{
  15.219 -	if (connected_device != NULL)
  15.220 -		return 1;
  15.221 -
  15.222 -	FXint cur_item = device_list->getCurrentItem();
  15.223 -	if (cur_item < 0)
  15.224 -		return -1;
  15.225 -	FXListItem *item = device_list->getItem(cur_item);
  15.226 -	if (!item)
  15.227 -		return -1;
  15.228 -	struct hid_device_info *device_info = (struct hid_device_info*) item->getData();
  15.229 -	if (!device_info)
  15.230 -		return -1;
  15.231 -
  15.232 -	connected_device =  hid_open_path(device_info->path);
  15.233 -
  15.234 -	if (!connected_device) {
  15.235 -		FXMessageBox::error(this, MBOX_OK, "Device Error", "Unable To Connect to Device");
  15.236 -		return -1;
  15.237 -	}
  15.238 -
  15.239 -	hid_set_nonblocking(connected_device, 1);
  15.240 -
  15.241 -	getApp()->addTimeout(this, ID_TIMER,
  15.242 -		5 * timeout_scalar /*5ms*/);
  15.243 -
  15.244 -	FXString s;
  15.245 -	s.format("Connected to: %04hx:%04hx -", device_info->vendor_id, device_info->product_id);
  15.246 -	s += FXString(" ") + device_info->manufacturer_string;
  15.247 -	s += FXString(" ") + device_info->product_string;
  15.248 -	connected_label->setText(s);
  15.249 -	output_button->enable();
  15.250 -	feature_button->enable();
  15.251 -	get_feature_button->enable();
  15.252 -	connect_button->disable();
  15.253 -	disconnect_button->enable();
  15.254 -	input_text->setText("");
  15.255 -	//
  15.256 -	iButtonClearDisplay->enable();
  15.257 -	iButtonDimming->enable();
  15.258 -	iButtonDisplayDataInput->enable();
  15.259 -	iButtonReadId->enable();
  15.260 -	iButtonReadFirmwareRevision->enable();
  15.261 -	iButtonPowerSupplyMonitor->enable();
  15.262 -    iTextFieldX->enable();
  15.263 -    iTextFieldY->enable();
  15.264 -    iButtonSetPixel->enable();
  15.265 -	iButtonResetPixel->enable();
  15.266 -    iButtonSetAllPixels->enable();
  15.267 -
  15.268 -	//
  15.269 -	iOutputReportBuffer=new unsigned char[KFutabaMaxHidReportSize]; //TODO: use connected_device->output_report_length
  15.270 -
  15.271 -	return 1;
  15.272 -}
  15.273 -
  15.274 -long
  15.275 -MainWindow::onDisconnect(FXObject *sender, FXSelector sel, void *ptr)
  15.276 -{
  15.277 -	hid_close(connected_device);
  15.278 -	connected_device = NULL;
  15.279 -	connected_label->setText("Disconnected");
  15.280 -	output_button->disable();
  15.281 -	feature_button->disable();
  15.282 -	get_feature_button->disable();
  15.283 -	connect_button->enable();
  15.284 -	disconnect_button->disable();
  15.285 -
  15.286 -	getApp()->removeTimeout(this, ID_TIMER);
  15.287 -
  15.288 -	//
  15.289 -	iButtonClearDisplay->disable();
  15.290 -	iButtonDimming->disable();
  15.291 -	iButtonDisplayDataInput->disable();
  15.292 -	iButtonReadId->disable();
  15.293 -	iButtonReadFirmwareRevision->disable();
  15.294 -	iButtonPowerSupplyMonitor->disable();
  15.295 -    iTextFieldX->disable();
  15.296 -    iTextFieldY->disable();
  15.297 -    iButtonSetPixel->disable();
  15.298 -	iButtonResetPixel->disable();
  15.299 -    iButtonSetAllPixels->disable();
  15.300 -	//
  15.301 -
  15.302 -
  15.303 -	delete iOutputReportBuffer;
  15.304 -	iOutputReportBuffer=NULL;
  15.305 -
  15.306 -	return 1;
  15.307 -}
  15.308 -
  15.309 -long
  15.310 -MainWindow::onRescan(FXObject *sender, FXSelector sel, void *ptr)
  15.311 -{
  15.312 -	struct hid_device_info *cur_dev;
  15.313 -
  15.314 -	device_list->clearItems();
  15.315 -
  15.316 -	// List the Devices
  15.317 -	hid_free_enumeration(devices);
  15.318 -	devices = hid_enumerate(0x0, 0x0);
  15.319 -	cur_dev = devices;
  15.320 -	while (cur_dev) {
  15.321 -		// Add it to the List Box only if it is a Futaba device
  15.322 -		if (cur_dev->vendor_id == KFutabaVendorId)
  15.323 -			{
  15.324 -			FXString s;
  15.325 -			FXString usage_str;
  15.326 -			s.format("%04hx:%04hx -", cur_dev->vendor_id, cur_dev->product_id);
  15.327 -			s += FXString(" ") + cur_dev->manufacturer_string;
  15.328 -			s += FXString(" ") + cur_dev->product_string;
  15.329 -			usage_str.format(" (usage: %04hx:%04hx) ", cur_dev->usage_page, cur_dev->usage);
  15.330 -			s += usage_str;
  15.331 -			FXListItem *li = new FXListItem(s, NULL, cur_dev);
  15.332 -			device_list->appendItem(li);
  15.333 -			}
  15.334 -
  15.335 -		cur_dev = cur_dev->next;
  15.336 -	}
  15.337 -
  15.338 -	if (device_list->getNumItems() == 0)
  15.339 -		device_list->appendItem("*** No Devices Connected ***");
  15.340 -	else {
  15.341 -		device_list->selectItem(0);
  15.342 -	}
  15.343 -
  15.344 -	return 1;
  15.345 -}
  15.346 -
  15.347 -size_t
  15.348 -MainWindow::getDataFromTextField(FXTextField *tf, char *buf, size_t len)
  15.349 -{
  15.350 -	const char *delim = " ,{}\t\r\n";
  15.351 -	FXString data = tf->getText();
  15.352 -	const FXchar *d = data.text();
  15.353 -	size_t i = 0;
  15.354 -
  15.355 -	// Copy the string from the GUI.
  15.356 -	size_t sz = strlen(d);
  15.357 -	char *str = (char*) malloc(sz+1);
  15.358 -	strcpy(str, d);
  15.359 -
  15.360 -	// For each token in the string, parse and store in buf[].
  15.361 -	char *token = strtok(str, delim);
  15.362 -	while (token) {
  15.363 -		char *endptr;
  15.364 -		long int val = strtol(token, &endptr, 0);
  15.365 -		buf[i++] = val;
  15.366 -		token = strtok(NULL, delim);
  15.367 -	}
  15.368 -
  15.369 -	free(str);
  15.370 -	return i;
  15.371 -}
  15.372 -
  15.373 -/* getLengthFromTextField()
  15.374 -   Returns length:
  15.375 -	 0: empty text field
  15.376 -	>0: valid length
  15.377 -	-1: invalid length */
  15.378 -int
  15.379 -MainWindow::getLengthFromTextField(FXTextField *tf)
  15.380 -{
  15.381 -	long int len;
  15.382 -	FXString str = tf->getText();
  15.383 -	size_t sz = str.length();
  15.384 -
  15.385 -	if (sz > 0) {
  15.386 -		char *endptr;
  15.387 -		len = strtol(str.text(), &endptr, 0);
  15.388 -		if (endptr != str.text() && *endptr == '\0') {
  15.389 -			if (len <= 0) {
  15.390 -				FXMessageBox::error(this, MBOX_OK, "Invalid length", "Enter a length greater than zero.");
  15.391 -				return -1;
  15.392 -			}
  15.393 -			return len;
  15.394 -		}
  15.395 -		else
  15.396 -			return -1;
  15.397 -	}
  15.398 -
  15.399 -	return 0;
  15.400 -}
  15.401 -
  15.402 -long
  15.403 -MainWindow::onSendOutputReport(FXObject *sender, FXSelector sel, void *ptr)
  15.404 -{
  15.405 -	char buf[256];
  15.406 -	size_t data_len, len;
  15.407 -	int textfield_len;
  15.408 -
  15.409 -	memset(buf, 0x0, sizeof(buf));
  15.410 -	textfield_len = getLengthFromTextField(output_len);
  15.411 -	data_len = getDataFromTextField(output_text, buf, sizeof(buf));
  15.412 -
  15.413 -	if (textfield_len < 0) {
  15.414 -		FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is invalid. Please enter a number in hex, octal, or decimal.");
  15.415 -		return 1;
  15.416 -	}
  15.417 -
  15.418 -	if (textfield_len > sizeof(buf)) {
  15.419 -		FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is too long.");
  15.420 -		return 1;
  15.421 -	}
  15.422 -
  15.423 -	len = (textfield_len)? textfield_len: data_len;
  15.424 -
  15.425 -	int res = hid_write(connected_device, (const unsigned char*)buf, len);
  15.426 -	if (res < 0) {
  15.427 -		FXMessageBox::error(this, MBOX_OK, "Error Writing", "Could not write to device. Error reported was: %ls", hid_error(connected_device));
  15.428 -	}
  15.429 -
  15.430 -	return 1;
  15.431 -}
  15.432 -
  15.433 -long
  15.434 -MainWindow::onSendFeatureReport(FXObject *sender, FXSelector sel, void *ptr)
  15.435 -{
  15.436 -	char buf[256];
  15.437 -	size_t data_len, len;
  15.438 -	int textfield_len;
  15.439 -
  15.440 -	memset(buf, 0x0, sizeof(buf));
  15.441 -	textfield_len = getLengthFromTextField(feature_len);
  15.442 -	data_len = getDataFromTextField(feature_text, buf, sizeof(buf));
  15.443 -
  15.444 -	if (textfield_len < 0) {
  15.445 -		FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is invalid. Please enter a number in hex, octal, or decimal.");
  15.446 -		return 1;
  15.447 -	}
  15.448 -
  15.449 -	if (textfield_len > sizeof(buf)) {
  15.450 -		FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is too long.");
  15.451 -		return 1;
  15.452 -	}
  15.453 -
  15.454 -	len = (textfield_len)? textfield_len: data_len;
  15.455 -
  15.456 -	int res = hid_send_feature_report(connected_device, (const unsigned char*)buf, len);
  15.457 -	if (res < 0) {
  15.458 -		FXMessageBox::error(this, MBOX_OK, "Error Writing", "Could not send feature report to device. Error reported was: %ls", hid_error(connected_device));
  15.459 -	}
  15.460 -
  15.461 -	return 1;
  15.462 -}
  15.463 -
  15.464 -long
  15.465 -MainWindow::onGetFeatureReport(FXObject *sender, FXSelector sel, void *ptr)
  15.466 -{
  15.467 -	char buf[256];
  15.468 -	size_t len;
  15.469 -
  15.470 -	memset(buf, 0x0, sizeof(buf));
  15.471 -	len = getDataFromTextField(get_feature_text, buf, sizeof(buf));
  15.472 -
  15.473 -	if (len != 1) {
  15.474 -		FXMessageBox::error(this, MBOX_OK, "Too many numbers", "Enter only a single report number in the text field");
  15.475 -	}
  15.476 -
  15.477 -	int res = hid_get_feature_report(connected_device, (unsigned char*)buf, sizeof(buf));
  15.478 -	if (res < 0) {
  15.479 -		FXMessageBox::error(this, MBOX_OK, "Error Getting Report", "Could not get feature report from device. Error reported was: %ls", hid_error(connected_device));
  15.480 -	}
  15.481 -
  15.482 -	if (res > 0) {
  15.483 -		FXString s;
  15.484 -		s.format("Returned Feature Report. %d bytes:\n", res);
  15.485 -		for (int i = 0; i < res; i++) {
  15.486 -			FXString t;
  15.487 -			t.format("%02hhx ", buf[i]);
  15.488 -			s += t;
  15.489 -			if ((i+1) % 4 == 0)
  15.490 -				s += " ";
  15.491 -			if ((i+1) % 16 == 0)
  15.492 -				s += "\n";
  15.493 -		}
  15.494 -		s += "\n";
  15.495 -		input_text->appendText(s);
  15.496 -		input_text->setBottomLine(INT_MAX);
  15.497 -	}
  15.498 -
  15.499 -	return 1;
  15.500 -}
  15.501 -
  15.502 -long
  15.503 -MainWindow::onClear(FXObject *sender, FXSelector sel, void *ptr)
  15.504 -{
  15.505 -	input_text->setText("");
  15.506 -	return 1;
  15.507 -}
  15.508 -
  15.509 -
  15.510 -long
  15.511 -MainWindow::onFutabaClearDisplay(FXObject *sender, FXSelector sel, void *ptr)
  15.512 -{
  15.513 -	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  15.514 -	iOutputReportBuffer[0]=0x00; //Report ID
  15.515 -	iOutputReportBuffer[1]=0x04; //Report length
  15.516 -	iOutputReportBuffer[2]=0x1B; //
  15.517 -	iOutputReportBuffer[3]=0x5B; //
  15.518 -	iOutputReportBuffer[4]=0x32; //
  15.519 -	iOutputReportBuffer[5]=0x4A; //
  15.520 -	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  15.521 -
  15.522 -	return 1;
  15.523 -}
  15.524 -
  15.525 -long
  15.526 -MainWindow::onFutabaDimming(FXObject *sender, FXSelector sel, void *ptr)
  15.527 -{
  15.528 -	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  15.529 -	iOutputReportBuffer[0]=0x00; //Report ID
  15.530 -	iOutputReportBuffer[1]=0x06; //Report length
  15.531 -	iOutputReportBuffer[2]=0x1B; //
  15.532 -	iOutputReportBuffer[3]=0x5C; //
  15.533 -	iOutputReportBuffer[4]=0x3F; //
  15.534 -	iOutputReportBuffer[5]=0x4C; //
  15.535 -	iOutputReportBuffer[6]=0x44; //
  15.536 -	iDimming = (iDimming==0x35?0x30:++iDimming);
  15.537 -	iOutputReportBuffer[7]=iDimming;
  15.538 -	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  15.539 -
  15.540 -	return 1;
  15.541 -}
  15.542 -
  15.543 -long
  15.544 -MainWindow::onFutabaDisplayDataInput(FXObject *sender, FXSelector sel, void *ptr)
  15.545 -{
  15.546 -	//@1B 5B F0 00 00 07 00 01 FF
  15.547 -
  15.548 -	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  15.549 -	iOutputReportBuffer[0]=0x00; //Report ID
  15.550 -	iOutputReportBuffer[1]=0x09; //Report length
  15.551 -	iOutputReportBuffer[2]=0x1B; //
  15.552 -	iOutputReportBuffer[3]=0x5B; //
  15.553 -	iOutputReportBuffer[4]=0xF0; //
  15.554 -	iOutputReportBuffer[5]=0x00; //X
  15.555 -	iOutputReportBuffer[6]=0x00; //Y
  15.556 -	iOutputReportBuffer[7]=0x07; //
  15.557 -	iOutputReportBuffer[8]=0x00; //
  15.558 -	iOutputReportBuffer[9]=0x01; //
  15.559 -	iOutputReportBuffer[10]=0xFF; //
  15.560 -	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  15.561 -
  15.562 -
  15.563 -	return 1;
  15.564 -}
  15.565 -
  15.566 -
  15.567 -
  15.568 -
  15.569 -/**
  15.570 -Set a single pixel to the specified value.
  15.571 -@param X coordinate of our pixel.
  15.572 -@param Y coordinate of our pixel.
  15.573 -@param The LSB defines our pixel value.
  15.574 -*/
  15.575 -void MainWindow::SetPixel(int aX, int aY, unsigned char aValue)
  15.576 -	{
  15.577 -	//Just specify a one pixel block
  15.578 -	SetPixelBlock(aX,aY,0x00,0x01,aValue);
  15.579 -	}
  15.580 -
  15.581 -/**
  15.582 -Set the defined pixel block to the given value.
  15.583 -@param X coordinate of our pixel block starting point.
  15.584 -@param Y coordinate of our pixel block starting point.
  15.585 -@param The height of our pixel block.
  15.586 -@param The size of our pixel data. Number of pixels divided by 8.
  15.587 -@param The value set to 8 pixels.
  15.588 -*/
  15.589 -void MainWindow::SetPixelBlock(int aX, int aY, int aHeight, int aSize, unsigned char aValue)
  15.590 -	{
  15.591 -	//Size must be 63 or below
  15.592 -	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  15.593 -	iOutputReportBuffer[0]=0x00; //Report ID
  15.594 -	iOutputReportBuffer[1]=0x08+aSize; //Report length
  15.595 -	iOutputReportBuffer[2]=0x1B; //
  15.596 -	iOutputReportBuffer[3]=0x5B; //
  15.597 -	iOutputReportBuffer[4]=0xF0; //
  15.598 -	iOutputReportBuffer[5]=aX; //X
  15.599 -	iOutputReportBuffer[6]=aY; //Y
  15.600 -	iOutputReportBuffer[7]=aHeight; //Y length before return. Though outside the specs, setting this to zero apparently allows us to modify a single pixel without touching any other.
  15.601 -	iOutputReportBuffer[8]=0x00; //Size of pixel data in bytes (MSB)
  15.602 -	iOutputReportBuffer[9]=aSize; //Size of pixel data in bytes (LSB)
  15.603 -	memset(iOutputReportBuffer+10, aValue, KFutabaMaxHidReportSize);
  15.604 -	//iOutputReportBuffer[10]=aValue; //Pixel data
  15.605 -	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  15.606 -	}
  15.607 -
  15.608 -/**
  15.609 -Send an output report to a Futaba VFD device.
  15.610 -*/
  15.611 -/*
  15.612 -void MainWindow::SendFutabaOutputReport(unsigned char* aReportData, unsigned char aSize)
  15.613 -    {
  15.614 -    //
  15.615 -    memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  15.616 -    iOutputReportBuffer[0]=0x00; //Report ID is always null
  15.617 -    iOutputReportBuffer[1]=0x08+aSize; //Report length
  15.618 -    iOutputReportBuffer[2]=0x1B; //
  15.619 -    iOutputReportBuffer[3]=0x5B; //
  15.620 -    iOutputReportBuffer[4]=0xF0; //
  15.621 -    iOutputReportBuffer[5]=aX; //X
  15.622 -    iOutputReportBuffer[6]=aY; //Y
  15.623 -    iOutputReportBuffer[7]=aHeight; //Y length before return. Though outside the specs, setting this to zero apparently allows us to modify a single pixel without touching any other.
  15.624 -    iOutputReportBuffer[8]=0x00; //Size of pixel data in bytes (MSB)
  15.625 -    iOutputReportBuffer[9]=aSize; //Size of pixel data in bytes (LSB)
  15.626 -    memset(iOutputReportBuffer+10, aValue, KFutabaMaxHidReportSize);
  15.627 -    //iOutputReportBuffer[10]=aValue; //Pixel data
  15.628 -    int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  15.629 -    }
  15.630 -*/
  15.631 -
  15.632 -
  15.633 -/**
  15.634 -*/
  15.635 -long MainWindow::onFutabaSetPixel(FXObject *sender, FXSelector sel, void *ptr)
  15.636 -{
  15.637 -	int x=0;
  15.638 -	int y=0;
  15.639 -	iTextFieldX->getText().scan("%d",&x);
  15.640 -	iTextFieldY->getText().scan("%d",&y);
  15.641 -    SetPixel(x,y,0x01);
  15.642 -	return 1;
  15.643 -}
  15.644 -
  15.645 -/**
  15.646 -*/
  15.647 -long MainWindow::onFutabaResetPixel(FXObject *sender, FXSelector sel, void *ptr)
  15.648 -{
  15.649 -	int x=0;
  15.650 -	int y=0;
  15.651 -	iTextFieldX->getText().scan("%d",&x);
  15.652 -	iTextFieldY->getText().scan("%d",&y);
  15.653 -    SetPixel(x,y,0x00);
  15.654 -    return 1;
  15.655 -}
  15.656 -
  15.657 -long MainWindow::onFutabaSetAllPixels(FXObject *sender, FXSelector sel, void *ptr)
  15.658 -	{
  15.659 -	//One pixel at a time
  15.660 -	/*
  15.661 -	for (int i=0;i<256;i++)
  15.662 -		{
  15.663 -		for (int j=0;j<64;j++)
  15.664 -			{
  15.665 -			SetPixel(i,j,0x01);
  15.666 -			}
  15.667 -		}
  15.668 -	*/
  15.669 -	//16x16=256 pixels at a time goes much faster
  15.670 -	for (int i=0;i<256;i+=16)
  15.671 -		{
  15.672 -		for (int j=0;j<64;j+=16)
  15.673 -			{
  15.674 -			SetPixelBlock(i,j,15,32,0xFF);
  15.675 -			//FXThread::sleep(1000000000);
  15.676 -			}
  15.677 -		}
  15.678 -
  15.679 -    return 1;
  15.680 -	}
  15.681 -
  15.682 -long
  15.683 -MainWindow::onFutabaReadId(FXObject *sender, FXSelector sel, void *ptr)
  15.684 -{
  15.685 -	//1BH,5BH,63H,49H,44H
  15.686 -	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  15.687 -	iOutputReportBuffer[0]=0x00; //Report ID
  15.688 -	iOutputReportBuffer[1]=0x05; //Report length
  15.689 -	iOutputReportBuffer[2]=0x1B; //
  15.690 -	iOutputReportBuffer[3]=0x5B; //
  15.691 -	iOutputReportBuffer[4]=0x63; //
  15.692 -	iOutputReportBuffer[5]=0x49; //
  15.693 -	iOutputReportBuffer[6]=0x44; //
  15.694 -	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  15.695 -
  15.696 -	return 1;
  15.697 -}
  15.698 -
  15.699 -long
  15.700 -MainWindow::onFutabaReadFirmwareRevision(FXObject *sender, FXSelector sel, void *ptr)
  15.701 -{
  15.702 -	//1BH,5BH,63H,46H,52H
  15.703 -	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  15.704 -	iOutputReportBuffer[0]=0x00; //Report ID
  15.705 -	iOutputReportBuffer[1]=0x05; //Report length
  15.706 -	iOutputReportBuffer[2]=0x1B; //
  15.707 -	iOutputReportBuffer[3]=0x5B; //
  15.708 -	iOutputReportBuffer[4]=0x63; //
  15.709 -	iOutputReportBuffer[5]=0x46; //
  15.710 -	iOutputReportBuffer[6]=0x52; //
  15.711 -	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  15.712 -
  15.713 -	return 1;
  15.714 -}
  15.715 -
  15.716 -long
  15.717 -MainWindow::onFutabaPowerSupplyMonitor(FXObject *sender, FXSelector sel, void *ptr)
  15.718 -{
  15.719 -	//1BH,5BH,63H,50H,4DH
  15.720 -	memset(iOutputReportBuffer, 0x0, KFutabaMaxHidReportSize);
  15.721 -	iOutputReportBuffer[0]=0x00; //Report ID
  15.722 -	iOutputReportBuffer[1]=0x05; //Report length
  15.723 -	iOutputReportBuffer[2]=0x1B; //
  15.724 -	iOutputReportBuffer[3]=0x5B; //
  15.725 -	iOutputReportBuffer[4]=0x63; //
  15.726 -	iOutputReportBuffer[5]=0x50; //
  15.727 -	iOutputReportBuffer[6]=0x4D; //
  15.728 -	int res = hid_write(connected_device, iOutputReportBuffer, KFutabaMaxHidReportSize);
  15.729 -
  15.730 -	return 1;
  15.731 -}
  15.732 -
  15.733 -
  15.734 -
  15.735 -long
  15.736 -MainWindow::onTimeout(FXObject *sender, FXSelector sel, void *ptr)
  15.737 -{
  15.738 -	unsigned char buf[256];
  15.739 -	int res = hid_read(connected_device, buf, sizeof(buf));
  15.740 -
  15.741 -	if (res > 0) {
  15.742 -		FXString s;
  15.743 -		s.format("Received %d bytes:\n", res);
  15.744 -		for (int i = 0; i < res; i++) {
  15.745 -			FXString t;
  15.746 -			t.format("%02hhx ", buf[i]);
  15.747 -			s += t;
  15.748 -			if ((i+1) % 4 == 0)
  15.749 -				s += " ";
  15.750 -			if ((i+1) % 16 == 0)
  15.751 -				s += "\n";
  15.752 -		}
  15.753 -		s += "\n";
  15.754 -		input_text->appendText(s);
  15.755 -		input_text->setBottomLine(INT_MAX);
  15.756 -	}
  15.757 -	if (res < 0) {
  15.758 -		input_text->appendText("hid_read() returned error\n");
  15.759 -		input_text->setBottomLine(INT_MAX);
  15.760 -	}
  15.761 -
  15.762 -	getApp()->addTimeout(this, ID_TIMER,
  15.763 -		5 * timeout_scalar /*5ms*/);
  15.764 -	return 1;
  15.765 -}
  15.766 -
  15.767 -long
  15.768 -MainWindow::onMacTimeout(FXObject *sender, FXSelector sel, void *ptr)
  15.769 -{
  15.770 -#ifdef __APPLE__
  15.771 -	check_apple_events();
  15.772 -
  15.773 -	getApp()->addTimeout(this, ID_MAC_TIMER,
  15.774 -		50 * timeout_scalar /*50ms*/);
  15.775 -#endif
  15.776 -
  15.777 -	return 1;
  15.778 -}
  15.779 -
  15.780 -/**
  15.781 -
  15.782 -*/
  15.783 -long MainWindow::onSelectFont(FXObject *sender, FXSelector sel, void *ptr)
  15.784 -    {
  15.785 -    FXFontDialog* dlg=new FXFontDialog(this,"Pick a font");
  15.786 -    if (dlg->execute())
  15.787 -        {
  15.788 -        dlg->getFontSelection(iCurrentFontDesc);
  15.789 -        delete iCurrentFont;
  15.790 -        iCurrentFont = NULL;
  15.791 -        iCurrentFont = new FXFont(getApp(),iCurrentFontDesc);
  15.792 -        iCurrentFont->create();
  15.793 -        //
  15.794 -        delete iFontImage;
  15.795 -        iFontImage = NULL;
  15.796 -        //
  15.797 -        FXString text="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-[]{}();%$£&~#|_";
  15.798 -        //Create an image the proper size for our text
  15.799 -        iFontImage = new FXTGAImage(getApp(),NULL,IMAGE_SHMI|IMAGE_SHMP,iCurrentFont->getTextWidth(text),iCurrentFont->getFontHeight());
  15.800 -        iFontImage->create();
  15.801 -        //Perform our drawing
  15.802 -            {
  15.803 -            FXDCWindow dc(iFontImage);
  15.804 -            //dc.begin(iFontImage);
  15.805 -            dc.setFont(iCurrentFont);
  15.806 -            dc.setForeground(0xFFFFFFFF);
  15.807 -            //dc.setBackground(0xFF000000);
  15.808 -            //dc.setFillStyle(FILL_SOLID);
  15.809 -            dc.fillRectangle(0,0,iFontImage->getWidth(),iFontImage->getHeight());
  15.810 -            dc.setForeground(0xFF000000);
  15.811 -            dc.drawText(0,iCurrentFont->getFontAscent(),text);
  15.812 -            //dc.end();
  15.813 -            }
  15.814 -        FXFileStream file;
  15.815 -        file.open("fonttest.tga",FXStreamSave);
  15.816 -        iFontImage->restore();
  15.817 -        iFontImage->savePixels(file);
  15.818 -        file.close();
  15.819 -
  15.820 -        //
  15.821 -
  15.822 -        }
  15.823 -
  15.824 -    delete dlg;
  15.825 -    return 1;
  15.826 -    }
  15.827 -
  15.828 -
  15.829 -