Renamed testgui from hidapi to FutabaVfd.
authorsl
Mon, 19 May 2014 21:10:35 +0200
changeset 0b112defa99c0
child 1 5c2c48109457
Renamed testgui from hidapi to FutabaVfd.
FutabaVfd.sln
FutabaVfd.vcxproj
Makefile-manual
Makefile.am
Makefile.freebsd
Makefile.linux
Makefile.mac
Makefile.mingw
TestGUI.app.in/Contents/Info.plist
TestGUI.app.in/Contents/PkgInfo
TestGUI.app.in/Contents/Resources/English.lproj/InfoPlist.strings
TestGUI.app.in/Contents/Resources/Signal11.icns
copy_to_bundle.sh
mac_support.cpp
mac_support.h
mac_support_cocoa.m
start.sh
test.cpp
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/FutabaVfd.sln	Mon May 19 21:10:35 2014 +0200
     1.3 @@ -0,0 +1,8 @@
     1.4 +
     1.5 +Microsoft Visual Studio Solution File, Format Version 12.00
     1.6 +# Visual Studio 2012
     1.7 +Global
     1.8 +	GlobalSection(SolutionProperties) = preSolution
     1.9 +		HideSolutionNode = FALSE
    1.10 +	EndGlobalSection
    1.11 +EndGlobal
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/FutabaVfd.vcxproj	Mon May 19 21:10:35 2014 +0200
     2.3 @@ -0,0 +1,118 @@
     2.4 +<?xml version="1.0" encoding="utf-8"?>
     2.5 +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
     2.6 +  <ItemGroup Label="ProjectConfigurations">
     2.7 +    <ProjectConfiguration Include="Debug|Win32">
     2.8 +      <Configuration>Debug</Configuration>
     2.9 +      <Platform>Win32</Platform>
    2.10 +    </ProjectConfiguration>
    2.11 +    <ProjectConfiguration Include="Release|Win32">
    2.12 +      <Configuration>Release</Configuration>
    2.13 +      <Platform>Win32</Platform>
    2.14 +    </ProjectConfiguration>
    2.15 +  </ItemGroup>
    2.16 +  <PropertyGroup Label="Globals">
    2.17 +    <ProjectGuid>{08769AC3-785A-4DDC-BFC7-1775414B7AB7}</ProjectGuid>
    2.18 +    <RootNamespace>testgui</RootNamespace>
    2.19 +    <Keyword>Win32Proj</Keyword>
    2.20 +  </PropertyGroup>
    2.21 +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
    2.22 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    2.23 +    <ConfigurationType>Application</ConfigurationType>
    2.24 +    <PlatformToolset>v110</PlatformToolset>
    2.25 +    <CharacterSet>Unicode</CharacterSet>
    2.26 +    <WholeProgramOptimization>true</WholeProgramOptimization>
    2.27 +  </PropertyGroup>
    2.28 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    2.29 +    <ConfigurationType>Application</ConfigurationType>
    2.30 +    <PlatformToolset>v110</PlatformToolset>
    2.31 +    <CharacterSet>Unicode</CharacterSet>
    2.32 +  </PropertyGroup>
    2.33 +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
    2.34 +  <ImportGroup Label="ExtensionSettings">
    2.35 +  </ImportGroup>
    2.36 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
    2.37 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
    2.38 +  </ImportGroup>
    2.39 +  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
    2.40 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
    2.41 +  </ImportGroup>
    2.42 +  <PropertyGroup Label="UserMacros" />
    2.43 +  <PropertyGroup>
    2.44 +    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>
    2.45 +  </PropertyGroup>
    2.46 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    2.47 +    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
    2.48 +    <IntDir>$(Configuration)\</IntDir>
    2.49 +    <LinkIncremental>true</LinkIncremental>
    2.50 +  </PropertyGroup>
    2.51 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    2.52 +    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
    2.53 +    <IntDir>$(Configuration)\</IntDir>
    2.54 +    <LinkIncremental>false</LinkIncremental>
    2.55 +  </PropertyGroup>
    2.56 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    2.57 +    <ClCompile>
    2.58 +      <Optimization>Disabled</Optimization>
    2.59 +      <AdditionalIncludeDirectories>..\hidapi-externals\fox\include;..\hidapi\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    2.60 +      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    2.61 +      <MinimalRebuild>true</MinimalRebuild>
    2.62 +      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
    2.63 +      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
    2.64 +      <PrecompiledHeader />
    2.65 +      <WarningLevel>Level3</WarningLevel>
    2.66 +      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
    2.67 +    </ClCompile>
    2.68 +    <Link>
    2.69 +      <AdditionalDependencies>setupapi.lib;fox-1.6.lib;%(AdditionalDependencies)</AdditionalDependencies>
    2.70 +      <OutputFile>$(TargetPath)</OutputFile>
    2.71 +      <AdditionalLibraryDirectories>..\hidapi\hidapi\objfre_wxp_x86\i386;..\hidapi-externals\fox\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
    2.72 +      <GenerateDebugInformation>true</GenerateDebugInformation>
    2.73 +      <SubSystem>Windows</SubSystem>
    2.74 +      <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
    2.75 +      <TargetMachine>MachineX86</TargetMachine>
    2.76 +    </Link>
    2.77 +    <PostBuildEvent>
    2.78 +      <Command />
    2.79 +    </PostBuildEvent>
    2.80 +  </ItemDefinitionGroup>
    2.81 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    2.82 +    <ClCompile>
    2.83 +      <Optimization>MaxSpeed</Optimization>
    2.84 +      <IntrinsicFunctions>true</IntrinsicFunctions>
    2.85 +      <AdditionalIncludeDirectories>..\..\hidapi-externals\fox\include;..\hidapi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    2.86 +      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    2.87 +      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
    2.88 +      <FunctionLevelLinking>true</FunctionLevelLinking>
    2.89 +      <PrecompiledHeader />
    2.90 +      <WarningLevel>Level3</WarningLevel>
    2.91 +      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
    2.92 +    </ClCompile>
    2.93 +    <Link>
    2.94 +      <AdditionalDependencies>setupapi.lib;fox-1.6.lib;%(AdditionalDependencies)</AdditionalDependencies>
    2.95 +      <OutputFile>$(ProjectName).exe</OutputFile>
    2.96 +      <AdditionalLibraryDirectories>..\hidapi\objfre_wxp_x86\i386;..\..\hidapi-externals\fox\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
    2.97 +      <GenerateDebugInformation>true</GenerateDebugInformation>
    2.98 +      <SubSystem>Windows</SubSystem>
    2.99 +      <OptimizeReferences>true</OptimizeReferences>
   2.100 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
   2.101 +      <EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
   2.102 +      <TargetMachine>MachineX86</TargetMachine>
   2.103 +    </Link>
   2.104 +    <PostBuildEvent>
   2.105 +      <Command />
   2.106 +    </PostBuildEvent>
   2.107 +  </ItemDefinitionGroup>
   2.108 +  <ItemGroup>
   2.109 +    <ClCompile Include="..\hidapi\windows\hid.c" />
   2.110 +    <ClCompile Include="test.cpp" />
   2.111 +  </ItemGroup>
   2.112 +  <ItemGroup>
   2.113 +    <ClInclude Include="..\hidapi\hidapi.h" />
   2.114 +  </ItemGroup>
   2.115 +  <ItemGroup>
   2.116 +    <Text Include="ReadMe.txt" />
   2.117 +  </ItemGroup>
   2.118 +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   2.119 +  <ImportGroup Label="ExtensionTargets">
   2.120 +  </ImportGroup>
   2.121 +</Project>
   2.122 \ No newline at end of file
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/Makefile-manual	Mon May 19 21:10:35 2014 +0200
     3.3 @@ -0,0 +1,26 @@
     3.4 +
     3.5 +
     3.6 +OS=$(shell uname)
     3.7 +
     3.8 +ifeq ($(OS), Darwin)
     3.9 +	FILE=Makefile.mac
    3.10 +endif
    3.11 +
    3.12 +ifneq (,$(findstring MINGW,$(OS)))
    3.13 +	FILE=Makefile.mingw
    3.14 +endif
    3.15 +
    3.16 +ifeq ($(OS), Linux)
    3.17 +	FILE=Makefile.linux
    3.18 +endif
    3.19 +
    3.20 +ifeq ($(OS), FreeBSD)
    3.21 +	FILE=Makefile.freebsd
    3.22 +endif
    3.23 +
    3.24 +ifeq ($(FILE), )
    3.25 +all:
    3.26 +	$(error Your platform ${OS} is not supported at this time.)
    3.27 +endif
    3.28 +
    3.29 +include $(FILE)
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/Makefile.am	Mon May 19 21:10:35 2014 +0200
     4.3 @@ -0,0 +1,43 @@
     4.4 +
     4.5 +AM_CPPFLAGS = -I$(top_srcdir)/hidapi/ $(CFLAGS_TESTGUI)
     4.6 +
     4.7 +if OS_LINUX
     4.8 +## Linux
     4.9 +bin_PROGRAMS = hidapi-hidraw-testgui hidapi-libusb-testgui
    4.10 +
    4.11 +hidapi_hidraw_testgui_SOURCES = test.cpp
    4.12 +hidapi_hidraw_testgui_LDADD = $(top_builddir)/linux/libhidapi-hidraw.la $(LIBS_TESTGUI)
    4.13 +
    4.14 +hidapi_libusb_testgui_SOURCES = test.cpp
    4.15 +hidapi_libusb_testgui_LDADD = $(top_builddir)/libusb/libhidapi-libusb.la $(LIBS_TESTGUI)
    4.16 +else
    4.17 +## Other OS's
    4.18 +bin_PROGRAMS = hidapi-testgui
    4.19 +
    4.20 +hidapi_testgui_SOURCES = test.cpp
    4.21 +hidapi_testgui_LDADD = $(top_builddir)/$(backend)/libhidapi.la $(LIBS_TESTGUI)
    4.22 +endif
    4.23 +
    4.24 +if OS_DARWIN
    4.25 +hidapi_testgui_SOURCES = test.cpp mac_support_cocoa.m mac_support.h
    4.26 +# Rules for copying the binary and its dependencies into the app bundle.
    4.27 +TestGUI.app/Contents/MacOS/hidapi-testgui$(EXEEXT): hidapi-testgui$(EXEEXT)
    4.28 +	$(srcdir)/copy_to_bundle.sh
    4.29 +
    4.30 +all: all-am TestGUI.app/Contents/MacOS/hidapi-testgui$(EXEEXT)
    4.31 +
    4.32 +endif
    4.33 +
    4.34 +EXTRA_DIST = \
    4.35 + copy_to_bundle.sh \
    4.36 + Makefile-manual \
    4.37 + Makefile.freebsd \
    4.38 + Makefile.linux \
    4.39 + Makefile.mac \
    4.40 + Makefile.mingw \
    4.41 + TestGUI.app.in \
    4.42 + testgui.sln \
    4.43 + testgui.vcproj
    4.44 +
    4.45 +distclean-local:
    4.46 +	rm -rf TestGUI.app
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/Makefile.freebsd	Mon May 19 21:10:35 2014 +0200
     5.3 @@ -0,0 +1,33 @@
     5.4 +###########################################
     5.5 +# Simple Makefile for HIDAPI test program
     5.6 +#
     5.7 +# Alan Ott
     5.8 +# Signal 11 Software
     5.9 +# 2010-06-01
    5.10 +###########################################
    5.11 +
    5.12 +all: testgui
    5.13 +
    5.14 +CC=cc
    5.15 +CXX=c++
    5.16 +COBJS=../libusb/hid.o
    5.17 +CPPOBJS=test.o
    5.18 +OBJS=$(COBJS) $(CPPOBJS)
    5.19 +CFLAGS=-I../hidapi -I/usr/local/include `fox-config --cflags` -Wall -g -c
    5.20 +LDFLAGS= -L/usr/local/lib
    5.21 +LIBS= -lusb -liconv `fox-config --libs` -pthread
    5.22 +
    5.23 +
    5.24 +testgui: $(OBJS)
    5.25 +	$(CXX) -Wall -g $^ $(LDFLAGS) -o $@ $(LIBS)
    5.26 +
    5.27 +$(COBJS): %.o: %.c
    5.28 +	$(CC) $(CFLAGS) $< -o $@
    5.29 +
    5.30 +$(CPPOBJS): %.o: %.cpp
    5.31 +	$(CXX) $(CFLAGS) $< -o $@
    5.32 +
    5.33 +clean:
    5.34 +	rm *.o testgui
    5.35 +
    5.36 +.PHONY: clean
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/Makefile.linux	Mon May 19 21:10:35 2014 +0200
     6.3 @@ -0,0 +1,32 @@
     6.4 +###########################################
     6.5 +# Simple Makefile for HIDAPI test program
     6.6 +#
     6.7 +# Alan Ott
     6.8 +# Signal 11 Software
     6.9 +# 2010-06-01
    6.10 +###########################################
    6.11 +
    6.12 +all: testgui
    6.13 +
    6.14 +CC=gcc
    6.15 +CXX=g++
    6.16 +COBJS=../libusb/hid.o
    6.17 +CPPOBJS=test.o
    6.18 +OBJS=$(COBJS) $(CPPOBJS)
    6.19 +CFLAGS=-I../hidapi -Wall -g -c `fox-config --cflags` `pkg-config libusb-1.0 --cflags`
    6.20 +LIBS=-ludev -lrt -lpthread `fox-config --libs` `pkg-config libusb-1.0 --libs`
    6.21 +
    6.22 +
    6.23 +testgui: $(OBJS)
    6.24 +	g++ -Wall -g $^ $(LIBS) -o testgui
    6.25 +
    6.26 +$(COBJS): %.o: %.c
    6.27 +	$(CC) $(CFLAGS) $< -o $@
    6.28 +
    6.29 +$(CPPOBJS): %.o: %.cpp
    6.30 +	$(CXX) $(CFLAGS) $< -o $@
    6.31 +
    6.32 +clean:
    6.33 +	rm *.o testgui
    6.34 +
    6.35 +.PHONY: clean
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/Makefile.mac	Mon May 19 21:10:35 2014 +0200
     7.3 @@ -0,0 +1,46 @@
     7.4 +###########################################
     7.5 +# Simple Makefile for HIDAPI test program
     7.6 +#
     7.7 +# Alan Ott
     7.8 +# Signal 11 Software
     7.9 +# 2010-07-03
    7.10 +###########################################
    7.11 +
    7.12 +all: hidapi-testgui
    7.13 +
    7.14 +CC=gcc
    7.15 +CXX=g++
    7.16 +COBJS=../mac/hid.o
    7.17 +CPPOBJS=test.o
    7.18 +OBJCOBJS=mac_support_cocoa.o
    7.19 +OBJS=$(COBJS) $(CPPOBJS) $(OBJCOBJS)
    7.20 +CFLAGS=-I../hidapi -Wall -g -c `fox-config --cflags`
    7.21 +LDFLAGS=-L/usr/X11R6/lib
    7.22 +LIBS=`fox-config --libs` -framework IOKit -framework CoreFoundation -framework Cocoa
    7.23 +
    7.24 +
    7.25 +hidapi-testgui: $(OBJS) TestGUI.app
    7.26 +	g++ -Wall -g $(OBJS) $(LIBS) $(LDFLAGS) -o hidapi-testgui
    7.27 +	./copy_to_bundle.sh
    7.28 +	#cp TestGUI.app/Contents/MacOS/hidapi-testgui  TestGUI.app/Contents/MacOS/tg
    7.29 +	#cp start.sh TestGUI.app/Contents/MacOS/hidapi-testgui
    7.30 +
    7.31 +$(COBJS): %.o: %.c
    7.32 +	$(CC) $(CFLAGS) $< -o $@
    7.33 +
    7.34 +$(CPPOBJS): %.o: %.cpp
    7.35 +	$(CXX) $(CFLAGS) $< -o $@
    7.36 +
    7.37 +$(OBJCOBJS): %.o: %.m
    7.38 +	$(CXX) $(CFLAGS) -x objective-c++ $< -o $@
    7.39 +
    7.40 +TestGUI.app: TestGUI.app.in
    7.41 +	rm -Rf TestGUI.app
    7.42 +	mkdir -p TestGUI.app
    7.43 +	cp -R TestGUI.app.in/ TestGUI.app
    7.44 +
    7.45 +clean:
    7.46 +	rm -f $(OBJS) hidapi-testgui
    7.47 +	rm -Rf TestGUI.app
    7.48 +
    7.49 +.PHONY: clean
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/Makefile.mingw	Mon May 19 21:10:35 2014 +0200
     8.3 @@ -0,0 +1,32 @@
     8.4 +###########################################
     8.5 +# Simple Makefile for HIDAPI test program
     8.6 +#
     8.7 +# Alan Ott
     8.8 +# Signal 11 Software
     8.9 +# 2010-06-01
    8.10 +###########################################
    8.11 +
    8.12 +all: hidapi-testgui
    8.13 +
    8.14 +CC=gcc
    8.15 +CXX=g++
    8.16 +COBJS=../windows/hid.o
    8.17 +CPPOBJS=test.o
    8.18 +OBJS=$(COBJS) $(CPPOBJS)
    8.19 +CFLAGS=-I../hidapi -I../../hidapi-externals/fox/include -g -c
    8.20 +LIBS= -mwindows -lsetupapi -L../../hidapi-externals/fox/lib -Wl,-Bstatic -lFOX-1.6 -Wl,-Bdynamic -lgdi32 -Wl,--enable-auto-import -static-libgcc -static-libstdc++ -lkernel32
    8.21 +
    8.22 +
    8.23 +hidapi-testgui: $(OBJS)
    8.24 +	g++ -g $^ $(LIBS) -o hidapi-testgui
    8.25 +
    8.26 +$(COBJS): %.o: %.c
    8.27 +	$(CC) $(CFLAGS) $< -o $@
    8.28 +
    8.29 +$(CPPOBJS): %.o: %.cpp
    8.30 +	$(CXX) $(CFLAGS) $< -o $@
    8.31 +
    8.32 +clean:
    8.33 +	rm -f *.o hidapi-testgui.exe
    8.34 +
    8.35 +.PHONY: clean
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/TestGUI.app.in/Contents/Info.plist	Mon May 19 21:10:35 2014 +0200
     9.3 @@ -0,0 +1,28 @@
     9.4 +<?xml version="1.0" encoding="UTF-8"?>
     9.5 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
     9.6 +<plist version="1.0">
     9.7 +<dict>
     9.8 +	<key>CFBundleDevelopmentRegion</key>
     9.9 +	<string>English</string>
    9.10 +	<key>CFBundleDisplayName</key>
    9.11 +	<string></string>
    9.12 +	<key>CFBundleExecutable</key>
    9.13 +	<string>hidapi-testgui</string>
    9.14 +	<key>CFBundleIconFile</key>
    9.15 +	<string>Signal11.icns</string>
    9.16 +	<key>CFBundleIdentifier</key>
    9.17 +	<string>us.signal11.hidtestgui</string>
    9.18 +	<key>CFBundleInfoDictionaryVersion</key>
    9.19 +	<string>6.0</string>
    9.20 +	<key>CFBundleName</key>
    9.21 +	<string>testgui</string>
    9.22 +	<key>CFBundlePackageType</key>
    9.23 +	<string>APPL</string>
    9.24 +	<key>CFBundleSignature</key>
    9.25 +	<string>????</string>
    9.26 +	<key>CFBundleVersion</key>
    9.27 +	<string>1.0</string>
    9.28 +	<key>CSResourcesFileMapped</key>
    9.29 +	<true/>
    9.30 +</dict>
    9.31 +</plist>
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/TestGUI.app.in/Contents/PkgInfo	Mon May 19 21:10:35 2014 +0200
    10.3 @@ -0,0 +1,1 @@
    10.4 +APPL????
    10.5 \ No newline at end of file
    11.1 Binary file TestGUI.app.in/Contents/Resources/English.lproj/InfoPlist.strings has changed
    12.1 Binary file TestGUI.app.in/Contents/Resources/Signal11.icns has changed
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/copy_to_bundle.sh	Mon May 19 21:10:35 2014 +0200
    13.3 @@ -0,0 +1,97 @@
    13.4 +#!/bin/bash
    13.5 +
    13.6 +#### Configuration:
    13.7 +# The name of the executable. It is assumed
    13.8 +# that it is in the current working directory.
    13.9 +EXE_NAME=hidapi-testgui
   13.10 +# Path to the executable directory inside the bundle.
   13.11 +# This must be an absolute path, so use $PWD.
   13.12 +EXEPATH=$PWD/TestGUI.app/Contents/MacOS
   13.13 +# Libraries to explicitly bundle, even though they
   13.14 +# may not be in /opt/local. One per line. These
   13.15 +# are used with grep, so only a portion of the name
   13.16 +# is required. eg: libFOX, libz, etc.
   13.17 +LIBS_TO_BUNDLE=libFOX
   13.18 +
   13.19 +
   13.20 +function copydeps {
   13.21 +	local file=$1
   13.22 +	# echo "Copying deps for $file...."
   13.23 +	local BASE_OF_EXE=`basename $file`
   13.24 +
   13.25 +	# A will contain the dependencies of this library
   13.26 +	local A=`otool -LX $file |cut -f 1 -d " "`
   13.27 +	local i
   13.28 +	for i in $A; do
   13.29 +		local BASE=`basename $i`
   13.30 +
   13.31 +		# See if it's a lib we specifically want to bundle
   13.32 +		local bundle_this_lib=0
   13.33 +		local j
   13.34 +		for j in $LIBS_TO_BUNDLE; do
   13.35 +			echo $i |grep -q $j
   13.36 +			if [ $? -eq 0 ]; then
   13.37 +				bundle_this_lib=1
   13.38 +				echo "bundling $i because it's in the list."
   13.39 +				break;
   13.40 +			fi
   13.41 +		done
   13.42 +
   13.43 +		# See if it's in /opt/local. Bundle all in /opt/local
   13.44 +		local isOptLocal=0
   13.45 +		echo $i |grep -q /opt/local
   13.46 +		if [ $? -eq 0 ]; then
   13.47 +			isOptLocal=1
   13.48 +			echo "bundling $i because it's in /opt/local."
   13.49 +		fi
   13.50 +		
   13.51 +		# Bundle the library
   13.52 +		if [ $isOptLocal -ne 0 ] || [ $bundle_this_lib -ne 0 ]; then
   13.53 +
   13.54 +			# Copy the file into the bundle if it exists.
   13.55 +			if [ -f $EXEPATH/$BASE ]; then
   13.56 +				z=0
   13.57 +			else
   13.58 +				cp $i $EXEPATH
   13.59 +				chmod 755 $EXEPATH/$BASE
   13.60 +			fi
   13.61 +			
   13.62 +			
   13.63 +			# echo "$BASE_OF_EXE depends on $BASE"
   13.64 +			
   13.65 +			# Fix the paths using install_name_tool and then
   13.66 +			# call this function recursively for each dependency
   13.67 +			# of this library. 
   13.68 +			if [ $BASE_OF_EXE != $BASE ]; then
   13.69 +			
   13.70 +				# Fix the paths
   13.71 +				install_name_tool -id @executable_path/$BASE $EXEPATH/$BASE
   13.72 +				install_name_tool -change $i @executable_path/$BASE $EXEPATH/$BASE_OF_EXE
   13.73 +
   13.74 +				# Call this function (recursive) on
   13.75 +				# on each dependency of this library.
   13.76 +				copydeps $EXEPATH/$BASE
   13.77 +			fi
   13.78 +		fi
   13.79 +	done
   13.80 +}
   13.81 +
   13.82 +rm -f $EXEPATH/*
   13.83 +
   13.84 +# Copy the binary into the bundle. Use ../libtool to do this if it's
   13.85 +# available beacuse if $EXE_NAME was built with autotools, it will be
   13.86 +# necessary.  If ../libtool not available, just use cp to do the copy, but
   13.87 +# only if $EXE_NAME is a binary.
   13.88 +if [ -x ../libtool ]; then
   13.89 +	../libtool --mode=install cp $EXE_NAME $EXEPATH
   13.90 +else
   13.91 +	file -bI $EXE_NAME |grep binary
   13.92 +	if [ $? -ne 0 ]; then
   13.93 +		echo "There is no ../libtool and $EXE_NAME is not a binary."
   13.94 +		echo "I'm not sure what to do."
   13.95 +		exit 1
   13.96 +	else
   13.97 +		cp $EXE_NAME $EXEPATH
   13.98 +	fi
   13.99 +fi
  13.100 +copydeps $EXEPATH/$EXE_NAME
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/mac_support.cpp	Mon May 19 21:10:35 2014 +0200
    14.3 @@ -0,0 +1,134 @@
    14.4 +/*******************************
    14.5 + Mac support for HID Test GUI
    14.6 + 
    14.7 + Alan Ott
    14.8 + Signal 11 Software
    14.9 +
   14.10 + Some of this code is from Apple Documentation, most notably
   14.11 + http://developer.apple.com/legacy/mac/library/documentation/AppleScript/Conceptual/AppleEvents/AppleEvents.pdf 
   14.12 +*******************************/
   14.13 +
   14.14 +#include <Carbon/Carbon.h>
   14.15 +#include <fx.h>
   14.16 +
   14.17 +
   14.18 +extern FXMainWindow *g_main_window;
   14.19 +
   14.20 +static pascal OSErr HandleQuitMessage(const AppleEvent *theAppleEvent, AppleEvent 
   14.21 +									  *reply, long handlerRefcon) 
   14.22 +{
   14.23 +	puts("Quitting\n");
   14.24 +	FXApp::instance()->exit();
   14.25 +	return 0;
   14.26 +}
   14.27 +
   14.28 +static pascal OSErr HandleReopenMessage(const AppleEvent *theAppleEvent, AppleEvent 
   14.29 +									  *reply, long handlerRefcon) 
   14.30 +{
   14.31 +	puts("Showing");
   14.32 +	g_main_window->show();
   14.33 +	return 0;
   14.34 +}
   14.35 +
   14.36 +static pascal OSErr HandleWildCardMessage(const AppleEvent *theAppleEvent, AppleEvent 
   14.37 +									  *reply, long handlerRefcon) 
   14.38 +{
   14.39 +	puts("WildCard\n");
   14.40 +	return 0;
   14.41 +}
   14.42 +
   14.43 +OSStatus AEHandler(EventHandlerCallRef inCaller, EventRef inEvent, void* inRefcon) 
   14.44 +{ 
   14.45 +    Boolean     release = false; 
   14.46 +    EventRecord eventRecord; 
   14.47 +    OSErr       ignoreErrForThisSample; 
   14.48 +	
   14.49 +    // Events of type kEventAppleEvent must be removed from the queue 
   14.50 +    //  before being passed to AEProcessAppleEvent. 
   14.51 +    if (IsEventInQueue(GetMainEventQueue(), inEvent)) 
   14.52 +    { 
   14.53 +        // RemoveEventFromQueue will release the event, which will 
   14.54 +        //  destroy it if we don't retain it first. 
   14.55 +        RetainEvent(inEvent); 
   14.56 +        release = true; 
   14.57 +        RemoveEventFromQueue(GetMainEventQueue(), inEvent); 
   14.58 +    } 
   14.59 +    // Convert the event ref to the type AEProcessAppleEvent expects. 
   14.60 +    ConvertEventRefToEventRecord(inEvent, &eventRecord); 
   14.61 +    ignoreErrForThisSample = AEProcessAppleEvent(&eventRecord); 
   14.62 +    if (release) 
   14.63 +        ReleaseEvent(inEvent); 
   14.64 +    // This Carbon event has been handled, even if no AppleEvent handlers 
   14.65 +    //  were installed for the Apple event. 
   14.66 +    return noErr; 
   14.67 +}
   14.68 +
   14.69 +static void HandleEvent(EventRecord *event) 
   14.70 +{ 
   14.71 +	//printf("What: %d message %x\n", event->what, event->message);
   14.72 +	if (event->what == osEvt) {
   14.73 +		if (((event->message >> 24) & 0xff) == suspendResumeMessage) {
   14.74 +			if (event->message & resumeFlag) {
   14.75 +				g_main_window->show();				
   14.76 +			}
   14.77 +		}
   14.78 +	}
   14.79 +
   14.80 +#if 0
   14.81 +    switch (event->what) 
   14.82 +    { 
   14.83 +        case mouseDown: 
   14.84 +            //HandleMouseDown(event); 
   14.85 +            break; 
   14.86 +        case keyDown: 
   14.87 +        case autoKey: 
   14.88 +            //HandleKeyPress(event); 
   14.89 +            break; 
   14.90 +        case kHighLevelEvent: 
   14.91 +			puts("Calling ProcessAppleEvent\n");
   14.92 +            AEProcessAppleEvent(event); 
   14.93 +            break; 
   14.94 +    } 
   14.95 +#endif
   14.96 +} 
   14.97 +
   14.98 +void
   14.99 +init_apple_message_system()
  14.100 +{
  14.101 +	OSErr err;
  14.102 +	static const EventTypeSpec appleEvents[] = 
  14.103 +	{
  14.104 +		{ kEventClassAppleEvent, kEventAppleEvent }
  14.105 +	};
  14.106 +	
  14.107 +	/* Install the handler for Apple Events */
  14.108 +	InstallApplicationEventHandler(NewEventHandlerUPP(AEHandler), 
  14.109 +	              GetEventTypeCount(appleEvents), appleEvents, 0, NULL); 
  14.110 +
  14.111 +	/* Install handlers for the individual Apple Events that come
  14.112 +	   from the Dock icon: the Reopen (click), and the Quit messages. */
  14.113 +	err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, 
  14.114 +	              NewAEEventHandlerUPP(HandleQuitMessage), 0, false);
  14.115 +	err = AEInstallEventHandler(kCoreEventClass, kAEReopenApplication, 
  14.116 +	              NewAEEventHandlerUPP(HandleReopenMessage), 0, false);
  14.117 +#if 0
  14.118 +	// Left as an example of a wild card match.
  14.119 +	err = AEInstallEventHandler(kCoreEventClass, typeWildCard, 
  14.120 +	              NewAEEventHandlerUPP(HandleWildMessage), 0, false);
  14.121 +#endif
  14.122 +}
  14.123 +
  14.124 +void
  14.125 +check_apple_events()
  14.126 +{
  14.127 +	RgnHandle       cursorRgn = NULL; 
  14.128 +	Boolean         gotEvent=TRUE; 
  14.129 +	EventRecord     event; 
  14.130 +
  14.131 +	while (gotEvent) { 
  14.132 +		gotEvent = WaitNextEvent(everyEvent, &event, 0L/*timeout*/, cursorRgn); 
  14.133 +		if (gotEvent) { 
  14.134 +			HandleEvent(&event); 
  14.135 +		} 
  14.136 +	}
  14.137 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/mac_support.h	Mon May 19 21:10:35 2014 +0200
    15.3 @@ -0,0 +1,17 @@
    15.4 +/*******************************
    15.5 + Mac support for HID Test GUI
    15.6 + 
    15.7 + Alan Ott
    15.8 + Signal 11 Software
    15.9 + 
   15.10 +*******************************/
   15.11 +
   15.12 +#ifndef MAC_SUPPORT_H__
   15.13 +#define MAC_SUPPORT_H__
   15.14 +
   15.15 +extern "C" {
   15.16 +	void init_apple_message_system();
   15.17 +	void check_apple_events();
   15.18 +}
   15.19 +
   15.20 +#endif
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/mac_support_cocoa.m	Mon May 19 21:10:35 2014 +0200
    16.3 @@ -0,0 +1,94 @@
    16.4 +/*******************************
    16.5 + Mac support for HID Test GUI
    16.6 + 
    16.7 + Alan Ott
    16.8 + Signal 11 Software
    16.9 +*******************************/
   16.10 +
   16.11 +#include <fx.h>
   16.12 +#import <Cocoa/Cocoa.h>
   16.13 +
   16.14 +extern FXMainWindow *g_main_window;
   16.15 +
   16.16 +
   16.17 +@interface MyAppDelegate : NSObject
   16.18 +{
   16.19 +} 
   16.20 +@end
   16.21 +
   16.22 +@implementation MyAppDelegate
   16.23 +- (void) applicationWillBecomeActive:(NSNotification*)notif
   16.24 +{
   16.25 +	printf("WillBecomeActive\n");
   16.26 +	g_main_window->show();
   16.27 +
   16.28 +}
   16.29 +
   16.30 +- (void) applicationWillTerminate:(NSNotification*)notif
   16.31 +{
   16.32 +	/* Doesn't get called. Not sure why */
   16.33 +	printf("WillTerminate\n");
   16.34 +	FXApp::instance()->exit();
   16.35 +}
   16.36 +
   16.37 +- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication*)sender
   16.38 +{
   16.39 +	/* Doesn't get called. Not sure why */
   16.40 +	printf("ShouldTerminate\n");
   16.41 +	return YES;
   16.42 +}
   16.43 +
   16.44 +- (void) applicationWillHide:(NSNotification*)notif
   16.45 +{
   16.46 +	printf("WillHide\n");
   16.47 +	g_main_window->hide();
   16.48 +}
   16.49 +
   16.50 +- (void) handleQuitEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
   16.51 +{
   16.52 +	printf("QuitEvent\n");
   16.53 +	FXApp::instance()->exit();
   16.54 +}
   16.55 +
   16.56 +@end
   16.57 +
   16.58 +extern "C" {
   16.59 +
   16.60 +void
   16.61 +init_apple_message_system()
   16.62 +{
   16.63 +	static MyAppDelegate *d = [MyAppDelegate new];
   16.64 +
   16.65 +	[[NSApplication sharedApplication] setDelegate:d];
   16.66 +
   16.67 +	/* Register for Apple Events. */
   16.68 +	/* This is from
   16.69 +	   http://stackoverflow.com/questions/1768497/application-exit-event */
   16.70 +	NSAppleEventManager *aem = [NSAppleEventManager sharedAppleEventManager];
   16.71 +	[aem setEventHandler:d
   16.72 +	     andSelector:@selector(handleQuitEvent:withReplyEvent:)
   16.73 +	     forEventClass:kCoreEventClass andEventID:kAEQuitApplication];
   16.74 +}
   16.75 +
   16.76 +void
   16.77 +check_apple_events()
   16.78 +{
   16.79 +	NSApplication *app = [NSApplication sharedApplication];
   16.80 +
   16.81 +	NSAutoreleasePool *pool = [NSAutoreleasePool new];
   16.82 +	while (1) {
   16.83 +		NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
   16.84 +		                        untilDate:nil
   16.85 +                                        inMode:NSDefaultRunLoopMode
   16.86 +                                        dequeue:YES];
   16.87 +		if (event == NULL)
   16.88 +			break;
   16.89 +		else {
   16.90 +			//printf("Event happened: Type: %d\n", event->_type);
   16.91 +			[app sendEvent: event];
   16.92 +		}
   16.93 +	}
   16.94 +	[pool release];
   16.95 +}
   16.96 +
   16.97 +} /* extern "C" */
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/start.sh	Mon May 19 21:10:35 2014 +0200
    17.3 @@ -0,0 +1,2 @@
    17.4 +#!/bin/bash
    17.5 +xterm -e /Users/alan/work/hidapi/testgui/TestGUI.app/Contents/MacOS/tg
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/test.cpp	Mon May 19 21:10:35 2014 +0200
    18.3 @@ -0,0 +1,532 @@
    18.4 +/*******************************************************
    18.5 + Demo Program for HIDAPI
    18.6 + 
    18.7 + Alan Ott
    18.8 + Signal 11 Software
    18.9 +
   18.10 + 2010-07-20
   18.11 +
   18.12 + Copyright 2010, All Rights Reserved
   18.13 + 
   18.14 + This contents of this file may be used by anyone
   18.15 + for any reason without any conditions and may be
   18.16 + used as a starting point for your own applications
   18.17 + which use HIDAPI.
   18.18 +********************************************************/
   18.19 +
   18.20 +
   18.21 +#include <fx.h>
   18.22 +
   18.23 +#include "hidapi.h"
   18.24 +#include "mac_support.h"
   18.25 +#include <string.h>
   18.26 +#include <stdlib.h>
   18.27 +#include <limits.h>
   18.28 +
   18.29 +#ifdef _WIN32
   18.30 +	// Thanks Microsoft, but I know how to use strncpy().
   18.31 +	#pragma warning(disable:4996)
   18.32 +#endif
   18.33 +
   18.34 +class MainWindow : public FXMainWindow {
   18.35 +	FXDECLARE(MainWindow)
   18.36 +	
   18.37 +public:
   18.38 +	enum {
   18.39 +		ID_FIRST = FXMainWindow::ID_LAST,
   18.40 +		ID_CONNECT,
   18.41 +		ID_DISCONNECT,
   18.42 +		ID_RESCAN,
   18.43 +		ID_SEND_OUTPUT_REPORT,
   18.44 +		ID_SEND_FEATURE_REPORT,
   18.45 +		ID_GET_FEATURE_REPORT,
   18.46 +		ID_CLEAR,
   18.47 +		ID_TIMER,
   18.48 +		ID_MAC_TIMER,
   18.49 +		ID_LAST,
   18.50 +	};
   18.51 +	
   18.52 +private:
   18.53 +	FXList *device_list;
   18.54 +	FXButton *connect_button;
   18.55 +	FXButton *disconnect_button;
   18.56 +	FXButton *rescan_button;
   18.57 +	FXButton *output_button;
   18.58 +	FXLabel *connected_label;
   18.59 +	FXTextField *output_text;
   18.60 +	FXTextField *output_len;
   18.61 +	FXButton *feature_button;
   18.62 +	FXButton *get_feature_button;
   18.63 +	FXTextField *feature_text;
   18.64 +	FXTextField *feature_len;
   18.65 +	FXTextField *get_feature_text;
   18.66 +	FXText *input_text;
   18.67 +	FXFont *title_font;
   18.68 +	
   18.69 +	struct hid_device_info *devices;
   18.70 +	hid_device *connected_device;
   18.71 +	size_t getDataFromTextField(FXTextField *tf, char *buf, size_t len);
   18.72 +	int getLengthFromTextField(FXTextField *tf);
   18.73 +
   18.74 +
   18.75 +protected:
   18.76 +	MainWindow() {};
   18.77 +public:
   18.78 +	MainWindow(FXApp *a);
   18.79 +	~MainWindow();
   18.80 +	virtual void create();
   18.81 +	
   18.82 +	long onConnect(FXObject *sender, FXSelector sel, void *ptr);
   18.83 +	long onDisconnect(FXObject *sender, FXSelector sel, void *ptr);
   18.84 +	long onRescan(FXObject *sender, FXSelector sel, void *ptr);
   18.85 +	long onSendOutputReport(FXObject *sender, FXSelector sel, void *ptr);
   18.86 +	long onSendFeatureReport(FXObject *sender, FXSelector sel, void *ptr);
   18.87 +	long onGetFeatureReport(FXObject *sender, FXSelector sel, void *ptr);
   18.88 +	long onClear(FXObject *sender, FXSelector sel, void *ptr);
   18.89 +	long onTimeout(FXObject *sender, FXSelector sel, void *ptr);
   18.90 +	long onMacTimeout(FXObject *sender, FXSelector sel, void *ptr);
   18.91 +};
   18.92 +
   18.93 +// FOX 1.7 changes the timeouts to all be nanoseconds.
   18.94 +// Fox 1.6 had all timeouts as milliseconds.
   18.95 +#if (FOX_MINOR >= 7)
   18.96 +	const int timeout_scalar = 1000*1000;
   18.97 +#else
   18.98 +	const int timeout_scalar = 1;
   18.99 +#endif
  18.100 +
  18.101 +FXMainWindow *g_main_window;
  18.102 +
  18.103 +
  18.104 +FXDEFMAP(MainWindow) MainWindowMap [] = {
  18.105 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_CONNECT, MainWindow::onConnect ),
  18.106 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_DISCONNECT, MainWindow::onDisconnect ),
  18.107 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_RESCAN, MainWindow::onRescan ),
  18.108 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_SEND_OUTPUT_REPORT, MainWindow::onSendOutputReport ),
  18.109 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_SEND_FEATURE_REPORT, MainWindow::onSendFeatureReport ),
  18.110 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_GET_FEATURE_REPORT, MainWindow::onGetFeatureReport ),
  18.111 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_CLEAR, MainWindow::onClear ),
  18.112 +	FXMAPFUNC(SEL_TIMEOUT, MainWindow::ID_TIMER, MainWindow::onTimeout ),
  18.113 +	FXMAPFUNC(SEL_TIMEOUT, MainWindow::ID_MAC_TIMER, MainWindow::onMacTimeout ),
  18.114 +};
  18.115 +
  18.116 +FXIMPLEMENT(MainWindow, FXMainWindow, MainWindowMap, ARRAYNUMBER(MainWindowMap));
  18.117 +
  18.118 +MainWindow::MainWindow(FXApp *app)
  18.119 +	: FXMainWindow(app, "HIDAPI Test Application", NULL, NULL, DECOR_ALL, 200,100, 425,700)
  18.120 +{
  18.121 +	devices = NULL;
  18.122 +	connected_device = NULL;
  18.123 +
  18.124 +	FXVerticalFrame *vf = new FXVerticalFrame(this, LAYOUT_FILL_Y|LAYOUT_FILL_X);
  18.125 +
  18.126 +	FXLabel *label = new FXLabel(vf, "HIDAPI Test Tool");
  18.127 +	title_font = new FXFont(getApp(), "Arial", 14, FXFont::Bold);
  18.128 +	label->setFont(title_font);
  18.129 +	
  18.130 +	new FXLabel(vf,
  18.131 +		"Select a device and press Connect.", NULL, JUSTIFY_LEFT);
  18.132 +	new FXLabel(vf,
  18.133 +		"Output data bytes can be entered in the Output section, \n"
  18.134 +		"separated by space, comma or brackets. Data starting with 0x\n"
  18.135 +		"is treated as hex. Data beginning with a 0 is treated as \n"
  18.136 +		"octal. All other data is treated as decimal.", NULL, JUSTIFY_LEFT);
  18.137 +	new FXLabel(vf,
  18.138 +		"Data received from the device appears in the Input section.",
  18.139 +		NULL, JUSTIFY_LEFT);
  18.140 +	new FXLabel(vf,
  18.141 +		"Optionally, a report length may be specified. Extra bytes are\n"
  18.142 +		"padded with zeros. If no length is specified, the length is \n"
  18.143 +		"inferred from the data.",
  18.144 +		NULL, JUSTIFY_LEFT);
  18.145 +	new FXLabel(vf, "");
  18.146 +
  18.147 +	// Device List and Connect/Disconnect buttons
  18.148 +	FXHorizontalFrame *hf = new FXHorizontalFrame(vf, LAYOUT_FILL_X);
  18.149 +	//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);
  18.150 +	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);
  18.151 +	FXVerticalFrame *buttonVF = new FXVerticalFrame(hf);
  18.152 +	connect_button = new FXButton(buttonVF, "Connect", NULL, this, ID_CONNECT, BUTTON_NORMAL|LAYOUT_FILL_X);
  18.153 +	disconnect_button = new FXButton(buttonVF, "Disconnect", NULL, this, ID_DISCONNECT, BUTTON_NORMAL|LAYOUT_FILL_X);
  18.154 +	disconnect_button->disable();
  18.155 +	rescan_button = new FXButton(buttonVF, "Re-Scan devices", NULL, this, ID_RESCAN, BUTTON_NORMAL|LAYOUT_FILL_X);
  18.156 +	new FXHorizontalFrame(buttonVF, 0, 0,0,0,0, 0,0,50,0);
  18.157 +
  18.158 +	connected_label = new FXLabel(vf, "Disconnected");
  18.159 +	
  18.160 +	new FXHorizontalFrame(vf);
  18.161 +	
  18.162 +	// Output Group Box
  18.163 +	FXGroupBox *gb = new FXGroupBox(vf, "Output", FRAME_GROOVE|LAYOUT_FILL_X);
  18.164 +	FXMatrix *matrix = new FXMatrix(gb, 3, MATRIX_BY_COLUMNS|LAYOUT_FILL_X);
  18.165 +	new FXLabel(matrix, "Data");
  18.166 +	new FXLabel(matrix, "Length");
  18.167 +	new FXLabel(matrix, "");
  18.168 +
  18.169 +	//hf = new FXHorizontalFrame(gb, LAYOUT_FILL_X);
  18.170 +	output_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  18.171 +	output_text->setText("1 0x81 0");
  18.172 +	output_len = new FXTextField(matrix, 5, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  18.173 +	output_button = new FXButton(matrix, "Send Output Report", NULL, this, ID_SEND_OUTPUT_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
  18.174 +	output_button->disable();
  18.175 +	//new FXHorizontalFrame(matrix, LAYOUT_FILL_X);
  18.176 +
  18.177 +	//hf = new FXHorizontalFrame(gb, LAYOUT_FILL_X);
  18.178 +	feature_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  18.179 +	feature_len = new FXTextField(matrix, 5, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  18.180 +	feature_button = new FXButton(matrix, "Send Feature Report", NULL, this, ID_SEND_FEATURE_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
  18.181 +	feature_button->disable();
  18.182 +
  18.183 +	get_feature_text = new FXTextField(matrix, 30, NULL, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN);
  18.184 +	new FXWindow(matrix);
  18.185 +	get_feature_button = new FXButton(matrix, "Get Feature Report", NULL, this, ID_GET_FEATURE_REPORT, BUTTON_NORMAL|LAYOUT_FILL_X);
  18.186 +	get_feature_button->disable();
  18.187 +
  18.188 +
  18.189 +	// Input Group Box
  18.190 +	gb = new FXGroupBox(vf, "Input", FRAME_GROOVE|LAYOUT_FILL_X|LAYOUT_FILL_Y);
  18.191 +	FXVerticalFrame *innerVF = new FXVerticalFrame(gb, LAYOUT_FILL_X|LAYOUT_FILL_Y);
  18.192 +	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);
  18.193 +	input_text->setEditable(false);
  18.194 +	new FXButton(innerVF, "Clear", NULL, this, ID_CLEAR, BUTTON_NORMAL|LAYOUT_RIGHT);
  18.195 +	
  18.196 +
  18.197 +}
  18.198 +
  18.199 +MainWindow::~MainWindow()
  18.200 +{
  18.201 +	if (connected_device)
  18.202 +		hid_close(connected_device);
  18.203 +	hid_exit();
  18.204 +	delete title_font;
  18.205 +}
  18.206 +
  18.207 +void
  18.208 +MainWindow::create()
  18.209 +{
  18.210 +	FXMainWindow::create();
  18.211 +	show();
  18.212 +
  18.213 +	onRescan(NULL, 0, NULL);
  18.214 +	
  18.215 +
  18.216 +#ifdef __APPLE__
  18.217 +	init_apple_message_system();
  18.218 +#endif
  18.219 +	
  18.220 +	getApp()->addTimeout(this, ID_MAC_TIMER,
  18.221 +		50 * timeout_scalar /*50ms*/);
  18.222 +}
  18.223 +
  18.224 +long
  18.225 +MainWindow::onConnect(FXObject *sender, FXSelector sel, void *ptr)
  18.226 +{
  18.227 +	if (connected_device != NULL)
  18.228 +		return 1;
  18.229 +	
  18.230 +	FXint cur_item = device_list->getCurrentItem();
  18.231 +	if (cur_item < 0)
  18.232 +		return -1;
  18.233 +	FXListItem *item = device_list->getItem(cur_item);
  18.234 +	if (!item)
  18.235 +		return -1;
  18.236 +	struct hid_device_info *device_info = (struct hid_device_info*) item->getData();
  18.237 +	if (!device_info)
  18.238 +		return -1;
  18.239 +	
  18.240 +	connected_device =  hid_open_path(device_info->path);
  18.241 +	
  18.242 +	if (!connected_device) {
  18.243 +		FXMessageBox::error(this, MBOX_OK, "Device Error", "Unable To Connect to Device");
  18.244 +		return -1;
  18.245 +	}
  18.246 +	
  18.247 +	hid_set_nonblocking(connected_device, 1);
  18.248 +
  18.249 +	getApp()->addTimeout(this, ID_TIMER,
  18.250 +		5 * timeout_scalar /*5ms*/);
  18.251 +	
  18.252 +	FXString s;
  18.253 +	s.format("Connected to: %04hx:%04hx -", device_info->vendor_id, device_info->product_id);
  18.254 +	s += FXString(" ") + device_info->manufacturer_string;
  18.255 +	s += FXString(" ") + device_info->product_string;
  18.256 +	connected_label->setText(s);
  18.257 +	output_button->enable();
  18.258 +	feature_button->enable();
  18.259 +	get_feature_button->enable();
  18.260 +	connect_button->disable();
  18.261 +	disconnect_button->enable();
  18.262 +	input_text->setText("");
  18.263 +
  18.264 +
  18.265 +	return 1;
  18.266 +}
  18.267 +
  18.268 +long
  18.269 +MainWindow::onDisconnect(FXObject *sender, FXSelector sel, void *ptr)
  18.270 +{
  18.271 +	hid_close(connected_device);
  18.272 +	connected_device = NULL;
  18.273 +	connected_label->setText("Disconnected");
  18.274 +	output_button->disable();
  18.275 +	feature_button->disable();
  18.276 +	get_feature_button->disable();
  18.277 +	connect_button->enable();
  18.278 +	disconnect_button->disable();
  18.279 +
  18.280 +	getApp()->removeTimeout(this, ID_TIMER);
  18.281 +	
  18.282 +	return 1;
  18.283 +}
  18.284 +
  18.285 +long
  18.286 +MainWindow::onRescan(FXObject *sender, FXSelector sel, void *ptr)
  18.287 +{
  18.288 +	struct hid_device_info *cur_dev;
  18.289 +
  18.290 +	device_list->clearItems();
  18.291 +	
  18.292 +	// List the Devices
  18.293 +	hid_free_enumeration(devices);
  18.294 +	devices = hid_enumerate(0x0, 0x0);
  18.295 +	cur_dev = devices;	
  18.296 +	while (cur_dev) {
  18.297 +		// Add it to the List Box.
  18.298 +		FXString s;
  18.299 +		FXString usage_str;
  18.300 +		s.format("%04hx:%04hx -", cur_dev->vendor_id, cur_dev->product_id);
  18.301 +		s += FXString(" ") + cur_dev->manufacturer_string;
  18.302 +		s += FXString(" ") + cur_dev->product_string;
  18.303 +		usage_str.format(" (usage: %04hx:%04hx) ", cur_dev->usage_page, cur_dev->usage);
  18.304 +		s += usage_str;
  18.305 +		FXListItem *li = new FXListItem(s, NULL, cur_dev);
  18.306 +		device_list->appendItem(li);
  18.307 +		
  18.308 +		cur_dev = cur_dev->next;
  18.309 +	}
  18.310 +
  18.311 +	if (device_list->getNumItems() == 0)
  18.312 +		device_list->appendItem("*** No Devices Connected ***");
  18.313 +	else {
  18.314 +		device_list->selectItem(0);
  18.315 +	}
  18.316 +
  18.317 +	return 1;
  18.318 +}
  18.319 +
  18.320 +size_t
  18.321 +MainWindow::getDataFromTextField(FXTextField *tf, char *buf, size_t len)
  18.322 +{
  18.323 +	const char *delim = " ,{}\t\r\n";
  18.324 +	FXString data = tf->getText();
  18.325 +	const FXchar *d = data.text();
  18.326 +	size_t i = 0;
  18.327 +	
  18.328 +	// Copy the string from the GUI.
  18.329 +	size_t sz = strlen(d);
  18.330 +	char *str = (char*) malloc(sz+1);
  18.331 +	strcpy(str, d);
  18.332 +	
  18.333 +	// For each token in the string, parse and store in buf[].
  18.334 +	char *token = strtok(str, delim);
  18.335 +	while (token) {
  18.336 +		char *endptr;
  18.337 +		long int val = strtol(token, &endptr, 0);
  18.338 +		buf[i++] = val;
  18.339 +		token = strtok(NULL, delim);
  18.340 +	}
  18.341 +	
  18.342 +	free(str);
  18.343 +	return i;
  18.344 +}
  18.345 +
  18.346 +/* getLengthFromTextField()
  18.347 +   Returns length:
  18.348 +	 0: empty text field
  18.349 +	>0: valid length
  18.350 +	-1: invalid length */
  18.351 +int
  18.352 +MainWindow::getLengthFromTextField(FXTextField *tf)
  18.353 +{
  18.354 +	long int len;
  18.355 +	FXString str = tf->getText();
  18.356 +	size_t sz = str.length();
  18.357 +
  18.358 +	if (sz > 0) {
  18.359 +		char *endptr;
  18.360 +		len = strtol(str.text(), &endptr, 0);
  18.361 +		if (endptr != str.text() && *endptr == '\0') {
  18.362 +			if (len <= 0) {
  18.363 +				FXMessageBox::error(this, MBOX_OK, "Invalid length", "Enter a length greater than zero.");
  18.364 +				return -1;
  18.365 +			}
  18.366 +			return len;
  18.367 +		}
  18.368 +		else
  18.369 +			return -1;
  18.370 +	}
  18.371 +
  18.372 +	return 0;
  18.373 +}
  18.374 +
  18.375 +long
  18.376 +MainWindow::onSendOutputReport(FXObject *sender, FXSelector sel, void *ptr)
  18.377 +{
  18.378 +	char buf[256];
  18.379 +	size_t data_len, len;
  18.380 +	int textfield_len;
  18.381 +
  18.382 +	memset(buf, 0x0, sizeof(buf));
  18.383 +	textfield_len = getLengthFromTextField(output_len);
  18.384 +	data_len = getDataFromTextField(output_text, buf, sizeof(buf));
  18.385 +
  18.386 +	if (textfield_len < 0) {
  18.387 +		FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is invalid. Please enter a number in hex, octal, or decimal.");
  18.388 +		return 1;
  18.389 +	}
  18.390 +
  18.391 +	if (textfield_len > sizeof(buf)) {
  18.392 +		FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is too long.");
  18.393 +		return 1;
  18.394 +	}
  18.395 +
  18.396 +	len = (textfield_len)? textfield_len: data_len;
  18.397 +
  18.398 +	int res = hid_write(connected_device, (const unsigned char*)buf, len);
  18.399 +	if (res < 0) {
  18.400 +		FXMessageBox::error(this, MBOX_OK, "Error Writing", "Could not write to device. Error reported was: %ls", hid_error(connected_device));
  18.401 +	}
  18.402 +	
  18.403 +	return 1;
  18.404 +}
  18.405 +
  18.406 +long
  18.407 +MainWindow::onSendFeatureReport(FXObject *sender, FXSelector sel, void *ptr)
  18.408 +{
  18.409 +	char buf[256];
  18.410 +	size_t data_len, len;
  18.411 +	int textfield_len;
  18.412 +
  18.413 +	memset(buf, 0x0, sizeof(buf));
  18.414 +	textfield_len = getLengthFromTextField(feature_len);
  18.415 +	data_len = getDataFromTextField(feature_text, buf, sizeof(buf));
  18.416 +
  18.417 +	if (textfield_len < 0) {
  18.418 +		FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is invalid. Please enter a number in hex, octal, or decimal.");
  18.419 +		return 1;
  18.420 +	}
  18.421 +
  18.422 +	if (textfield_len > sizeof(buf)) {
  18.423 +		FXMessageBox::error(this, MBOX_OK, "Invalid length", "Length field is too long.");
  18.424 +		return 1;
  18.425 +	}
  18.426 +
  18.427 +	len = (textfield_len)? textfield_len: data_len;
  18.428 +
  18.429 +	int res = hid_send_feature_report(connected_device, (const unsigned char*)buf, len); 
  18.430 +	if (res < 0) {
  18.431 +		FXMessageBox::error(this, MBOX_OK, "Error Writing", "Could not send feature report to device. Error reported was: %ls", hid_error(connected_device));
  18.432 +	}
  18.433 +
  18.434 +	return 1;
  18.435 +}
  18.436 +
  18.437 +long
  18.438 +MainWindow::onGetFeatureReport(FXObject *sender, FXSelector sel, void *ptr)
  18.439 +{
  18.440 +	char buf[256];
  18.441 +	size_t len;
  18.442 +
  18.443 +	memset(buf, 0x0, sizeof(buf));
  18.444 +	len = getDataFromTextField(get_feature_text, buf, sizeof(buf));
  18.445 +
  18.446 +	if (len != 1) {
  18.447 +		FXMessageBox::error(this, MBOX_OK, "Too many numbers", "Enter only a single report number in the text field");
  18.448 +	}
  18.449 +
  18.450 +	int res = hid_get_feature_report(connected_device, (unsigned char*)buf, sizeof(buf));
  18.451 +	if (res < 0) {
  18.452 +		FXMessageBox::error(this, MBOX_OK, "Error Getting Report", "Could not get feature report from device. Error reported was: %ls", hid_error(connected_device));
  18.453 +	}
  18.454 +
  18.455 +	if (res > 0) {
  18.456 +		FXString s;
  18.457 +		s.format("Returned Feature Report. %d bytes:\n", res);
  18.458 +		for (int i = 0; i < res; i++) {
  18.459 +			FXString t;
  18.460 +			t.format("%02hhx ", buf[i]);
  18.461 +			s += t;
  18.462 +			if ((i+1) % 4 == 0)
  18.463 +				s += " ";
  18.464 +			if ((i+1) % 16 == 0)
  18.465 +				s += "\n";
  18.466 +		}
  18.467 +		s += "\n";
  18.468 +		input_text->appendText(s);
  18.469 +		input_text->setBottomLine(INT_MAX);
  18.470 +	}
  18.471 +	
  18.472 +	return 1;
  18.473 +}
  18.474 +
  18.475 +long
  18.476 +MainWindow::onClear(FXObject *sender, FXSelector sel, void *ptr)
  18.477 +{
  18.478 +	input_text->setText("");
  18.479 +	return 1;
  18.480 +}
  18.481 +
  18.482 +long
  18.483 +MainWindow::onTimeout(FXObject *sender, FXSelector sel, void *ptr)
  18.484 +{
  18.485 +	unsigned char buf[256];
  18.486 +	int res = hid_read(connected_device, buf, sizeof(buf));
  18.487 +	
  18.488 +	if (res > 0) {
  18.489 +		FXString s;
  18.490 +		s.format("Received %d bytes:\n", res);
  18.491 +		for (int i = 0; i < res; i++) {
  18.492 +			FXString t;
  18.493 +			t.format("%02hhx ", buf[i]);
  18.494 +			s += t;
  18.495 +			if ((i+1) % 4 == 0)
  18.496 +				s += " ";
  18.497 +			if ((i+1) % 16 == 0)
  18.498 +				s += "\n";
  18.499 +		}
  18.500 +		s += "\n";
  18.501 +		input_text->appendText(s);
  18.502 +		input_text->setBottomLine(INT_MAX);
  18.503 +	}
  18.504 +	if (res < 0) {
  18.505 +		input_text->appendText("hid_read() returned error\n");
  18.506 +		input_text->setBottomLine(INT_MAX);
  18.507 +	}
  18.508 +
  18.509 +	getApp()->addTimeout(this, ID_TIMER,
  18.510 +		5 * timeout_scalar /*5ms*/);
  18.511 +	return 1;
  18.512 +}
  18.513 +
  18.514 +long
  18.515 +MainWindow::onMacTimeout(FXObject *sender, FXSelector sel, void *ptr)
  18.516 +{
  18.517 +#ifdef __APPLE__
  18.518 +	check_apple_events();
  18.519 +	
  18.520 +	getApp()->addTimeout(this, ID_MAC_TIMER,
  18.521 +		50 * timeout_scalar /*50ms*/);
  18.522 +#endif
  18.523 +
  18.524 +	return 1;
  18.525 +}
  18.526 +
  18.527 +int main(int argc, char **argv)
  18.528 +{
  18.529 +	FXApp app("HIDAPI Test Application", "Signal 11 Software");
  18.530 +	app.init(argc, argv);
  18.531 +	g_main_window = new MainWindow(&app);
  18.532 +	app.create();
  18.533 +	app.run();
  18.534 +	return 0;
  18.535 +}