1# - try to find Windows HID support, part of the WDK/DDK
2#
3# Cache Variables: (probably not for direct use in your scripts)
4#  WINHID_INCLUDE_DIR
5#  WINHID_CRT_INCLUDE_DIR
6#  WINHID_LIBRARY
7#
8# Non-cache variables you might use in your CMakeLists.txt:
9#  WINHID_FOUND
10#  WINHID_INCLUDE_DIRS
11#  WINHID_LIBRARIES
12#
13# Requires these CMake modules:
14#  FindPackageHandleStandardArgs (known included with CMake >=2.6.2)
15#  PrefixListGlob
16#  CleanDirectoryList
17#  MinGWSearchPathExtras
18#  FindWindowsSDK
19#
20# Original Author:
21# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
22# http://academic.cleardefinition.com
23# Iowa State University HCI Graduate Program/VRAC
24#
25# Copyright Iowa State University 2009-2010.
26# Distributed under the Boost Software License, Version 1.0.
27# (See accompanying file LICENSE_1_0.txt or copy at
28# http://www.boost.org/LICENSE_1_0.txt)
29
30if(NOT WIN32)
31	find_package_handle_standard_args(WinHID
32		"Skipping search for Windows HID on non-Windows platform"
33		WIN32)
34	return()
35endif()
36
37if(MSVC)
38	if( (NOT WINHID_ROOT_DIR) AND (NOT ENV{DDKROOT} STREQUAL "") )
39		set(WINHID_ROOT_DIR "$ENV{DDKROOT}")
40	endif()
41endif()
42
43set(WINHID_ROOT_DIR
44	"${WINHID_ROOT_DIR}"
45	CACHE
46	PATH
47	"Directory to search")
48
49set(_deps_check)
50set(_need_crt_dir)
51if(MSVC)
52
53	find_package(WindowsSDK)
54	set(WINSDK_LIBDIRS)
55	if(WINDOWSSDK_FOUND)
56		get_windowssdk_library_dirs_multiple(WINSDK_LIBDIRS ${WINDOWSSDK_PREFERRED_FIRST_DIRS})
57		foreach(WINSDKDIR ${WINDOWSSDK_DIRS})
58			get_windowssdk_library_dirs(${WINSDKDIR} WINSDK_CURRENT_LIBDIRS)
59			list(APPEND WINSDK_LIBDIRS ${WINSDK_CURRENT_LIBDIRS})
60		endforeach()
61	endif()
62
63	if(CMAKE_SIZEOF_VOID_P MATCHES "8")
64		set(_arch amd64) # what the architecture used to be called
65		set(_arch8 x64) # what the WDK for Win8+ calls this architecture
66	else()
67		set(_arch i386) # what the architecture used to be called
68		set(_arch8 x86) # what the WDK for Win8+ calls this architecture
69	endif()
70	include(PrefixListGlob)
71	include(CleanDirectoryList)
72	prefix_list_glob(_prefixed
73		"*/"
74		"$ENV{SYSTEMDRIVE}/WinDDK/"
75		"$ENV{ProgramFiles}/Windows Kits/"
76		"c:/WinDDK/")
77	clean_directory_list(_prefixed)
78	find_library(WINHID_LIBRARY
79		NAMES
80		hid
81		libhid
82		PATHS
83		"${WINHID_ROOT_DIR}"
84		${WINSDK_LIBDIRS}
85		${_prefixed}
86		PATH_SUFFIXES
87		"lib/w2k/${_arch}" # Win2k min requirement
88		"lib/wxp/${_arch}" # WinXP min requirement
89		"lib/wnet/${_arch}" # Win Server 2003 min requirement
90		"lib/wlh/${_arch}" # Win Vista ("Long Horn") min requirement
91		"lib/wlh/um/${_arch8}" # Win Vista ("Long Horn") min requirement
92		"lib/win7/${_arch}" # Win 7 min requirement
93		"lib/win7/um/${_arch8}" # Win 7 min requirement
94		"lib/win8/${_arch}" # Win 8 min requirement
95		"lib/win8/um/${_arch8}" # Win 8 min requirement
96		)
97	# Might want to look close to the library first for the includes.
98	if(WINHID_LIBRARY)
99		get_filename_component(WINHID_LIBRARY_DIR "${WINHID_LIBRARY}" PATH)
100		if(WINDOWSSDK_FOUND)
101			get_windowssdk_from_component("${WINHID_LIBRARY}" _USED_WINSDK)
102			set(WINHID_LIBRARY_FROM_WINDOWSSDK ON)
103			get_windowssdk_include_dirs(${_USED_WINSDK} WINHID_INCLUDE_HINTS)
104		endif()
105	endif()
106
107	find_library(WINHID_SETUPAPI_LIBRARY
108		NAMES
109		setupapi
110		HINTS
111		"${WINHID_LIBRARY_DIR}"
112		PATHS
113		"${WINHID_ROOT_DIR}"
114		${WINSDK_LIBDIRS}
115		${_prefixed}
116		PATH_SUFFIXES
117		"lib/w2k/${_arch}" # Win2k min requirement
118		"lib/wxp/${_arch}" # WinXP min requirement
119		"lib/wnet/${_arch}" # Win Server 2003 min requirement
120		"lib/wlh/${_arch}" # Win Vista ("Long Horn") min requirement
121		"lib/wlh/um/${_arch8}" # Win Vista ("Long Horn") min requirement
122		"lib/win7/${_arch}" # Win 7 min requirement
123		"lib/win7/um/${_arch8}" # Win 7 min requirement
124		"lib/win8/${_arch}" # Win 8 min requirement
125		"lib/win8/um/${_arch8}" # Win 8 min requirement
126		)
127
128	if(WINHID_LIBRARY AND NOT WINHID_LIBRARY_FROM_WINDOWSSDK)
129		set(_basedir "${WINHID_LIBRARY_DIR}")
130		set(_prevdir)
131		while(NOT IS_DIRECTORY "${_basedir}/lib" AND NOT (_basedir STREQUAL _prevdir))
132			set(_prevdir "${_basedir}")
133			get_filename_component(_basedir "${_basedir}/.." ABSOLUTE)
134		endwhile()
135
136		set(WINHID_INCLUDE_HINTS "${_basedir}")
137
138		if(EXISTS "${_basedir}/inc")
139			find_path(WINHID_CRT_INCLUDE_DIR # otherwise you get weird compile errors
140				NAMES
141				stdio.h
142				HINTS
143				"${_basedir}"
144				PATHS
145				"${WINHID_ROOT_DIR}"
146				PATH_SUFFIXES
147				inc/crt
148				NO_DEFAULT_PATH)
149			list(APPEND _deps_check WINHID_CRT_INCLUDE_DIR)
150			set(_need_crt_dir ON)
151		endif()
152	endif()
153	find_path(WINHID_INCLUDE_DIR
154		NAMES
155		hidsdi.h
156		HINTS
157		${WINHID_INCLUDE_HINTS}
158		PATHS
159		"${WINHID_ROOT_DIR}"
160		PATH_SUFFIXES
161		inc/ddk
162		inc/api
163		inc/w2k
164		inc/wxp
165		inc/wnet
166		include/shared)
167else()
168	# This is the non-MSVC path.
169	if(MINGW)
170		include(MinGWSearchPathExtras)
171
172		find_library(WINHID_LIBRARY
173			NAMES
174			libhid
175			HINTS
176			"${WINHID_ROOT_DIR}"
177			${MINGWSEARCH_LIBRARY_DIRS}
178			/mingw
179			PATH_SUFFIXES
180			lib
181			lib/w32api)
182		find_library(WINHID_SETUPAPI_LIBRARY
183			NAMES
184			libsetupapi
185			HINTS
186			"${WINHID_ROOT_DIR}"
187			${MINGWSEARCH_LIBRARY_DIRS}
188			/mingw
189			PATH_SUFFIXES
190			lib
191			lib/w32api)
192	else()
193		find_library(WINHID_LIBRARY
194			NAMES
195			hid
196			libhid
197			HINTS
198			"${WINHID_ROOT_DIR}"
199			/mingw
200			PATH_SUFFIXES
201			lib
202			lib/w32api)
203		find_library(WINHID_SETUPAPI_LIBRARY
204			NAMES
205			setupapi
206			libsetupapi
207			HINTS
208			"${WINHID_ROOT_DIR}"
209			/mingw
210			PATH_SUFFIXES
211			lib
212			lib/w32api)
213	endif()
214	find_path(WINHID_INCLUDE_DIR
215		NAMES
216		hidsdi.h
217		PATHS
218		"${WINHID_ROOT_DIR}"
219		${MINGWSEARCH_INCLUDE_DIRS}
220		/mingw
221		PATH_SUFFIXES
222		include/w32api/ddk
223		include/ddk
224		ddk)
225endif()
226
227include(FindPackageHandleStandardArgs)
228find_package_handle_standard_args(WinHID
229	DEFAULT_MSG
230	WINHID_LIBRARY
231	WINHID_SETUPAPI_LIBRARY
232	WINHID_INCLUDE_DIR
233	${_deps_check})
234
235if(WINHID_FOUND)
236	if(MSVC)
237		set(_winreq)
238		if(WINHID_LIBRARY MATCHES "[Ll]ib/w2k")
239			set(_winreq "Windows 2000")
240		elseif(WINHID_LIBRARY MATCHES "[Ll]ib/wxp")
241			set(_winreq "Windows XP")
242		elseif(WINHID_LIBRARY MATCHES "[Ll]ib/wnet")
243			set(_winreq "Windows Server 2003")
244		elseif(WINHID_LIBRARY MATCHES "[Ll]ib/wlh")
245			set(_winreq "Windows Vista")
246		elseif(WINHID_LIBRARY MATCHES "[Ll]ib/win7")
247			set(_winreq "Windows 7")
248		elseif(WINHID_LIBRARY MATCHES "[Ll]ib/win8")
249			set(_winreq "Windows 8")
250			set(_winreq_uncertain ON)
251		elseif(WINHID_LIBRARY MATCHES "[Ll]ib/winv6.3")
252			set(_winreq "Windows 8.1")
253			set(_winreq_uncertain ON)
254		elseif(WINHID_LIBRARY MATCHES "[Ll]ib/10.0")
255			set(_winreq "Windows 10")
256			set(_winreq_uncertain ON)
257		endif()
258		if(NOT "${WINHID_MIN_WINDOWS_VER}" STREQUAL "${_winreq}")
259			if(NOT WinHID_FIND_QUIETLY)
260				if(NOT _winreq)
261					message("Couldn't determine if the WINHID_LIBRARY would result in a minimum version compatibility requirement.")
262				elseif(_winreq_uncertain)
263					message(STATUS
264					"Found WINHID_LIBRARY in the Windows SDK for ${_winreq} , which may or may not affect minimum compatible Windows version.")
265				else()
266					message(STATUS
267						"Linking against WINHID_LIBRARY will enforce this minimum version: ${_winreq}")
268				endif()
269			endif()
270			set(WINHID_MIN_WINDOWS_VER "${_winreq}" CACHE INTERNAL "" FORCE)
271		endif()
272	endif()
273	set(WINHID_LIBRARIES "${WINHID_LIBRARY}" "${WINHID_SETUPAPI_LIBRARY}")
274	if(_need_crt_dir)
275		set(WINHID_INCLUDE_DIRS
276			"${WINHID_CRT_INCLUDE_DIR}"
277			"${WINHID_INCLUDE_DIR}")
278	else()
279		# Don't need that CRT include dir for WDK 8+
280		set(WINHID_INCLUDE_DIRS
281			"${WINHID_INCLUDE_DIR}")
282	endif()
283	mark_as_advanced(WINHID_ROOT_DIR)
284endif()
285
286mark_as_advanced(WINHID_INCLUDE_DIR
287	WINHID_CRT_INCLUDE_DIR
288	WINHID_LIBRARY)
289