From ec4303a38f6e509646df8365326a4a293bdc7b33 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Mon, 19 Dec 2005 20:40:31 +0000 Subject: got the basic sketch working, but now I have to figure out the hid.dll nameclash issue... arg svn path=/trunk/externals/hcs/hid/; revision=4258 --- Makefile | 142 +++++++++++++++++++------ hid_windows.c | 337 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 448 insertions(+), 31 deletions(-) create mode 100755 hid_windows.c diff --git a/Makefile b/Makefile index be7e008..1013a3e 100644 --- a/Makefile +++ b/Makefile @@ -1,35 +1,76 @@ +TARGET=hid -OS_NAME = $(shell uname -s) +default: + make -C ../../ $(TARGET) +install: + make -C ../../ $(TARGET)_install -# ----------------------- GNU/LINUX i386 ----------------------- -ifeq ($(OS_NAME),Linux) -LDFLAGS = -export_dynamic -shared -.SUFFIXES: .pd_linux +clean: + make -C ../../ $(TARGET)_clean + + + +# this stuff below probably works, but its not maintained anymore since I use +# externals/Makefile + +CWD := $(shell pwd) + +# these are setup to be overridden by the packages/Makefile +cvs_root_dir = $(CWD)/../../.. +DESTDIR = $(CWD)/build/ +BUILDLAYOUT_DIR = $(cvs_root_dir)/packages + +include $(BUILDLAYOUT_DIR)/Makefile.buildlayout + +CFLAGS = $(OPT_FLAGS) -Wall -I./ -I../../../pd/src +LDFLAGS = +LIBS = -lm -all: input_arrays pd_linux -pd_linux: hid.pd_linux +#SRC = $(wildcard $(externals_src)/hcs/hid/hid*.c) +SRC = $(wildcard *.c) +SRC = input_arrays.c hid_$(OS_NAME).c +OBJ := $(SRC:.c=.o) + +# ----------------------- GNU/LINUX i386 ----------------------- +ifeq ($(OS_NAME),linux) + EXTENSION = pd_linux + LDFLAGS += -export_dynamic -shared + LIBS += -lc + STRIP = strip --strip-unneeded + hid.$(EXTENSION): input_arrays $(OBJ) +endif + +# ----------------------- Windows MinGW ----------------------- +ifeq ($(OS_NAME),win) + EXTENSION = dll + CFLAGS += -mms-bitfields + LDFLAGS += -shared + LIBS += -lhid -lsetupapi -L../../../pd/bin -lpd + STRIP = strip --strip-unneeded + hid.$(EXTENSION): input_arrays $(OBJ) endif # ----------------------- DARWIN ----------------------- -ifeq ($(OS_NAME),Darwin) -FRAMEWORKS = Carbon IOKit ForceFeedback -LDFLAGS = -bundle -bundle_loader $(PDEXECUTABLE) \ - -L/sw/lib -L./HID\ Utilities\ Source/build \ - -lHIDUtilities \ - $(patsubst %,-framework %,$(FRAMEWORKS)) -.SUFFIXES: .pd_darwin +ifeq ($(OS_NAME),darwin) + EXTENSION = pd_darwin + CFLAGS += -I./HID\ Utilities\ Source + PDEXECUTABLE = ../../../pd/bin/pd + FRAMEWORKS = Carbon IOKit ForceFeedback + LDFLAGS += -bundle -bundle_loader $(PDEXECUTABLE) + LIBS += -lc -L/sw/lib -L./HID\ Utilities\ Source/build \ + -lHIDUtilities $(patsubst %,-framework %,$(FRAMEWORKS)) + STRIP = strip -x + hid.$(EXTENSION): input_arrays hid_utilites $(OBJ) +endif -all: input_arrays hid_utilities pd_darwin -pd_darwin: hid.pd_darwin +all: hid.$(EXTENSION) -endif +.SUFFIXES: .$(EXTENSION) # ----------------------- GENERAL --------------------------------------------- -PDEXECUTABLE = ../../../pd/bin/pd - # generic optimization OPT_FLAGS = -O3 -ffast-math # G4 optimization on Mac OS X @@ -41,26 +82,65 @@ OPT_FLAGS = -O3 -ffast-math # faster G4 7450 optimization (gives errors) on Mac OS X #OPT_FLAGS = -ffast -mcpu=7450 -faltivec -ffast-math -fPIC -CFLAGS = $(OPT_FLAGS) -Wall -W -Wno-shadow -Wstrict-prototypes -Wno-unused +%.o: %.c + $(CC) $(CFLAGS) -o "$*.o" -c "$*.c" + +%.$(EXTENSION): %.o + $(CC) $(LDFLAGS) -o "$*.$(EXTENSION)" "$*.o" $(OBJ) $(LIBS) \ + `test -f $*.libs && cat $*.libs` \ + `test -f $(dir $*)../$(OS_NAME)/$(notdir $*).libs && \ + cat $(dir $*)../$(OS_NAME)/$(notdir $*).libs` + chmod a-x "$*.$(EXTENSION)" + $(STRIP) $*.$(EXTENSION) + rm -f -- $*.o -INCLUDE = -I./ -I../../../pd/src -I./HID\ Utilities\ Source -.c.o: - $(CC) $(CFLAGS) $(INCLUDE) -c *.c +input_arrays: input_arrays.c input_arrays.h -.o.pd_darwin: - $(CC) $(LDFLAGS) -o $*.pd_darwin *.o +input_arrays.c: linux/input.h + ./make-arrays-from-input.h.pl -.o.pd_linux: - ld $(LDFLAGS) -o $*.pd_linux *.o -lc -lm - strip --strip-unneeded $*.pd_linux +input_arrays.h: linux/input.h + ./make-arrays-from-input.h.pl -input_arrays: - test -f input_arrays.h || ./make-arrays-from-input.h.pl hid_utilities: test -f ./HID\ Utilities\ Source/build/libHIDUtilities.a || \ ( cd ./HID\ Utilities\ Source && pbxbuild ) -clean: ; rm -f *.pd_* *.o *~ input_arrays.? doc/ev*-list.pd +local_clean: + -rm -f -- *.$(EXTENSION) *~ + -find . -name '*.o' | xargs rm -f -- + +distclean: local_clean + -rm -f -- input_arrays.? doc/ev*-list.pd + +.PHONY: all input_arrays hid_utilities clean distclean + + +test_locations: + @echo "EXTENSION: $(EXTENSION)" + @echo "CFLAGS: $(CFLAGS)" + @echo "LDFLAGS: $(LDFLAGS)" + @echo "LIBS: $(LIBS)" + @echo "STRIP: $(STRIP)" + @echo " " + @echo "SRC: $(SRC)" + @echo "OBJ: $(OBJ)" + @echo " " + @echo "OS_NAME: $(OS_NAME)" + @echo "PD_VERSION: $(PD_VERSION)" + @echo "PACKAGE_VERSION: $(PACKAGE_VERSION)" + @echo "CWD $(CWD)" + @echo "DESTDIR $(DESTDIR)" + @echo "PREFIX $(prefix)" + @echo "BINDIR $(bindir)" + @echo "LIBDIR $(libdir)" + @echo "OBJECTSDIR $(objectsdir)" + @echo "PDDOCDIR $(pddocdir)" + @echo "LIBPDDIR $(libpddir)" + @echo "LIBPDBINDIR $(libpdbindir)" + @echo "HELPDIR $(helpdir)" + @echo "MANUALSDIR $(manualsdir)" + @echo "EXAMPLESDIR $(examplesdir)" diff --git a/hid_windows.c b/hid_windows.c new file mode 100755 index 0000000..da5060d --- /dev/null +++ b/hid_windows.c @@ -0,0 +1,337 @@ +#ifdef _WIN32 +/* + * Microsoft Windows DDK HID support for Pd [hid] object + * + * Copyright (c) 2004 Hans-Christoph All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + */ + +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#else +#include +#endif /* _MSC_VER */ +#include "hid.h" + +//#define DEBUG(x) +#define DEBUG(x) x + +/*============================================================================== + * GLOBAL VARS + *======================================================================== */ + +extern t_int hid_instance_count; + +/*============================================================================== + * FUNCTION PROTOTYPES + *============================================================================== + */ + + +/*============================================================================== + * Event TYPE/CODE CONVERSION FUNCTIONS + *============================================================================== + */ + + + + +/* ============================================================================== */ +/* WINDOWS DDK HID SPECIFIC SUPPORT FUNCTIONS */ +/* ============================================================================== */ + +void hid_get_device_by_number(t_int device_number) +{ + +} + + +void hid_build_element_list(t_hid *x) +{ + +} + +t_int hid_print_element_list(t_hid *x) +{ + DEBUG(post("hid_print_element_list");); + + + return (0); +} + +t_int hid_print_device_list(t_hid *x) +{ + struct _GUID GUID; + SP_INTERFACE_DEVICE_DATA DeviceInterfaceData; + struct {DWORD cbSize; char DevicePath[256];} FunctionClassDeviceData; + HIDD_ATTRIBUTES HIDAttributes; + SECURITY_ATTRIBUTES SecurityAttributes; + int i; + HANDLE PnPHandle, HIDHandle; + ULONG BytesReturned; + int Success, ManufacturerName, ProductName; + char ManufacturerBuffer[256]; + char ProductBuffer[256]; + const char NotSupplied[] = "NULL"; + DWORD lastError = 0; + +#if 0 +// Initialize the GUID array and setup the security attributes for Win2000 + HidD_GetHidGuid(&GUID); + SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + SecurityAttributes.lpSecurityDescriptor = NULL; + SecurityAttributes.bInheritHandle = FALSE; + +// Get a handle for the Plug and Play node and request currently active devices + PnPHandle = SetupDiGetClassDevs(&GUID, NULL, NULL, + DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); + + if ((int)PnPHandle == -1) + { + error("[hid] ERROR: Could not attach to PnP node\n"); + return (t_int) GetLastError(); + } + +// Lets look for a maximum of 32 Devices + for (i = 0; i < 32; i++) { +// Initialize our data + DeviceInterfaceData.cbSize = sizeof(DeviceInterfaceData); +// Is there a device at this table entry + Success = SetupDiEnumDeviceInterfaces(PnPHandle, NULL, &GUID, i, + &DeviceInterfaceData); + if (Success) { +// There is a device here, get it's name + FunctionClassDeviceData.cbSize = 5; + Success = SetupDiGetDeviceInterfaceDetail(PnPHandle, + &DeviceInterfaceData, + (PSP_INTERFACE_DEVICE_DETAIL_DATA)&FunctionClassDeviceData, + 256, &BytesReturned, NULL); + if (!Success) + { + error("[hid] ERROR: Could not find the system name for device %d\n",i); + return GetLastError(); + } +// Can now open this device + HIDHandle = CreateFile(FunctionClassDeviceData.DevicePath, + 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, + &SecurityAttributes, OPEN_EXISTING, 0, NULL); + lastError = GetLastError(); + if (HIDHandle == INVALID_HANDLE_VALUE) + { + error("[hid] ERROR: Could not open HID #%d, Errorcode = %d\n", i, (int)lastError); + return lastError; + } + +// Get the information about this HID + Success = HidD_GetAttributes(HIDHandle, &HIDAttributes); + if (!Success) + { + error("[hid] ERROR: Could not get HID attributes\n"); + return GetLastError(); + } + ManufacturerName = HidD_GetManufacturerString(HIDHandle, ManufacturerBuffer, 256); + ProductName = HidD_GetProductString(HIDHandle, ProductBuffer, 256); +// And display it! + post("[hid]: Device %d: %s %s\n",i, + ManufacturerName ? ManufacturerBuffer : NotSupplied, + ProductName ? ProductBuffer : NotSupplied); + post("\tVenderID = %4.4x, Name = ", HIDAttributes.VendorID); + post("%s\n", ManufacturerName ? ManufacturerBuffer : NotSupplied); + post("\tProductID = %4.4x, Name = ", HIDAttributes.ProductID); + post("%s\n", ProductName ? ProductBuffer : NotSupplied); + + CloseHandle(HIDHandle); + } // if (SetupDiEnumDeviceInterfaces . . + } // for (i = 0; i < 32; i++) + SetupDiDestroyDeviceInfoList(PnPHandle); +#endif + return 0; +} + +void hid_output_device_name(t_hid *x, char *manufacturer, char *product) +{ + char *device_name; + t_symbol *device_name_symbol; + + device_name = malloc( strlen(manufacturer) + 1 + strlen(product) + 1 ); +// device_name = malloc( 7 + strlen(manufacturer) + 1 + strlen(product) + 1 ); +// strcpy( device_name, "append " ); + strcat( device_name, manufacturer ); + strcat ( device_name, " "); + strcat( device_name, product ); +// outlet_anything( x->x_device_name_outlet, gensym( device_name ),0,NULL ); + outlet_symbol( x->x_device_name_outlet, gensym( device_name ) ); +} + +/* ------------------------------------------------------------------------------ */ +/* FORCE FEEDBACK FUNCTIONS */ +/* ------------------------------------------------------------------------------ */ + +/* cross-platform force feedback functions */ +t_int hid_ff_autocenter( t_hid *x, t_float value ) +{ + return ( 0 ); +} + + +t_int hid_ff_gain( t_hid *x, t_float value ) +{ + return ( 0 ); +} + + +t_int hid_ff_motors( t_hid *x, t_float value ) +{ + return ( 0 ); +} + + +t_int hid_ff_continue( t_hid *x ) +{ + return ( 0 ); +} + + +t_int hid_ff_pause( t_hid *x ) +{ + return ( 0 ); +} + + +t_int hid_ff_reset( t_hid *x ) +{ + return ( 0 ); +} + + +t_int hid_ff_stopall( t_hid *x ) +{ + return ( 0 ); +} + + + +// these are just for testing... +t_int hid_ff_fftest ( t_hid *x, t_float value) +{ + return ( 0 ); +} + + +void hid_ff_print( t_hid *x ) +{ +} + +/* ============================================================================== */ +/* Pd [hid] FUNCTIONS */ +/* ============================================================================== */ + +t_int hid_get_events(t_hid *x) +{ + //DEBUG(post("hid_get_events");); + + return (0); +} + + +t_int hid_open_device(t_hid *x, t_int device_number) +{ + DEBUG(post("hid_open_device");); + t_int result = 0; + + + return(result); +} + + +t_int hid_close_device(t_hid *x) +{ + DEBUG(post("hid_close_device");); + + t_int result = 0; + + return(result); +} + + +t_int hid_build_device_list(t_hid *x) +{ + DEBUG(post("hid_build_device_list");); + +/* + * The Windows DDK "hid.dll" has to be loaded manually because Windows gets + * confused by this object, which is also named "hid.dll". This is the first + * platform-specific function called in hid.c, so that's why this is happening + * here. + */ + TCHAR hidDllPath[MAX_PATH]; + UINT hidDllPathLength; + HMODULE hModule = NULL; + + hidDllPathLength = GetSystemDirectory(hidDllPath, MAX_PATH); + if( !hidDllPathLength ) + { + error("[hid] ERROR: cannot get SystemRoot"); + return 0; + } + strcat(hidDllPath,"\\hid.dll"); + post("hidDllPath: %s",hidDllPath); + hModule = LoadLibrary(hidDllPath); + if ( !hModule ) + { + error("[hid] ERROR: couldn't load %s: error %d",hidDllPath,GetLastError()); + return 0; + } + + return 1; +} + + +void hid_print(t_hid *x) +{ + hid_print_device_list(x); + + if(x->x_device_open) + { + hid_print_element_list(x); + hid_ff_print( x ); + } +} + + +void hid_platform_specific_free(t_hid *x) +{ + DEBUG(post("hid_platform_specific_free");); +/* only call this if the last instance is being freed */ + if (hid_instance_count < 1) + { + DEBUG(post("RELEASE ALL hid_instance_count: %d", hid_instance_count);); + } +} + + + + + + +#endif /* _WIN32 */ -- cgit v1.2.1